如何在DB2的where子句中使用动态AND或OR运算符?

时间:2019-03-18 12:43:02

标签: sql db2

DECLARE FILTER_DATA CURSOR WITH RETURN FOR
SELECT C_ID, C_NAME 
FROM DB2ADMIN.COURSES
WHERE C_ID = PARM_ID AND AND C_NAME = PARM_NAME

过程包含此游标,并且游标在AND子句中具有WHERE运算符,但我想根据过程参数使该运算符动态化。

以便光标根据ANDOR运算符返回结果集。

谢谢!

2 个答案:

答案 0 :(得分:1)

使用动态SQL。

begin
  ...  
  DECLARE FILTER_DATA CURSOR WITH RETURN FOR s1;

  CASE PARM_FLAG
    WHEN 1 THEN
      PREPARE S1 FROM 'SELECT C_ID, C_NAME FROM DB2ADMIN.COURSES WHERE C_ID = ? AND C_NAME = ?';
    ELSE
      PREPARE S1 FROM 'SELECT C_ID, C_NAME FROM DB2ADMIN.COURSES WHERE C_ID = ? OR C_NAME = ?';
  END CASE;

  OPEN FILTER_DATA USING PARM_ID, PARM_NAME;
end@

如果期望输入NULL参数,则可以对每个语句执行以下操作:

PREPARE S1 FROM 'SELECT C_ID, C_NAME FROM DB2ADMIN.COURSES WHERE '
||case when PARM_ID is null then 'cast(? as int) is null' else 'C_ID = ?' end
||' AND '
||case when PARM_NAME is null then 'cast(? as varchar(1)) is null' else 'C_NAME = ?' end;

答案 1 :(得分:1)

不要。

为每种可能的大小写/谓词(每种可能的where子句)准备/使用不同的SQL语句,并根据所获得的用户输入选择要使用的那个。

从技术上讲,写这样的东西是可以接受的

WHERE :PARM_ID IS NULL OR ID = :PARM_ID

WHERE (:CASE = 'OR' AND (C_1 OR C_2)) OR (:CASE = 'AND' AND (C_1 AND C_2))

,但是您很少有机会接受可接受的性能。 (几乎可以保证每次调用都进行全表扫描。)