我有一个SQL Server数据库,它将包含许多连接的表,每个表都有一个主键。我有一个Dictionary
跟踪每个表的主键字段。我的任务是每天从以属性为中心的XML文件中提取数据,并将它们插入到主数据库中。每个XML文件都具有相同的架构。我是通过使用XMLReader
并将数据导入DataSet
。
我无法使用AutoNumber
作为密钥。假设昨天的XML文件生成了DataTable
,类似于以下内容,并将其导入数据库
-------------------------------------
| Key | Column1 | Column2 | Column3 |
|-----------------------------------|
| 0 | dsfsfsd | sdfsrer | sdfsfsf |
|-----------------------------------|
| 1 | dertert | qweqweq | xczxsdf |
|-----------------------------------|
| 2 | prwersd | xzcsdfw | qwefkgs |
-------------------------------------
如果今天的XML文件产生以下DataTable
-------------------------------------
| Key | Column1 | Column2 | Column3 |
|-----------------------------------|
| 0 | sesdfsd | hjghjgh | edrgffb |
|-----------------------------------|
| 1 | wrwerwr | zxcxfsd | pijghjh |
|-----------------------------------|
| 2 | vcbcvbv | vbnvnbn | bnvfgnf |
-------------------------------------
然后当我使用SqlBulkCopy
将新数据导入数据库时,会有重复的键。我的解决方案是使用DateTime.Now.Ticks
生成唯一键。从理论上讲,这应该始终创建一个唯一的密钥。
但是,出于某种原因,DateTime.Now.Ticks
并不是唯一的。例如,一行中的5个记录可能都具有键635387859864435908
,并且接下来的7个记录可能具有键635387859864592164
,即使我在不同时间生成该值。我想说问题的原因是我的脚本在更新时间之前多次调用DateTime.Now.Ticks
。
其他人可以想到更好的生成密钥的方法吗?
答案 0 :(得分:3)
出于性能原因,DateTime.Now的值可能会缓存一小段时间。我们做了类似的事情,我们使用了两种可能的选项:
System.Guid.NewGuid().ToString();
显然,这些计划都不会使碰撞风险为零,但它们可以帮助减少碰撞。
答案 1 :(得分:2)
如果您有大量数据,并且每行需要一个唯一的密钥,请使用GUID
答案 2 :(得分:0)
您可以执行以下操作来获取唯一ID(SQL Fiddle):
SELECT
CONCAT(YEAR(GETDATE()), DATEDIFF(DAY, STR(YEAR(GETDATE()), 4) + '0101',
GETDATE() ) + 1, ROW_NUMBER() OVER(ORDER BY id DESC)) UniqueID
FROM supportContacts s
如果您每天只运行一次查询,这将有效。如果你每天运行多次,你需要抓住秒或其他东西(SQL Fiddle):
SELECT CONCAT(CurrYear, CurrJulian, CurrSeconds, Row) AS UniqueID
FROM
(
SELECT
YEAR(GETDATE()) AS CurrYear,
DATEDIFF(DAY, STR(YEAR(GETDATE()), 4) + '0101', GETDATE() ) + 1 AS CurrJulian,
ROW_NUMBER() OVER(ORDER BY id DESC) AS Row,
datediff(second, left(convert(varchar(20), getdate(), 126), 10), getdate()) AS CurrSeconds
from supportContacts s
) AS m