【问题标题】:How to initialize a matrix in plsql如何在plsql中初始化一个矩阵
【发布时间】:2018-01-15 18:38:01
【问题描述】:

我试图用关联数组映射一个表,但我不知道如何初始化它

这是一个例子:

TYPE RecType IS RECORD
 (
  value1   NUMBER,
  value2   NUMBER,
  value3   NUMBER
 );
 TYPE TblType IS TABLE OF RecType INDEX BY PLS_INTEGER;
 TYPE TblOfTblType IS TABLE OF TblType INDEX BY PLS_INTEGER;
 matrix   TblOfTblType;

现在当我尝试像这样初始化矩阵时:

FOR i IN matrix.FIRST .. matrix.LAST LOOP
  FOR j IN matrix (i).FIRST .. matrix (i).LAST LOOP
       matrix(i)(j) := NULL;  
  END LOOP;
END LOOP;

不行!我也试过了

matrix := TblOfTblType()();

它显示以下错误:

PLS-00363 表达式“矩阵”不能用作赋值目标。

【问题讨论】:

  • 感谢您的回复,您能帮我如何在 plsql 中创建矩阵,我的程序应该是什么样的?

标签: oracle matrix plsql hashmap associative-array


【解决方案1】:

您不需要使用关联数组 - 集合即可。

DECLARE
  TYPE RecType IS RECORD
  (
    value1   NUMBER,
    value2   NUMBER,
    value3   NUMBER
  );
  TYPE TblType IS TABLE OF RecType;
  TYPE TblOfTblType IS TABLE OF TblType;
  matrix   TblOfTblType := TblOfTblType();
BEGIN
  matrix.EXTEND(3);
  FOR i IN 1 .. matrix.COUNT LOOP
    matrix(i) := TblType();
    matrix(i).EXTEND(4);
    FOR j IN 1 .. matrix(i).COUNT LOOP
      matrix(i)(j).value1 := i;
      matrix(i)(j).value2 := j;
      matrix(i)(j).value3 := DBMS_RANDOM.VALUE;
    END LOOP;
  END LOOP;

  FOR i IN 1 .. matrix.COUNT LOOP
    FOR j IN 1 .. matrix(i).COUNT LOOP
      DBMS_OUTPUT.PUT( '[' || matrix(i)(j).value1
                    || ',' || matrix(i)(j).value2
                    || ',' || matrix(i)(j).value3 || ']' || CHR(11) );
    END LOOP;
    DBMS_OUTPUT.NEW_LINE;
  END LOOP;
END;
/

【讨论】:

  • 可以打印一下矩阵吗?
  • @XING OP 只是询问初始化矩阵。但是,在另一组循环中使用DBMS_OUTPUT.PUT( matrix(i)(j).value1 )DBMS_OUTPUT.PUT_LINE( matrix(i)(j).value3 ) 是一件简单的事情。
  • 这行不通,我猜矩阵也行不通
  • @xing - 您的代码不起作用,因为 value 是嵌套集合的属性,而您正在引用外部集合。看 MT0 评论中的代码:它有效。
  • @XING 加了一个很简单的例子。
【解决方案2】:

虽然我同意@MTO 的方法,但循环方法的错误是因为您试图在一个空表上引用FIRSTLAST,并且此时它们都评估为null。您实际上是在尝试这样做:

FOR i IN null .. null LOOP

它获得与原始FOR 循环相同的ORA-06502: PL/SQL: numeric or value error

您还没有在任何地方定义矩阵的尺寸。您需要在某个地方执行此操作才能“初始化”它,例如使用固定值来匹配 MTO 和您的类型声明:

DECLARE
  TYPE RecType IS RECORD
  (
    value1   NUMBER,
    value2   NUMBER,
    value3   NUMBER
  );
  TYPE TblType IS TABLE OF RecType INDEX BY PLS_INTEGER;
  TYPE TblOfTblType IS TABLE OF TblType INDEX BY PLS_INTEGER;
  matrix   TblOfTblType;
BEGIN
  FOR i IN 1 .. 3 LOOP
    FOR j IN 1 .. 4 LOOP
      matrix(i)(j) := null;
    END LOOP;
  END LOOP;
END;
/

PL/SQL procedure successfully completed.

要填充非空值,您需要一个单独的记录变量来填充,然后分配给矩阵位置:

  FOR i IN 1 .. 3 LOOP
    FOR j IN 1 .. 4 LOOP
      rec.value1 := i;
      rec.value2 := j;
      rec.value3 := DBMS_RANDOM.VALUE;
      matrix(i)(j) := rec;
    END LOOP;
  END LOOP;

或者,如果您在其他地方获取这些表格,您可以在没有循环的情况下定位特定的矩阵元素。您也可以按照 MTO 显示的方式打印出来,或者使用现在有效的 FIRSTLAST

  FOR i IN matrix.FIRST .. matrix.LAST LOOP
    FOR j IN matrix(i).FIRST .. matrix(i).LAST LOOP
      DBMS_OUTPUT.PUT( '[' || matrix(i)(j).value1
                    || ',' || matrix(i)(j).value2
                    || ',' || matrix(i)(j).value3 || ']' || CHR(11) );
    END LOOP;
    DBMS_OUTPUT.NEW_LINE;
  END LOOP;

【讨论】:

  • 如果您将FIRSTLAST 与关联数组一起使用,那么最好假设一个稀疏数组并使用i := matrix.FIRST; WHILE i IS NOT NULL LOOP 循环的内容i := matrix.NEXT(i); END LOOP; 而不是使用@ 987654335@循环。
  • 是的,我假设它已按照 OP 的预期进行初始化,因此它实际上是密集的。如果可以在原始 3x4 范围之外添加元素,则需要更强大的东西。您添加到答案中的输出循环也有效,但需要检查每个点是否存在某些东西,如果它可以是稀疏的。
【解决方案3】:
CREATE OR REPLACE TYPE RecType AS OBJECT (
  value1   NUMBER,
  value2   NUMBER,
  value3   NUMBER
 );
/   

CREATE OR REPLACE TYPE TblType IS TABLE OF RecType;
/

CREATE OR REPLACE TYPE TblOfTblType IS TABLE OF TblType;
/

DECLARE
     matrix   TblOfTblType;   
       rec1   RecType;
       rec2   TblType; 
BEGIN
    rec1 := RecType(1,2,3);
    rec2 := TblType(rec1);   
    matrix := TblOfTblType(rec2);
    dbms_output.put_line(matrix(1)(1).value2);
END;

【讨论】:

    猜你喜欢
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 2018-12-13
    • 1970-01-01
    相关资源
    最近更新 更多