zoukankan      html  css  js  c++  java
  • VARCHAR2到底支持多长的字符?

    VARCHAR2使用说明:
    在表列中或者在PLSQL中操作该类型最大长度是4000字节;
    SELECT rpad('a', 32767, 'b') FROM DUAL;--PLSQL窗口执行,默认只截取了4000字节
    --如下可以看到,结果统计的长度只有4000
    SELECT length(rpad('a', 32767, 'b')) FROM DUAL;
    LENGTH(RPAD('A',32767,'B'))
    ---------------------------
       4000
       
    在存储过程或函数的变量该类型最大长度是32767,但是要注意,变量最长可以虽可达到32767,但不能对该变量做读取,
    函数的返回值也不能超过4000字节。
    CREATE OR REPLACE FUNCTION funny2 RETURN VARCHAR2 IS
      v_yct  VARCHAR2(32767);
      v_find VARCHAR2(1000);
    BEGIN
      v_yct := rpad('a', 32767, 'b');
      SELECT instr(v_yct, ',', 1) INTO v_find FROM dual;--由于v_yct的长度超过了4000字节
      RETURN v_find;
    END;
    如下执行该函数报错:
    SELECT funny2 FROM DUAL;
    提示:ORA-01460: 转换请求无法实现或不合理

    如果将函数中的v_yct改为只有4000个字节,则可成功执行该函数:
    CREATE OR REPLACE FUNCTION funny2 RETURN VARCHAR2 IS
      v_yct  VARCHAR2(32767);
      v_find VARCHAR2(1000);
    BEGIN
      v_yct := rpad('a', 4000, 'b');
      SELECT instr(v_yct, ',', 1) INTO v_find FROM dual;--改成4000字节
      RETURN v_find;
    END;

    但是函数中VARCHAR2类型长度为32767,可对该变量执行长度统计
    CREATE OR REPLACE FUNCTION funny2 RETURN VARCHAR2 IS
      v_yct  VARCHAR2(32767);
    BEGIN
      v_yct := rpad('a', 32767, 'b');
      RETURN length(v_yct);
    END;
    SQL> SELECT funny2 FROM DUAL;
    FUNNY2
    ---------------
    32767

    --如果函数返回的VARCHAR2类型超过了4000字节也会报错,如下所示:
    CREATE OR REPLACE FUNCTION funny2 RETURN VARCHAR2 IS
      v_yct  VARCHAR2(32767);
    BEGIN
      v_yct := rpad('a', 32767, 'b');
      /*SELECT instr(v_yct, ',', 1) INTO v_find FROM dual;*/
      RETURN v_yct;
    END;
    执行 SELECT funny2 FROM DUAL;
    提示:ORA-06502: PL/SQL: 数字或值错误

    --因此,如果函数如果返回值超过4000,可以使用CLOB类型替代,如下所示:
    CREATE OR REPLACE FUNCTION funny2 RETURN CLOB IS
      v_yct  CLOB;
    BEGIN
      v_yct := rpad('a', 32767, 'b');
      RETURN v_yct;
    END;

    引申:

    使用LONG的限制:
    1、每个表仅能有一个LONG列
    --创建带一个字段long型的表
    CREATE TABLE FFF (ID NUMBER,NAME LONG);
    --再增加一个long型后,提示:ORA-01754: 表只能包含一个 LONG 类型的列
    ALTER TABLE FFF ADD CODE LONG;

    2、LONG列不能出现在完整性约束中(除了NULL和NOT   NULL约束)
    --比如主键约束,如下创建long型字段为主键的话提示:ORA-02269: 关键字列不能是 LONG 数据类型
    DROP TABLE FFF;
    CREATE TABLE FFF (ID NUMBER,NAME LONG primary key);

    3、LONG列不能被索引
    CREATE TABLE FFF (ID NUMBER,NAME LONG);
    --如果在long型的字段上创建索引会提示:ORA-00997: 非法使用 LONG 数据类型
    CREATE INDEX INX_NAME ON FFF(NAME);

    4、存储函数不能返回LONG值
    --如下函数所示,返回long型,执行该函数会提示(ORA-00997: 非法使用 LONG 数据类型)
    CREATE OR REPLACE FUNCTION funny2 RETURN LONG IS
      v_yct  LONG;
    BEGIN
      v_yct := rpad('a', 32760, 'b');
      RETURN length(v_yct);
    END;

    5、LONG列不能出现在SQL语句的某些部分中:
    在SELECT语句中的 WHERE,GROUP BY,ORDER BY、CONNECT BY 子句或 DISTINCT 操作符中;
    SQL函数(如SUBSTR、INSTR);
    子查询或被集合操作符结合的查询中的选择列表;
    CREATE TABLE AS SELECT 语句中的选择列表若包含long型的字段则不能创建。

    INSERT INTO FFF SELECT OBJECT_ID,OBJECT_NAME FROM USER_OBJECTS WHERE ROWNUM<4;
    --如下查询均会提示:ORA-00997: 非法使用 LONG 数据类型
    SELECT * FROM FFF WHERE NAME='1';
    SELECT name FROM FFF GROUP BY name;
    SELECT * FROM FFF ORDER BY name;
    SELECT DISTINCT NAME FROM FFF;
    SELECT * FROM user_objects WHERE object_name IN (SELECT name FROM fff);
    SELECT name FROM fff UNION
    SELECT name FROM fff ;
    CREATE TABLE ffff AS SELECT * FROM fff;
    --如下查询提示:ORA-00932: 数据类型不一致: 应为NUMBER, 但却获得LONG
    SELECT substr(name,1,2) FROM fff;
    SELECT instr(name,'1') FROM fff;

    --long类型是不是存储字符的时候只能有32760个字节?如果将其加到32761就提示(ORA-06502: PL/SQL: 数字或值错误)
    CREATE OR REPLACE FUNCTION funny2 RETURN VARCHAR2 IS
      v_yct  LONG;
    BEGIN
      v_yct := rpad('a', 32760, 'b');
      RETURN length(v_yct);
    END;

    对于字符过长的字段或变量可以采用clob类型,一般不要使用long型。

  • 相关阅读:
    ZROI2018提高day5t1
    noi.ac day1t1 candy
    ARC102E Stop. Otherwise...
    TOP命令详解(负载情况)
    mysql 时间函数 时间转换函数
    maven编译时错误:无效的目标发行版
    jsp base路径
    mybatis typehandler
    终极解决方案 at org.apache.jsp.index_jsp._jspInit(index_jsp.java:22) 报空指针
    【转】 IntelliJ IDEA像Eclipse一样打开多个项目
  • 原文地址:https://www.cnblogs.com/lanzi/p/2089291.html
Copyright © 2011-2022 走看看