简体   繁体   中英

Arithmetic overflow error converting expression to data type nvarchar

I am creating a helpdesk system but seem to of run into a slight problem, when the user clicks a button to "pre register" the helpdesk ticket number, my script fires off to the SQL Express server, creating a new row -> gets the row ID -> Uses the row ID to create the final ticket ref (in the format of RAD000001 for example for row 1) this process seems to work for me fine, until i get to number 9... when the user clicks the "create new Ticket ref" button(Generating ticket number 10) i get the following error:

Arithmetic overflow error converting expression to data type nvarchar.

It creates the row, but seems to fail on the update(the row is created, the ID returned and then the ref created from the ID)

My SQL table is looks like this:

CREATE TABLE [dbo].[tickets](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [ticket_ref] [varchar](15) NULL,
    [details_id] [int] NULL,
    [state] [int] NULL,
    [create_date_Time] [datetime] NOT NULL,
    [details_subject] [varchar](255) NULL,
    [details_main_body] [text] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

and this is the c# code behind:

private string Reform_TicketId(string original_ticket_id)
{
    switch (original_ticket_id.Length)
    {
        case 1:
            return "RAD00000" + original_ticket_id.ToString();
        case 2:
            return "RAD0000" + original_ticket_id.ToString();
        case 3:
            return "RAD000" + original_ticket_id.ToString();
        case 4:
            return "RAD00" + original_ticket_id.ToString();
        case 5:
            return "RAD0" + original_ticket_id.ToString();
        case 6:
            return "RAD" + original_ticket_id.ToString();
        default:
            return "ERROR!";
    }
}

protected void DsCreateTicketEntry_Inserted(object sender, SqlDataSourceStatusEventArgs e)
{
    string original_id = e.Command.Parameters["@ticket_id"].Value.ToString();
    string reformed_id = Reform_TicketId(original_id.ToString()).ToString();

    if (original_id != "0")
    {
        //It has returned a value that is a DB ID field and seems correct! lets proceed!
        DsCreateTicketEntry.UpdateParameters["ticket_db_id"].DefaultValue = original_id;
        //DsCreateTicketEntry.UpdateParameters["new_ticket_id"].DefaultValue = reformed_id;
        DsCreateTicketEntry.UpdateParameters["new_ticket_id"].DefaultValue = "RAD000002";
        DsCreateTicketEntry.Update();
        LblTicketOutput.Text = reformed_id;
    }
    else
    {
        //@TODO: Write to the label stating we had problems generating a Ticket ID!
    }
}

protected void btnCreateTicket_Click(object sender, EventArgs e)
{
    DsCreateTicketEntry.Insert();
    btnCreateTicket.Enabled = false;
}

with the following queries in my SQLDataSource:

InsertCommand="INSERT INTO tickets(state, create_date_Time) VALUES (1,GETDATE()) SET @ticket_id=SCOPE_IDENTITY();"    
UpdateCommand="UPDATE tickets SET ticket_ref = @new_ticket_id WHERE (id = @ticket_db_id)"

Hopfully someone is able to cast some light on where i am going wrong!? I have been looking at this code all day, and its fallen slightly outside my league of learning...

You would need to define @ticket_id as an output parameter, and you may need a semicolon before your SET statement.

Use:

String.Format("RAD{0:d6}", ticket_Id)

to format your ticket number. Note that in my example ticket_id is an integer.

As a general recommendation I'd avoid the SQLDataSource and that design pattern in general. There are far better and more elegant solutions to data access now days. Take a look at Entity Framework . EF will get you up and running quickly, with no SQL statements embedded in your code. You can generate Entity classes from your DB, or even use the Code First approach to generate your DB schema from your classes.

Not exactly solution to your problem but it may work, if you could redefine your table as:

...

    Id int identity not null,
    Ticket_ref as 'RAD'+replicate('0', 5-len(cast(Id as varchar)))+Cast(Id as Varchar) persisted,
...

you would drop a lot of lines on unnecessary code...

After Saille's Answer, i reviewed my code and noticed that where i declared @ticket_id i declared it like this:

<asp:Parameter DefaultValue="0" Direction="Output" Name="ticket_id" />

After stating the "DbType=Int32" like:

<asp:Parameter DefaultValue="0" Direction="Output" DbType=Int32 Name="ticket_id" />

All seemed to work correctly and the problem is not resolved!

Although im not 100% sure why this caused a problem, is anyone able to explain this to me, allowing me(and hopfully others) to understand why this did what it did...

PS. I am using this project to learn general C#/ASP.net (sessions,etc..) once it is done, Version 1.5 will be built with a better DataBase layer(such as Entity)...Im still a bit of a n00b!

Thanks for all the help guys!

Tom.

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