我想在脚本中运行以下Insert`s的100个Insert语句。模式名称db1和db2必须在占位符变量SourceDatabase和TargetDatabase中使用。
DECLARE
SourceDatabase VARCHAR2(50) := 'DB1';
TargetDatabase VARCHAR2(50) := 'DB2';
BEGIN
Insert Into TargetDatabase.TableName (SELECT * FROM SourceDatabase.TableName);
Insert Into TargetDatabase.TableName (SELECT * FROM SourceDatabase.TableName);
Insert Into TargetDatabase.TableName (SELECT * FROM SourceDatabase.TableName);
...
Commit
END;
如何以Oracle接受此声明的动态方式编写它?
答案 0 :(得分:4)
你真的是指Oracle术语中的“数据库”吗?或者你的意思是“架构”?您发布的伪代码似乎假设SourceDatabase
和TargetDatabase
是单个数据库中的模式。如果您真的想表明它们是独立的数据库,则需要使用数据库链接来查询远程表。
假设你的意思是模式
DECLARE
l_src_schema varchar2(30) := 'Source';
l_dest_schema varchar2(30) := 'Destination';
l_sql_stmt varchar2(4000);
BEGIN
l_sql_stmt :=
'INSERT INTO ' || l_dest_schema || '.table_name ' ||
' SELECT * FROM ' || l_src_schema || '.table_name';
dbms_output.put_line( 'Preparing to execute: ' || l_sql_stmt;
execute immediate l_sql_stmt;
END;
请注意,在一个可以打印的单独变量中生成动态SQL语句通常是个好主意,因为这样可以更轻松地调试代码。否则,如果出现错误,则无法检索代码尝试执行的实际SQL语句。
答案 1 :(得分:2)
您必须使用execute immediate
。
DECLARE
SourceDatabase VARCHAR2(50) := 'DB1';
TargetDatabase VARCHAR2(50) := 'DB2';
BEGIN
execute immediate 'Insert Into '|| TargetDatabase || '.TableName
(SELECT *
FROM ' || SourceDatabase || '.TableName)';
...
commit;
END;
,或明确说明数据库名称。
begin
insert into DB2.TableName select * from DB1.TableName;
commit;
end;