Oracle - 如何使用动态绑定参数定义动态SQL?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle - 如何使用动态绑定参数定义动态SQL?相关的知识,希望对你有一定的参考价值。
我在Oracle数据库中有这个简单的搜索存储过程,并且想要动态地为我的绑定变量指定值。例如,如果只指定了employee no,那么我的sql只有一个绑定变量,但是如果指定了employee no和name,那么我的sql将有两个绑定变量。我怎样才能在“USING”条款中实现这一点?
CREATE OR REPLACE PROCEDURE SP_EMPLOYEE_SEARCH_TEST
(IN_EMP_NO IN VARCHAR2,
IN_EMP_NAME IN VARCHAR2,
OUT_C_SEARCH_RESULT OUT sys_refcursor)
IS
SQL_QUERY VARCHAR2(500);
BEGIN
SQL_QUERY := 'SELECT * FROM EMPLOYEE WHERE ' ;
IF (IN_EMP_NO IS NOT NULL) THEN
SQL_QUERY := SQL_QUERY || 'EMPLOYEE_NO = :1 ';
END IF;
IF (IN_EMP_NAME IS NOT NULL) THEN
SQL_QUERY := SQL_QUERY || ' AND EMPLOYEE_NAME = :2';
END IF;
dbms_output.put_line(SQL_QUERY);
OPEN OUT_C_SEARCH_RESULT FOR
SQL_QUERY USING <<How to define dynamically>>;
END SP_EMPLOYEE_SEARCH_TEST;
答案
只需传递它们但改变你的动态部分:
IF (IN_EMP_NO IS NOT NULL) THEN
SQL_QUERY := SQL_QUERY || 'EMPLOYEE_NO = :1 ';
ELSE
SQL_QUERY := SQL_QUERY || ':1 IS NULL ';
END IF;
IF (IN_EMP_NAME IS NOT NULL) THEN
SQL_QUERY := SQL_QUERY || ' AND EMPLOYEE_NAME = :2';
ELSE
SQL_QUERY := SQL_QUERY || ' AND :2 IS NULL';
END IF;
这样查询仍具有相同数量的绑定。
您也可以像这样重写查询:
SELECT * FROM EMPLOYEE
WHERE EMPLOYEE_NO = NVL(:1, EMPLOYEE_NO)
AND EMPLOYEE_NAME = NVL(:2, EMPLOYEE_NAME)
当绑定值为null时,它仍然使用相同数量的参数并获得所需的结果。
另一答案
如果你有最大值2-3个可选参数我会采用手动方式:
IF IN_EMP_NO IS NULL AND IN_EMP_NAME IS NULL THEN
OPEN OUT_C_SEARCH_RESULT FOR SQL_QUERY;
ELSIF IN_EMP_NO IS NOT NULL AND IN_EMP_NAME IS NULL THEN
OPEN OUT_C_SEARCH_RESULT FOR SQL_QUERY USING IN_EMP_NO;
ELSIF IN_EMP_NO IS NULL AND IN_EMP_NAME IS NOT NULL THEN
OPEN OUT_C_SEARCH_RESULT FOR SQL_QUERY USING IN_EMP_NAME;
ELSIF IN_EMP_NO IS NOT NULL AND IN_EMP_NAME IS NOT NULL THEN
OPEN OUT_C_SEARCH_RESULT FOR SQL_QUERY USING IN_EMP_NO, IN_EMP_NAME;
END IF;
或者像这样构建你的查询:
SQL_QUERY := 'SELECT * FROM EMPLOYEE WHERE ' ;
SQL_QUERY := SQL_QUERY || ' (EMPLOYEE_NO = :1 OR :2 IS NULL)';
SQL_QUERY := SQL_QUERY || ' AND (EMPLOYEE_NAME = :3 OR :4 IS NULL)';
OPEN OUT_C_SEARCH_RESULT FOR
SQL_QUERY USING IN_EMP_NO, IN_EMP_NO, IN_EMP_NAME, IN_EMP_NAME;
否则,如果你想拥有更多的灵活性,那么看看DBMS_SQL包。一个有效的例子就是这个:
CREATE OR REPLACE PROCEDURE SP_EMPLOYEE_SEARCH_TEST
(IN_EMP_NO IN VARCHAR2,
IN_EMP_NAME IN VARCHAR2,
OUT_C_SEARCH_RESULT OUT sys_refcursor)
IS
SQL_QUERY VARCHAR2(500);
cur INTEGER;
ret NUMBER;
bind BOOLEAN := FALSE;
BEGIN
IF (IN_EMP_NO IS NOT NULL) THEN
SQL_QUERY := SQL_QUERY || 'AND EMPLOYEE_NO = :p1 '; -- note the space at the end!
bind := TRUE;
END IF;
IF (IN_EMP_NAME IS NOT NULL) THEN
SQL_QUERY := SQL_QUERY || 'AND EMPLOYEE_NAME = :p2 ';
bind := TRUE;
END IF;
IF bind then
SQL_QUERY := 'SELECT * FROM EMPLOYEE '||REGEXP_REPLACE(SQL_QUERY, '^AND', 'WHERE');
ELSE
SQL_QUERY := 'SELECT * FROM EMPLOYEE';
END IF:
dbms_output.put_line(SQL_QUERY);
cur := dbms_sql.open_cursor;
DBMS_SQL.PARSE(cur, SQL_QUERY, DBMS_SQL.NATIVE);
IF (IN_EMP_NO IS NOT NULL) THEN
DBMS_SQL.BIND_VARIABLE(cur, ':p1', IN_EMP_NO);
END IF;
IF (IN_EMP_NAME IS NOT NULL) THEN
DBMS_SQL.BIND_VARIABLE(cur, ':p2', IN_EMP_NAME);
END IF;
ret := DBMS_SQL.EXECUTE(cur);
OUT_C_SEARCH_RESULT := DBMS_SQL.TO_REFCURSOR(cur);
END SP_EMPLOYEE_SEARCH_TEST;
以上是关于Oracle - 如何使用动态绑定参数定义动态SQL?的主要内容,如果未能解决你的问题,请参考以下文章
Oracle数据库中字段定义为Char类型,Hibernate用该字段进行动态绑定参数查询,获取不到结果的问题
Oracle数据库中字段定义为Char类型,Hibernate用该字段进行动态绑定参数查询,获取不到结果的问题