你可以试试这个。您需要声明一个包来捕获您的 id,否则 SQL 语句将看不到它,您将收到错误:
pls-00231: 函数 名 不能在 SQL 中使用
因此,首先创建包含要捕获的函数的包,然后从合并语句中访问 ID:
CREATE OR REPLACE PACKAGE CaptureId
AS
FUNCTION SaveId(newId IN NUMBER) RETURN NUMBER;
FUNCTION GetId RETURN NUMBER;
END;
CREATE OR REPLACE PACKAGE BODY CaptureId
AS
capturedId NUMBER(10);
FUNCTION SaveId(newId IN NUMBER) RETURN NUMBER IS
BEGIN
capturedId := newId;
RETURN capturedId;
END;
FUNCTION GetId RETURN NUMBER IS
BEGIN
RETURN capturedId;
END;
END;
给定一个简单的表和序列生成器,定义为:
CREATE TABLE EMPLOYEE
(
EMPLOYEE_ID NUMBER(10) NOT NULL,
FIRST_NAME VARCHAR2(120) NOT NULL,
LAST_NAME VARCHAR2(120) NOT NULL,
CONSTRAINT PK_EMPLOYEE PRIMARY KEY (EMPLOYEE_ID) ENABLE
);
CREATE SEQUENCE SEQ_EMPLOYEE;
然后,您可以使用带有合并语句的匿名块中的包来捕获 id 并将其返回。请注意,这是一个非常简单的示例,它不适用于数组绑定变量,除非您重新设计包以将 ID 捕获到表类型中。如果有机会,我可能会尝试整理一个示例来说明这一点。
BEGIN
MERGE INTO EMPLOYEE USING (SELECT CaptureId.SaveId(:myInputId) AS EMPLOYEE_ID,
:myFirstName as FIRST_NAME,
:myLastName as LAST_NAME
FROM DUAL) B
ON (A.EMPLOYEE_ID = B.EMPLOYEE_ID)
WHEN NOT MATCHED THEN
INSERT (EMPLOYEE_ID,
FIRST_NAME,
LAST_NAME)
VALUES (CaptureId.SaveId(SEQ_EMPLOYEE.NEXTVAL),
B.FIRST_NAME,
B.LAST_NAME)
WHEN MATCHED THEN
UPDATE SET A.FIRST_NAME= B.FIRST_NAME,
A.LAST_NAME= B.LAST_NAME;
SELECT CaptureId.GetId INTO :myOutputId FROM DUAL;
END;