为啥 BULK COLLECT 在 Oracle Package PROC 中给出错误的绑定变量编译错误?
Posted
技术标签:
【中文标题】为啥 BULK COLLECT 在 Oracle Package PROC 中给出错误的绑定变量编译错误?【英文标题】:Why does BULK COLLECT give a bad bind variable compile error in Oracle Package PROC?为什么 BULK COLLECT 在 Oracle Package PROC 中给出错误的绑定变量编译错误? 【发布时间】:2016-01-07 20:41:46 【问题描述】:我正在尝试使用 3 个字符串来表示一组姓氏、名字和中间名。
传入的参数最终看起来像这样:
lastNames IN VARCHAR2 := NULL
'Smith/Brown/Green'
firstNames IN VARCHAR2 := NULL,
'Joseph/Dan/Sam'
miNames IN VARCHAR2 := NULL,
'c.//J.'
目标是为动态 SQL 构建一个过滤器,如下所示:
v_namesFilter VARCHAR(32767 BYTE);
v_namesFilter := ' AND (last_name = ''Smith'' AND middle_name = ''C'' AND first_name = ''Joseph'') OR (last_name = ''Brown'' AND first_name = ''Dan'') OR (last_name = ''Green'' AND middle_name = ''J.'' AND first_name = ''Sam'')
到目前为止,我有一个这样的传入参数:
lastNames IN VARCHAR2 := NULL,
然后
IS(
我有:
v_last_names_tab LAST_NAMES_TAB;
LAST_NAMES_TAB 的定义如下:
create or replace TYPE "LAST_NAMES_TAB" AS TABLE OF LAST_NAMES;
LAST_NAMES 的定义如下:
create or replaceTYPE "LAST_NAMES" AS OBJECT(
lastName VARCHAR2(32767)
);
在我开始之后,我有:
-- split last names into table
SELECT LAST_NAMES( lastName )
BULK COLLECT INTO :v_last_names_tab
FROM (
SELECT trim( regexp_substr(lastNames, '[^/]+', 1, LEVEL) )AS lastName
FROM DUAL
CONNECT BY instr(lastNames, '/', 1, LEVEL - 1) > 0
);
我认为这会填满 TYPE LAST_NAMES_TAB 的名为 v_last_names_tab 的表,如下所示:
lastName
--------
Smith
Brown
Green
但我在尝试编译时收到“Bad Bind variable”:v_last_names_tab”错误消息。
我怎样才能像这样格式化我的传入数据,以便我可以滚动它。
【问题讨论】:
在 PL/SQL 上下文中,您不需要使用冒号 (":") 来指示绑定变量。 【参考方案1】:您不需要所有额外的类型和对象,并且可以在 PL/SQL 中完成所有操作:
CREATE OR REPLACE FUNCTION split_String(
i_str IN VARCHAR2,
i_delim IN VARCHAR2 DEFAULT ','
) RETURN SYS.ODCIVARCHAR2LIST DETERMINISTIC
AS
p_result SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST();
p_start NUMBER(5) := 1;
p_end NUMBER(5);
c_len CONSTANT NUMBER(5) := LENGTH( i_str );
c_ld CONSTANT NUMBER(5) := LENGTH( i_delim );
BEGIN
IF c_len > 0 THEN
p_end := INSTR( i_str, i_delim, p_start );
WHILE p_end > 0 LOOP
p_result.EXTEND;
p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, p_end - p_start );
p_start := p_end + c_ld;
p_end := INSTR( i_str, i_delim, p_start );
END LOOP;
IF p_start <= c_len + 1 THEN
p_result.EXTEND;
p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, c_len - p_start + 1 );
END IF;
END IF;
RETURN p_result;
END;
/
CREATE OR REPLACE PROCEDURE get_Names_Filter(
i_lastNames IN VARCHAR2,
i_firstNames IN VARCHAR2,
i_miNames IN VARCHAR2,
o_filter OUT VARCHAR2
)
AS
p_ln SYS.ODCIVARCHAR2LIST := split_String( i_lastNames, '/' );
p_fn SYS.ODCIVARCHAR2LIST := split_String( i_firstNames, '/' );
p_mn SYS.ODCIVARCHAR2LIST := split_String( i_miNames, '/' );
BEGIN
FOR i IN 1 .. p_ln.COUNT LOOP
o_filter := o_filter
|| ' AND ( last_name ' || CASE WHEN p_ln(i) IS NULL THEN 'IS NULL' ELSE '= ''' || p_ln(i) || '''' END
|| ' AND middle_name ' || CASE WHEN p_mn(i) IS NULL THEN 'IS NULL' ELSE '= ''' || p_mn(i) || '''' END
|| ' AND first_name ' || CASE WHEN p_fn(i) IS NULL THEN 'IS NULL' ELSE '= ''' || p_fn(i) || '''' END
|| ')';
END LOOP;
END;
/
【讨论】:
【参考方案2】:替换
BULK COLLECT INTO :v_last_names_tab
由
BULK COLLECT INTO v_last_names_tab
以 :
开头的绑定变量不是正确的 PL/SQL 语法。
【讨论】:
以上是关于为啥 BULK COLLECT 在 Oracle Package PROC 中给出错误的绑定变量编译错误?的主要内容,如果未能解决你的问题,请参考以下文章
Oracle bulk collect into 的几种用法
oracle plsql中同时记录类型、Collection和Bulk collect
重构 Oracle 存储过程以使用 BULK COLLECT