我正在为DB2编写监视器。我们有几个版本运行,9.7,10.1,10.5,我想要一个调用监视功能的监视器。它们采用" TABLE(过程(范围调用))的形式:
我希望监视器针对任何版本运行并查询版本并针对它运行正确的SQL我可以拉出版本:
SELECT FLOAT(PROD_RELEASE) FROM SYSIBMADM.ENV_PROD_INFO
where license_installed = 'Y' fetch first row only
当我运行它时,它会正确返回:
create variable dbVersion float;
set dbVersion = (SELECT FLOAT(PROD_RELEASE) FROM SYSIBMADM.ENV_PROD_INFO
where license_installed = 'Y' fetch first row only);
select dbVersion from sysibm.sysdummy1;
例如返回9.7。当我对数据库运行9.7版本的监视器时,它可以工作:
SELECT (DAYS(current timestamp) - DAYS(last_backup))
FROM sysibm.sysdummy1, TABLE(snap_get_db_v97('', -1));
返回2,这是正确的 当我尝试将它放入case语句时,它会命中第一行,错过条件,尝试执行该过程并失败:
set dbVersion = (SELECT FLOAT(PROD_RELEASE) FROM SYSIBMADM.ENV_PROD_INFO where license_installed = 'Y' fetch first row only);
select dbVersion from sysibm.sysdummy1; --this returns the correct version of DB2
create variable dbCommand varchar(256);
create variable dbBU float;
set dbBU=
case
when (SELECT PROD_RELEASE FROM SYSIBMADM.ENV_PROD_INFO
where license_installed like 'Y') = 10.5
then (SELECT (DAYS(current timestamp) - DAYS(last_backup))
FROM sysibm.sysdummy1, TABLE(mon_get_database(-1)))
when (SELECT FLOAT(PROD_RELEASE) FROM SYSIBMADM.ENV_PROD_INFO
where license_installed = 'Y' fetch first row only) >= 10.0
then (SELECT (DAYS(current timestamp) - DAYS(last_backup))
FROM sysibm.sysdummy1, TABLE(snap_get_db('', -1)))
when (SELECT FLOAT(PROD_RELEASE) FROM SYSIBMADM.ENV_PROD_INFO
where license_installed = 'Y' fetch first row only) = 9.7
then (SELECT (DAYS(current timestamp) - DAYS(last_backup))
FROM sysibm.sysdummy1, TABLE(snap_get_db_v97('', -1)))
when (SELECT FLOAT(PROD_RELEASE) FROM SYSIBMADM.ENV_PROD_INFO
where license_installed = 'Y' fetch first row only) = 9.5
then (SELECT (DAYS(current timestamp) - DAYS(last_backup))
FROM sysibm.sysdummy1, TABLE(snap_get_db_v95('', -1)))
when (SELECT FLOAT(PROD_RELEASE) FROM SYSIBMADM.ENV_PROD_INFO
where license_installed = 'Y' fetch first row only) = 9.1
then (SELECT (DAYS(current timestamp) - DAYS(last_backup))
FROM sysibm.sysdummy1, TABLE(snap_get_db_v91('', -1)))
else (SELECT (DAYS(current timestamp) - DAYS(last_backup))
FROM sysibm.sysdummy1, TABLE(snap_get_db('', -1)))
end;
select dbBU ;
commit work;
这从案例"No authorized routine named "MON_GET_DATABASE" of type "FUNCTION" having compatible arguments was found.. SQLCODE=-440, SQLSTATE=42884"
返回,这是正确的,因为那是DB2 v10.5过程。
我缺少什么以及如何在DB2中执行此操作?
答案 0 :(得分:1)
首先,您的代码仍然不依赖于版本。我相信,CREATE VARIABLE
语句仅在v9.7之后可用。
复合SQL语句中的所有语句都将在执行之前进行编译 - DB2 SQL PL不是解释语言,因此在遇到不存在的对象时始终无法编译。您必须使用动态SQL将编译推迟到运行时,例如:
begin
declare st varchar(1000);
declare rel float;
set rel = (SELECT FLOAT(PROD_RELEASE) FROM SYSIBMADM.ENV_PROD_INFO
where license_installed = 'Y' fetch first row only);
set st =
case
when rel = 10.5
then 'SELECT (DAYS(current timestamp) - DAYS(last_backup)) FROM TABLE(mon_get_database(-1))'
when rel >= 10.0
then 'SELECT (DAYS(current timestamp) - DAYS(last_backup)) FROM TABLE(snap_get_db('', -1))'
when rel = 9.7
then 'SELECT (DAYS(current timestamp) - DAYS(last_backup)) FROM TABLE(snap_get_db_v97('', -1))'
when rel = 9.5
then 'SELECT (DAYS(current timestamp) - DAYS(last_backup)) FROM TABLE(snap_get_db_v95('', -1))'
when rel = 9.1
then 'SELECT (DAYS(current timestamp) - DAYS(last_backup)) FROM TABLE(snap_get_db_v91('', -1))'
else 'SELECT (DAYS(current timestamp) - DAYS(last_backup)) FROM TABLE(snap_get_db('', -1))'
end;
prepare s from st;
execute s into dbBU;
end