我需要比较两个不同DB2数据库实例的数据。我们不允许设置联盟。我发现了如何指定远程数据库中的数据加载的引用,以及如何指定数据库连接的引用,包括数据库名称,用户名等。理想情况下,我可以对一个数据库执行查询,然后将其与第二个数据库是逐个(使用SQL PL循环等),或作为单个大型连接。我已经到了SQL PL脚本可以依次连接到每个脚本的位置(并且它提示我输入密码),但是当我尝试查询表时它只识别第二个。
我们尝试过:在开头添加两个不同的CONNECT语句。
声明游标并指定数据库名称(这似乎仅在从一个数据库加载到另一个数据库时才起作用,我们试图避免这种情况)。
set serveroutput on@
set sqlcompat DB2@
connect to first user myname@
connect to second user myname@
-- run command: db2 -td@ -vf test3.sql
begin
declare loop_counter int;
call dbms_output.enable(100000);
set loop_counter = 0;
FIRSTLOOP: for o as ord1 cursor for
select field1, field2 from first.firstschema.firsttable fetch first 10 rows only with ur
do
set loop_counter = loop_counter + 1;
call dbms_output.put_line('Field: '||field1||', other '||field2);
end for;
call dbms_output.put_line('End first program: ');
SECONDLOOP: for p as ord2 cursor for
select field1, field2 from second.secondschema.secondtable fetch first 10 rows only with ur
do
set loop_counter = loop_counter + 1;
call dbms_output.put_line('Field: '||field1||', other '||field2);
end for;
call dbms_output.put_line('After second call');
end@
理想情况下,两个游标循环中的每一个都会打印10行。实际上,无论哪个CONNECT完成第二个是有效的。例如,如果我连接到SECOND,然后连接到FIRST,第一个循环工作,第二个循环说“.....是一个未定义的名称”。如果我连接到FIRST然后连接到SECOND,第一个循环抛出错误,我没有输出。
SQL PL一次只能连接到一个数据库 - 这就是设计。
在脚本示例中,第二个连接将首先关闭所有当前连接。
联合允许您访问远程表,就像它们是本地的一样。
如果您无法使用联盟,则您的选项包括:
在IBM i的Db2上,联合仅可通过Db2 LUW框获得...
但是,以下适用于IBM i的Db2 ...
create or replace function myschema.myudtf ()
returns table (SERVER VARCHAR(18)
, as_of timestamp
, ORDINAL_POSITION INTEGER
, JOB_NAME VARCHAR(28)
, SUBSYSTEM VARCHAR(10)
, AUTHORIZATION_NAME VARCHAR(10)
, JOB_TYPE VARCHAR(3)
)
modifies SQL data
external action
not deterministic
language SQL
specific CHKAWSJOBS
begin
declare insertStmt varchar(1500);
declare global temporary table
GLOBAL_TEMP_MY_JOBS (
SERVER VARCHAR(18)
, as_of timestamp
, ORDINAL_POSITION INTEGER
, JOB_NAME VARCHAR(28)
, SUBSYSTEM VARCHAR(10)
, AUTHORIZATION_NAME VARCHAR(10)
, JOB_TYPE VARCHAR(3)
) with replace;
for systemLoop as systemsCursor cursor for
select * from table( values ('mysys1'),('mysys2'),('mysys3'))
as systems (server_Name)
do
set insertStmt =
' insert into GLOBAL_TEMP_MY_JOBS
select
current_server as server, current_timestamp as as_of
, ordinal_position, job_name, subsystem, authorization_name, job_type
from table(QSYS2.ACTIVE_JOB_INFO(
SUBSYSTEM_LIST_FILTER => ''MYSBS'')) X
where exists (select 1 from ' concat server_name concat '.sysibm.sysdummy1)';
execute immediate InsertStmt;
end for;
return select * from GLOBAL_TEMP_MY_JOBS;
end;
上面的示例比您的用例更复杂,我从远程系统上的UDTF中提取数据,诀窍是在where子句中使用3部分名称,这迫使DB运行整个select
语句远程机器;随着insert
进入本地机器的表。
您应该能够构建一个动态插入
set insertStmt = 'insert into lcltable
select field1, field2
from ' concat server_name concat table_name
concat ' fetch first 10 rows only with ur';
不确定这会对Db2 LUW有效,但是很有可能。