C# SQL查询数据时间值在表中插入两次

C# SQL查询数据时间值在表中插入两次,c#,sql-server,sql-server-2005,sql-server-2008,C#,Sql Server,Sql Server 2005,Sql Server 2008,我正在编写一个简单的csv解析器,它从我的csv中读取数据并将其插入到我的表中。当我使用小数据集进行测试时,程序运行良好。当我使用大数据集时,我的datatime值在表行中显示两次。不知道为什么 例如:在下面的图片中,你可以看到它打印了两次datetime,这应该只打印一次。但是我的其他列数据是rite CREATE TABLE [dbo].[SAMPLE]( [Number] [int] NULL, [DateTime] [datetime] NULL, [Value]

我正在编写一个简单的csv解析器,它从我的csv中读取数据并将其插入到我的表中。当我使用小数据集进行测试时,程序运行良好。当我使用大数据集时,我的datatime值在表行中显示两次。不知道为什么

例如:在下面的图片中,你可以看到它打印了两次datetime,这应该只打印一次。但是我的其他列数据是rite

CREATE TABLE [dbo].[SAMPLE](
    [Number] [int] NULL,
    [DateTime] [datetime] NULL,
    [Value] [decimal](9, 2) NULL
) ON [PRIMARY]

我正在运行一个简单的查询,它运行了将近45000次

string sqlQuery = "insert into Sample values ( " + number+ ",'" + row.dateT + "'," + value + ");"; 
SqlCommand sqlComm  = new SqlCommand(sqlQuery, dbcon);

为了测试我的输入值,我将“sqlquery”写入了一个文本文件,这是完美的,我100%确定我没有将相同的datetime写入表中

您可以尝试在锁定范围内执行查询。不过这只是一个猜测。

试试这个:

select datetime, count(1) as countDT 
from SAMPLE
group by datetime
having count(1) > 1

这将告诉您是否有两次相同的日期时间值。

日期时间值作为唯一标识符不起作用(或者至少不太可能起作用)。考虑使用具有身份属性的积分值来实现唯一性。 期望插入/更新的日期/时间为每一行提供唯一的datetime值是一种悲哀,原因有二

  • 首先,SQL Server日期时间值的精度为1ms。在内部,SQLServer日期时间值是包含两个32位整数的元组。第一个整数是自纪元以来的天数(对于SQL Server,即1900年1月1日)。第二个是从一天开始(00:00:00.000,又称12:00am)的偏移量(以毫秒为单位)。在现代计算机处理器的世界里,1百万秒是一个漫长的时间。正因为这个原因,你很可能会遇到碰撞

  • 其次,SQL DateTime值的粒度大约为3ms(实际上,DateTime值“四舍五入”为3ms或4ms存储桶,进一步增加了冲突的可能性

    • 最后(我不知道这是真的),我认为如果在一个事务中插入多行(例如,
      insert foo select*from bar
      )并且使用默认属性设置当前日期/时间,您很可能会在事务被认为同时完成时使用相同的datetime值标记所有内容

“舍入”值也将是0, 3或7毫秒的倍数。考虑下面的脚本。它创建一个临时表,插入一些日期/时间字符串,并将它们转换为日期时间值:

drop table #temp
go
create table #temp
(
  value       varchar(32) not null primary key clustered ,
  dtConverted as convert(datetime,value,121)
)
go
set nocount on

insert #temp (value) values( '2011-01-31 23:59:59.000' )
insert #temp (value) values( '2011-01-31 23:59:59.001' )
insert #temp (value) values( '2011-01-31 23:59:59.002' )
insert #temp (value) values( '2011-01-31 23:59:59.003' )
insert #temp (value) values( '2011-01-31 23:59:59.004' )
insert #temp (value) values( '2011-01-31 23:59:59.005' )
insert #temp (value) values( '2011-01-31 23:59:59.006' )
insert #temp (value) values( '2011-01-31 23:59:59.007' )
insert #temp (value) values( '2011-01-31 23:59:59.008' )
insert #temp (value) values( '2011-01-31 23:59:59.009' )
insert #temp (value) values( '2011-01-31 23:59:59.010' )

insert #temp (value) values( '2011-01-31 23:59:59.990' )
insert #temp (value) values( '2011-01-31 23:59:59.991' )
insert #temp (value) values( '2011-01-31 23:59:59.992' )
insert #temp (value) values( '2011-01-31 23:59:59.993' )
insert #temp (value) values( '2011-01-31 23:59:59.994' )
insert #temp (value) values( '2011-01-31 23:59:59.995' )
insert #temp (value) values( '2011-01-31 23:59:59.996' )
insert #temp (value) values( '2011-01-31 23:59:59.997' )
insert #temp (value) values( '2011-01-31 23:59:59.998' )
insert #temp (value) values( '2011-01-31 23:59:59.999' )

set nocount off
go
select * from #temp
go
当您运行上述脚本时,结果可能不是您所期望的。不仅值被四舍五入到3ms或4ms的间隔,而且任何毫秒值大于997的datetime值都会被四舍五入到第二天(在本例中是月)。这是一个边界条件,在实际场景中会影响您(不要问我是怎么知道的)。以下是结果,你会得到:

value dtConverted ----------------------- ----------------------- 2011-01-31 23:59:59.000 2011-01-31 23:59:59.000 2011-01-31 23:59:59.001 2011-01-31 23:59:59.000 2011-01-31 23:59:59.002 2011-01-31 23:59:59.003 2011-01-31 23:59:59.003 2011-01-31 23:59:59.003 2011-01-31 23:59:59.004 2011-01-31 23:59:59.003 2011-01-31 23:59:59.005 2011-01-31 23:59:59.007 2011-01-31 23:59:59.006 2011-01-31 23:59:59.007 2011-01-31 23:59:59.007 2011-01-31 23:59:59.007 2011-01-31 23:59:59.008 2011-01-31 23:59:59.007 2011-01-31 23:59:59.009 2011-01-31 23:59:59.010 2011-01-31 23:59:59.010 2011-01-31 23:59:59.010 2011-01-31 23:59:59.990 2011-01-31 23:59:59.990 2011-01-31 23:59:59.991 2011-01-31 23:59:59.990 2011-01-31 23:59:59.992 2011-01-31 23:59:59.993 2011-01-31 23:59:59.993 2011-01-31 23:59:59.993 2011-01-31 23:59:59.994 2011-01-31 23:59:59.993 2011-01-31 23:59:59.995 2011-01-31 23:59:59.997 2011-01-31 23:59:59.996 2011-01-31 23:59:59.997 2011-01-31 23:59:59.997 2011-01-31 23:59:59.997 2011-01-31 23:59:59.998 2011-01-31 23:59:59.997 2011-01-31 23:59:59.999 2011-02-01 00:00:00.000 (21 row(s) affected) 数值转换 ----------------------- ----------------------- 2011-01-31 23:59:59.000 2011-01-31 23:59:59.000 2011-01-31 23:59:59.001 2011-01-31 23:59:59.000 2011-01-31 23:59:59.002 2011-01-31 23:59:59.003 2011-01-31 23:59:59.003 2011-01-31 23:59:59.003 2011-01-31 23:59:59.004 2011-01-31 23:59:59.003 2011-01-31 23:59:59.005 2011-01-31 23:59:59.007 2011-01-31 23:59:59.006 2011-01-31 23:59:59.007 2011-01-31 23:59:59.007 2011-01-31 23:59:59.007 2011-01-31 23:59:59.008 2011-01-31 23:59:59.007 2011-01-31 23:59:59.009 2011-01-31 23:59:59.010 2011-01-31 23:59:59.010 2011-01-31 23:59:59.010 2011-01-31 23:59:59.990 2011-01-31 23:59:59.990 2011-01-31 23:59:59.991 2011-01-31 23:59:59.990 2011-01-31 23:59:59.992 2011-01-31 23:59:59.993 2011-01-31 23:59:59.993 2011-01-31 23:59:59.993 2011-01-31 23:59:59.994 2011-01-31 23:59:59.993 2011-01-31 23:59:59.995 2011-01-31 23:59:59.997 2011-01-31 23:59:59.996 2011-01-31 23:59:59.997 2011-01-31 23:59:59.997 2011-01-31 23:59:59.997 2011-01-31 23:59:59.998 2011-01-31 23:59:59.997 2011-01-31 23:59:59.999 2011-02-01 00:00:00.000 (受影响的21排)
祝你好运!

谢谢你的回答。我发现它的创建问题只是因为我们将DataTime格式转换为字符串以进行格式更改。我将DataTime作为SqldbType.DateTime插入。下面给出了我的代码片段,解决了我的所有问题

using (SqlCommand cmd = new SqlCommand(query, conn))
        {
          int 123;

          cmd.Parameters.Add(new SqlParameter(@"Number", SqlDbType.int)).Value = 123;
          cmd.Parameters.Add(new SqlParameter(@"aDateTime", SqlDbType.DateTime)).Value = mydate;
cmd.Parameters.Add(new SqlParameter(@"aDateTime", SqlDbType.decimal)).Value = value;
          cmd.ExecuteNonQuery();
        }

显然,它不是完美的复制。发布用于迭代查询的代码。你必须在某处缓存数据。需要查看示例数据。需要查看SQL之前的代码。需要查看执行sqlComm的位置/方式。因为看起来一切都在复制!这与源数据有两条t记录有关吗相同的日期时间有不同的值?您的示例的两行分别为0.05和0.06。@嗨,我将日期转换为row.dateT=row.temp.ToString(“MM/dd/yyyy hh:MM:ss”);转换为指定的格式,然后我将其插入表中。这是一个日期时间格式的字符串为什么?您不能相信自己的眼睛吗?:)屏幕截图清楚地显示存在重复的日期时间值。@Andy感谢您的回复。这是因为我接受了查询并将其写入了一个txt文件,在该文件中我看到了不同的日期时间。