pl/sql 函数 - 为 SELECT ... NOT IN() 动态传递多个 varchar2 值
Posted
技术标签:
【中文标题】pl/sql 函数 - 为 SELECT ... NOT IN() 动态传递多个 varchar2 值【英文标题】:pl/sql function- pass multiple varchar2 values dynamically for SELECT ... NOT IN() 【发布时间】:2014-03-05 05:47:27 【问题描述】:我有一张表EMP
,其定义如下:
EMP_ID NOT NULL NUMBER(6)
EMP_NAME NOT NULL VARCHAR2(25)
EMAIL NOT NULL VARCHAR2(25)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
如果我们想计算姓名不在“King”、“Steve”、“John”中的员工,我们只需使用以下查询:
SELECT count(*) FROM emp WHERE emp_name NOT IN('King','Steve','John');
现在这是我想要的:
我想做的是,创建一个PL/SQL Function
,它根据动态输入返回计数,就像我们通过:
SELECT count_emp('King,Steve,John') FROM dual;
SELECT count_emp('William,Donald') FROM dual;
SELECT count_emp('Daniel') FROM dual;
需要返回适当的计数,我如何使用PL/SQL FUNCTION
实现此目的
这是我尝试过的,需要指南:
CREATE OR REPLACE FUNCTION count_emp(emp_nm IN varchar)
RETURN number
IS
cnt NUMBER;
BEGIN
SELECT count(*) INTO cnt FROM emp WHERE emp_name NOT IN(emp_nm);
RETURN cnt;
END;
它给出了单个名称的结果,但是我如何拆分/格式化多个输入(即emp_nm
)以传入NOT IN()
?
【问题讨论】:
您可以将字符串放入一个变量中拆分它,然后将列表传递到 in 子句中,这样您就可以使用 'King','Steve','John' 而不是 'King,Steve,约翰 您也可以使用动态 SQL。 SO上有很多类似的问题。 即this 和 another one. How to use parameters in a 'where value in...' clause?的可能重复 【参考方案1】:这样试试,
CREATE OR REPLACE
FUNCTION count_emp(emp_nm IN VARCHAR)
RETURN NUMBER
IS
cnt NUMBER;
BEGIN
SELECT count(*)
INTO cnt
FROM emp
WHERE ename NOT IN(
SELECT regexp_substr (emp_nm, '[^,]+', 1, ROWNUM)
FROM dual
CONNECT BY LEVEL <= LENGTH (regexp_replace (emp_nm, '[^,]+')) + 1);
RETURN cnt;
END;
【讨论】:
【参考方案2】:你可以试试动态sql:
CREATE OR REPLACE FUNCTION count_emp(emp_nm IN varchar)
RETURN number
IS
cnt NUMBER;
BEGIN
Execute immediate 'SELECT count(*) FROM emp WHERE emp_name NOT IN(' || emp_nm || ')' returning into cnt;
RETURN cnt;
END;
【讨论】:
【参考方案3】:您也可以使用MEMBER OF
。这是一个sn-p。希望这会有所帮助!
-- Create a type in SQL
CREATE OR REPLACE TYPE t_emp_name AS TABLE OF VARCHAR2 (10);
-- use MEMBER OF to use your list as IN parameter
CREATE OR REPLACE FUNCTION count_emp (emp_nm IN t_emp_name)
RETURN NUMBER
IS
cnt NUMBER;
BEGIN
SELECT COUNT (*)
INTO cnt
FROM emp
WHERE emp_name NOT MEMBER OF (emp_nm);
RETURN cnt;
END;
-- Assign values to the list, you can do it dynamically as well. Call the function
DECLARE
l_emp_name_list t_emp_name;
lv_count NUMBER;
BEGIN
l_emp_name_list := t_emp_name ('King', 'Steve'); --add more names as needed
lv_count := count_emp (l_emp_name_list);
END;
【讨论】:
这正是我所需要的。感谢分享! 很高兴看到它有帮助!以上是关于pl/sql 函数 - 为 SELECT ... NOT IN() 动态传递多个 varchar2 值的主要内容,如果未能解决你的问题,请参考以下文章
ORACLE 中的 PL/SQL、IF-ELSE 或 SELECT DECODE 哪个更好