如何部署一个DB2存储过程,该存储过程写入一个尚不存在的表(但是当它这样做时)?

时间:2016-01-13 15:35:04

标签: stored-procedures db2 ibm-data-studio

正如您很可能从以下问题中推断出的那样,我对DB2一般都是新手。我正在尝试使用IBM Data Studio编写我的第二个存储过程,并在尝试部署它时遇到错误。存储过程的要点是在不同表中的字段中搜索文本字符串。注意:代码不完整,在当前形式下无用。我试图在我进行测试的每一步。

以下是我目前所有的代码:

<div><table id='myDataTable'></table></div>

尝试部署时出现此错误:

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 

当我注释掉insert语句时,它部署得很好(但是当然,如​​果没有插入的能力,这个程序对我没什么用处):

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;

任何人都可以告诉我如何在表存在时,不存在时或两者都部署此过程吗?

非常感谢你,让我知道还需要什么其他细节。此外,关于如何改进代码的建议也很好。

2 个答案:

答案 0 :(得分:0)

最简单的解决方案就是创建该表,使其在编译过程之前存在。如果您只是在编译过程之前手动运行create table语句,那么就没有问题了。

评论者建议您使用Declare Global Temporary Table,我同意这一点,因为您似乎将此作为临时表使用。但是,它实际上并没有解决您的特定问题,因为如果在编译时临时表不存在,则仍然过程将无法编译。所以,是的,使用临时表,但你仍然需要做同样的事情。

insert语句更改为动态SQL也可以,但这是一个丑陋的解决方案。这里没有必要,但有时需要它。

答案 1 :(得分:0)

可能会有点迟,但最好的方法是使用您的查询创建一个字符串,而不是直接使用查询,然后立即使用EXECUTE