2015-03-10 2 views
0

Я пишу монитор для DB2. У нас есть несколько версий, 9.7, 10.1, 10.5, и я хочу, чтобы монитор вызывал функции мониторинга. Они принимают форму «TABLE (процедура (сфера вызовов)):SQL на DB2, как правильно выполнить правильную функцию TABLE()?

  • 10,5 - Таблица (mon_get_database (-1))
  • 10.1 - Таблица (snap_get_db ('', -1))
  • 9,7 - ТАБЛИЦА (snap_get_db_v97 («», -1))

Я хочу, чтобы монитор для запуска любой версии и запросить версию и запустить правильный 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, например. Когда я запускаю версию монитора против DB 9.7, он работает:

SELECT (DAYS(current timestamp) - DAYS(last_backup)) 
     FROM sysibm.sysdummy1, TABLE(snap_get_db_v97('', -1)); 

возвращает 2, который является правильным Когда я пытаюсь поставить его в саз, он попадет в первую линию, не попадет в условии , пытается выполнить процедуру и не:

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" который является правильным, так что процедура v10.5 DB2.

Что мне не хватает и как это сделать в DB2?

ответ

1

Прежде всего, ваш код по-прежнему не зависит от версии. Оператор CREATE VARIABLE доступен только с версии 9.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