如何通过 PL/SQL 将结构传递给 oracle PROCEDURE - 绑定问题

How to pass structure to oracle PROCEDURE thru PL/SQL - binding issue

我正在尝试通过 PL/SQL 将日志发送到远程 oracle 数据库。它被发送到过程 RECORD_MANAGEMENT.ADD_INTO(@bottom of the post)。这个过程有点像一个入口点。

挑战存在于过程所需的 4 个对象类型中。

我尝试过的两件事:

  1. 尝试隐式调用 - 这里不会绑定数组
oci_execute(): ORA-06550: line 1, column 7: PLS-00306:
  1. 原始方法 - 语法错误?
oci_bind_array_by_name(): ORA-01036: illegal variable name/number

更新 #1 3、与第二种方式类似;这会将变量作为字符串插入原始 PL

//for all 4 object types it reports this err
oci_execute(): ORA-06550: line 2, column 11:
PLS-00201: identifier 'PROJ_DB.EMPLOYEE_TYPE' must be declared
ORA-06550: line 2, column 11:

//on three occasions this is also stated
PL/SQL: Item ignored
ORA-06550: line 19, column 3:
PLS-00320: the declaration of the type of this expression is incomplete or malformed

如果有人有任何建议,那将非常有帮助!最近刚开始 'oracling'.

第一次尝试的例子;

    $var1 = ["1111", null, null, null, null, null, null, null, null, null, null, null];
    $var2 = 'String 1';
    $var3 = ["String 2", null, null, null, null, null, null, null, null, null];
    $var4 = '2020-06-03 07:00:00';
    $var5 = ["String 3",null,null];
    $var6 = ["String 4",null];
    $var7 = '222222';
    $var8 = NULL;
    $var9 = NULL;
    $var10= 'String 5';
    $var11= '333333';
    $var12= '444444';
    $var13= '555555';
    $var14= '666666';
    $var15= NULL;

    $stmt = oci_parse($conn, "BEGIN PROJ_DB.RECORD_MANAGEMENT.ADD_INTO(:val1, :val2, :val3, :val4, :val5, :val6, :val7, :val8, :val9, :val10, :val11, :val12, :val13, :val14, :val15); END;");

    oci_bind_array_by_name($stmt,':var1',$var1,count($var1),-1);
    oci_bind_by_name($stmt,':var2', $var2);
    oci_bind_array_by_name($stmt,':var3', $var3,count($var3),-1);
    oci_bind_by_name($stmt,':var4', $var4);
    oci_bind_array_by_name($stmt,':var5', $var5,count($var5),-1);
    oci_bind_array_by_name($stmt,':var6', $var6,count($var6),-1);
    oci_bind_by_name($stmt,':var7', $var7);
    oci_bind_by_name($stmt,':var8', $var8);
    oci_bind_by_name($stmt,':var9', $var9);
    oci_bind_by_name($stmt,':var10', $var10);
    oci_bind_by_name($stmt,':var11', $var11);
    oci_bind_by_name($stmt,':var12', $var12);
    oci_bind_by_name($stmt,':var13', $var13);
    oci_bind_by_name($stmt,':var14', $var14);
    oci_bind_by_name($stmt,':var15', $var15);

    oci_execute($stmt); 

第二次尝试的示例(尝试了不同的语法 A:a A:=a )。

$proc="
DECLARE
  VAR_A PROJ_DB.EMPLOYEE_TYPE;
  VAR_B VARCHAR2(200);
  VAR_C PROJ_DB.PROJECT_TYPE;
  VAR_D DATE;
  VAR_E PROJ_DB.SYSTEM_TYPE;
  VAR_F PROJ_DB.ACTION_TYPE;
  VAR_G NUMBER;
  VAR_H VARCHAR2(200);
  VAR_I VARCHAR2(200);
  VAR_J CLOB;
  VAR_K NUMBER;
  VAR_L NUMBER;
  VAR_M NUMBER;
  VAR_N NUMBER;
  VAR_O VARCHAR2(200);
BEGIN
  VAR_A var1;
  VAR_B var2;
  VAR_C var3;
  VAR_D var4;
  VAR_E var5;
  VAR_F var6;
  VAR_G var7;
  VAR_H var8;
  VAR_I var9;
  VAR_J var10;
  VAR_K var11;
  VAR_L var12;
  VAR_M var13;
  VAR_N var14;
  VAR_O var15;

  RECORD_MANAGEMENT.ADD_INTO(
    VAR_A => VAR_A,
    VAR_B => VAR_B,
    VAR_C => VAR_C,
    VAR_D => VAR_D,
    VAR_E => VAR_E,
    VAR_F => VAR_F,
    VAR_G => VAR_G,
    VAR_H => VAR_H,
    VAR_I => VAR_I,
    VAR_J => VAR_J,
    VAR_K => VAR_K,
    VAR_L => VAR_L,
    VAR_M => VAR_M,
    VAR_N => VAR_N,
    VAR_O => VAR_O
  );
  COMMIT;
END;
";
//variables same as in first example
$stmt = oci_parse($conn, $proc);
//binding also same
oci_execute($stmt); 

第三次尝试的示例,变量在 pl 中作为字符串插入,因此避免了绑定

//$var1-3-5-6 is not anymore array
        VAR_A := PROJ_DB.EMPLOYEE_TYPE($var1, null, null, null, null, null, null, null, null, null, null, null); 
        VAR_B :='".$var2."'; 
        VAR_C := PROJ_DB.PROJECT_TYPE($var3, null, null, null, null, null, null, null, null, null);
        VAR_D := to_date('".$var4."', 'dd.mm.yyyy hh24:mi:ss'); 
        VAR_E := PROJ_DB.SYSTEM_TYPE($var5, null, null); 
        VAR_F := PROJ_DB.ACTION_TYPE('".$var6."', null);
        VAR_G :=$var7; 
        VAR_H :=NULL; 
        VAR_I :=NULL; 
        VAR_J :='".$var10."'; 
        VAR_K :=$var11; 
        VAR_L :=$var12; 
        VAR_M :=$var13; 
        VAR_N :=$var14; 
        VAR_O := NULL; 

程序的一个条目示例(第二次尝试基于此示例);

DECLARE
  VAR_A PROJ_DB.EMPLOYEE_TYPE;
  VAR_B VARCHAR2(200);
  VAR_C PROJ_DB.PROJECT_TYPE;
  VAR_D DATE;
  VAR_E PROJ_DB.SYSTEM_TYPE;
  VAR_F PROJ_DB.ACTION_TYPE;
  VAR_G NUMBER;
  VAR_H VARCHAR2(200);
  VAR_I VARCHAR2(200);
  VAR_J CLOB;
  VAR_K NUMBER;
  VAR_L NUMBER;
  VAR_M NUMBER;
  VAR_N NUMBER;
  VAR_O VARCHAR2(200);
BEGIN
  VAR_A := PROJ_DB.EMPLOYEE_TYPE(11111, null, null, null, null, null, null, null, null, null, null, null);
  VAR_B := 'String 1';
  VAR_C := PROJ_DB.PROJECT_TYPE('String 2', null, null, null, null, null, null, null, null, null);
  VAR_D := to_date('24.02.2020 08:00:00', 'dd.mm.yyyy hh24:mi:ss');
  VAR_E := PROJ_DB.SYSTEM_TYPE('String 3', null, null);
  VAR_F := PROJ_DB.ACTION_TYPE('String 4', null);
  VAR_G := 2222222;
  VAR_H := NULL;
  VAR_I := NULL;
  VAR_J := 'String 5';
  VAR_K := 3333333;
  VAR_L := 4444444;
  VAR_M := 5555555;
  VAR_N := 6666666;
  VAR_O := NULL;

  RECORD_MANAGEMENT.ADD_INTO(
    VAR_A => VAR_A,
    VAR_B => VAR_B,
    VAR_C => VAR_C,
    VAR_D => VAR_D,
    VAR_E => VAR_E,
    VAR_F => VAR_F,
    VAR_G => VAR_G,
    VAR_H => VAR_H,
    VAR_I => VAR_I,
    VAR_J => VAR_J,
    VAR_K => VAR_K,
    VAR_L => VAR_L,
    VAR_M => VAR_M,
    VAR_N => VAR_N,
    VAR_O => VAR_O
  );
  COMMIT;
END;

不要尝试传入对象类型。而是传递您用于初始化对象类型的值。您可以 DECLARE 中间变量中的项目首先,或者您可以直接将它们初始化为过程的参数而无需中间变量:

BEGIN
  RECORD_MANAGEMENT.ADD_INTO(
    VAR_A => PROJ_DB.EMPLOYEE_TYPE(
               :var_a, null, null, null, null, null, null, null, null, null, null, null
             ),
    VAR_B => :var_b,
    VAR_C => PROJ_DB.PROJECT_TYPE(
               :var_c, null, null, null, null, null, null, null, null, null
             ),
    VAR_D => to_date(:var_d, 'dd.mm.yyyy hh24:mi:ss'),
    VAR_E => PROJ_DB.SYSTEM_TYPE(:var_e, null, null),
    VAR_F => PROJ_DB.ACTION_TYPE(:var_f, null),
    VAR_G => :var_g,
    VAR_H => :var_h,
    VAR_I => :var_i,
    VAR_J => :var_,
    VAR_K => :var_k,
    VAR_L => :var_l,
    VAR_M => :var_m,
    VAR_N => :var_n,
    VAR_O => :var_o
  );
  COMMIT;
END;