又一个sql(oracle)问题。
我正在尝试返回插入行的ID,但是有一个问题。插入使用子查询。
create or replace procedure NEW_FORECAST_PROFILE (CA_ID IN NUMBER, FP_ID OUT NUMBER)
BEGIN
INSERT INTO FORECAST_PROFILE(
NAME,
COMPANY_ACCOUNT_ID
)
SELECT
TO_CHAR(SYSDATE, 'MON-DD-yyyy HH:MM AM') AS NAME,
COMPANY_ACCOUNT_ID
FROM MASTER_DEFAULTS
WHERE COMPANY_ACCOUNT_ID = CA_ID
RETURNING FORECAST_PROFILE_ID INTO FP_ID;
END;
我正在尝试做什么:
1)在一个表中查找一行并将其复制到另一个表中。
2)返回新行的ID(FORECAST_PROFILE_ID),该ID由触发/序列组合自动递增。
我愿意接受各种想法。这不起作用,因为我猜测sql解析器期望返回多个ID。
我发现了一些接近但我需要转换为oracle语法:
DECLARE @inserted_ids TABLE ([id] INT);
INSERT INTO [dbo].[some_table] ([col1],[col2],[col3],[col4],[col5],[col6])
OUTPUT INSERTED.[id] INTO @inserted_ids
VALUES (@col1,@col2,@col3,@col4,@col5,@col6)
**更新** 解决问题的一种(坏)方法是获取用于生成列的序列的当前值。但是,如果有多个用户更新表格,我认为这会遇到问题。
FP_ID := FORECAST_PROFILES_SEQ.CURRVAL;
答案 0 :(得分:2)
这里的问题是你的select 可能会返回多行。也许不是现在,但是谁知道将来会对你的架构进行屠宰。 Oracle无需检查company_account_id
是否具有唯一约束,并且约束是否有效并已启用。
我会按如下方式重新组织声明:
FOR r_profile IN (
SELECT
TO_CHAR(SYSDATE, 'MON-DD-yyyy HH:MM AM') AS NAME,
COMPANY_ACCOUNT_ID
FROM MASTER_DEFAULTS
WHERE COMPANY_ACCOUNT_ID = CA_ID
)
LOOP
INSERT INTO FORECAST_PROFILE (
NAME,
COMPANY_ACCOUNT_ID
) VALUES (
r_profile.NAME,
r_profile.COMPANY_ACCOUNT_ID
) RETURNING
FORECAST_PROFILE_ID INTO L_FP_ID
;
END;
FP_ID := L_FP_ID;
您只需要声明L_FP_ID
局部变量,尽管您可以完全跳过它并使用FP_ID
。缺点是,如果系统发生了更改,以至于查询返回多行,则只返回最后一个ID。