【问题标题】:PLSQL insert and returning id form trigger on tablePLSQL 在表上插入和返回 id 表单触发器
【发布时间】:2017-01-21 02:29:17
【问题描述】:

我正在尝试在 PLSQL 插入中执行插入语句并返回从使用序列的表上的触发器生成的 id,但是 我的错误剂量低于任何人对此有任何想法吗?

ORA-00905:缺少关键字

ORA-06512:在“ADMIN.F_INSERT_ORDER_DATA”,第 22 行

ORA-06512:在第 5 行

CREATE OR REPLACE FUNCTION F_INSERT_ORDER_DATA (P_CUSTOMER_ID   IN NUMBER,
                                                                                                      P_NOTES                IN VARCHAR2)
       RETURN NUMBER
    IS
       vCreated_ON   DATE := SYSDATE;
       vORDER_ID     NUMBER;
       vSQL          VARCHAR2 (1024);
    BEGIN
       vSQL := 'INSERT INTO orders'
                                          ||'(ORDER_ID,'
                                          || 'CUSTOMER_ID,'
                                          || 'NOTES,'
                                          || 'CREATED_BY,'
                                          || 'CREATED_ON)'
                                          || 'VALUES (NULL,'                                    --ORDER_ID Filled by trigger
                                          || P_CUSTOMER_ID|| ','                           --CUSTOMER_ID
                                          || ''''|| P_NOTES|| ''','                             --NOTES
                                          || '''SYSTEM'','                                        --CREATED_BY
                                          || ''''|| vCREATED_ON|| ''')'                   --CREATED_ON
               || 'RETURNING ORDER_ID INTO vORDER_ID';

       EXECUTE IMMEDIATE vSQL;
       DBMS_OUTPUT.PUT_LINE(vORDER_ID);

       RETURN (vORDER_ID);
    END F_INSERT_ORDER_DATA;
    /

如下调用函数

declare
   result varchar2(1024);
begin
   -- Call the function
   result := F_INSERT_ORDER_DATA (1000,'----');

end;

代码更新

CREATE OR REPLACE FUNCTION F_INSERT_ORDER_DATA (P_CUSTOMER_ID   IN NUMBER,
                                                P_NOTES         IN VARCHAR2)
   RETURN NUMBER
IS
   vORDER_ID     NUMBER;
   vCreated_by   VARCHAR2 (128) := 'SYSTEM';
   vCreated_ON   DATE := SYSDATE;
   sql_stmt      VARCHAR2 (1024);
BEGIN
   sql_stmt :=
      'INSERT INTO orders (ORDER_ID,
                                                         CUSTOMER_ID,
                                                         NOTES,
                                                        CREATED_BY,
                                                        CREATED_ON)
                                        VALUES (NULL,                                 --ORDER_ID Filled by trigger
                                                       :PCUSTOMER_ID,               --CUSTOMER_ID
                                                       :PNOTES,                            --NOTES
                                                       :PCREATED_BY,                  --CREATED_BY
                                                       :PCREATED_ON,                 --CREATED_ON
                     RETURNING ORDER_ID INTO :vORDER_ID';

   EXECUTE IMMEDIATE sql_stmt
      USING P_CUSTOMER_ID,
            P_NOTES,
            VCreated_by,
            vCreated_ON
      RETURNING INTO vORDER_ID;

   DBMS_OUTPUT.PUT_LINE (vORDER_ID);

   RETURN (vORDER_ID);
END F_INSERT_ORDER_DATA;
/

调用函数

DECLARE
   vSQL    VARCHAR2 (4000);
   var     NUMBER;
BEGIN
   vSQL := 'F_INSERT_ORDER_DATA(:P_CUSTOMER_ID,:P_NOTES);';

   EXECUTE IMMEDIATE vSQL USING 1000, 'TEST' RETURNING INTO var;

   DBMS_OUTPUT.PUT_LINE (var);
END;

【问题讨论】:

    标签: oracle plsql oracle11gr2


    【解决方案1】:

    您的代码几乎没有问题。一是与return子句的绑定不正确。在下面的链接中查看它的工作原理。

    Execute Immediate with returning clause

    CREATE OR REPLACE FUNCTION F_INSERT_ORDER_DATA(P_CUSTOMER_ID IN NUMBER,
                                                   P_NOTES       IN VARCHAR2)
      RETURN NUMBER IS
      vCreated_ON DATE := SYSDATE;
      vORDER_ID   NUMBER;
    
    BEGIN
      vSQL := 'INSERT INTO orders' || '(ORDER_ID,' || 'CUSTOMER_ID,' ||
              'NOTES,' || 'CREATED_BY,' || 'CREATED_ON)' || 'VALUES (NULL,' --ORDER_ID Filled by trigger
              || P_CUSTOMER_ID|| ',' --CUSTOMER_ID
              || P_NOTES || ','--NOTES
              || '''SYSTEM'',' --CREATED_BY
              || '''' || vCREATED_ON || ''')' --CREATED_ON
              || 'RETURNING ORDER_ID INTO :vORDER_ID';
    
      EXECUTE IMMEDIATE vSQL RETURNING INTO vORDER_ID ;
      DBMS_OUTPUT.PUT_LINE(vORDER_ID);
    
      RETURN(vORDER_ID);
    END F_INSERT_ORDER_DATA;
    /
    

    演示:

    SQL> declare
      2    var varchar2(4000);
      3    var1 number;
      4  begin
      5  
      6    var := 'insert into dummy_emp(empid)values(2) RETURNING empID INTO :var1';
      7  
      8    execute immediate var
      9      RETURNING INTO var1;
     10    commit;
     11    
     12    dbms_output.put_line(var1);
     13  
     14  end;
     15  /
    
     2
    
    PL/SQL procedure successfully completed.
    
    SQL> 
    

    这就是您需要在 PLSQL 块中调用函数的方式:

    DECLARE      
       var     NUMBER;
    BEGIN
       var := F_INSERT_ORDER_DATA(1000,'TEST');
       DBMS_OUTPUT.PUT_LINE (var);
    END;
    

    在 Simple SQL 中,您可以如下调用:

      Select F_INSERT_ORDER_DATA(1000,'TEST') from dual;
    

    【讨论】:

    • 我已经根据您提供的链接更新了我的代码,现在我在调用函数部分时遇到错误...ORA-00900: invalid SQL statement 和错误ORA-06512: at line 7 请如果您这样做,专业方式对我来说是新的不介意看看..谢谢
    • 查看我更新的帖子如何在 plsql 块中调用函数
    • 非常感谢具有专业技能的杰出人士的支持......我非常感谢您的善意支持:
    • 其他人注意Select F_INSERT_ORDER_DATA(1000,'TEST') from dual; 方式调用函数将导致错误消息ORA-14551: cannot perform a DML operation inside a query 并且仅在这种情况下不会起作用,因为消息说存在DML函数内部的操作
    【解决方案2】:

    这是我的版本(我需要file_id,它是另一个表的外键):

    create or replace function INSERT_INTO_table_name_ID return number 
     is
      v_file_name  VARCHAR2(690) := 'List from .. on '||sysdate;
      v_file_id    NUMBER;
     BEGIN     
      INSERT INTO table_name(file_id, file_name) --file_id filled by trigger to
           VALUES (null, v_file_name) 
        RETURNING file_id 
             INTO v_file_id;                  
      COMMIT;
      RETURN(v_file_id);
     END;
    

    演示:

    declare
    v_id number;
    begin
    v_id := INSERT_INTO_table_name_ID ;
     dbms_output.put_line(v_id);
    end;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-01
      • 2013-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多