如何在写入表之前检查数据是否存在

时间:2018-04-27 07:08:42

标签: c# sql sql-server primary-key

我有一个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();
            }

6 个答案:

答案 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

编辑:是的,还有其他方法,但如果你想在同一个插页中插入多行,这种方法很有用。