我应该使用C#中的哪种数据类型将数据输入到T-SQL中的十进制列中?

时间:2011-07-31 20:14:00

标签: c# tsql types sqldatatypes

我很难弄清楚我将在C#中使用哪种数据类型将数据输入到包含小数(5,2)的数据库中的表格中。当我尝试使用C#十进制数据类型时,它表示将数字转换为十进制时出错。当我尝试字符串时,它说它无法将nvarchar转换为十进制。当我尝试浮动时...同样的事情发生了,除了借口是一个“真正的”数据类型。双倍也没能奏效。

我有一个存储过程将数据输入到我的表中,但在我运行并将存储过程中的数据类型转换为实际的十进制数之前,还有其他任何方法我可以将ac#data类型转换为适合我的小数(5,2)字段?

private void btnAddClientComputer_Click(object sender, EventArgs e)
{
    SQLCommands comm = new SQLCommands();
    try
    {
        comm.AddClientComputer(int.Parse(cbCustomerID.Text), cbAction.Text, decimal.Parse(tbCost.Text));
    }
    catch (FormatException)
    {
        MessageBox.Show("The cost you have entered is invalid. Please ensure the cost is above 0, and is an actual number", "Invalid Input at Cost", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
    }
}

...

public void AddClientComputer(int CustomerID, string Action, decimal Cost)
{
    try
    {
        comm = new SqlCommand("UspAddClientComputer", conn); // Stored Procedure - see sql file
        comm.Parameters.AddWithValue("@CustomerID", CustomerID);
        comm.Parameters.AddWithValue("@Action", Action);
        comm.Parameters.AddWithValue("@Cost", Cost);
        comm.CommandType = CommandType.StoredProcedure;
        comm.ExecuteNonQuery();
    }
    catch (Exception ex)
    {
        System.Windows.Forms.MessageBox.Show(ex.Message, "Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
    }
}

...

CREATE TABLE ClientComputers
            (ClientComputerID int Identity(1,1) primary key clustered
            ,CustomerID int
            ,Action varchar(7) check (Action = 'Upgrade' OR Action = 'Store')
            ,Cost decimal(5,2) check (Cost > 0)
            ,Constraint FKCustomerComputer FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID));
Go

...

CREATE PROCEDURE uspAddClientComputer @CustomerID int, @Action varchar(7), @Cost decimal(5,2)
AS
BEGIN TRY
    BEGIN TRANSACTION TrnAddClientComputer;
     INSERT INTO [TCTdb].[dbo].[ClientComputers]
           ([CustomerID]
           ,[Action]
           ,[Cost])
     VALUES
           (@CustomerID
           ,@Action
           ,@Cost)
    COMMIT TRANSACTION TrnAddClientComputer;
END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION TrnAddClientComputer;

    DECLARE @ErrorMessage NVARCHAR(4000);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState INT;

    SELECT 
        @ErrorMessage = ERROR_MESSAGE(),
        @ErrorSeverity = ERROR_SEVERITY(),
        @ErrorState = ERROR_STATE();

    RAISERROR (@ErrorMessage,
               @ErrorSeverity,
               @ErrorState
               );
END CATCH
GO

enter image description here

3 个答案:

答案 0 :(得分:1)

试试

 comm.Parameters.Add(new SqlParameter("@Cost", Cost));

顺便说一句,

你可以在块

之后重构
 try
    {
        comm.AddClientComputer(int.Parse(cbCustomerID.Text), cbAction.Text, decimal.Parse(tbCost.Text));
    }
    catch (FormatException)
    {
        MessageBox.Show("The cost you have entered is invalid. Please ensure the cost is above 0, and is an actual number", "Invalid Input at Cost", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
    }

// TODO: do the same for int.Parse as well
decimal userDefinedCost;
if (decimal.TryParse(tbCost.Text, out userDefinedCost))
{
     comm.AddClientComputer(int.Parse(cbCustomerID.Text), cbAction.Text, userDefinedCOst);
}
else
{
     MessageBox.Show("The cost you have entered is invalid. Please ensure the cost is above 0, and is an actual number", "Invalid Input at Cost", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}

答案 1 :(得分:1)

我建议你添加指定类型的decimal参数。这意味着不仅要使用AddWithValue,还要创建一个Parameter对象。

我怀疑问题是由于代码无法完全转换而造成的。

ETA:

您的代码是

comm.Parameters.Add("@Cost",SqlDbType.Decimal);
comm.Parameters["@Cost"].Value = Cost;

你需要做类似的事情(正如我所说,我没有容易获得的语法检查)

SqlParameter param= new SqlParameter("@Cost", SqlDbType.Decimal, Cost);//there are more parameters which I cannot remember
comm.Parameters.Add(param);

重要的是创建一个对象,您可以在其中传递所有可以将其明确定义为SQL十进制的参数。

答案 2 :(得分:0)

在这种情况下,我找到了解决问题的方法,这要归功于我的一些注意事项。以下代码对我有用。

private void btnAddClientComputer_Click(object sender, EventArgs e)
{
    SQLCommands comm = new SQLCommands();
    double trycost;
    if (double.TryParse(tbCost.Text,out trycost))
    {
        comm.AddClientComputer(int.Parse(cbCustomerID.Text), cbAction.Text, trycost);
    }
    else
    {
        MessageBox.Show("The cost you have entered is invalid. Please ensure the cost is above 0, and is an actual number", "Invalid Input at Cost", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
    }
}

...

public void AddClientComputer(int CustomerID, string Action, double Cost)
    {
        try
        {
            comm = new SqlCommand("UspAddClientComputer", conn); // Stored Procedure - see sql file
            comm.Parameters.AddWithValue("@CustomerID", CustomerID);
            comm.Parameters.AddWithValue("@Action", Action);
            comm.Parameters.Add(new SqlParameter("@Cost",Cost));
            comm.CommandType = CommandType.StoredProcedure;
            comm.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            System.Windows.Forms.MessageBox.Show(ex.Message, "Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
        }
    }

..这是解决方案的一部分。我用小钱币替换了十进制(5,2)。

CREATE TABLE ClientComputers
            (ClientComputerID int Identity(1,1) primary key clustered
            ,CustomerID int
            ,Action varchar(7) check (Action = 'Upgrade' OR Action = 'Store')
            ,Cost smallmoney check (Cost > 0)
            ,Constraint FKCustomerComputer FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID));
Go

---------STORED PROCEDURES
--ADD CLIENT COMPUTER
CREATE PROCEDURE uspAddClientComputer @CustomerID int, @Action varchar(7), @Cost smallmoney
AS
BEGIN TRY
    BEGIN TRANSACTION TrnAddClientComputer;
     INSERT INTO [TCTdb].[dbo].[ClientComputers]
           ([CustomerID]
           ,[Action]
           ,[Cost])
     VALUES
           (@CustomerID
           ,@Action
           ,@Cost)
    COMMIT TRANSACTION TrnAddClientComputer;
END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION TrnAddClientComputer;

    DECLARE @ErrorMessage NVARCHAR(4000);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState INT;

    SELECT 
        @ErrorMessage = ERROR_MESSAGE(),
        @ErrorSeverity = ERROR_SEVERITY(),
        @ErrorState = ERROR_STATE();

    RAISERROR (@ErrorMessage,
               @ErrorSeverity,
               @ErrorState
               );
END CATCH
GO

感谢所有尝试过的人。这回答了我的问题。正确的想法,错误数据类型。