sql - 在不存在的地方插入值

标签 sql sql-server

好的,所以我正在尝试改进我的 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);
        }

    }
}

最佳答案

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

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

您可以使用SELECT在没有IF的情况下完成此操作

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

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

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

<强> Example on 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);

<强> Example of Merge on SQL Fiddle

关于sql - 在不存在的地方插入值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17991479/

相关文章:

sql - 加入一列,如果没有匹配加入另一列

sql - 基于Count使用IF ELSE语句执行不同的Insert语句

SQL 分组和某个日期范围内未清项目的运行总计

sql - 交叉应用 VS STUFF 功能

sql - 在另一个 SELECT 中使用 SELECT 结果

java - 通过 JDBC 将 DDL 与 SELECT 混合时为 "ERROR: cached plan must not change result type"

sql - 如何将实际的where子句传递给SQL函数?

sql-server - 列出有关 SQL Server 中所有数据库文件的信息

c# - 使用 LINQ 查询语法 EF Core C# 的左外部联接

asp.net - SQL Server - 数据库问题