我有3个输入参数,根据每个输入参数的值,我必须动态地在程序中准备SQL。我正在以下方式但它失败了,如果参数值为null,那么我必须从where子句中排除它。
IN参数:
在varchar2 ||中empname IN varchar2 || emps 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命令在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;
答案 0 :(得分: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;
答案 1 :(得分:0)
您可以从头开始创建一个,包括if和elses,或者您可以使用名为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;
我在一个项目中使用它,这是一个很好的工具。
答案 2 :(得分: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;