@@IDENTITY after INSERT statement always returns 0

后端 未结 13 1174
一整个雨季
一整个雨季 2021-01-11 13:00

I need a function which executes an INSERT statement on a database and returns the Auto_Increment primary key. I have the following C# code but, while the INSERT statement w

相关标签:
13条回答
  • 2021-01-11 13:03

    1) combine the INSERT and SELECT statement (concatenate using ";") into 1 db command

    2) use SCOPE_IDENTITY() instead of @@IDENTITY

    INSERT INTO blabla... ; SELECT OID FROM table WHERE OID = SCOPE_IDENTITY()

    -- update:

    as it turned out that the question was related to MS ACCESS, I found this article which suggests that simply reusing the first command and setting its CommandText to "SELECT @@IDENTITY" should be sufficient.

    0 讨论(0)
  • 2021-01-11 13:03

    As you're using Access, take a look at this article from aspfaq, scroll down to about half way down the page. The code's in classic ASP, but hopefully the principles should still stand.


    The SELECT @@Identity ends up being treated as a separate execution context, I believe. Code that should work would be:

    public int ExecuteInsertStatement(string statement)
    {
        InitializeAndOpenConnection();
    
        IDbCommand cmdInsert = connection.CreateCommand();
        cmdInsert.CommandText = statement + "; SELECT @@Identity";
        object result = cmdInsert.ExecuteScalar();
    
        if (object == DBNull.Value)
        {
           return -1;
        }
        else
        {
           return Convert.ToInt32(result);
        }
    }
    

    You'd probably want/need to tidy up the concatenation that adds the 'SELECT @@Identity' onto the end of the code though.

    0 讨论(0)
  • 2021-01-11 13:06
    CREATE procedure dbo.sp_whlogin
    (
     @id nvarchar(20),
     @ps nvarchar(20),
     @curdate datetime,
     @expdate datetime
    )
    
    AS
    BEGIN
     DECLARE @role nvarchar(20)
     DECLARE @menu varchar(255)
     DECLARE @loginid int
    
     SELECT     @role = RoleID
     FROM         dbo.TblUsers
     WHERE    UserID = @id AND UserPass = @ps
    
     if @role is not null 
     BEGIN
      INSERT INTO TblLoginLog (UserID, LoginAt, ExpireAt, IsLogin) VALUES (@id, @curdate, @expdate, 1);
      SELECT @loginid = @@IDENTITY;
      SELECT @loginid as loginid, RoleName as role, RoleMenu as menu FROM TblUserRoles WHERE RoleName = @role
     END
     else
     BEGIN
      SELECT '' as role, '' as menu
     END
    END
    GO
    
    0 讨论(0)
  • 2021-01-11 13:14

    you need to return the identity at the same time as you open the initial connection. Return a result set from your insert or an output variable.

    You should also always use SCOPE_IDENTITY() not @@identity. Reference here

    You should add

    SELECT SCOPE_IDENTITY() 
    

    After the insert.

    0 讨论(0)
  • 2021-01-11 13:14

    If you would like to retrieve value of auto running number of transaction that you're inserting and your environment following 1. Database is MsAccess. 2. Driver is Jet4 with connection string like this "Provider=Microsoft.Jet.OLEDB.4.0;Password={0};Data Source={1};Persist Security Info=True" 3. use Oledb

    You can apply my example to your code

    OleDbConnection connection =  String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Password={0};Data Source={1};Persist Security Info=True",dbinfo.Password,dbinfo.MsAccessDBFile);
    connection.Open();
    OleDbTransaction transaction = null;
    try{
        connection.BeginTransaction();
        String commandInsert = "INSERT INTO TB_SAMPLE ([NAME]) VALUES ('MR. DUKE')";
        OleDbCommand cmd = new OleDbCommand(commandInsert , connection, transaction);
        cmd.ExecuteNonQuery();
        String commandIndentity = "SELECT @@IDENTITY";
        cmd = new OleDbCommandcommandIndentity, connection, transaction);
        Console.WriteLine("New Running No = {0}", (int)cmd.ExecuteScalar());
        connection.Commit();
    }catch(Exception ex){
        connection.Rollback();
    }finally{
        connection.Close();
    }   
    
    0 讨论(0)
  • 2021-01-11 13:15

    The short answer:
    1. Create two commands each accepting a single query.
    2. First sql query is the INSERT record.
    3. Second sql query is "SELECT @@Identity;" which returns the AutoNumber.
    4. Use cmd.ExecuteScalar() which returns a first column of first row.
    5. The returned result output is the AutoNumber value generated in the current insert query.

    It is referenced from this link. The example code is as under. Note the difference for "SAME Connection VS NEW Connection". The SAME Connection gives the desired output.

     class Program
    {
        static string path = @"<your path>";
        static string db = @"Test.mdb";
        static void Main(string[] args)
        {
            string cs = String.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}\{1}", path, db);
            // Using the same connection for the insert and the SELECT @@IDENTITY
            using (OleDbConnection con = new OleDbConnection(cs))
            {
                con.Open();
                OleDbCommand cmd = con.CreateCommand();
                for (int i = 0; i < 3; i++)
                {
                    cmd.CommandText = "INSERT INTO TestTable(OurTxt) VALUES ('" + i.ToString() + "')";
                    cmd.ExecuteNonQuery();
    
                    cmd.CommandText = "SELECT @@IDENTITY";
                    Console.WriteLine("AutoNumber: {0}", (int)cmd.ExecuteScalar());
                }
                con.Close();
            }
            // Using a new connection and then SELECT @@IDENTITY
            using (OleDbConnection con = new OleDbConnection(cs))
            {
                con.Open();
                OleDbCommand cmd = con.CreateCommand();
                cmd.CommandText = "SELECT @@IDENTITY";
                Console.WriteLine("\nNew connection, AutoNumber: {0}", (int)cmd.ExecuteScalar());
                con.Close();
            }
        }
    }
    

    This should produce the self-explanatory output:

    AutoNumber: 1 <br>
    AutoNumber: 2 <br>
    AutoNumber: 3 <br>
    
    New connection, AutoNumber: 0
    
    0 讨论(0)
提交回复
热议问题