我想从oracle合并查询中返回主键。 我使用单个语句插入,如果不存在,我不想使用过程或函数这样做..
这是示例查询
merge into myTable e
using (select :empname name from dual) s
on (UPPER(TRIM(e.empname)) = UPPER(TRIM(s.name)))
when not matched then insert (empname)
values (s.name)
我需要获取myTable的另一个主键字段。使用序列和触发器插入主键
我尝试添加RETURNING empID into :empId
,但却出错
答案 0 :(得分:10)
有一个问题。
Merge Into
不支持Returning Into
,因此无效。要解决它:
sql%rowcount
返回0,请改为执行插入。UPPER(TRIM(name))
)查找已更新的记录。 答案 1 :(得分:3)
你可以试试这个。您需要声明一个包来捕获您的id,否则它将不会对SQL语句可见,您将收到错误:
pls-00231:功能 名称 可能未在SQL中使用
因此,首先使用要捕获的函数创建包,然后再从merge语句中访问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;
然后,您可以在匿名块中使用包与merge语句来捕获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;