正如您很可能从下面的问题中推断出的那样,我通常是DB2的新手。我正试图使用IBMDataStudio编写我的第二个存储过程,但在尝试部署它时遇到了错误。存储过程的目的是在不同表的字段中搜索文本字符串。注意:代码不完整,在当前形式下没有用处。我正在尝试在执行过程中测试每一步。
以下是我迄今为止的所有代码:
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.
当我注释掉insert语句时,它部署得很好(当然,如果没有插入的能力,这个过程对我没有多大好处):
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.
有人能告诉我如何在表存在或不存在时部署此过程吗?
非常感谢,并让我知道还需要什么其他细节。此外,关于如何改进代码的建议也很好。
最简单的解决方案就是在编译过程之前创建该表,使其存在。如果您只是在编译过程之前手动运行createtable语句,那么就不会有问题。
评论员建议您应该使用Declare Global Temporary Table
,我同意这一点,因为您似乎将其用作临时表。然而,它实际上并不能解决您的特定问题,因为如果临时表在编译时不存在,过程仍然不会编译。所以,是的,使用一个临时表,但你仍然必须做同样的事情。
将insert
语句更改为动态SQL也是可行的,尽管这是一个丑陋的解决方案。这里没有必要,但有时是需要的。
可能有点晚,但最好的方法是用查询创建一个字符串,而不是直接使用查询,然后使用EXECUTE IMEDIATELY