我有一个场景,我的oracle
数据库有大约 20 个表,所有表都有一个名为itemId的索引字段。我想从所有 20 个表中复制具有 id(称为 101)的记录,并使用新的 id(称为 102)插入它们。我不想有 20 个或 20 个游标,functions/procedures
因为表列表将来可能会增长。帮助我以更好的方式实现这一目标。
问问题
430 次
1 回答
0
由于表的数量可能可变,因此您需要使用动态 SQL 来实现您的目标。像下面这样的东西应该会有所帮助:
DECLARE
l_insert_column_list VARCHAR2(4000);
l_select_column_list VARCHAR2(4000);
BEGIN
FOR table_rec IN (SELECT table_name
FROM user_tab_columns
WHERE UPPER(column_name) = 'ITEMID')
LOOP
l_insert_column_list := '';
l_select_column_list := '';
FOR col_rec IN (SELECT column_name
FROM user_tab_columns
WHERE table_name = table_rec.table_name)
LOOP
l_insert_column_list := l_insert_column_list || col_rec.column_name || ',';
IF UPPER(col_rec.column_name) = 'ITEMID' THEN
l_select_column_list := l_select_column_list || '102,';
ELSE
l_select_column_list := l_select_column_list || col_rec.column_name || ',';
END IF;
END LOOP;
l_insert_column_list := RTRIM(l_insert_column_list, ',');
l_select_column_list := RTRIM(l_select_column_list, ',');
EXECUTE IMMEDIATE 'INSERT INTO ' || table_rec.table_name || ' ('
|| l_insert_column_list || ') SELECT ' || l_select_column_list ||
' FROM ' || table_rec.table_name || ' WHERE ITEMID = 101';
END LOOP;
END;
/
这里的想法是使用user_tab_columns
数据字典视图列出所有具有ITEMID
列的表。然后,对于每个这样的表,我们使用user_tab_columns
列出表中的所有列,然后构建一个 SQL 字符串来复制数据。
我在这里做了一些假设:
您的所有表都在同一个模式中。如果不是,您可能需要使用
all_tab_columns
而不是user_tab_columns
,并将架构所有者包含在也使用table_rec
的 SQL 字符串中。table_rec.table_name
您的表名或列名都没有需要用双引号括起来的名称。(如果是这样,您必须调整 SQL 字符串以包含双引号。)
对于表中的所有列名,4000 个字符就足够了。(由于列名限制为 30 个字符,您需要超过 100 列才能触发此问题。)
在你让这个脚本在你的数据库上松动之前,我强烈建议你EXECUTE IMMEDIATE
用一个调用来替换,dbms_output.put_line
这样你就可以看到正在生成的 SQL 字符串。
于 2013-10-08T08:48:11.453 回答