在两个表之间同步并在 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 函数中显示结果的主要内容,如果未能解决你的问题,请参考以下文章