【问题标题】:Pass parameters dynamically to stored procedure将参数动态传递给存储过程
【发布时间】:2016-03-29 11:44:23
【问题描述】:

我正在尝试将值动态传递给 db2 中的以下存储过程,

CREATE OR REPLACE PROCEDURE E_Enquiry 
    (IN SourceQueue1 VARCHAR(30), IN ExceptionId1 Integer, IN EventSource1 VARCHAR(30) ) 
LANGUAGE SQL
DYNAMIC RESULT SETS 1
BEGIN 
    DECLARE C1 CURSOR WITH RETURN TO CLIENT FOR 
        select CreationTime 
        from Exception_Message 
        where (SourceQueue=SourceQueue1 or ExceptionId=ExceptionId1 or EventSource=EventSource1); 
    open c1; 
END;

我在 IBM Data Studio 3.1 中创建了这个存储过程。 在这里,我试图将参数动态传递给值 SourceQueue1、ExceptionId1 或 EventSource1。我的要求是,当至少传递上述参数之一时,该过程应该起作用。如果只传递了两个参数,它应该搜索这两个参数并检索数据。谁能给我一个解决这个问题的想法。 我正在尝试通过 Mule 数据库连接器调用它。

【问题讨论】:

  • 多个可选参数通常表示动态SQL。出于某种原因,这不是一种选择吗?您仍然希望将其准备为参数化以避免 SQL 注入,但只有三个参数会很容易编写(尤其是像这样)。

标签: stored-procedures dynamic db2 mule


【解决方案1】:

SQL 过程可以重载。制作一个同名不同参数的过程。然后根据您调用过程的方式,按名称和参数调用正确的过程。

为 exceptionid 重载一个 parm 过程的示例。

CREATE OR REPLACE PROCEDURE E_Enquiry 
    (IN ExceptionId1 Integer ) 
LANGUAGE SQL
DYNAMIC RESULT SETS 1
BEGIN 
    DECLARE C1 CURSOR WITH RETURN TO CLIENT FOR 
        select CreationTime 
        from Exception_Message 
        where (ExceptionId=ExceptionId1); 
    open c1; 
END;

【讨论】:

  • 嗨,丹尼,谢谢。我有以下疑问。这也适用于 DB2 吗?如果它有效,那么我是否需要从过程中删除 REPLACE 并重载它?
  • 在 DB2 中,重载的存储过程由参数的数量来解析,而不是它们的类型(或名称)。换句话说,不可能确定调用E_Enquiry(?) 的三个可能变体中的哪一个。
  • 即便如此,其中两个参数仍然具有相同的类型,因此无论如何都会模棱两可。
  • @mustaccio 我不知道 db2 重载过程是按参数计数的。感谢您的更新。
【解决方案2】:

除了@danny117 提供的超载答案...

根据您使用的 DB2 平台和版本,您可以为未传递的参数分配默认值。

使用 DB2 for IBM i 7.1 TR5 或更高版本,您需要执行以下操作

CREATE OR REPLACE PROCEDURE E_Enquiry 
    (IN SourceQueue1 VARCHAR(30) DEFAULT NULL
     , IN ExceptionId1 Integer DEFAULT NULL
     , IN EventSource1 VARCHAR(30) DEFAULT NULL) 

在调用时,你会使用这样的命名参数:

CALL E_ENQUIRY(ExceptionId1=>0201);

【讨论】:

  • 嗨,查尔斯,在添加 DEFAULT NULL 时,我可以看到它正在检查数据库中的空值。但我想要的是,如果我单独传递 SourceQueue1 和 ExceptionId1 的值,那么它应该检查这两个值并忽略 EventSource1。但是,如果我给出 DEFAULT NULL 它也在检查 EventSource1 的空值。请协助我。
  • 不应该。即使两个值都为 NULL,WHERE COL1 = MYVAL 也不会为真。此外,您正在对测试进行 ORing。也许您想要@mustaccio 答案中的WHERE 子句。
【解决方案3】:

光标的WHERE 子句的简单修改应该可以解决问题:

where 
 (SourceQueue=SourceQueue1 or SourceQueue1 is null) and 
 (ExceptionId=ExceptionId1 or ExceptionId1 is null) and 
 (EventSource=EventSource1 or EventSource1 is null)

【讨论】:

  • 当我读到它时,OP 希望能够CALL E_Enquiry('SOMEVAL'),因此他将需要重载名称或使用默认参数(如果可用)。
猜你喜欢
  • 2011-07-16
  • 2016-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-17
相关资源
最近更新 更多