2014-02-26 48 views
0

又一個sql(oracle)問題。返回使用子查詢的插入行的ID

我想返回插入行的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),它是由觸發器/序列組合自動遞增的。

我很樂意接受。這不起作用,因爲我猜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; 
+1

使用'返回FORECAST_PROFILE_ID批量收集到your_nt',然後閱讀'your_nt(1)' –

+0

@EgorSkriptunoff - 這很好,我不知道你可以這樣做 – ninesided

回答

2

這裏的問題是,你的選擇威力返回多行。也許不是現在,但是誰知道誰將在未來屠殺你的模式。 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。缺點是,如果系統發生過任何更改,以致查詢DOES返回多行,則只會返回最後一個ID。

+0

我跳過L_FP_ID並直接進入FP_ID。像魅力一樣工作。謝謝! :) –