在不存在的地方插入值

新手上路,请多包涵

好的,所以我正在尝试改进我的 asp 数据输入页面,以确保进入我的数据表的条目是唯一的。

所以在这张表中,我有 SoftwareName 和 SoftwareType。我正在尝试获取它,因此如果条目页面发送一个插入查询,其参数与表中的内容相匹配(因此相同的标题和类型),则会引发错误并且未输入数据。

像这样的东西:

 INSERT INTO tblSoftwareTitles(
            SoftwareName,
            SoftwareSystemType)
            VALUES(@SoftwareName,@SoftwareType)
            WHERE NOT EXISTS (SELECT SoftwareName
            FROM tblSoftwareTitles
            WHERE Softwarename = @SoftwareName
            AND SoftwareType = @Softwaretype)

因此,这种语法非常适合从一个表中选择列到另一个表中而无需输入重复项,但似乎不想使用参数化的插入查询。谁能帮我解决这个问题?

编辑:

这是我在 ASP 插入方法中使用的代码

    private void ExecuteInsert(string name, string type)
{
    //Creates a new connection using the HWM string
    using (SqlConnection HWM = new SqlConnection(GetConnectionStringHWM()))
    {
        //Creates a sql string with parameters
        string sql = " INSERT INTO tblSoftwareTitles( "
                   + " SoftwareName, "
                   + " SoftwareSystemType) "
                   + " SELECT "
                   + " @SoftwareName, "
                   + " @SoftwareType "
                   + " WHERE   NOT EXISTS  "
                   + " ( SELECT  1 "
                   + " FROM tblSoftwareTitles "
                   + " WHERE Softwarename = @SoftwareName "
                   + " AND SoftwareSystemType = @Softwaretype); ";

        //Opens the connection
        HWM.Open();
        try
        {
            //Creates a Sql command
            using (SqlCommand addSoftware = new SqlCommand{
                CommandType = CommandType.Text,
                Connection = HWM,
                CommandTimeout = 300,
                CommandText = sql})
            {
                //adds parameters to the Sql command
                addSoftware.Parameters.Add("@SoftwareName", SqlDbType.NVarChar, 200).Value = name;
                addSoftware.Parameters.Add("@SoftwareType", SqlDbType.Int).Value = type;
                //Executes the Sql
                addSoftware.ExecuteNonQuery();
            }
            Alert.Show("Software title saved!");
        }
        catch (System.Data.SqlClient.SqlException ex)
        {
            string msg = "Insert Error:";
            msg += ex.Message;
            throw new Exception(msg);
        }

    }
}

原文由 Tinydan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 396
2 个回答

您可以使用 IF 语句来执行此操作:

 IF NOT EXISTS
    (   SELECT  1
        FROM    tblSoftwareTitles
        WHERE   Softwarename = @SoftwareName
        AND     SoftwareSystemType = @Softwaretype
    )
    BEGIN
        INSERT tblSoftwareTitles (SoftwareName, SoftwareSystemType)
        VALUES (@SoftwareName, @SoftwareType)
    END;

你可以不用 IF 使用 SELECT

 INSERT  tblSoftwareTitles (SoftwareName, SoftwareSystemType)
SELECT  @SoftwareName,@SoftwareType
WHERE   NOT EXISTS
        (   SELECT  1
            FROM    tblSoftwareTitles
            WHERE   Softwarename = @SoftwareName
            AND     SoftwareSystemType = @Softwaretype
        );

这两种方法都容易受到 竞争条件 的影响,所以虽然我仍然会使用上述方法之一进行插入,但您可以使用唯一约束来保护重复插入:

 CREATE UNIQUE NONCLUSTERED INDEX UQ_tblSoftwareTitles_Softwarename_SoftwareSystemType
    ON tblSoftwareTitles (SoftwareName, SoftwareSystemType);

SQL-Fiddle 示例


附录

在 SQL Server 2008 或更高版本中,您可以使用 MERGEHOLDLOCK 来消除竞争条件的可能性(这仍然不能替代唯一约束)。

 MERGE tblSoftwareTitles WITH (HOLDLOCK) AS t
USING (VALUES (@SoftwareName, @SoftwareType)) AS s (SoftwareName, SoftwareSystemType)
    ON s.Softwarename = t.SoftwareName
    AND s.SoftwareSystemType = t.SoftwareSystemType
WHEN NOT MATCHED BY TARGET THEN
    INSERT (SoftwareName, SoftwareSystemType)
    VALUES (s.SoftwareName, s.SoftwareSystemType);

SQL Fiddle 上的合并示例

原文由 GarethD 发布,翻译遵循 CC BY-SA 4.0 许可协议

我知道这篇文章很旧,但我找到了一种将值插入到带有关键字 INSERT INTO 和 EXISTS 的表中的原始方法。

我说原创是因为我在网上没有找到。

这里是 :

 INSERT INTO targetTable(c1,c2)
select value1,value2
WHERE NOT EXISTS(select 1 from targetTable where c1=value1 and c2=value2 )

原文由 Jean-Pierre R 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进