我有一个由过程代码填充的数据临时表。
TABLE BatchRecord{
BatchRecordID NUMBER PRIMARY KEY,
BatchID NUMBER, --Assigned by the procedural code
RecordID NUMBER, --Relative to the batch
FieldID NUMBER, --Assigned by the procedural code; FK to another table
Value VARCHAR2(MAX)
Instance NUMBER}然后,需要将每个记录转换为三个相关的表: BatchRecord、RecordFields、FieldValues。
TABLE Record{
RecordID NUMBER PRIMARY KEY,
BatchID NUMBER, --Same from BatchRecords}
TABLE RecordFields{
RecordFieldID NUMBER PRIMARY KEY,
RecordID NUMBER, --FK from Records
FieldID NUNBER --Same from BatchRecords}
TABLE FieldValues{
RecordFieldID NUMBER PRIMARY KEY,
Instance NUMBER PRIMARY KEY, --Same from BatchRecords
Value VARCHAR2(MAX) --Same from BatchRecords}在SQL Server中,我可以使用一条MERGE语句并使用OUTPUT来捕获新插入的键:
CREATE TABLE #InsertedRecords(RecordID INT, NewRecordID INT);
MERGE INTO Records USING (
SELECT RecordID
FROM BatchRecords
WHERE BatchID = @BatchID
GROUP BY RecordID) AS BR ON 1 = 0
WHEN NOT MATCHED THEN
INSERT (BatchID)
VALUES (@BatchID)
OUTPUT BR.RecordID, INSERTED.RecordID INTO #InsertedRecords;插入RecordFields采用类似的方法,并使用INSERT...SELECT语句插入到FieldValues中。
但是,在Oracle中,不能在MERGE语句中使用RETURNING (等同于OUTPUT),甚至不能在SELECT...INTO语句中使用它。
有没有可能在Oracle中完成相同的任务,同时避免FORALL循环,因为BatchRecords的总数可能会超过几百万?
发布于 2014-11-27 03:48:36
您可以尝试使用oracle管道函数从BatchRecord中选择所有记录,然后将行通过管道传输到不同的表中。如果需要的话,我可以展示一个例子。
编辑
create or replace package test_pkg AS
TYPE REP_CURS IS REF CURSOR;
TYPE output_REC IS RECORD(
RecordID_ number,
BatchID_ number);
TYPE output_TAB IS TABLE OF output_REC;
FUNCTION Get_Data RETURN output_TAB
PIPELINED;
END test_pkg;
CREATE OR REPLACE PACKAGE BODY test_pkg IS
FUNCTION Get_Data RETURN output_TAB
PIPELINED IS
output_REC_ output_REC;
rep_lines_ REP_CURS;
stmt_ VARCHAR2(5000);
table_rec_ BatchRecord%ROWTYPE;
begin
stmt_ := ' (select BatchRecordID,BatchID ....Instance from BatchRecord) ';
OPEN rep_lines_ FOR stmt_;
LOOP
FETCH rep_lines_
INTO table_rec_;
EXIT WHEN rep_lines_%NOTFOUND;
output_REC_.RecordID_ := <<whatever valu that you want>;
output_REC_.BatchID_ := table_rec_.BatchID;
PIPE ROW(output_REC_);
END LOOP;
CLOSE rep_lines_;
RETURN;
exception
when others then
DBMS_OUTPUT.put_line('Error:' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE ||
DBMS_UTILITY.FORMAT_ERROR_STACK ||
DBMS_UTILITY.FORMAT_CALL_STACK);
END Get_Data;
END test_pkg;我已经展示了一个插入到记录中的示例。您也必须对其他两个表执行类似的操作。希望这能有所帮助!!
https://stackoverflow.com/questions/27157030
复制相似问题