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

zbq4xfa0  于 2023-04-10  发布在  PHP
关注(0)|答案(2)|浏览(205)

我正在开发一个在Oracle数据库中执行批量插入的应用程序(~ 12 k,但可能不止于此)。下面是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 OCI 8执行 *)
有人可以请帮助我如何调试/打印失败的脚本的具体记录数据?真的很感激你的帮助.谢谢!

wfsdck30

wfsdck301#

如异常所述,您尚未初始化集合。
假设:1:2:3:49是绑定变量,并且你正在绑定一个包中定义的PL/SQL关联数组。基于oci_bind_array_by_name documentation,你可以使用这样的东西(未经测试,因为我没有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);
ni65a41a

ni65a41a2#

集合的初始化方式如下例所示:

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端传递的。至于向Oracle发送数据的客户端应用程序,我不知道你如何在那里批量绑定一个集合。

相关问题