2009-08-26 70 views
12

我知道在Oracle我可以從插入的行獲取生成的id(或任何其他列)作爲輸出參數。 例如:如何使用ExecuteScalar從插入的行中獲取生成的ID?

insert into foo values('foo','bar') returning id into :myOutputParameter 

有沒有辦法做同樣的,但使用的ExecuteScalar代替的ExecuteNonQuery?

我不想使用輸出參數或存儲過程。

ps:我正在使用Oracle,而不是sql server !!!

+0

把這個作爲,因爲它是投機性的,但SQL Server HA「@@ SCOPE_IDENTITY」這樣的語句可以評論「插入FO ....;選擇@@ SCOPE_IDENTITY」 ...... Oracle是否有東西類似? – Rob 2009-08-26 19:23:25

+2

這將是答案:) – andrecarlucci 2009-08-26 19:32:23

+0

爲SQL Server中,我不知道這個系統變量@@ SCOPE_IDENTITY,所以我知道的IDENT_CURRENT標量函數做同樣的(SELECT IDENT_CURRENT(N'TableName') – 2009-09-02 17:20:27

回答

6

如果我們可以這樣說,Oracle使用序列作爲他的身份列。

如果您爲表主鍵設置了一個序列,還必須編寫一個觸發器,將Sequence.NextValue左右插入到主鍵字段中。

假設你已經熟悉這個概念,只需查詢你的序列,那麼你將得到你的答案。在Oracle中實踐的一點是讓自己成爲一個函數,它將返回一個INT,然後在你的函數中執行INSERT。假設你已經正確設置你的觸發器,你將能夠通過查詢返回序列的值。

這裏有一個實例:

CREATE TABLE my_table (
    id_my_table INT PRIMARY KEY 
    description VARCHAR2(100) NOT NULL 
) 

CREATE SEQUENCE my_table_seq 
    MINVALUE 1 
    MAXVALUE 1000 
    START WITH 1 
    INCREMENT BY 2 
    CACHE 5; 

如果你要管理的自動遞增自己,這裏是如何:

INSERT INTO my_table (
    id_my_table, 
    description 
) VALUES (my_table_seq.NEXTVAL, "Some description"); 
COMMIT; 

在另一方面,如果你想不關心主按鍵增量,您可以繼續觸發。

CREATE OR REPLACE TRIGGER my_table_insert_trg 
    BEFORE INSERT ON my_table FOR EACH ROW 
BEGIN 
    SELECT my_table_seq.NEXTVAL INTO :NEW.id_my_table FROM DUAL; 
END; 

然後,當你插入,您只需鍵入INSERT語句如下:

INSERT INTO my_table (description) VALUES ("Some other description"); 
COMMIT; 

一個INSERT後,我猜你會想

SELECT my_table_seq.CURRVAL 

或像這樣的東西來選擇你的序列的實際值。

這裏有一些鏈接,可以幫助:

http://www.orafaq.com/wiki/Sequence

http://www.orafaq.com/wiki/AutoNumber_and_Identity_columns

希望這有助於!

+0

嗨Will, 不錯,我沒有考慮seq.CURRVAL。但是這是保存嗎?我的意思是,如果有人在我的兩個調用之間插入一行(插入,選擇)? – andrecarlucci 2009-08-28 13:20:50

+0

通常,這些類型的操作與您的數據庫連接/會話有關,以防止出現這種情況。對於Oracle,我無法在黑白中找到它,但這就是它適用於MySQL,Access,SQL Server等的方式。 – 2009-08-28 18:26:03

+1

Oracle將按順序執行插入操作。一旦它通過第一個INSERT語句並返回新的當前序列的值,它將執行另一個插入。 如前所述通過瘋狂的喬·馬洛伊先生,那就是不管是什麼反正做它的方式。 :) 我們不能忘記Oracle以事務處理的方式工作。因此,只要INSERT語句不是COMMIT的,就不會從序列中選擇NEXTVALUE。 ,無論如何,如果我沒有記錯,有somekind的鎖的地方(表或序列)在執行交易。 – 2009-09-02 17:18:04

24

如果你在oracle上,你必須使用ExecuteNonQuery和ResultParameter。沒有辦法將其寫爲查詢。

using (OracleCommand cmd = con.CreateCommand()) { 
    cmd.CommandText = "insert into foo values('foo','bar') returning id into :myOutputParameter"; 
    cmd.Parameters.Add(new OracleParameter("myOutputParameter", OracleDbType.Decimal), ParameterDirection.ReturnValue); 
    cmd.ExecuteNonQuery(); // an INSERT is always a Non Query 
    return Convert.ToDecimal(cmd.Parameters["myOutputParameter"].Value); 
} 
+0

什麼是ParameterDirection.ReturnValue'和'ParameterDirection.Output'? – Timeless 2014-08-07 08:00:59

+0

ParameterDirection.ReturnValue之間'的差的函數的結果。ParameterDirection.Output是用於方法(函數或程序)參數,這些參數被定義爲out或inout。 – Christian13467 2014-08-20 08:00:48

+1

嘆氣!我不斷收到'ORA-12537:網絡會話:在的ExecuteNonQuery file'的結束,無論我怎麼努力:( – 2017-04-21 14:25:07

1

如果可以在表中添加一個名爲「guid」的列,那麼一種可能: 從c#插入一條記錄時,生成一個guid並將其寫入guid列。 然後執行選擇與生成的GUID,和你有插入的記錄:)

0
Select t.userid_pk From Crm_User_Info T 
Where T.Rowid = (select max(t.rowid) from crm_user_info t) 

這將返回您所需的ID

2

的ID,您可以使用下面的代碼。

using (OracleCommand cmd = conn.CreateCommand()) 
    { 
     cmd.CommandText = @"INSERT INTO my_table(name, address) 
      VALUES ('Girish','Gurgaon India') 
      RETURNING my_id INTO :my_id_param"; 
     OracleParameter outputParameter = new OracleParameter("my_id_param", OracleDbType.Decimal); 
     outputParameter.Direction = ParameterDirection.Output; 
     cmd.Parameters.Add(outputParameter);   
     cmd.ExecuteNonQuery();   
     return Convert.ToDecimal(outputParameter.Value); 
    } 
相關問題