【发布时间】:2013-08-26 12:02:16
【问题描述】:
问题:
我有一个包含 CLOB 的表,它是来自外部源的固定长度记录。其中位置 1-5 = fieldA,位置 6-12 = fieldB,等等。
我有另一个表 (LayoutDefinition) 定义了记录布局,其中
FieldName = 'fieldA'
FieldStart = 1
FieldLength = 5
FieldName = 'fieldB'
FieldStart = 6
FieldLength = 6
我需要从 CLOB 中检索数据并将其放入 %rowtype 变量中,例如“tableA_rec tableA%rowtype”。
我已经实现了一个使用大量 case 语句的例程,并且 LayoutDefiniton 表中每一行的循环将 CLOB 的区域移动到 tablea_rec 中的适当变量中;
CASE LayoutDefiniton.FieldName
WHEN 'fieldA' THEN tablea_rec.fieldA:= SUBSTR(inputClob,LayoutDefiniton.FieldStart,LayoutDefiniton.FieldLength);
WHEN 'fieldB' THEN tablea_rec.fieldB:= SUBSTR(inputClob,LayoutDefiniton.FieldStart,LayoutDefiniton.FieldLength);
这当然是非常低效的,因为我需要遍历我的布局,以便为每条记录挑选我的数据。
我想做的是创建一个动态 sql 选择语句,该语句将把表中的数据检索到适当的变量中。例如,如果它不是动态的,它可能看起来像;
select substr(inputCLOB,1,5), substr(inputCLOB,6,6) into FieldA, fieldB from CLOBTable;
这可以使用动态 SQL 来完成吗?
如果是这样,语法会是什么样子?
【问题讨论】:
-
您最初是如何获取数据的?它是在文件中交付的吗?如果是这样,您不应该将它放在 CLOB 中,而是使用外部表或 SQL*Loader。如果它是从另一个数据库收到的,请查看 DBMS_FILE_TRANSFER 和 DBMS_DATAPUMP...
-
它来自另一个使用 Oracle 的系统。我可以让其他系统将数据写入文件,然后使用 sql*loader 导入数据,但这需要手动干预以及性能损失。 CLOB 超过 20,000 字节,包含数百个字段。
-
如果它在另一个 Oracle 数据库中,那么我说您应该考虑 DBMS_DATAPUMP... 而不是 SQL*Loader。 20,000 字节真的没那么大,你已经在读取和传输数据了;我只是建议你以一种最终会给你一张漂亮的桌子的方式来做这件事。或者,您可以直接在数据库链接上插入?
-
对不起,它在同一个数据库的另一个模式中。另一个应用程序构建一个 CLOB,因为在大多数情况下,它会输出要在其他系统中使用的数据。我通过搜索他们的模式找到了 CLOB。我不想导出数据并重新导入它,而是想从 CLOB 中获取数据并将其放入我架构中表的适当列中。
-
其他应用程序永远不会以 CLOB 以外的任何其他格式保存数据。