2015-10-20 41 views
0

我正在處理遺留項目,需要插入一行並返回該行或其標識。返回使用sql存儲過程插入的行的標識

新行以正確的值插入,只有在返回到.net時,數據集中才會返回任何內容。

我試過選擇@@identity,RETURN,OUTPUT,但我試過的一切數據集都是空的(但不是空的)。

這不是MyUtils.DBHelper.GetDataSet的錯,因爲它在其他地方使用並執行並返回正常。

USE [dbname] 
GO 

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER Procedure [dbo].[DuplicateOrder] 
(
    @sourceid int, 
    @var1 int, 
    @var2 decimal(10,2), 
) 
AS 

INSERT INTO OrderHeader (
    Users_ID, 
    Stores_ID, 
    ) 
SELECT 
    @var1, 
    @var2 
FROM Order 
WHERE id = @sourceid 
GO 

我使用執行存儲過程的代碼是:

Using cmd As New SqlCommand("DuplicateOrder") With {.CommandType = CommandType.StoredProcedure} 
        cmd.Parameters.AddWithValue("@sourceid", sourceId) 
        cmd.Parameters.AddWithValue("@var1 ", var1) 
        cmd.Parameters.AddWithValue("@var2 ", var2) 
        ds = MyUtils.DBHelper.GetDataSet(cmd) 
End Using 
+0

如何你有沒有試過選擇@@身份?除非您處於多連接環境中,否則這通常很適用 – Grantly

回答

1

這應該是關鍵:

ALTER Procedure [dbo].[DuplicateOrder] 
(
    @sourceid int, 
    @var1 int, 
    @var2 decimal(10,2) 
) 
AS 

INSERT INTO OrderHeader (
    Users_ID, 
    Stores_ID 
    ) 
SELECT 
    @var1, 
    @var2 

SELECT @@IDENTITY AS ident 
GO 

我測試了它o n SQL服務器,它返回一行,列ident

0

你試圖執行此SELECT IDENT_CURRENT ('Table') AS Current_Identity;應該在當前會話中返回最後生成的標識和範圍

0

@@身份和返回將無法正常工作(SCOPE_IDENT(),IDENT_CURRENT()以及如果您打算一次插入多個行將無法正常工作)。

最好的辦法是使用OUTPUT,但在代碼中看不到任何OUTPUT。下面是一個例子(代碼部分是用C#編寫的,但你可以很容易地轉換它,比如使用Telerik轉換器或者自己編寫 - 有N種方法可以傳遞數據,我在本例中選擇了XML):

SQL代碼生成的示例表和過程:

USE [Test]; 
GO 

CREATE TABLE IdentityTest 
    (
    Id INT IDENTITY 
      NOT NULL 
      PRIMARY KEY , 
    FirstName VARCHAR(20) , 
    LastName VARCHAR(20) 
); 
GO 

CREATE PROCEDURE InsertTestData 
    (
    @XML VARCHAR(MAX) , 
    @NodeName VARCHAR(1000) 
) 
AS 
    BEGIN 

    DECLARE @myIDTable TABLE (theID INT); 

    DECLARE @hDoc INT; 
    DECLARE @tbl TABLE 
     (
     fName VARCHAR(20) , 
     lName VARCHAR(20) 
    ); 
    EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML; 
    INSERT @tbl 
    SELECT * 
    FROM OPENXML(@hDoc, @NodeName, 1) WITH (fName VARCHAR(20), lName VARCHAR(20)); 
    EXEC sp_xml_removedocument @hDoc; 

    INSERT INTO [IdentityTest] ([FirstName], [LastName]) 
    OUTPUT [Inserted].[Id] 
      INTO @myIDTable 
    SELECT t.[fName], t.[lName] 
    FROM @tbl AS t; 

    SELECT * 
    FROM @myIDTable AS [mit]; 

    END; 
GO 

這是用SP和插入多行和找回自己的ID的C#代碼(可能已經返回了全行數據):

void Main() 
{ 
    List<Person> people = new List<Person> { 
    new Person { FName = "Sam", LName="Jones"}, 
    new Person { FName = "Cetin", LName="Basoz"}, 
    new Person { FName = "John", LName="Doe"}, 
    new Person { FName = "Steven", LName="Smith"}, 
    new Person { FName = "Bob", LName="Carpenter"}, 
    }; 

    for (int i = 0; i < 100; i++) 
    { 
    people.Add(new Person 
    { 
     FName = string.Format("FName#{0}", i), 
     LName = string.Format("LName#{0}", i) 
    }); 
    } 

    var peopleAsXML = new XElement("People", 
    from p in people 
    select new XElement("Person", 
     new XAttribute("fName", p.FName), 
     new XAttribute("lName", p.LName))); 

    string sql = @"InsertTestData"; 
    DataTable result = new DataTable(); 
    using (SqlConnection con = new SqlConnection(@"server=.\SQLExpress2012;Trusted_Connection=yes;Database=Test")) 
    { 
    SqlCommand cmd = new SqlCommand(sql, con); 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.AddWithValue("@XML", peopleAsXML.ToString()); 
    cmd.Parameters.AddWithValue("@NodeName", "/People/Person"); 
    con.Open(); 
    result.Load(cmd.ExecuteReader()); 
    con.Close(); 
    } 
    // check top 5 returned 
    for (int i = 0; i < 5; i++) 
    { 
    Console.WriteLine((int)result.Rows[i]["theID"]); 
    } 
} 

public class Person 
{ 
    public string FName { get; set; } 
    public string LName { get; set; } 
}