简体   繁体   中英

scope_identity throwing System.Data.SqlClient.SqlException (0x80131904): Arithmetic overflow error converting IDENTITY to data type int

I understand what the error means (your trying to store a number bigger than int in an int) but can't see where this is coming from.

Because of the mention of IDENTITY in the error, I'm assuming its the call to scope_identity() that's problematic. I understand that it returns decimal(38,0) but my table should never return a PK that is not an int.

I've just started receiving this last week after this code has run for months.

Help!!!!!

I have a table with this PK

CREATE TABLE [dbo].[plan_languages](
    [plan_language_id] [int] IDENTITY(1,1) NOT NULL,
....
)

and a stored proc that returns the newly created PK

CREATE PROC [dbo].[sp_plan_languages_insert] (
....,
,@new_pk INT = 0 OUTPUT
)
...
INSERT INTO dbo.plan_languages ( ... )
VALUES ( ... )
SET @new_pk = scope_identity()

and c# code that executes that stored proc and retrieves that PK

        private int InsertPlanLanguage(PlanLanguageDTO language)
        {
            int pk = 0;
            try
            {
                using (SqlConnection con = new SqlConnection(DbConnetionString))
                {
                    con.Open();
                    using (SqlCommand cmd = con.CreateCommand())
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.CommandText = "dbo.sp_plan_languages_insert";
....
                        cmd.Parameters.Add(new SqlParameter { ParameterName = "@new_pk", Direction = ParameterDirection.Output, DbType = DbType.Int32 });


                        cmd.ExecuteNonQuery();
                        if (cmd.Parameters["@new_pk"].Value != DBNull.Value)
                        {
                            pk = (int)cmd.Parameters["@new_pk"].Value;
                        }
                    }

and I should have plenty of room

SELECT MAX(l.plan_language_id) from dbo.plan_languages l 

returns 190891

Type casting the return value of SQL functions that return an identity to int usually fails for me. I think because System.Data.SqlClient treats the value as decimal. Try doing this instead.

pk = Convert.ToIn32(cmd.Parameters["@new_pk"].Value);

SELECT MAX(l.plan_language_id) from dbo.plan_languages l

This isn't relevant: it returns the current maximum value of the plan_language_id column. The next identity value is not necessarily MAX(id)+1 since rows may have been deleted.

Try:

DBCC CHECKIDENT(plan_languages)

DBCC CHECKIDENT also has an option to reseed the identity value. Though presumably you'll hit the same problem again after running for another few months of inserting and deleting rows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM