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型。

posted on 2011-06-24 18:46  蓝紫  阅读(4842)  评论(0编辑  收藏  举报