我总是使用类似下面的东西来实现它:
INSERT INTO TheTable
SELECT
@primaryKey,
@value1,
@value2
WHERE
NOT EXISTS
(SELECT
NULL
FROM
TheTable
WHERE
PrimaryKey = @primaryKey)
Run Code Online (Sandbox Code Playgroud)
...但是一旦加载,就会发生主键违规.这是唯一插入此表的语句.那么这是否意味着上述陈述不是原子的?
问题是,这几乎不可能随意重建.
也许我可以将其更改为以下内容:
INSERT INTO TheTable
WITH
(HOLDLOCK,
UPDLOCK,
ROWLOCK)
SELECT
@primaryKey,
@value1,
@value2
WHERE
NOT EXISTS
(SELECT
NULL
FROM
TheTable
WITH
(HOLDLOCK,
UPDLOCK,
ROWLOCK)
WHERE
PrimaryKey = @primaryKey)
Run Code Online (Sandbox Code Playgroud)
虽然,也许我使用错误的锁或使用过多的锁定或其他东西.
我在stackoverflow.com上看到了其他问题,其中答案是建议"IF(SELECT COUNT(*)... INSERT"等),但我总是在(可能是不正确的)假设单个SQL语句是原子的.
有没有人有任何想法?
我目前正试图将数据表插入到数据库中.它工作得很好,速度很快.如果数据库中已存在任何行(重复键),则会出现唯一的问题.
为了解决这个问题,我修改了我的程序,以便我首先检查每个新条目是否已存在于数据库中.这是.......慢(在目前的情况下,我没有很多条目,但后来我需要检查的超过200k条目和那几次).因此,我需要让它变得更快(如果可能的话).
数据表的结构如下:
DataTable transactionTable.Columns.Add("DeviceId", typeof(Int32));
transactionTable.Columns.Add("LogDate", typeof(DateTime));
transactionTable.Columns.Add("LogType", typeof(Int32));
transactionTable.Columns.Add("LogText", typeof(String));
transactionTable.PrimaryKey = new DataColumn[3] {
transactionTable.Columns[0],
transactionTable.Columns[1],
transactionTable.Columns[2]
};
Run Code Online (Sandbox Code Playgroud)
到目前为止我所拥有的是以下内容:
DataTable insertTable = transactionTable.Copy();
insertTable.Clear();
using (SqlConnection sqlcon = new SqlConnection(this.GetConnString()))
{
sqlcon.Open();
foreach (var entry in transactionTable.AsEnumerable())
{
using (SqlCommand sqlCom = sqlCon.CreateCommand())
{
sqlCom.Parameters.Clear();
sqlCom.CommandText = "SELECT 1 FROM myTable WHERE"
+ " DeviceId = @DeviceId AND LogDate = @LogDate"
+ " AND LogType = @LogType"
sqlCom.Parameters.AddWithValue("@DeviceId", entry.Field<Int32>("DeviceId"));
sqlCom.Parameters.AddWithValue("@LogDate", entry.Field<DateTime>("LogDate"));
sqlCom.Parameters.AddWithValue("@LogType", entry.Field<Int32>("LogType"));
using (SqlDataREader myRead = …Run Code Online (Sandbox Code Playgroud) 我意识到在这个相同的主题上有很多回答SO问题,但我似乎无法使用任何这些信息来弄清楚我的查询有什么问题.
我正在尝试将记录插入到我的表中,只有具有相同记录database_owner和database_name(我的两个列名称)的记录尚不存在.
我正在使用查询:
INSERT INTO users_databases (database_name, database_key, database_secret, database_owner)
VALUES ('DB1', '263f690d-7ac3-49f2-aa3b-f5672e4639a2', '367123d8-e5a7-46a0-8101-21f39e6ac8d9', 'x@x.com')
WHERE
NOT EXISTS
(SELECT database_name FROM uses_databases WHERE database_name = 'DB1' AND database_owner = 'x@x.com');
Run Code Online (Sandbox Code Playgroud)
但是我收到了错误 Incorrect syntax near the keyword 'WHERE'.
我还应该指出运行查询
SELECT database_name
FROM uses_databases
WHERE database_name = 'DB1' AND database_owner = 'x@x.com'
Run Code Online (Sandbox Code Playgroud)
确实会返回记录.
我哪里可能出错?从我在其他问题中看到的内容来看,这看起来是正确的.但显然不是.:-)任何建议都会非常有帮助.