C# SQL Server UDT和存储过程从.Net代码中修剪十进制数字值
我们使用的是.NETFramework 4.7.2。我们使用用户定义的类型变量作为其唯一参数来调用spC# SQL Server UDT和存储过程从.Net代码中修剪十进制数字值,c#,.net,sql-server,C#,.net,Sql Server,我们使用的是.NETFramework 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
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;
}
}
但是,当我尝试从.net代码插入记录时,十进制值小于0.5将变为0,大于0.5的值将变为1。像4.2变成4,5.87变成6
我的.net代码有什么问题吗 我想
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;
}
}
private IEnumerable CreateSqlRecord(IEnumerable实体)
{
SqlMetaData[]metaData=新的SqlMetaData[4];
metaData[0]=新的SqlMetaData(“A”,SqlDbType.Int);
metaData[1]=新的SqlMetaData(“B”,SqlDbType.DateTime);
metaData[2]=新的SqlMetaData(“C”,SqlDbType.DateTime);
metaData[3]=新的SqlMetaData(“值”,SqlDbType.Decimal,19,6);
SqlDataRecord=新的SqlDataRecord(元数据);
foreach(实体中的模型myModel)
{
record.SetInt32(0,myModel.A);
record.SetDateTime(1,myModel.B);
record.SetDateTime(2,myModel.C);
record.SetDecimal(3,(十进制)myModel.Value);
收益回报记录;
}
}
为了防止其他人有此问题,我应用了上述建议,但除此之外,在UDT(用户定义的表类型)中发送此数据时,似乎要求数字类型为数字(18,2),而不是十进制(18,2)。由于某种原因,在使用十进制类型时,系统正在对值进行舍入。现在,对于数值,这些值与从C#应用程序发送的值相同。如果不使用UDT,则情况并非如此。
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;
}
}