SQL-仅当主键值尚未存在于表中时才插入表中

时间:2016-04-08 01:33:40

标签: c# sql-server

如果我有桌子:

 Table A
 Column1(Primary Key) | Column2 | Column3

当我插入新行时,如果已经存在具有该主键的行,它将如何确保它不会插入新行?

我当前的c#代码和SQL命令:

string sqlConnectionString = ConfigurationManager.ConnectionStrings["blah"].ConnectionString;

string cmdString = "INSERT INTO TableA (Column1,Column2,Column3) VALUES (@val1, @val2, @val3)";

using (SqlConnection conn = new SqlConnection(sqlConnectionString))
{
    using (SqlCommand comm = new SqlCommand())
    {
        comm.Connection = conn;
        comm.CommandText = cmdString;
        comm.Parameters.AddWithValue("@val1", x);
        comm.Parameters.AddWithValue("@val2", y);
        try
        {
            conn.Open();
            comm.ExecuteNonQuery();
        }
        Catch(SqlException e)
        {
            // do something with the exception
            // don't hide it
        }
    }
}

这是否自动处理,因为Column1被指定为主?

编辑:

我在下面的SQL命令中遇到错误,有什么想法?

  

“INSERT INTO TableA(Column1,Column2)VALUES(@ val1,@ val2)WHERE   NOT EXISTS(从TableA中选择1,其中Column1 = @ val1)“

3 个答案:

答案 0 :(得分:0)

正如@tdelepine建议的那样。您可以在命令中使用merge方法。这是一个简单的例子。对于您的使用,您只需要摆脱“When Matched Then”条款。我在存储过程中大量使用此方法来执行添加或更新。

MERGE [dbo].[TableName] AS tar
USING (SELECT @Key As UserKey) AS src
ON (tar.[KeyColumn] = src.UserKey)
WHEN MATCHED THEN
    UPDATE SET [ValueColumn] = @Value
WHEN NOT MATCHED BY TARGET THEN
    INSERT ([KeyColumn], [ValueColumn])
    VALUES (@Key, @Value);

答案 1 :(得分:0)

无需事先检查。如果存在主键,则第二个插入将失败。只需捕获该错误条件,以便在尝试复制时采取任何有意义的操作。

这是明智的,因为(a)它避免了竞争条件,(b)它更容易要求宽恕而不是许可通常是一种很好的编程理念(通常会导致更清晰的代码)。

答案 2 :(得分:0)

如果您使用存储过程但不是必需的话,这会更容易。

如果主键已存在但其他值已更新,是否要更新其他列?

MERGE TableA with (holdlock) AS target
    USING (SELECT @val1, @val2, @val3) AS source (value1, value2, value2)
    ON (target.Column1 = source.value1)
    WHEN MATCHED THEN 
        UPDATE SET
            Column2 = source.value2,
            Column3 = source.value3
WHEN NOT MATCHED THEN
    INSERT (Column1, Column2, Column3)
    VALUES (source.value1, source.value2, source.value3);

您可以在不合并的情况下执行此操作。当您的输入是表值参数或来自另一个表的SELECT时,这更有用。它允许您在单个操作中执行许多这些操作。您还可以对插入使用OUTPUT INTO子句以返回实际为新插入的主键。