pl / sql函数 - 为SELECT动态传递多个varchar2值... NOT IN()

时间:2014-03-05 05:47:27

标签: sql oracle plsql

我有一个表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()

3 个答案:

答案 0 :(得分:3)

试试这个,

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;

答案 1 :(得分: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;

答案 2 :(得分:2)

您也可以使用MEMBER OF。这是一个片段。希望这有帮助!

-- 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;