使用动态模式名​​称运行多个Insert语句

时间:2012-01-12 11:10:44

标签: sql oracle oracle10g

我想在脚本中运行以下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接受此声明的动态方式编写它?

2 个答案:

答案 0 :(得分:4)

你真的是指Oracle术语中的“数据库”吗?或者你的意思是“架构”?您发布的伪代码似乎假设SourceDatabaseTargetDatabase是单个数据库中的模式。如果您真的想表明它们是独立的数据库,则需要使用数据库链接来查询远程表。

假设你的意思是模式

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;