CSV 导出导致 ORA-01489
CSV exporting causing ORA-01489
我正在使用假脱机工具将数据从我的 Oracle 10g 数据库导出到 CSV 文件。但是在导出几行 184170 行之后,出现以下错误:
ERROR:
ORA-01489: result of string concatenation is too long
我的 table 中有一个字段 FIELD2,它是 VARCHAR2(4000 BYTE) 类型,我有一些包含 4000 个字符的行。
我的 select 请求如下:
select FIELD1 ||'|'||FIELD2 ||'|'||FIELD3 from table;
有没有不用截断 FIELD2 的解决方案?
所以问题是因为我的 select 请求太长了。下面是生成请求的函数:
create or replace FUNCTION build_select (
p_table_name IN VARCHAR2
)
RETURN VARCHAR2
AS
l_ret VARCHAR2 (32767);
BEGIN
FOR eachcol IN ( SELECT column_name, data_type
, LEAD (column_name)
OVER (
PARTITION BY table_name ORDER BY column_id
)
next_column
FROM all_tab_cols
WHERE table_name = p_table_name
ORDER BY column_id)
LOOP
IF eachcol.data_type = 'CLOB' THEN
l_ret := l_ret || 'dbms_lob.substr( '||eachcol.column_name||', 3000, 1 )'|| CASE WHEN eachcol.next_column IS NULL THEN NULL ELSE ' ||''|''||' END;
ELSE
l_ret := l_ret || eachcol.column_name|| CASE WHEN eachcol.next_column IS NULL THEN NULL ELSE ' ||''|''||' END;
END IF;
END LOOP;
IF l_ret IS NULL
THEN
raise_application_error (-20001, 'table ' || p_table_name || ' not found');
END IF;
l_ret := 'select ' || l_ret || ' from ' || p_table_name || ';';
RETURN l_ret;
END build_select;
你说
FIELD2, in my table which is of is VARCHAR2(4000 BYTE) and you have some rows which
contains 4000 char,
选择列为select field1,field2,field3
不会有问题。但是,因为您使用“|”将它们连接在一起,最终字符串超过 4000 个字符,这是 VARCHAR2
列的限制。因此,Oracle 会抛出错误,因为您甚至不能拥有隐式数据类型 VARCHAR2
超过 4000 个字符的别名列。
一种选择是使用
set colsep '|'
在您的 SQL* Plus 会话中,只需将其选择为
select field1,field2,field3 from yourtable
.
另一种选择是使用 TO_CLOB
函数将结果显式转换为 CLOB
。
select TO_CLOB(NULL)||FIELD1 ||'|'||FIELD2 ||'|'||FIELD3 from table;
我正在使用假脱机工具将数据从我的 Oracle 10g 数据库导出到 CSV 文件。但是在导出几行 184170 行之后,出现以下错误:
ERROR: ORA-01489: result of string concatenation is too long
我的 table 中有一个字段 FIELD2,它是 VARCHAR2(4000 BYTE) 类型,我有一些包含 4000 个字符的行。 我的 select 请求如下:
select FIELD1 ||'|'||FIELD2 ||'|'||FIELD3 from table;
有没有不用截断 FIELD2 的解决方案?
所以问题是因为我的 select 请求太长了。下面是生成请求的函数:
create or replace FUNCTION build_select (
p_table_name IN VARCHAR2
)
RETURN VARCHAR2
AS
l_ret VARCHAR2 (32767);
BEGIN
FOR eachcol IN ( SELECT column_name, data_type
, LEAD (column_name)
OVER (
PARTITION BY table_name ORDER BY column_id
)
next_column
FROM all_tab_cols
WHERE table_name = p_table_name
ORDER BY column_id)
LOOP
IF eachcol.data_type = 'CLOB' THEN
l_ret := l_ret || 'dbms_lob.substr( '||eachcol.column_name||', 3000, 1 )'|| CASE WHEN eachcol.next_column IS NULL THEN NULL ELSE ' ||''|''||' END;
ELSE
l_ret := l_ret || eachcol.column_name|| CASE WHEN eachcol.next_column IS NULL THEN NULL ELSE ' ||''|''||' END;
END IF;
END LOOP;
IF l_ret IS NULL
THEN
raise_application_error (-20001, 'table ' || p_table_name || ' not found');
END IF;
l_ret := 'select ' || l_ret || ' from ' || p_table_name || ';';
RETURN l_ret;
END build_select;
你说
FIELD2, in my table which is of is VARCHAR2(4000 BYTE) and you have some rows which contains 4000 char,
选择列为select field1,field2,field3
不会有问题。但是,因为您使用“|”将它们连接在一起,最终字符串超过 4000 个字符,这是 VARCHAR2
列的限制。因此,Oracle 会抛出错误,因为您甚至不能拥有隐式数据类型 VARCHAR2
超过 4000 个字符的别名列。
一种选择是使用
set colsep '|'
在您的 SQL* Plus 会话中,只需将其选择为
select field1,field2,field3 from yourtable
.
另一种选择是使用 TO_CLOB
函数将结果显式转换为 CLOB
。
select TO_CLOB(NULL)||FIELD1 ||'|'||FIELD2 ||'|'||FIELD3 from table;