0

我有 3 个输入参数,根据每个输入参数的值,我必须动态准备 SQL 过程。我正在按照以下方式进行操作,但它失败了,如果参数值为空,那么我必须从 where 子句中排除它。

输入参数:

varchar2 中的 empid || empname IN varchar2 || empsal IN varchar2

SELECT
      EMP_NAME
INTO
      V_EMP_NAME
FROM
      EMPLOYEE
WHERE
         ( EMP_ID = EMPID
          OR ( EMP_ID IS NULL
             AND EMPID IS NULL ) )
      AND ( EMP_NAME = EMPNAME
          OR ( EMP_NAME IS NULL
             AND EMPNAME IS NULL ) )
      AND ( EMP_SAL = EMPSAL
          OR ( EMP_SAL IS NULL
             AND EMPSAL IS NULL ) );

更新后,我修改了如下查询,它已编译但运行时错误提示 ORA-00933: SQL command not properly end on just before EXECUTE IMMEDIATE

  V_SQL :='SELECT EMP_NAME INTO V_empname FROM employee WHERE ';
    BEGIN
    IF(EMPID IS NOT NULL) THEN
     V_SQL := V_SQL || ' emp_id='||EMPID;
    END IF; 
    IF(EMPNAME IS NOT NULL) THEN
      V_SQL := V_SQL || ' AND emp_name='||EMPNAME;
    END IF; 
    IF(V_empsalIS NOT NULL) THEN
      V_SQL := V_SQL || ' AND  emp_sal='||empsal;
 V_SQL := V_SQL ||' AND ACTIVE =''Y''' ;
    END IF; 
        EXECUTE IMMEDIATE V_SQL;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      V_check:= '' ;
    END;
4

3 回答 3

1

在这里,您是另一种选择:

V_SQL_WHERE := null;

  V_SQL :='SELECT EMP_NAME INTO V_empname FROM employee';
    BEGIN

    IF(EMPID IS NOT NULL) THEN
      V_SQL_WHERE := V_SQL_WHERE || ' emp_id='||EMPID;
    END IF; 

    IF(EMPNAME IS NOT NULL) THEN

      IF (V_SQL_WHERE is not null) THEN 
        V_SQL_WHERE := V_SQL_WHERE || ' AND ';
      END IF;

      V_SQL_WHERE := V_SQL_WHERE || ' emp_name='||EMPNAME;
    END IF; 

    IF(V_empsalIS NOT NULL) THEN

      IF (V_SQL_WHERE is not null) THEN 
         V_SQL_WHERE := V_SQL_WHERE || ' AND ';
      END IF; 
      V_SQL_WHERE := V_SQL_WHERE || ' emp_sal=' || empsal;
      V_SQL_WHERE := V_SQL_WHERE || ' AND ACTIVE =''Y''' ;

    END IF; 

    IF (V_SQL_WHERE is not null) then
      V_SQL := V_SQL || ' WHERE ' || V_SQL_WHERE;
    end if;

        EXECUTE IMMEDIATE V_SQL;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      V_check:= '' ;
    END;
于 2013-10-16T08:42:01.537 回答
0

您可以从头开始创建一个,包括 if 和 else,或者您可以使用一个名为 plsql-utils 的包,即 SQL_BUILDER_PKG。它为您完成所有工作。

查看SQL 实用程序

http://code.google.com/p/plsql-utils/

例如:

declare
  l_my_query sql_builder_pkg.t_query;
  l_sql varchar2(32000);
begin

  sql_builder_pkg.add_select (l_my_query, 'ename');
  sql_builder_pkg.add_select (l_my_query, 'sal');
  sql_builder_pkg.add_select (l_my_query, 'deptno');
  sql_builder_pkg.add_from (l_my_query, 'emp');
  sql_builder_pkg.add_where (l_my_query, 'ename = :p_ename');
  sql_builder_pkg.add_where (l_my_query, 'sal > :p_sal');
  l_sql := sql_builder_pkg.get_sql (l_my_query);
  dbms_output.put_line (l_sql);
end;

我在一个项目中使用了它,它是一个很好的工具。

于 2013-10-15T15:30:46.853 回答
0

像这样的东西:(未经测试,但只是一个想法)

BEGIN
    IF EMPID IS NOT NULL
    THEN
        CLAUSE1   := 'EMP_ID = EMPID';
    ELSE
        CLAUSE1   := '1=1';
    END IF;

    IF EMPNAME IS NOT NULL
    THEN
        CLAUSE2   := 'EMP_NAME = EMPNAME';
    ELSE
        CLAUSE2   := '1=1';
    END IF;

    IF EMPSAL IS NOT NULL
    THEN
        CLAUSE3   := 'EMP_SAL = EMPSAL';
    ELSE
        CLAUSE3   := '1=1';
    END IF;

    IF (    EMPSAL IS NULL
        AND EMPNAME IS NULL
        AND EMPID IS NOT NULL )
    THEN
        CLAUSE1   := '1=0';
        CLAUSE2   := '1=0';

        CLAUSE3   := '1=0';
    END IF;

    QUERY_STR   :=
           '    SELECT EMP_NAME INTO V_EMP_NAME FROM EMPLOYEE WHERE'
        || CLAUSE1
        || ' AND '
        || CLAUSE2
        || ' AND '
        || CLAUSE3;
END;
于 2013-10-15T15:44:01.740 回答