在PL/SQL存储过程中将多个变量传递到WHERE条件

arc*_*123 2 sql plsql stored-procedures

传递参数时执行此代码块时出现问题.参数rf是要输入WHERE子句的变量列表.要输入的变量数不是静态的.

create or replace
procedure test_pl(rf in varchar2)
IS 
counter number;

BEGIN
  select count(*) into counter from test_pl_imp where column_name in (rf);
  dbms_output.put_line(counter);
END;
Run Code Online (Sandbox Code Playgroud)

执行代码如下:

declare 
inparam varchar2(20) := 'xyz,ran,dom';
begin
goku.test_pl(inparam);
end;
/
Run Code Online (Sandbox Code Playgroud)

我希望WHERE条件执行如下:

where column_name in ('xyz','ran','dom');
Run Code Online (Sandbox Code Playgroud)

但它会被视为xyz,ran,dom一个字符串本身而被执行.

有没有办法实现它?

Joh*_*n D 5

您可以将字符串分解出来,或者最简单的方法是使用INSTR.

rf := ',' || rf || ',';

SELECT
    COUNT(*)
INTO
    counter
FROM
    test_pl_imp
WHERE
    INSTR(rf, ',' || column_name || ',') > 0;
Run Code Online (Sandbox Code Playgroud)

如果您可以选择稍微重新设计一下,我认为采用字符串数组并将其转换为TABLE是一种更简洁的设计,以便您可以加入test_pl_imp.

这可以按如下方式完成:

DECLARE
    l_array   goku.t_type := goku.t_type();
BEGIN
    l_array.extend(3);
    l_array(1) := 'xzy';
    l_array(2) := 'abc';
    l_array(2) := '123';

    goku.test_pl(l_array);
END;
Run Code Online (Sandbox Code Playgroud)

然后您的包规范将包括以下内容,因为您希望上述调用的类型和过程是公共的:

CREATE OR REPLACE PACKAGE goku
    TYPE r_type IS RECORD (
        search_term    VARCHAR2 (30)
    );

    TYPE t_type IS TABLE OF r_type;

    PROCEDURE test_pl(l_array IN t_type);
END goku;
Run Code Online (Sandbox Code Playgroud)

你的包体将如下所示:

CREATE OR REPLACE PACKAGE BODY goku
    PROCEDURE test_pl(l_array IN t_type) IS
        v_counter NUMBER;
    BEGIN

        SELECT
            COUNT(tpi.*)
        INTO
            v_counter
        FROM
            test_pl_imp tpi
            , TABLE( CAST(l_array as r_type)) la
        WHERE
            tpi.column_name = la.search_term;

        DBMS_OUTPUT.PUT_LINE('Count :' || v_counter);
    END;
END goku;
Run Code Online (Sandbox Code Playgroud)

  • 当仅提供"MyString"作为变量时,INSTR可能会遇到诸如"MyString"和"MyStringTest"之类的问题.但是为了解决这个问题,你可以使用特殊字符和变量填充原始值,以便查找"; MyString;" 代替.我之前也做过这个伎俩. (3认同)