基于过程输入变量的条件 Where 子句 Oracle SQL

Posted

技术标签:

【中文标题】基于过程输入变量的条件 Where 子句 Oracle SQL【英文标题】:Conditional Where Clause Oracle SQL based on procedure input varaible 【发布时间】:2015-10-06 21:30:13 【问题描述】:

我有一个带有输入变量的 plsql 过程。这个变量 (my_plsql_var) 我需要决定我的 select 语句的 where 子句。如果我的变量是 A,那么我需要查询特定的 where 子句,如果是 B,它使用特定的 where 子句,C 也是如此。我尝试了一些查询,但它们不起作用。我得到的最接近的是这个,但似乎存在语法错误,甚至不确定查询是否会产生我需要的内容。

SELECT ID, 
    CASE(CAST WHEN my_col1 in ('A') and my_col2 = 'A' then 'A GROUP'
                             WHEN my_col1 in ('B') and my_col2 = 'B' then 'B GROUP'
                             WHEN my_col1 in ('C') and my_col2 = 'C' then 'C GROUP'
                             else null
        end as varachar2)) as my_awesome_col
        FROM
        my_table
        WHERE
        id= 100 and
        name = 'Smith' and 
        CASE (WHEN my_plsql_var = 'A' then my_col1 in ('A') and my_col2 = 'A'
             WHEN my_plsql_var = 'B' then my_col1 in ('B') and my_col2 = 'B' and my_special_col = 'B'
             WHEN my_plsql_var = 'C' then my_col1 in ('C') and my_col2 = 'C'
        end as varachar2)

【问题讨论】:

【参考方案1】:

这不能简单地简化成这样吗?

SELECT ID,
    my_plsql_var || ' GROUP' AS Group
FROM my_table
WHERE ID = 100
    AND NAME = 'Smith'
    AND (
           (my_plsql_var = 'A' AND my_col1 IN ('A') AND my_col2 = 'A')
        OR (my_plsql_var = 'B' AND my_col1 IN ('B') AND my_col2 = 'B' AND my_special_col = 'B')
        OR (my_plsql_var = 'C' AND my_col1 IN ('C') AND my_col2 = 'C')
    );

【讨论】:

【参考方案2】:

最好的办法是使用动态 SQL...

在字符串中构建您的 select 语句,然后使用 execute immediate 来运行查询,如下所示。下面的代码未经测试,因此可能存在一些语法错误,但应该让您了解如何执行此操作。否则谷歌动态 SQL。

my_sql_string := 'SELECT ID, 
                  CASE(CAST WHEN my_col1 in (''A'') and my_col2 = ''A'' then ''A GROUP'' 
                       WHEN my_col1 in (''B'') and my_col2 = ''B'' then ''B GROUP''
                       WHEN my_col1 in (''C'') and my_col2 = ''C'' then ''C GROUP''
                       else null
        end as varachar2)) as my_awesome_col
        FROM
        my_table
        WHERE
        id= 100 and
        name = ''Smith'' and ';

 if my_plsql_var = 'A' then
  my_sql_string := my_sql_string || 'my_col1 in (''A'') and my_col2 = ''A''';
 else if my_plsql_var = 'B' then 
  my_sql_string := my_sql_string || 'my_col1 in (''B'') and my_col2 = ''B''';
 else if my_plsql_var = 'C' then
  my_sql_string := my_sql_string || my_col1 in (''C'') and my_col2 = ''C''';
 end if;
v_output := execute immediate my_sql_string;

【讨论】:

【参考方案3】:

您需要评估您的输入并动态构建......

不确定你想让这个过程做什么,但这个只是打开一个引用光标,大概你会用它做点什么。

希望这会有所帮助。

    create or replace procedure my_plsql_procedure
    (
        my_plsql_var in varchar2
    )
    is
        dataset sys_refcursor;
        strSql CLOB;
        strPred VARCHAR2(500);
        bAddOtherPred boolean := my_plsql_var = 'B';
    begin
        if bAddOtherPred then
            strPred :=  q'~ and my special_col = 'B' ~';
        else
            strPred := null;
        end if;

        strSql := q'~ 
            select id,
                   CASE when my_col1 = myCol2 and my_col1 = 'A' THEN 'A GROUP'
                        when my_col1 = myCol2 and my_col1 = 'B' THEN 'B GROUP'
                        when my_col1 = myCol2 and my_col1 = 'C' THEN 'C GROUP'
                        else null end as my_awesome_col
            from my_table
            where my_col1 = my_col2
            and my_col1 = :my_plsql_var 
            and id = 100
            and name = 'Smith' ~' || strPred;

        open dataset 
        for strSql
        using my_plsql_var;

    end;

【讨论】:

【参考方案4】:
        Hello you need to build the SELECT Clause dynamically based upon your input. Below is the example for this.


        CREATE OR REPLACE PROCEDURE TEST1_DYN(
        p_in IN VARCHAR2,
        p_ref OUT sys_refcursor )
    AS
      lv_select LONG;
    BEGIN
      lv_select:='SELECT ID,     
                  (CASE WHEN my_col1 in ('''||p_in||''')'|| 'and my_col2 = '''||p_in||''''||' then '||''''||p_in||' GROUP'''||
                  ' else null        
                  end)  my_awesome_col        
                  FROM        
                  my_table        
                  WHERE        
                  id= 100 and        
                  name = ''Smith'' and         
                  my_plsql_var = '||''''||p_in||''''||' then my_col1 in ('||''''||p_in||''''||') and my_col2 = '||''''||p_in||'''             
                  ';
      dbms_output.put_line(lv_select);
OPEN p_ref for lv_select;
    END;

【讨论】:

以上是关于基于过程输入变量的条件 Where 子句 Oracle SQL的主要内容,如果未能解决你的问题,请参考以下文章

在 PL/SQL 存储过程中将多个变量传递给 WHERE 条件

关于sql语句添加where条件问题,用java语句

where条件放在子SQL语句中是否查询速度更快?

如何有基于参数值的条件 where 子句

在 WHERE 子句中为 IN 条件声明变量

基于另一个参数的条件 where 子句