Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Oracle将NCLOB数据解析为输出或新表_Sql_Oracle_Parsing - Fatal编程技术网

Sql Oracle将NCLOB数据解析为输出或新表

Sql Oracle将NCLOB数据解析为输出或新表,sql,oracle,parsing,Sql,Oracle,Parsing,我有一个名为LOOKUPTABLE的Oracle 11.2.0.4.0表,有3个字段 LOOKUPTABLEID号(12) LOOKUPTABLENM NVARCHAR2(255) LookuptableContentnClob NCLOB字段中的数据在插入时经过高度验证,因此我确信数据始终是一个逗号分隔的字符串,末尾有一个CRLF,因此读取时与简单的CSV文件完全相同。示例([CRLF]是实际CRLF的表示,而不是文本) “851,所有工时玻璃,G,0,,,,,,[CRLF]935,所有加班和

我有一个名为LOOKUPTABLE的Oracle 11.2.0.4.0表,有3个字段

LOOKUPTABLEID号(12)
LOOKUPTABLENM NVARCHAR2(255)
LookuptableContentnClob

NCLOB字段中的数据在插入时经过高度验证,因此我确信数据始终是一个逗号分隔的字符串,末尾有一个CRLF,因此读取时与简单的CSV文件完全相同。示例([CRLF]是实际CRLF的表示,而不是文本)

“851,所有工时玻璃,G,0,,,,,,[CRLF]935,所有加班和工时,G,0,,,,,,,[CRLF]934,所有带薪工时,G,0,,,,,,,,[CRLF]”

我基本上希望有一个查询,可以为CLOB中的每一行输出一行。我使用的应用程序将读取此SQL并将其写入文本文件,但它无法处理CLOB数据类型,并且我没有从SQL本身直接写入文件的选项。我必须有一个查询,可以产生这个结果,并允许我的应用程序写入文件。我确实有能力创建/编写我自己的表,这样一个将CLOB读入一个新表,然后在我的应用程序中从该表中选择的过程是可以接受的,如果这样做更好的话,它现在就在我的头上。下面是所需的输出,提前感谢您的帮助:)


这是一个普通问题“如何拆分字符串”的具体案例,有关此问题的详细信息,请参阅。在本例中,要拆分的分隔符不是逗号,而是CRLF,或
chr(10)| | chr(13)

下面是一个使用
regexp\u substr
的简单解决方案。这不是最快的解决方案,但在简单的场景中效果很好。如果您需要更好的性能,请参阅上面链接中带有递归CTE且没有regexp的版本

WITH lookuptable AS (
SELECT
1 AS LOOKUPTABLEID,
'CODES.TBL' AS LOOKUPTABLENM,
TO_NCLOB('851,ALL HOURS WORKED GLASS,G,0,,,,,,'||chr(10)||chr(13)||
         '935,ALL OT AND HW HRS,G,0,,,,,,'||chr(10)||chr(13)||
         '934,ALL PAID TIME,G,0,,,,,,'||chr(10)||chr(13)) AS LOOKUPTABLECONTENT
FROM dual
)
SELECT lookuptableid as id, to_char(regexp_substr(lookuptablecontent,'[^('||chr(13)||chr(10)||')]+', 1, level))
FROM lookuptable 
WHERE lookuptablenm='CODES.TBL'
connect by level <= regexp_count(lookuptablecontent, '[^('||chr(13)||chr(10)||')]+')
and PRIOR lookuptableid =  lookuptableid and PRIOR SYS_GUID() is not null -- needed if more than 1 source row  
order by lookuptableid, level
;
我的示例数据和格式使用@kfinity提供的链接中不带regexp的递归CTE
谢谢@kfinity。这些信息引导我找到了我的解决方案。正如您提到的,您的示例在如此简单和小的数据集上运行良好。我的NCLOB记录中有将近1500个CRLF,尽管速度非常慢。我使用递归CTE访问了您提到的链接和部分,没有regexp。我会用我的示例数据和布局发布这个方法,以防有人遇到这个示例。
1. 851,ALL HOURS WORKED GLASS,G,0,,,,,,
2. 935,ALL OT AND HW HRS,G,0,,,,,,
3. 934,ALL PAID TIME,G,0,,,,,,
WITH lookuptable AS (
SELECT
1 AS LOOKUPTABLEID,
'CODES.TBL' AS LOOKUPTABLENM,
TO_NCLOB('851,ALL HOURS WORKED GLASS,G,0,,,,,,'||chr(10)||chr(13)||
         '935,ALL OT AND HW HRS,G,0,,,,,,'||chr(10)||chr(13)||
         '934,ALL PAID TIME,G,0,,,,,,'||chr(10)||chr(13)) AS LOOKUPTABLECONTENT
FROM dual
)
SELECT lookuptableid as id, to_char(regexp_substr(lookuptablecontent,'[^('||chr(13)||chr(10)||')]+', 1, level))
FROM lookuptable 
WHERE lookuptablenm='CODES.TBL'
connect by level <= regexp_count(lookuptablecontent, '[^('||chr(13)||chr(10)||')]+')
and PRIOR lookuptableid =  lookuptableid and PRIOR SYS_GUID() is not null -- needed if more than 1 source row  
order by lookuptableid, level
;
id  r
1   851,ALL HOURS WORKED GLASS,G,0,,,,,,
1   935,ALL OT AND HW HRS,G,0,,,,,,
1   934,ALL PAID TIME,G,0,,,,,,
WITH lookuptable (lookuptableid, lookuptablenm, lookuptablecontent) AS (
  SELECT
    1,
    'CODES.TBL',
    TO_NCLOB('ID,NAME,TYPE,ISMONEYSW,EARNTYPE,EARNCODE,RATESW,NEGATIVESW,OVERRIDEID,DAILYSW'||chr(13)||chr(10)||
             '851,ALL HOURS WORKED GLASS,G,0,,,,,,'||chr(13)||chr(10)||
             '935,ALL OT AND HW HRS,G,0,,,,,,'||chr(13)||chr(10)||
             '934,ALL PAID TIME,G,0,,,,,,'
              )
   FROM dual
), CTE (lookuptableid, lookuptablenm, lookuptablecontent, startposition, endposition) AS (
  SELECT
    lookuptableid,
    lookuptablenm,
    lookuptablecontent,
    1,
    INSTR(lookuptablecontent, chr(13)||chr(10))
   FROM lookuptable
   WHERE lookuptablenm = 'CODES.TBL'
  UNION ALL
  SELECT
    lookuptableid,
    lookuptablenm,
    lookuptablecontent,
    endposition + 1,
    INSTR(lookuptablecontent, chr(13)||chr(10), endposition+1)
   FROM CTE
   WHERE endposition > 0
)
SELECT
  lookuptableid,
  lookuptablenm,
  SUBSTR(lookuptablecontent, startposition, DECODE(endposition, 0, LENGTH(lookuptablecontent) + 1, endposition) - startposition) AS lookuptablecontent
 FROM CTE
ORDER BY lookuptableid, startposition;