我将参数`EBN,BGE'传递给一个过程,然后我将这个参数传递给游标。
create or replace procedure TEXT_MD (AS_IDS VARCHAR2)
is
CURSOR C_A (AS_ID VARCHAR2) IS
SELECT
name
FROM S_US
WHERE US_ID IN (AS_ID);
BEGIN
FOR A IN C_A (AS_IDS) LOOP
DBMS_OUTPUT.PUT_LINE('I got here: '||AS_IDS);
end loop;
END;
但是,在对游标计数进行调试时仍为空
所以我的问题是,为什么游标没有在条件
中返回值答案 0 :(得分:2)
您正在传递一个字符串参数,因此它将用作字符串,而不是字符串列表;所以,你的光标将是
SELECT name
FROM S_US
WHERE US_ID IN ('EBN,BGE')
当然,这不会做你需要的。 您可能需要更改过程和传递参数的方式;如果你想保留一个字符串参数,可以采用以下方法:
<强>设置:强>
SQL> CREATE TABLE S_US
2 (
3 US_ID,
4 NAME
5 ) AS
6 SELECT 'EBN', 'EBN name' FROM DUAL
7 UNION ALL
8 SELECT 'BGE', 'BGE name' FROM DUAL;
Table created.
<强>过程:强>
SQL> CREATE OR REPLACE PROCEDURE TEXT_MD_2(AS_IDS VARCHAR2) IS
2 vSQL varchar2(1000);
3 c sys_refcursor;
4 vName varchar2(16);
5 BEGIN
6 vSQL := 'SELECT name
7 FROM S_US
8 WHERE US_ID IN (' || AS_IDS || ')';
9 open c for vSQL;
10 loop
11 fetch c into vName;
12 if c%NOTFOUND then
13 exit;
14 end if;
15 DBMS_OUTPUT.PUT_LINE(vName);
16 END LOOP;
17 END;
18 /
Procedure created.
您需要使用已格式化为IN
的参数列表的字符串来调用它:
SQL> EXEC TEXT_MD_2('''EBN'',''BGE''');
EBN name
BGE name
PL/SQL procedure successfully completed.
这只是一种可能方式的例子,而不是我这样做的方式。 考虑到这种方法的原因,请考虑Justin Cave所说的内容: &#34;由于SQL注入会带来安全风险,并且由于持续的难以解析而会导致潜在的显着性能损失&#34;。
我相信您应该更好地检查如何将值列表传递给您的过程,而不是使用字符串来表示字符串列表。 以下是使用集合执行相同操作的可能方法:
SQL> CREATE OR REPLACE TYPE tabVarchar2 AS TABLE OF VARCHAR2(16)
2 /
Type created.
SQL>
SQL> CREATE OR REPLACE PROCEDURE TEXT_MD_3(AS_IDS tabVarchar2) IS
2 vSQL VARCHAR2(1000);
3 c SYS_REFCURSOR;
4 vName VARCHAR2(16);
5 BEGIN
6 FOR i IN (SELECT name
7 FROM S_US INNER JOIN TABLE(AS_IDS) tab ON (tab.COLUMN_VALUE = US_ID))
8 LOOP
9 DBMS_OUTPUT.PUT_LINE(i.name);
10 END LOOP;
11 END;
12 /
Procedure created.
SQL>
SQL> DECLARE
2 vList tabVarchar2 := NEW tabVarchar2();
3 BEGIN
4 vList.EXTEND(2);
5 vList(1) := 'BGE';
6 vList(2) := 'EBN';
7 TEXT_MD_3(vList);
8 END;
9 /
BGE name
EBN name
PL/SQL procedure successfully completed.
SQL>
同样,您可以在存储过程中以不同方式定义集合,是否已编制索引,等等;这只是其中一种可能的方式,不一定是最好的方式,具体取决于您的环境,需求。