我该如何在SQuirreL SQL中调用带有OUT参数的DB2存储过程?

7

我非常喜欢SQuirreL SQL作为SQL查询工具,但我从未能够让它调用我们AS/400 DB2数据库中的存储过程。我总是会收到错误消息“设置或注册的参数值数量与参数数量不匹配”。我已经仔细检查了参数数量,但没有成功。这是我尝试过的一个带有一个IN和一个OUT参数的存储过程的语法:

call SOMESPROC(12345, ?);

9个回答

7

看起来SQuirrel目前无法在AS/400 DB2上完成该操作。

使用开源工具“SQL Workbench/J” (http://www.sql-workbench.net/),我能够调用存储过程:

wbcall SOMESPROC(12345, ?);

它拥有自己的调用过程命令"wbcall"。对于输出参数,请使用“?”。

注意:在安装SQL Workbench/J时,请确保从IBM下载正确的DB2驱动程序,并在将驱动程序添加到SQL Workbench/J中时添加许可文件。


谢谢,看起来很有效。我不能将其标记为已接受的答案,因为它在技术上并没有回答原始问题,但它是一个有用的答案,所以我投了赞成票。 - KC Baltz
1
@KC Baltz:为什么这不是针对原问题的正确答案呢?基本上答案就是:你不能。然后我只是作为奖励展示了一个替代方案 :-) - farbgeist

3
在Squirrel中,你可以像这样使用。你需要确保所声明的变量类型与你存储过程中的输出参数类型匹配。
BEGIN
    DECLARE outParam INT;
    STORED_PROC_NAME(outParam);
END

如果您需要为该过程提供输入,您可以这样做。
BEGIN
    DECLARE outParam INT;
    STORED_PROC_NAME('input', outParam);
END

你还需要将语句分隔符更改为除 ; 以外的其他内容。否则它会将语句分开并尝试单独发送每个片段。


1
对我不起作用! 松鼠SQL:3.5.0 错误信息: 错误:DB2 SQL错误:SQLCODE=-104,SQLSTATE=42601,SQLERRMC=NUMBER;DECLARE outParam ;END-OF-STATEMENT,DRIVER=3.53.95 SQLState: 42601 ErrorCode: -104 发生错误在: DECLARE outParam NUMBER - Ajay Gautam
同意。如果将Declare放在BEGIN之外,它会抱怨NUMBER不被期望。如果我将其移动到BEGIN内部,它会抱怨BEGIN不被期望。我将语句分隔符更改为#,也没有成功。我猜你的答案适用于除DB2/400之外的某些数据库。 - KC Baltz
我在这里进行了一些修复:1)DECLARE需要在块内部。2)只有在启用兼容性时,NUMBER才支持DB2的某些版本。3)语句后面的/是Oracle特定的。您需要更改Squirrel中的语句分隔符才能运行此语句。现在应该适用于DB2。 - user1919238
我通过将分隔符设置为#,并在存储过程名称前添加“CALL”,成功使其工作。但是,我无法查看结果集或输出参数,因此这对我来说仍不是一个有效的解决方案。 - KC Baltz

2
在DbVisualizer的专业版中,启用SQL Commander菜单选项下的“处理SQL中的过程参数标记”后,将允许使用“?”参数。
call SOMESPROC(12345, ?);

1

通过反复试验,我能够在Squirrel中看到结果。

create or replace variable var4 char(1);
create or replace variable var5 decimal(3,0);
create or replace variable var6 char(60);
call getthedata('XXX',123456789,'1234567',var4,var5,var6);
select var4,var5,var6 from sysibm.sysdummy1;  -- displays OUT parms

目前你的回答写得不够清楚。请[编辑]并添加更多细节,以帮助其他人了解这如何回答所提出的问题。你可以在帮助中心找到更多有关如何撰写良好答案的信息。 - Community

0

我认为如果有一个输入,那么调用应该是:

CALL SomeSProc(12345)

要获得结果,可以尝试:

SELECT * FROM SomeSProc(12345)

1
问题不在于获取结果。我想,上次我尝试执行没有任何OUT参数的存储过程时,结果就像直接查询一样返回了。问题在于处理OUT参数。 - KC Baltz
OUT参数不是存储过程的结果吗? - Leslie
不,它们不是同一件事。 存储过程可以通过三种方式之一生成输出:通过结果集、OUT参数和第三种方式(我将其称为返回值,不确定正确的名称)。 因此,您可能会有类似于以下内容的东西:?= GetListOfCheckedOutBooks(IN userID,OUT overdue)。 这可能会返回第一个?的某种标志,OUT参数中的布尔值表示用户是否至少有一本逾期图书,以及他们当前已经检出的所有书籍的结果集。 - KC Baltz

0
这是一个在Squirrel 3.7上使用db2存储过程测试通过的示例。诀窍是通过一个过渡性的存储过程MY_PROC_TEST来调用真正的存储过程PROC_TEST。
在Squirrel中更改语句分隔符:会话 > 会话属性 > SQL: @。
DROP PROCEDURE MY_PROC_TEST()@
CREATE PROCEDURE MY_PROC_TEST()
RESULT SETS 1 -- out resultset (call product)
LANGUAGE SQL
BEGIN
  DECLARE flag SMALLINT; -- out parameter
  CALL MY_PROC('2015', flag);
END @
CALL MY_PROC_TEST()@
END @

然后你可以像这样调用存储过程:

CALL MY_PROC_TEST()@


0

如果您更改分隔符(如上所述),则此代码将在Squirrel中运行。 但是,要查看变量是什么,您需要执行以下操作...

在我的示例中,我将把分隔符设置为波浪线(〜)。 在最后一个“end”之后,在“select”之前插入。 代码从这里开始...

begin
declare inoutParm numeric(2,0);
call spMyStoredProcedure(
             1234567                                     
           , inoutParm                                           
       );
declare global temporary table session.myTempTbl  
       (MyResult   char(1024) )                                         
with replace ;
insert into session.myTempTbl
  (myResult)
   values(inoutParm) ;  
end
~
select myResult from session.myTempTbl

Mic Keeley 作为AS400(DB2)SQL开发人员


我刚试图让它工作,但出现了错误:"Error: [SQL0101] SQL语句过长或过于复杂。SQLState: 54001 ErrorCode: -101"。 - KC Baltz

0

我能够将所有上述答案的一些混合物拼凑在一起,并想出了这个对我有效的解决方案。我正在使用Squirrel SQL 2018连接到IBM AS/400 DB2数据库。我确实需要声明一个语句分隔符,我使用了“#”。

    BEGIN
        DECLARE success CHAR(1); -- output parameters
        DECLARE message CHAR(300);
        SET success = ' '; 
        SET message = ' ';
        CALL myProc('some', 'params', 4, success, message); 
        DECLARE GLOBAL TEMPORARY TABLE session.myTmp(s_res CHAR(1), m_res CHAR(300)) WITH REPLACE; 
        INSERT INTO session.myTmp(s_res, m_res) VALUES(success, message);
    END
    # -- <- statement separator needs to be set to something other than ";" in this case it's set to "#"
    SELECT * FROM session.myTmp;

-2

在Squirrel > 会话 > 会话属性 > SQL中更改语句分隔符:'#'

BEGIN
    DECLARE inOutParam varchar(200);
    set inOutParam =  'a value';
    STORED_PROC_NAME(outParam);
END;
#

在调用存储过程时,未使用inOutParam。 - Tilo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接