@ShannonSeverance在这个问题上得到了很好的答案
显示了如何将表中的行动态复制到同一个表(更改pk)
declare
r table_name%ROWTYPE;
begin
select *
into r
from table_name
where pk_id = "original_primary_key";
--
select pk_seq.nextval into r.pk_id from dual;
-- For 11g can use instead: r.pk_id := pk_seq.nextval;
r.fk_id := "new_foreign_key";
insert into table_name values r;
end;
我想应用这种方法但是在每次从表名数组中调用的函数中
所以基本上我可以使用execute immediate进行选择 - 但是如何声明'r'?我可以将代码中的'table_name'替换为传递给函数的变量吗?
table(1)="Table1";
table(2)="Table2";
for t 1..table.count loop
CopyTableContacts(table(i));
end loop;
TIA
麦克
答案 0 :(得分:0)
最后,我稍微修改了我的功能
我现在构建2个数组
1 - USER_TAB_COLUMNS表中的表名列表 2 - 对于array1中的每个表,我从ALL_TAB_COLUMNS表中构建一个逗号分隔的列名列表
所以我最终得到了2个数组(例子......)
tableName(1) = 'MEMBER'
tableName(2) = 'SALARY'
tableColumns(1) = 'ID, SURNAME, SEX, DOB'
tableColumns(2) = 'ID, CURRENTSAL, BONUS, GRADE'
然后我将这两个数组值传递给我的函数,并在循环tableName()数组期间使用一些动态SQL ...
PROCEDURE CopyTableRow(inOrigMemNo NUMBER, inNewMemNo NUMBER, inTableName USER_TAB_COLUMNS.TABLE_NAME%TYPE, inTableString LONG) AS
selectString VARCHAR2(32000):=null;
newTableString LONG:=null;
insertTableString LONG:=null;
sqlResultCount NUMBER:=0;
BEGIN
/*CHECK IF THERE IS AT LEAST ONE ROW TO COPY*/
EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || inTableName || ' WHERE ID= ' || inOrigMemNo INTO sqlResultCount;
IF sqlResultCount > 0 THEN
/*BUILD INSERT STATEMENT FOR EACH ROW RETURNED*/
dbms_output.put_line('At least one row found on ' || inTableName || '(' || sqlResultCount || ')');
newTableString := REPLACE(inTableString, 'ID', 'REPLACE(ID, ID,' || inNewMemNo || ')');
selectString := 'SELECT ' || newTableString || ' FROM ' || inTableName || ' WHERE ID = ' || inOrigMemNo;
insertTableString := 'INSERT INTO ' || inTableName || '(' || inTableString || ') (' || selectString || ')';
END IF;
然后我根据表定义和值执行INSERT语句
这似乎工作正常,适合我目前的需求
注意 - 仅当每个表只有一行要复制时才有效。我的下一个挑战是应对一些表,这些表为需要复制的ID返回多行(当我将自己画成非光标角时会很有趣!)
麦克