2013-08-22 13 views
60

Witam Wstawiam niektóre wartości do tabeli sql przy użyciu C# w MVC4. Właściwie chcę wstawić wartości i zwrócić "ID" ostatnio wstawionego rekordu. Używam następującego kodu.Wykonaj polecenie Wstaw i zwróć wstawiony identyfikator w Sql

public class MemberBasicData 
{ 
    public int Id { get; set; } 
    public string Mem_NA { get; set; } 
    public string Mem_Occ { get; set; }  
} 

ID automatycznie inkrementacji danych po włożeniu.

public int CreateNewMember(string Mem_NA, string Mem_Occ) 
{ 
    using (SqlConnection con=new SqlConnection(Config.ConnectionString)) 
    { 
     using(SqlCommand cmd=new SqlCommand("INSERT INTO Mem_Basic(Mem_Na,Mem_Occ) VALUES(@na,@occ)",con)) 
     { 
      cmd.Parameters.AddWithValue("@na", Mem_NA); 
      cmd.Parameters.AddWithValue("@occ", Mem_Occ); 
      con.Open(); 

      int modified = cmd.ExecuteNonQuery(); 

      if (con.State == System.Data.ConnectionState.Open) con.Close(); 
       return modified; 
     } 
    } 
} 

Wiem, że ExecuteNonQuery oznacza liczby wpływające na wiersz. Zamiast tego używam

int modified = (int)cmd.ExecuteScalar(); 

Ale nie działa. Pomóż mi rozwiązać ten problem. I jest tam jakikolwiek kod jak cmd.ExecuteInsertAndGetID() (nie działa z moim kodem).

+0

Co masz na myśli z 'InsertedID'? –

+0

Możesz rzucić okiem na http://stackoverflow.com/questions/9319532/return-value-from-sql-server-insert-command-using-c-sharp – Linky

Odpowiedz

107

następujące rozwiązanie będzie współpracować z serwerem sql 2005 i powyżej. Możesz użyć output, aby uzyskać wymagane pole. inplace of id możesz napisać swój klucz, który chcesz zwrócić. zrobić jak ten

dla SQL Server 2005 i powyżej

using(SqlCommand cmd=new SqlCommand("INSERT INTO Mem_Basic(Mem_Na,Mem_Occ) output INSERTED.ID VALUES(@na,@occ)",con)) 
    { 
     cmd.Parameters.AddWithValue("@na", Mem_NA); 
     cmd.Parameters.AddWithValue("@occ", Mem_Occ); 
     con.Open(); 

     int modified =(int)cmd.ExecuteScalar(); 

     if (con.State == System.Data.ConnectionState.Open) 
      con.Close(); 

     return modified; 
    } 
} 

dla poprzednich wersjach

using(SqlCommand cmd=new SqlCommand("INSERT INTO Mem_Basic(Mem_Na,Mem_Occ) VALUES(@na,@occ);SELECT SCOPE_IDENTITY();",con)) 
    { 
     cmd.Parameters.AddWithValue("@na", Mem_NA); 
     cmd.Parameters.AddWithValue("@occ", Mem_Occ); 
     con.Open(); 

     int modified = cmd.ExecuteScalar(); 

     if (con.State == System.Data.ConnectionState.Open) con.Close(); 
      return modified; 
    } 
} 
+1

int modified = (int) cmd.ExecuteScalar(); – neel

+7

Należy pamiętać, że nazwa kolumny musi być zgodna z nazwą kolumny tożsamości w tabeli.Na przykład tabela z tą nazwą kolumny tożsamości: 'wybierz EmployeeId, * from Employees' Wymaga tego fragmentu w instrukcji insert:' output inserted.EmployeeId' – joshjeppson

+0

W jaki sposób sprawdzisz, czy zapytanie rzeczywiście wstawiło w tym przypadku? – ATD

24

Zmień zapytanie do

"INSERT INTO Mem_Basic(Mem_Na,Mem_Occ) VALUES(@na,@occ); SELECT SCOPE_IDENTITY()" 

będzie to powrót ostatni zapisany identyfikator, który można następnie uzyskać z ExecuteScalar

+1

to pokazuje błąd "Wyjątek InValidCast został nieobsługiwany przez użytkownika kod " – neel

+1

@neel, ponieważ parametr scope_identity() zwraca numeryczny typ danych, który można rzutować tylko na dziesiętny typ danych .net. Innym sposobem jest użycie funkcji Convert.To () w celu uniknięcia problemu z obsadą. – Harsh

+1

Ta odpowiedź jest lepsza, ponieważ nie trzeba wpisywać kolumny ID tabeli, do której wstawiono. – goamn

0
USE AdventureWorks2012; 
GO 
IF OBJECT_ID(N't6', N'U') IS NOT NULL 
    DROP TABLE t6; 
GO 
IF OBJECT_ID(N't7', N'U') IS NOT NULL 
    DROP TABLE t7; 
GO 
CREATE TABLE t6(id int IDENTITY); 
CREATE TABLE t7(id int IDENTITY(100,1)); 
GO 
CREATE TRIGGER t6ins ON t6 FOR INSERT 
AS 
BEGIN 
    INSERT t7 DEFAULT VALUES 
END; 
GO 
--End of trigger definition 

SELECT id FROM t6; 
--IDs empty. 

SELECT id FROM t7; 
--ID is empty. 

--Do the following in Session 1 
INSERT t6 DEFAULT VALUES; 
SELECT @@IDENTITY; 
/*Returns the value 100. This was inserted by the trigger.*/ 

SELECT SCOPE_IDENTITY(); 
/* Returns the value 1. This was inserted by the 
INSERT statement two statements before this query.*/ 

SELECT IDENT_CURRENT('t7'); 
/* Returns value inserted into t7, that is in the trigger.*/ 

SELECT IDENT_CURRENT('t6'); 
/* Returns value inserted into t6. This was the INSERT statement four statements before this query.*/ 

-- Do the following in Session 2. 
SELECT @@IDENTITY; 
/* Returns NULL because there has been no INSERT action 
up to this point in this session.*/ 

SELECT SCOPE_IDENTITY(); 
/* Returns NULL because there has been no INSERT action 
up to this point in this scope in this session.*/ 

SELECT IDENT_CURRENT('t7'); 
/* Returns the last value inserted into t7.*/ 
1
using(SqlCommand cmd=new SqlCommand("INSERT INTO Mem_Basic(Mem_Na,Mem_Occ) " + 
    "VALUES(@na,@occ);SELECT SCOPE_IDENTITY();",con)) 
{ 
    cmd.Parameters.AddWithValue("@na", Mem_NA); 
    cmd.Parameters.AddWithValue("@occ", Mem_Occ); 
    con.Open(); 

    int modified = cmd.ExecuteNonQuery(); 

    if (con.State == System.Data.ConnectionState.Open) con.Close(); 
     return modified; 
} 

SCOPE_IDENTITY: RETUR ns ostatnią wartość tożsamości wstawioną do kolumny tożsamości w tym samym zakresie. Więcej szczegółów procedura przechowywana http://technet.microsoft.com/en-us/library/ms190315.aspx

+1

Byłoby miło, ale ExecuteNonQuery zwraca tylko liczbę wierszy, których dotyczy problem, a nie identyfikator. Użyj ExecuteScalar zamiast https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.executenonquery?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query % 3FappId% 3DDev15IDEF1% 26l% 3DEN-US% 26k% 3Dk (System.Data.SqlClient.SqlCommand.ExecuteNonQuery), k (SolutionItemsProject); k (TargetFrameworkMoniker-.NETFramework, wersja% 3Dv4.6.2); k (DevLang-csharp)% 26rd% 3Dtrue i view = netframework-4.7.1 – Brandtware

9

SQL Server:

CREATE PROCEDURE [dbo].[INS_MEM_BASIC] 
    @na varchar(50), 
    @occ varchar(50), 
    @New_MEM_BASIC_ID int OUTPUT 
AS 
BEGIN 
    SET NOCOUNT ON; 

    INSERT INTO Mem_Basic 
    VALUES (@na, @occ) 

    SELECT @New_MEM_BASIC_ID = SCOPE_IDENTITY() 
END 

kod C#:

public int CreateNewMember(string Mem_NA, string Mem_Occ) 
{ 
    // values 0 --> -99 are SQL reserved. 
    int new_MEM_BASIC_ID = -1971; 
    SqlConnection SQLconn = new SqlConnection(Config.ConnectionString); 
    SqlCommand cmd = new SqlCommand("INS_MEM_BASIC", SQLconn); 

    cmd.CommandType = CommandType.StoredProcedure; 

    SqlParameter outPutVal = new SqlParameter("@New_MEM_BASIC_ID", SqlDbType.Int); 

    outPutVal.Direction = ParameterDirection.Output; 
    cmd.Parameters.Add(outPutVal); 
    cmd.Parameters.Add("@na", SqlDbType.Int).Value = Mem_NA; 
    cmd.Parameters.Add("@occ", SqlDbType.Int).Value = Mem_Occ; 

    SQLconn.Open(); 
    cmd.ExecuteNonQuery(); 
    SQLconn.Close(); 

    if (outPutVal.Value != DBNull.Value) new_MEM_BASIC_ID = Convert.ToInt32(outPutVal.Value); 
     return new_MEM_BASIC_ID; 
} 

Mam nadzieję, że to pomoże wam ....

Można również użyć tego jeśli chcesz ...

public int CreateNewMember(string Mem_NA, string Mem_Occ) 
{ 
    using (SqlConnection con=new SqlConnection(Config.ConnectionString)) 
    { 
     int newID; 
     var cmd = "INSERT INTO Mem_Basic(Mem_Na,Mem_Occ) VALUES(@na,@occ);SELECT CAST(scope_identity() AS int)"; 

     using(SqlCommand cmd=new SqlCommand(cmd, con)) 
     { 
      cmd.Parameters.AddWithValue("@na", Mem_NA); 
      cmd.Parameters.AddWithValue("@occ", Mem_Occ); 

      con.Open(); 
      newID = (int)insertCommand.ExecuteScalar(); 

      if (con.State == System.Data.ConnectionState.Open) con.Close(); 
       return newID; 
     } 
    } 
} 
Powiązane problemy