2016-01-13 1 views
0

Как вы, скорее всего, вывели из следующего вопроса, я новичок в DB2 в целом. Я пытаюсь написать свою вторую хранимую процедуру, используя IBM Data Studio, и при попытке ее развернуть. Точкой хранимой процедуры является поиск текстовой строки в полях разных таблиц. ПРИМЕЧАНИЕ. Код не является полным и не является полезным в его текущей форме. Я пытаюсь проверить каждый шаг, когда я иду.Как я могу развернуть хранимую процедуру DB2, которая записывает в таблицу, которая еще не существует (но к моменту ее появления)?

Вот весь код, я до сих пор:

CREATE OR REPLACE PROCEDURE sp_find_string (in in_search_string varchar(200), in in_schema varchar(50)) 
    DYNAMIC RESULT SETS 1 
P1: BEGIN 
    -- ####################################################################### 
    -- # 
    -- ####################################################################### 
    declare table_a varchar(200); 
    declare colname varchar(200); 
    declare sqlcmd varchar(2000); 
    declare eof smallint default 0; 
    declare not_found condition for sqlstate '02000'; 

    -- Declare cursor 
    DECLARE cursor1 CURSOR WITH RETURN for 
     select tabname, colname from syscat.columns c 
     --inner join syscat.tables t on t.tabschema = c.tabschema 
     -- and t.tabname = c.tabname 
     where tabname like 'MERLIN%' 
     and tabschema = in_schema; 
    DECLARE CONTINUE HANDLER FOR SQLSTATE '42704' -- or SQLEXCEPTION 

    ------------------------------------------------- 
    if (exists 
      (
       select 1 from sysibm.systables 
       where creator = 'A2815' 
       and name = 'DBP_TEMP_SEARCH_RESULTS' 
      ) 
     ) then drop table A2815.DBP_TEMP_SEARCH_RESULTS; 
    end if; 

    create table A2815.DBP_TEMP_SEARCH_RESULTS 
    (text_to_match varchar(200) 
    ,table_a varchar(200) 
    ,colname varchar(200) 
    ,match_count bigint); 

    -- Cursor left open for client application 
    OPEN cursor1; 
     while eof = 0 do 
      p2: begin 
       declare continue handler for not_found set eof = 1; 
       fetch from cursor1 into table_a, colname; 
       insert into A2815.DPB_TEMP_SEARCH_RESULTS 
       values(table_a, colname); 
      end p2; 
     end while; 
    close cursor1; 
    --return; 

END P1 

Я получаю эту ошибку при попытке развернуть:

Deploy [TIO_D]A2815.SP_FIND_STRING(VARCHAR(200), VARCHAR(50)) 

Running 
A2815.SP_FIND_STRING - Deploy started. 
Create stored procedure returns SQLCODE: -204, SQLSTATE: 42704. 
A2815.SP_FIND_STRING: 44: "A2815.DPB_TEMP_SEARCH_RESULTS" is an undefined name.. SQLCODE=-204, SQLSTATE=42704, DRIVER=4.18.60 
"A2815.DPB_TEMP_SEARCH_RESULTS" is an undefined name.. SQLCODE=-204, SQLSTATE=42704, DRIVER=4.18.60 
A2815.SP_FIND_STRING - Deploy failed. 
A2815.SP_FIND_STRING - Roll back completed successfully. 

Когда я закомментируйте оператор вставки, развертывает просто (но, конечно, процедура не приносит мне много пользы без возможности ее вставки):

OPEN cursor1; 
     while eof = 0 do 
      p2: begin 
       declare continue handler for not_found set eof = 1; 
       fetch from cursor1 into table_a, colname; 
       --insert into A2815.DPB_TEMP_SEARCH_RESULTS 
       --values(table_a, colname); 
      end p2; 
     end while; 
    close cursor1; 

Верно, что таблица еще не существует, потому что она должна быть создана процедурой. Тем не менее, если я создаю таблицу затем развернуть процедуру я получаю эту ошибку:

Deploy [TIO_D]A2815.SP_FIND_STRING(VARCHAR(200), VARCHAR(50)) 

    Running 
    A2815.SP_FIND_STRING - Deploy started. 
    Create stored procedure returns SQLCODE: -601, SQLSTATE: 42710. 
    A2815.SP_FIND_STRING: 32: The name of the object to be created is identical to the existing name "A2815.DBP_TEMP_SEARCH_RESULTS" of type "TABLE".. SQLCODE=-601, SQLSTATE=42710, DRIVER=4.18.60 
    The name of the object to be created is identical to the existing name "A2815.DBP_TEMP_SEARCH_RESULTS" of type "TABLE".. SQLCODE=-601, SQLSTATE=42710, DRIVER=4.18.60 
    A2815.SP_FIND_STRING - Deploy failed. 
    A2815.SP_FIND_STRING - Roll back completed successfully. 

Может кто-нибудь сказать мне, как получить эту процедуру развернутой либо когда таблица существует, если она не существует, или оба?

Большое спасибо и дайте мне знать, какие еще детали необходимы. Кроме того, предложения по улучшению кода в целом также будут отличными.

+0

Смотрите, если это дает вам представление о том: http://dba.stackexchange.com/questions/126071/validation-of-views-even-though-auto-reval-is-set-to-deferred – mustaccio

+0

Лучшая идея - если ваша версия поддерживает ее, используйте ['DECLARE GLOBAL TEMPORARY TABLE'] (https://www-01.ibm.com/support/knowledgecenter/SSEPGG_9.7.0/com.ibm.db2.luw.sql.ref.doc/doc/r0003272.html). Ваша текущая процедура позволяет использовать одно только одно время (человек 2, используя эту процедуру, будет топать по всему лицу 1). Или, возможно, не сбрасывайтесь в временную таблицу и просто читайте исходный курсор: вам придется открыть вторую, чтобы прочитать точную информацию из вашего темпа. Не уверен, что вы планируете делать со всеми именами столбцов. –

+0

Спасибо за ответы @mustaccio и @ Clockwork-Muse. Я возвращаюсь к этому сегодня и буду исследовать оба ответа.Идея заключается в том, чтобы имитировать в конце концов, что делается в версии SQL Server этого показано здесь: 'набор @sqlcmd = 'вставить в temp_text_match (text_to_match, TABLE_A, ColName, match_count) \t \t \t выберите' + CHAR (39) + @ text_to_match + CHAR (39) + ',' + char (39) + @ table_a + CHAR (39) + ',' + char (39) + @ colname + CHAR (39) + ' \t , COUNT (*) от '+ @ TABLE_A + \t \t \t где '+ @ ColName +' как '+ полукокса (39) +' % '+ @ text_to_match +' %' + CHAR (39) \t печати @sqlcmd \t ехес (@sqlcmd) ' – dpberry178

ответ

0

Простым решением является просто создать этот стол так, чтобы он существовал до того, как вы скомпилируете процедуру. Если вы просто запускаете инструкцию create table вручную перед компиляцией процедуры, тогда проблем не будет.

Комментарители предложили вам использовать Declare Global Temporary Table, и я согласен с этим, так как вы, кажется, используете это как временную таблицу. Тем не менее, это фактически не решает вашу конкретную проблему, так как процедура еще не будет компилироваться, если временная таблица не существует во время компиляции. Итак, да, используйте временную таблицу, но вам все равно придется делать то же самое.

Замена оператора insert на динамический SQL также будет работать, хотя это уродливое решение. Здесь нет необходимости, но иногда это необходимо.

+0

Спасибо за отзыв nse @ dan1111. Я попытался развернуть эту процедуру с уже созданной таблицей, и это когда я получаю сообщение об ошибке «Имя создаваемого объекта идентично существующему имени». Я что-то не понимаю? – dpberry178

0

Может быть немного поздно, но лучший способ сделать это было бы создать строку с вашим запросом, вместо того чтобы использовать запрос непосредственно, а затем с помощью EXECUTE НЕМЕДЛЕННО