【问题标题】:Table variable as in parameter to populate a table in oracle Stored procedure表变量作为参数在 oracle 存储过程中填充表
【发布时间】:2016-03-16 16:17:03
【问题描述】:

我通常避免将表变量作为存储过程的输入参数。因为我不知道如何处理它们,但在这种情况下我别无选择。我需要将数百条记录从 Oracle Agile PLM 传递到数据库。我要做的是从输入记录/列表中填充一个表。为了实现这一点,我开发了一个对象类型,然后从该对象类型中开发了一个表类型。

CREATE OR REPLACE TYPE TEST_USER.MD_TYPE AS OBJECT
                  (QUERY_REF VARCHAR2 (1000 BYTE),
                   COL_NAME VARCHAR2 (100 BYTE),
                   COL_LENGTH VARCHAR2 (50 BYTE),
                   COL_SEQ NUMBER)
/

CREATE OR REPLACE TYPE TEST_USER.MD_TYPE_TABLE  AS TABLE OF  MD_TYPE
/

存储过程:

CREATE OR REPLACE PROCEDURE SP_TEST2
(
  P_MD_TABLE IN MD_TYPE_TABLE,
  p_success OUT number 
) 
IS

BEGIN

  INSERT INTO MDATA_TABLE
  (
QUERY_REF ,
                   COL_NAME ,
                   COL_LENGTH ,
                   COL_SEQ 

  )
    SELECT  ea.*
    FROM  TABLE(P_MD_TABLE) ea;

    p_success :=1;
    EXCEPTION 
    WHEN OTHERS THEN
    p_success := -1;
END SP_TEST2;

问题是我不知道如何填充,先是参数P_MD_TABLE,然后是MDATA_TABLE。并且程序编译没有任何错误。我没有测试过这个过程。

请帮忙。

通过向 MD_TYPE 传递参数来加载 MD_TYPE_TABLE 的过程

CREATE OR REPLACE PROCEDURE SP_UPLOAD_MD_TYPE
(
P_QUERY_REF VARCHAR2,
P_COL_NAME VARCHAR2,
P_COL_LENGTH VARCHAR2,
p_col_seq NUMBER,
p_no_of_rows_to_insert NUMBER,
p_num OUT NUMBER
)
IS

    p_type_tbl  MD_TYPE_TABLE := MD_TYPE_TABLE(); --initialize

BEGIN
  <<vartype>>
         FOR i IN 1..p_no_of_rows_to_insert
         LOOP
    p_type_tbl.extend();
    p_type_tbl(p_type_tbl.last) := MD_TYPE(P_QUERY_REF, P_COL_NAME, P_COL_LENGTH, p_col_seq);
         END LOOP vartype;


    SP_TEST2(p_type_tbl, p_num);


END;

【问题讨论】:

  • "我不知道如何填充表格MDATA_TABLE"...MDATA_TABLE or P_MD_TABLE ???
  • 我已经编辑了我的问题。

标签: oracle plsql


【解决方案1】:

您可以使用extend/ bulk collect 填充table type

使用extend

p_type_tbl.extend();
p_type_tbl(p_type_tbl.last) := MD_TYPE('QUERY_REF1', 'COL_NAME1', 'COL_LENGTH1', 1);

或使用bulk collect

SELECT MD_TYPE(c1, c2... cn)
  BULK COLLECT INTO p_type_tbl
  FROM   some_table;

演示

DECLARE
    p_type_tbl  MD_TYPE_TABLE := MD_TYPE_TABLE(); --initialize
    p_num NUMBER;
BEGIN
    p_type_tbl.extend();
    p_type_tbl(p_type_tbl.last) := MD_TYPE('QUERY_REF1', 'COL_NAME1', 'COL_LENGTH1', 1);

    p_type_tbl.extend();
    p_type_tbl(p_type_tbl.last) := MD_TYPE('QUERY_REF2', 'COL_NAME2', 'COL_LENGTH2', 2);

    SP_TEST2(p_type_tbl, p_num);

    DBMS_OUTPUT.PUT_LINE(p_num);
END;
/

输出
1

SELECT * FROM MDATA_TABLE;

输出

QUERY_REF   COL_NAME    COL_LENGTH  COL_SEQ
QUERY_REF1  COL_NAME1   COL_LENGTH1 1
QUERY_REF2  COL_NAME2   COL_LENGTH2 2

【讨论】:

  • 根据您的回答,我必须先创建一个加载 MD_TYPE 类型的过程,然后调用 sp_test2 过程。问题是每次执行我必须加载近 50000 条记录,而不是一两条记录。但是,我开发了一个可以传递 MD_TYPE 值然后执行过程 sp_test2 的过程。但它仅适用于 1 条记录。我怎样才能使它适用于 50000 条记录。我已经为这个程序编辑了我的问题。
  • 在我的测试中SP_UPLOAD_MD_TYPE将50000条数据插入到表MDATA_TABLE中。
  • DECLARE p_num NUMBER; BEGIN SP_UPLOAD_MD_TYPE('QUERY_REF1', 'COL_NAME1', 'COL_LENGTH1', 1, 50000, p_num); END;
  • SELECT Count(*) FROM MDATA_TABLE ---> 50000
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
  • 2012-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多