【问题标题】:Sync between two tables and show the result in an oracle function在两个表之间同步并在 oracle 函数中显示结果
【发布时间】:2014-10-09 03:30:10
【问题描述】:

我正在制作一个在两个表之间同步值的 oracle 函数,我的目的是显示一个字符串,该字符串显示受影响的行数并在用户执行该函数时显示它。

我的函数创建是这样的

    CREATE OR REPLACE FUNCTION WELTESADMIN.DUM_MST_SYNC(PROJNAME IN VARCHAR2)
RETURN NUMBER IS NUM_ROWS NUMBER;
  BEGIN
    MERGE INTO MASTER_DRAWING DST
    USING (SELECT WEIGHT_DUM, HEAD_MARK_DUM FROM DUMMY_MASTER_DRAWING) SRC
      ON (DST.HEAD_MARK = SRC.HEAD_MARK_DUM)
        WHEN MATCHED THEN UPDATE SET DST.WEIGHT = SRC.WEIGHT_DUM
          WHERE DST.PROJECT_NAME = SRC.PROJECT_NAME_DUM
          AND DST.PROJECT_NAME = PROJNAME;
          dbms_output.put_line( sql%rowcount || ' rows merged' ); 
  END;

如果我在 TOAD 或 SQL Developer 中执行开始部分,我可以看到有多少行受到影响。我的目标是将这个函数收集到一个过程中,当用户想要同步表时,他们只需要使用为特定项目提供的 PROJNAME 值运行该过程。

请帮助我如何改进此代码, 最好的问候

【问题讨论】:

    标签: oracle plsql


    【解决方案1】:

    您可以使用SQL%ROWCOUNT 获取受MERGE 影响的行数。在 MERGE 之后立即在代码中添加以下语句:

    dbms_output.put_line( sql%rowcount || ' rows merged' );

    要返回此值,请声明一个NUMBER 变量并将sql%rowcount 值分配给它。然后返回该值。类似的东西:

    Function
    .......
    
    Return NUMBER
    .......
    num_rows NUMBER;
    ......
    
    Begin
    
    Merge....
    
    num_rows := SQL%ROWCOUNT;
    
    RETURN num_rows;
    
    END;
    

    而且,您不需要过程来执行该功能。您可以在 SQL 中执行:

    select function(project_name) 
      from dual
    /
    

    更新由于 OP 试图在函数内部使用 DML,因此需要使其成为自治事务才能在不引发 ORA-14551 的情况下执行 DML。

    您可以使用指令pragma autonomous_transaction。这会将函数运行到一个独立的事务中,该事务将能够在不引发ORA-14551 的情况下执行 DML。但是,请记住,DML 的结果将在父事务范围之外提交。如果您只有一个事务,则可以使用我建议的解决方法。在 RETURN 语句之后紧跟在 BEGIN 之前添加 PRAGMA AUTONOMOUS_TRANSACTION;

    CREATE OR REPLACE
      FUNCTION WELTESADMIN.DUM_MST_SYNC(
          PROJNAME IN VARCHAR2)
        RETURN NUMBER
      IS
        num_rows NUMBER;
        PRAGMA AUTONOMOUS_TRANSACTION;
      BEGIN
        MERGE INTO MASTER_DRAWING DST USING
        (SELECT WEIGHT_DUM, HEAD_MARK_DUM FROM DUMMY_MASTER_DRAWING
        ) SRC ON (DST.HEAD_MARK = SRC.HEAD_MARK_DUM)
      WHEN MATCHED THEN
        UPDATE
        SET DST.WEIGHT         = SRC.WEIGHT_DUM
        WHERE DST.PROJECT_NAME = SRC.PROJECT_NAME_DUM
        AND DST.PROJECT_NAME   = PROJNAME;
        num_rows              := SQL%ROWCOUNT;
        COMMIT;
        RETURN num_rows;
      END;
      /
    

    【讨论】:

    • 你的意思是在 return 语句中添加该行?
    • 我还添加了如何执行该功能,而不是使用您最初想要的过程。
    • 我修改了我的函数,但是当我想像这样执行时,从 dual 中选择 DUM_MST_SYNC('PROCESSHOUSE');它说不能在查询 ORA14551 中执行 DML 操作
    • 是的,我在等你这么说。您可以使用指令pragma autonomous_transaction。这会将函数运行到一个独立的事务中,该事务将能够在不引发 ORA-14551 的情况下执行 DML。但是,请记住,DML 的结果将在父事务范围之外提交。如果您只有一个事务,则可以使用我建议的解决方法。在BEGIN 之前的RETURN 语句之后立即添加PRAGMA AUTONOMOUS_TRANSACTION;。看我的回答,我更新了。
    • @ChrisWeltes,使用我现在添加的代码。让我知道它是否有效。
    猜你喜欢
    • 2011-04-09
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多