今天调试存储过程出现“ORA-06531: 引用未初始化的收集”错误,仔细查找了一下metalink,发现是需要初始化,而以前采用的表结构的都没有作过初始化这个步骤,后来看了一下,是因为声明的方式没有按照表的方式声明,而是自己手工写的字段。先寒一个!
----------------
从metalink上面看到,这种类型应该像下面那样使用:
–Create EMPLOYEE_TYPE
CREATE OR REPLACE type employee_type as object(
empid number,
empname varchar2(20),
job varchar2(20));
/
–Create EMPLOYEE_TAB_TYPE
CREATE OR REPLACE type employee_tab_type as table of employee_type ;
/
–Create DEPARTMENT_TYPE — using employee_tab_type
CREATE OR REPLACE type department_type as object(
deptid number,
deptname varchar2(20),
deptlocation varchar2(20),
emp_tab employee_tab_type);
/
DECLARE
/* Initialize the collection , else you will get ORA-06531: Reference to uninitialized collection */
my_emp employee_tab_type:=employee_tab_type();
my_dept department_type;
Begin
my_emp.extend; — 必须指定,否则会报指针越界
my_emp(1):=employee_type(2,’Savitha’,'mgr’); — 如果是record也可以直接赋值employee_type
my_dept :=department_type(1,’RESEARCH’,'India’,my_emp);
END;
declare
-- Non-scalar parameters require additional processing
i_list cdw_table := cdw_table();
begin
i_list.extend(3);
i_list(1):=type_user('yangyong');
i_list(2):=type_user('zhangyu');
i_list(3):=type_user('lizhuang');
-- Call the procedure
p_userlist(i_username => :i_username,
i_list => i_list);
commit;
end;
declare
-- Non-scalar parameters require additional processing
i_list cdw_table := cdw_table();
i number(5);
begin
i := 10000;
i_list.extend(i);
for m in 1..i loop
i_list(m):=type_user('yangyong');
end loop;
-- Call the procedure
p_userlist(i_username => :i_username,
i_list => i_list);
commit;
end;
<procedure id="insertPeople" parameterClass="java.util.HashMap">
<![CDATA[
DECLARE
]]>
<dynamic>
<isNotEmpty property="list">
<iterate open="i_list CDW_TABLE := CDW_TABLE(" close=");" property="list" conjunction=",">
<![CDATA[i_list[].passwd:=#list[]#]]>
</iterate>
</isNotEmpty>
<isEmpty property="list">
<![CDATA[i_list CDW_TABLE:= CDW_TABLE();]]>
</isEmpty>
</dynamic>
<![CDATA[
BEGIN
p_userlist(i_username => #username,jdbcType=VARCHAR,mode=IN#,
i_list => list,
);
END;
]]>
</procedure>
Iterate:这属性遍历整个集合,并为List集合中的元素重复元素体的内容。
Iterate的属性:
prepend : 可被覆盖的SQL语句组成部分,添加在语句的前面(可选)
property : 类型为java.util.List的用于遍历的元素(必选)
open : 整个遍历内容体开始的字符串,用于定义括号(可选)
close : 整个遍历内容体结束的字符串,用于定义括号(可选)
conjunction : 每次遍历内容之间的字符串,用于定义AND或OR(可选)
<iterate>
遍历类型为java.util.List的元素。
例子:
<iterate prepend=”AND” property=”userNameList”
open=”(” close=”)” conjunction=”OR”>
username=#userNameList[]#
</iterate>
注意:使用<iterate>时,在List元素名后面包括方括号[]非常重要,方括号[]将对象标记为List,以防解析器简单地将List输出成String
以上内容引自: blog.csdn.net/dinglinhu/archive/2008/05/27/2487647.aspx
如果传用的参数是自己定义的类,如:
<update id="sqlMap" parameterClass="example.ManagerModel">
UPDATE TBL_COMPANY
SET ADDRESS = #address#
WHERE COMPANY_ID IN
<iterate conjunction="," open="(" close=")" property="companyIds" >
#companyIds[]#
</iterate>
</update>
生成Sql语句: UPDATE TBL_COMPANY SET ADDRESS='address' WHERE COMPANY_ID IN ( 45, 50, 70)
ManagerModel 是自己定义的类,companyIds是其中的List
这时要注意红色字体的参数写法,要和类中定义的变量名一致.
<procedure id="insertPeople" parameterClass="java.util.HashMap">
<![CDATA[declare]]>
<![CDATA[i_list cdw_table := cdw_table();]]>
<![CDATA[begin]]>
<![CDATA[i_list.extend(3);]]>
<![CDATA[i_list(1):=type_user('yangyong');]]>
<![CDATA[i_list(2):=type_user('zhangyu');]]>
<![CDATA[i_list(3):=type_user('lizhuang');]]>
<![CDATA[p_userlist(i_username =>'nihao',]]>
<![CDATA[i_list => i_list);]]>
<![CDATA[end;]]>
</procedure>
----------------
从metalink上面看到,这种类型应该像下面那样使用:
–Create EMPLOYEE_TYPE
CREATE OR REPLACE type employee_type as object(
empid number,
empname varchar2(20),
job varchar2(20));
/
–Create EMPLOYEE_TAB_TYPE
CREATE OR REPLACE type employee_tab_type as table of employee_type ;
/
–Create DEPARTMENT_TYPE — using employee_tab_type
CREATE OR REPLACE type department_type as object(
deptid number,
deptname varchar2(20),
deptlocation varchar2(20),
emp_tab employee_tab_type);
/
DECLARE
/* Initialize the collection , else you will get ORA-06531: Reference to uninitialized collection */
my_emp employee_tab_type:=employee_tab_type();
my_dept department_type;
Begin
my_emp.extend; — 必须指定,否则会报指针越界
my_emp(1):=employee_type(2,’Savitha’,'mgr’); — 如果是record也可以直接赋值employee_type
my_dept :=department_type(1,’RESEARCH’,'India’,my_emp);
END;
declare
-- Non-scalar parameters require additional processing
i_list cdw_table := cdw_table();
begin
i_list.extend(3);
i_list(1):=type_user('yangyong');
i_list(2):=type_user('zhangyu');
i_list(3):=type_user('lizhuang');
-- Call the procedure
p_userlist(i_username => :i_username,
i_list => i_list);
commit;
end;
declare
-- Non-scalar parameters require additional processing
i_list cdw_table := cdw_table();
i number(5);
begin
i := 10000;
i_list.extend(i);
for m in 1..i loop
i_list(m):=type_user('yangyong');
end loop;
-- Call the procedure
p_userlist(i_username => :i_username,
i_list => i_list);
commit;
end;
<procedure id="insertPeople" parameterClass="java.util.HashMap">
<![CDATA[
DECLARE
]]>
<dynamic>
<isNotEmpty property="list">
<iterate open="i_list CDW_TABLE := CDW_TABLE(" close=");" property="list" conjunction=",">
<![CDATA[i_list[].passwd:=#list[]#]]>
</iterate>
</isNotEmpty>
<isEmpty property="list">
<![CDATA[i_list CDW_TABLE:= CDW_TABLE();]]>
</isEmpty>
</dynamic>
<![CDATA[
BEGIN
p_userlist(i_username => #username,jdbcType=VARCHAR,mode=IN#,
i_list => list,
);
END;
]]>
</procedure>
Iterate:这属性遍历整个集合,并为List集合中的元素重复元素体的内容。
Iterate的属性:
prepend : 可被覆盖的SQL语句组成部分,添加在语句的前面(可选)
property : 类型为java.util.List的用于遍历的元素(必选)
open : 整个遍历内容体开始的字符串,用于定义括号(可选)
close : 整个遍历内容体结束的字符串,用于定义括号(可选)
conjunction : 每次遍历内容之间的字符串,用于定义AND或OR(可选)
<iterate>
遍历类型为java.util.List的元素。
例子:
<iterate prepend=”AND” property=”userNameList”
open=”(” close=”)” conjunction=”OR”>
username=#userNameList[]#
</iterate>
注意:使用<iterate>时,在List元素名后面包括方括号[]非常重要,方括号[]将对象标记为List,以防解析器简单地将List输出成String
以上内容引自: blog.csdn.net/dinglinhu/archive/2008/05/27/2487647.aspx
如果传用的参数是自己定义的类,如:
<update id="sqlMap" parameterClass="example.ManagerModel">
UPDATE TBL_COMPANY
SET ADDRESS = #address#
WHERE COMPANY_ID IN
<iterate conjunction="," open="(" close=")" property="companyIds" >
#companyIds[]#
</iterate>
</update>
生成Sql语句: UPDATE TBL_COMPANY SET ADDRESS='address' WHERE COMPANY_ID IN ( 45, 50, 70)
ManagerModel 是自己定义的类,companyIds是其中的List
这时要注意红色字体的参数写法,要和类中定义的变量名一致.
<procedure id="insertPeople" parameterClass="java.util.HashMap">
<![CDATA[declare]]>
<![CDATA[i_list cdw_table := cdw_table();]]>
<![CDATA[begin]]>
<![CDATA[i_list.extend(3);]]>
<![CDATA[i_list(1):=type_user('yangyong');]]>
<![CDATA[i_list(2):=type_user('zhangyu');]]>
<![CDATA[i_list(3):=type_user('lizhuang');]]>
<![CDATA[p_userlist(i_username =>'nihao',]]>
<![CDATA[i_list => i_list);]]>
<![CDATA[end;]]>
</procedure>