我正在创建一个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值来运行该过程。
请帮助我了解如何改进此代码, 最好的问候
答案 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;
/