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

Posted

技术标签:

【中文标题】在两个表之间同步并在 oracle 函数中显示结果【英文标题】:Sync between two tables and show the result in an oracle function 【发布时间】: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 值运行该过程。

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

【问题讨论】:

【参考方案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,使用我现在添加的代码。让我知道它是否有效。

以上是关于在两个表之间同步并在 oracle 函数中显示结果的主要内容,如果未能解决你的问题,请参考以下文章

Oracle不同数据库之间同步处理方案

在 Oracle 中进行表同步报告的优雅方式?

oracle函数不显示结果

在两个 postgres 数据库表之间同步数据

急!两个oracle数据库如何做数据交换

两个oracle数据库个有部分数据要同步给对方怎么办?