我有一个SQL命令,可以将数据插入SSMS
中名为FileTrackLog
的表中。
每次插入重复数据时,我的应用都会崩溃,因为[路径]字段为primary key
。
如何在不崩溃我的应用程序的情况下检查如何不重新添加已存在的数据?
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
SqlCommand cmd =
new SqlCommand(
"INSERT INTO [FileTrackLog] (Date, Client, Path, DateAddedToDb) " + // Dont foreget to add "DateAddedToDb" later when going live
" VALUES (@Date, @Client, @Path, @DateAddedToDb)"); // Dont foreget to add @"DateAddedToDb" later when going live
cmd.CommandType = CommandType.Text;
cmd.Connection = conn;
cmd.Parameters.Add("@Date", DbType.DateTime);
cmd.Parameters.Add("@Client", DbType.String);
cmd.Parameters.Add("@Path", DbType.String);
cmd.Parameters.Add(@"DateAddedToDb",DbType.DateTime);
foreach (var extractedRecord in extractedList)
{
cmd.Parameters[0].Value = extractedRecord.Date;
cmd.Parameters[1].Value = extractedRecord.Client;
cmd.Parameters[2].Value = extractedRecord.Path;
cmd.Parameters[3].Value = DateTime.Now;
cmd.ExecuteNonQuery();
}
conn.Close();
}
答案 0 :(得分:2)
使用EXISTS
,我们可以检查已存在的值。
如果该值已存在,则会跳过插入进度。
试试这个:
IF NOT EXISTS(SELECT 1 FROM [FileTrackLog] WHERE YourPrimaryKeyColumn = @PrimaryKeyInput)
BEGIN
INSERT INTO [FileTrackLog] (Date, Client, Path, DateAddedToDb)
VALUES (@Date, @Client, @Path, @DateAddedToDb)
END
答案 1 :(得分:1)
INSERT INTO [FileTrackLog] (Date, Client, Path, DateAddedToDb)
SELECT @Date, @Client, @Path, @DateAddedToDb
WHERE NOT EXISTS (SELECT 1 FROM [FileTrackLog] WHERE Path = @Path)
答案 2 :(得分:1)
您可以在NOT EXISTS
命令之前添加INSERT
检查,即 -
SqlCommand cmd =
new SqlCommand(
"IF NOT EXISTS (SELECT 1 FROM [FileTrackLog] WHERE Path = @Path) "+
"INSERT INTO [FileTrackLog] (Date, Client, Path, DateAddedToDb) " +
"VALUES (@Date, @Client, @Path, @DateAddedToDb)");
此外,您想要跟踪insertion
是否成功。
答案 3 :(得分:1)
我认为使用Merge命令在您的应用程序中实现AddOrUpdate范例是有用的。
MERGE [FileTrackLog] AS target
USING (SELECT _PrimeryKeyValue, _Date, _Client, _Path, _DateAddedToDb) AS source (@PrimaryKeyValue, @Date, @Client, @Path, @DateAddedToDb)
ON (target.YourPrimaryKeyColumn = source._PrimeryKeyValue)
WHEN MATCHED THEN
UPDATE SET Date = source._Date, Client = source._Client, Path = source._Path
WHEN NOT MATCHED THEN
INSERT (Date, Client, Path, DateAddedToDb)
VALUES (source._Date, source._Client, source._Path, source._DateAddedToDb)
如果ON
语句中的条件与目标表中的任何行匹配
然后我们将更新目标表中的数据(列DateAddedToDb
除外)。否则我们将在目标表中插入新行。
答案 4 :(得分:0)
您应该捕获异常并相应地处理它。
foreach (var extractedRecord in extractedList)
{
cmd.Parameters[0].Value = extractedRecord.Date;
cmd.Parameters[1].Value = extractedRecord.Client;
cmd.Parameters[2].Value = extractedRecord.Path;
cmd.Parameters[3].Value = DateTime.Now;
try
{
cmd.ExecuteNonQuery();
}
catch (SqlException ex)
{
if (ex.Number == 2627)
{
//Violation of primary key. Handle Exception
//continue to next iteration
}
}
}
答案 5 :(得分:0)
这样的事可能
Insert into TableX
select
A
,B
from (
VALUES ('1', '2')) as t
where A not in select A from TableX
编辑:是的,还有其他方法,但如果你想在同一个插页中插入多行,这种方法很有用。