【问题标题】:SQL Server UDT and stored procedure trimming decimal digit values from .Net codeSQL Server UDT 和存储过程从 .Net 代码中修剪十进制数字值
【发布时间】:2018-08-09 16:07:10
【问题描述】:

我们正在使用 .net 框架 4.7.2。我们调用一个以用户定义类型变量为唯一参数的 sp。

CREATE TYPE [dbo].[ABC] AS TABLE(
[A] [int] NOT NULL,
[B] [datetime] NOT NULL,
[C] [datetime] NOT NULL,
[Value] [decimal](19, 6) NULL)

对应的存储过程是

CREATE PROCEDURE [dbo].[myUSP]
@data dbo.ABC readonly AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (SELECT 1 FROM @data)
BEGIN
      INSERT INTO dbo.MyTable
      SELECT A, B, C, [Value] FROM @data;
END END

我的 .Net 代码是

            using (SqlConnection con = new SqlConnection(connectionString))
            {
                    using (SqlCommand insertCmd = new SqlCommand("dbo.myUSP", con))
                    {
                        con.Open();
                        using (transaction = con.BeginTransaction(IsolationLevel.RepeatableRead))
                        {
                            insertCmd.Transaction = transaction;
                            insertCmd.CommandType = CommandType.StoredProcedure;
                            try
                            {
                                SqlParameter parameter1 = insertCmd.Parameters.AddWithValue("@data", CreateSqlRecord(insert));
                                parameter1.SqlDbType = SqlDbType.Structured;
                                parameter1.TypeName = "dbo.ABC";
                                insertCmd.ExecuteNonQuery();
                                transaction.Commit();
                            }
                            catch (Exception ex)
                            {
                                transaction.Rollback();
                            }
                        }
                    }
            }

    private IEnumerable<SqlDataRecord> CreateSqlRecord(IEnumerable<DataElementInput> entities)
    {
        SqlMetaData[] metaData = new SqlMetaData[4];
        metaData[0] = new SqlMetaData("A", SqlDbType.Int);
        metaData[1] = new SqlMetaData("B", SqlDbType.DateTime);
        metaData[2] = new SqlMetaData("C", SqlDbType.DateTime);
        metaData[3] = new SqlMetaData("Value", SqlDbType.Decimal);
        SqlDataRecord record = new SqlDataRecord(metaData);
        foreach (Model myModel in entities)
        {
            record.SetInt32(0, myModel .A);
            record.SetDateTime(1,myModel.B);
            record.SetDateTime(2, myModel.C);
            record.SetDecimal(3, (Decimal)myModel.Value);
            yield return record;
        }
    }

在将 parameter1 传递给 SQLConnection 并使用 ExecuteNonQuery 执行之前,我检查了它的值,它正确包含十进制值。 另一方面,我还检查了直接从 SQL 服务器管理工​​作室运行我的 sp,它在表 dbo.MyTable 中插入正确的十进制值。

BEGIN DECLARE @data dbo.ElementFactData;INSERT @data (ElementId,StartDateTime, EndDateTime, Value) VALUES(  1002, '1/1/1800' , '1/1/1900' , 0.786); exec dbo.myUSP @data;END

但是,当我尝试从 .net 代码中插入记录时,小于 0.5 的十进制值变为 0,大于 0.5 的值变为 1。像 4.2 变为 4,5.87 变为 6

我的 .net 代码有什么问题吗?

【问题讨论】:

    标签: c# .net sql-server


    【解决方案1】:

    我猜

      metaData[3] = new SqlMetaData("Value", SqlDbType.Decimal);
    

    需要指定精度和比例。 所以它看起来像这样:

      metaData[3] = new SqlMetaData("Value", SqlDbType.Decimal, 19, 6);
    

    您的 CreateSqlRecord 方法应如下所示:

    private IEnumerable<SqlDataRecord> CreateSqlRecord(IEnumerable<DataElementInput> entities)
    {
        SqlMetaData[] metaData = new SqlMetaData[4];
        metaData[0] = new SqlMetaData("A", SqlDbType.Int);
        metaData[1] = new SqlMetaData("B", SqlDbType.DateTime);
        metaData[2] = new SqlMetaData("C", SqlDbType.DateTime);
        metaData[3] = new SqlMetaData("Value", SqlDbType.Decimal, 19, 6);
        SqlDataRecord record = new SqlDataRecord(metaData);
        foreach (Model myModel in entities)
        {
            record.SetInt32(0, myModel .A);
            record.SetDateTime(1,myModel.B);
            record.SetDateTime(2, myModel.C);
            record.SetDecimal(3, (Decimal)myModel.Value);
            yield return record;
        }
    }
    

    【讨论】:

    • 以防万一其他人有这个问题,我应用了上述建议,但除此之外,似乎在 UDT(用户定义的表类型)中发送此数据时需要数字类型为数字(18,2)而不是十进制(18,2)。由于某种原因,系统在使用十进制类型时对值进行了四舍五入。现在使用数字,值就像从 C# 应用程序发送的一样。如果您不使用 UDT,则情况并非如此。
    猜你喜欢
    • 1970-01-01
    • 2020-07-02
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    相关资源
    最近更新 更多