在两个表之间同步并在oracle函数中显示结果

时间:2014-10-09 03:30:11

标签: oracle plsql

我正在创建一个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中执行begin部分,我可以看到受影响的行数。我的目标是将此函数收集到一个过程中,当用户想要同步表时,他们只需要为特定项目提供PROJNAME值来运行该过程。

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

1 个答案:

答案 0 :(得分:0)

您可以使用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。这会将该函数运行到一个独立的事务中,该事务将能够执行DML而不会引发ORA-14551。但是,请记住,DML的结果将在父事务的范围之外提交。如果您只有一个事务,则可以使用我建议的解决方法。在PRAGMA AUTONOMOUS_TRANSACTION;之前的RETURN语句后立即添加BEGIN

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;
  /