【发布时间】:2019-03-15 08:09:50
【问题描述】:
我有一个 SQL 表:
CREATE TABLE "text_files"
( "FILE_NAME" VARCHAR2(4000 BYTE),
"FILE_CONTENT" CLOB
);
我正在尝试运行以下查询:
WITH rsqfc ( file_content, line, rn, max_rn, nm1, prv, depth ) AS (
SELECT file_content,
REGEXP_SUBSTR( file_content, '.+?(' || CHR(10) || '|$)', 1, 1 ),
1,
REGEXP_COUNT( file_content, '.+?(' || CHR(10) || '|$)' ) - 1,
CASE SUBSTR( file_content, 1, 4 ) WHEN 'NM1*' THEN 1 ELSE 0 END,
CASE SUBSTR( file_content, 1, 4 ) WHEN 'PRV*' THEN 1 ELSE 0 END,
CASE SUBSTR( file_content, 1, 4 ) WHEN 'NM1*' THEN 1 WHEN 'PRV*' THEN 2 ELSE 0 END
FROM text_files
UNION ALL
SELECT file_content,
REGEXP_SUBSTR( file_content, '.+?(' || CHR(10) || '|$)', 1, rn + 1 ),
rn + 1,
max_rn,
CASE SUBSTR( REGEXP_SUBSTR( file_content, '.+?(' || CHR(10) || '|$)', 1, rn + 1 ), 1, 4 ) WHEN 'NM1*' THEN nm1 + 1 ELSE nm1 END,
CASE SUBSTR( REGEXP_SUBSTR( file_content, '.+?(' || CHR(10) || '|$)', 1, rn + 1 ), 1, 4 ) WHEN 'PRV*' THEN prv + 1 ELSE prv END,
CASE SUBSTR( REGEXP_SUBSTR( file_content, '.+?(' || CHR(10) || '|$)', 1, rn + 1 ), 1, 4 ) WHEN 'NM1*' THEN 1 WHEN 'PRV*' THEN 2 ELSE depth END
FROM rsqfc
WHERE rn < max_rn
)
SELECT CASE depth
WHEN 2 THEN '2010A' || CHR( 64 + prv )
WHEN 1 THEN '1000' || CHR( 64 + nm1 )
WHEN 0 THEN '000'
END AS "LOOP",
line
FROM rsqfc;
但是它给了
ORA-00932:不一致的数据类型:预期的 CLOB 得到 CHAR 错误
我了解我们不能将 CLOB 用于正则表达式和 where 子句。但是CLOB 中的内容超过 4000 个字符,当我尝试使用 VARCHAR2(4000) 字段更改表并将 CLOB 复制到新字段时,它不会复制。
它给了我
ORA-22835:缓冲区太小,无法进行 CLOB 到 CHAR 或 BLOB 到 RAW 转换(实际:4436,最大值:4000)
我无法将文本分成多个字段。我需要 1 个字段中的整个文本。
任何帮助将不胜感激。
【问题讨论】:
-
不是解决方案,但这里也讨论了stackoverflow.com/questions/7357999/…。必须是 SQL 还是可以使用 pl/sql?
-
应该是SQL。是否可以调整我的查询以支持它?
-
我不认为你能在一列中获得超过 4000 个字符。 pl/sql 会给你 32K。
-
但是您仍然可以创建一个 pl/sql 函数并从您的 select 语句中调用它。该函数将执行您的正则表达式处理,只要您不必返回超过 4000 个字节,您仍然可以使用 select 语句获取数据。这样可以吗?
-
好的,我们试试吧。