Database DB2-在SQL PL中查询两个数据库
我需要比较两个不同DB2数据库实例中的数据。我们不允许成立联邦。我找到了关于如何指定远程数据库的数据加载的参考资料,也找到了关于如何指定数据库连接的参考资料,包括数据库名称、用户名等。理想情况下,我能够对一个数据库执行查询,然后使用SQL PL循环等逐个将其与第二个数据库进行比较。,或者作为单个大连接。我已经到了这样的地步,SQLPL脚本可以依次连接到这两个表,它会提示我输入这两个表的密码,但在我尝试查询表时,它只能识别第二个 我们尝试的是: 在开头添加两个不同的CONNECT语句 声明一个游标并指定数据库名称似乎只有在从一个数据库加载到另一个数据库时才起作用,这是我们试图避免的Database DB2-在SQL PL中查询两个数据库,database,db2,multiple-instances,Database,Db2,Multiple Instances,我需要比较两个不同DB2数据库实例中的数据。我们不允许成立联邦。我找到了关于如何指定远程数据库的数据加载的参考资料,也找到了关于如何指定数据库连接的参考资料,包括数据库名称、用户名等。理想情况下,我能够对一个数据库执行查询,然后使用SQL PL循环等逐个将其与第二个数据库进行比较。,或者作为单个大连接。我已经到了这样的地步,SQLPL脚本可以依次连接到这两个表,它会提示我输入这两个表的密码,但在我尝试查询表时,它只能识别第二个 我们尝试的是: 在开头添加两个不同的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行。事实上,无论第二个连接是什么,都是有效的。例如,如果连接到第二个,然后是连接到第一个,则第一个循环起作用,第二个循环表示。。。。。是一个未定义的名称。如果我先连接到第二个数据库,然后再连接到第二个数据库,那么第一个循环会抛出错误,我不会得到任何输出。SQL PL一次只能连接到一个数据库,这就是设计 在脚本示例中,第二个连接将首先关闭任何当前连接 联合使您可以像访问本地表一样访问远程表 如果阻止您使用联合,您的选项包括: 在本地实现远程表并复制数据 这可以通过从远程游标加载来完成。 然后可以使用SQL比较行,因为两个表都位于同一数据库中。 只有当您有足够的容量在同一个数据库中容纳两个表时,这才是可行的,尽管压缩在这方面会有所帮助 不使用SQL,而是使用其他工具 例如:根据数据量和数据类型,可以导出源/目标表 到平面文件并比较文件差异等。您还可以导出到管道并使用内存比较。 或者,您可以使用python、perl或任何脚本语言,在所有情况下在内存中分块进行比较 每个线程一次只能连接到一个数据库 使用第三方工具进行数据比较 如果使用嵌入式SQL,则type-2 connect提供了另一种可能性
在DB2forIBMi上,联邦仅通过DB2LUW框可用 但是,以下内容适用于DB2forIBMi
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语句;插入到本地计算机上的表中
您应该能够构建一个动态插入,它只是
set insertStmt = 'insert into lcltable
select field1, field2
from ' concat server_name concat table_name
concat ' fetch first 10 rows only with ur';
我不确定这是否能在DB2LUW上运行,但这是一个很好的机会。这正是我所担心的。我们的DBA熟悉向本地表进行复制,这是第一个建议;我们希望通过让我们动态地处理不同的数据子集,这个替代方案能够更顺利地工作。我们将采用最初的方法和/或请求某人允许我们加入联邦。