在Oracle数据库中批量插入失败-引用未初始化的集合



我正在研究一个应用程序,该应用程序在Oracle数据库中执行批量插入(~12k,但可以超过这个)。下面是SQL脚本:-

DECLARE
errstr VARCHAR2(4000) := '';
errors NUMBER;
i      NUMBER;
er     NUMBER;
bk1    acct_common.type_tabnumber;
bk2    acct_common.type_tabdate;
bk3    acct_common.type_tabnumber;
bk49   acct_common.type_tabnumber;
BEGIN
bk1 := :1;
bk2 := :2;
bk3 := :3;
bk49 := :49;
FORALL i IN 1..11655
INSERT INTO table_name (
col1,
col2,
col3,
col49
) VALUES (
bk1(i),
bk2(i),
bk3(i),
bk49(i)
);
END;

插入失败,出现以下错误:-

oci error 6531 (ORA-06531: Reference to uninitialized collection ORA-06512: at line 126 ORA-22160: element at index [1] does not exist ORA-06512: at line 106 )

由于有数千条记录,我无法找出哪条记录有数据问题。(这个查询是用PHP动态生成的,并且是用Oracle OCI8执行的)

有人能帮我如何调试/打印脚本失败的特定记录数据吗?非常感谢你的帮助。谢谢!

如异常所示,您尚未初始化集合。

假设:1,:2,:3:49是绑定变量,并且您正在绑定包中定义的PL/SQL关联数组。基于oci_bind_array_by_name文档,您可以使用类似的内容(未经测试,因为我没有PHP环境):

$stid = oci_parse(
$conn,
"DECLARE
errstr VARCHAR2(4000) := '';
errors NUMBER;
i      NUMBER;
er     NUMBER;
bk1    acct_common.type_tabnumber;
bk2    acct_common.type_tabnumber;
bk3    acct_common.type_tabnumber;
bk49   acct_common.type_tabnumber;
BEGIN
bk1 := :1;
bk2 := :2;
bk3 := :3;
bk49 := :49;
FORALL i IN INDICES OF bk1
INSERT INTO table_name (
col1,
col2,
col3,
col49
) VALUES (
bk1(i),
DATE '1970-01-01' + bk2(i) * INTERVAL '1' SECOND,
bk3(i),
bk49(i)
);
END;"
);
$bk1s  = array(1,2,3,4,5);
$bk2s  = array(
mktime(0, 0, 0, 1, 1, 2023),
mktime(0, 0, 0, 1, 2, 2023),
mktime(0, 0, 0, 1, 3, 2023),
mktime(0, 0, 0, 1, 4, 2023),
mktime(0, 0, 0, 1, 5, 2023)
);
$bk3s  = array(6,7,8,9,10);
$bk49s = array(11,12,13,14,15);
oci_bind_array_by_name($stid, ":1",  $bk1s,  5, -1, SQLT_INT);
oci_bind_array_by_name($stid, ":2",  $bk2s,  5, -1, SQLT_INT);
oci_bind_array_by_name($stid, ":3",  $bk3s,  5, -1, SQLT_INT);
oci_bind_array_by_name($stid, ":49", $bk49s, 5, -1, SQLT_INT);
oci_execute($stid);

集合的初始化方式如下:

declare
type t_tab_n is table of number;
tab_n t_tab_n;
begin
tab_n:=t_tab_n(1,3,12,13,33,44);
end;

前面的示例将使用许多元素初始化集合。或者可以是这样的:

declare
type t_tab_n is table of number;
tab_n t_tab_n;
begin
tab_n:=t_tab_n(); -- initialize collection with no elements
tab_n.extend; --- add one element to collection
tab_n(tab_n.last):=3; --- assign value to the added element
tab_n.extend;
tab_n(tab_n.last):=12;
end;

不能像您希望的那样将集合作为简单的绑定变量传递。这是甲骨文方面的说法。至于向Oracle发送数据的客户端应用程序,我不知道你如何在那里批量绑定一个集合。

最新更新