SQL 检查记录是不是存在

Posted

技术标签:

【中文标题】SQL 检查记录是不是存在【英文标题】:SQL check if record existsSQL 检查记录是否存在 【发布时间】:2016-12-11 13:29:30 【问题描述】:

所以我花了一些时间研究检查记录是否存在的最佳方法。就这样结束了。

var checkExistance = "SELECT TOP 1 exerVariName FROM exerciseVariants WHERE exerVariName = '" + exerVariName + "'";

但是,在我的页面上使用它时,我多次失败!

var exerVariName = Request.Form["exerVariName"];

var checkExistance = "SELECT TOP 1 exerVariName FROM exerciseVariants WHERE exerVariName = '" + exerVariName + "'";

if (IsPost && Validation.IsValid()) 
    if (ModelState.IsValid) 
        foreach (var c in db.Query(checkExistance))                     
            if (c.exerVariName != exerVariName) 
                var insertData = "INSERT INTO exerciseVariants (exerVariName, exerVariNameID) " + 
                "VALUES (@0, @1)";

                db.Execute(insertData, exerVariName, exerciseID); 
                Response.Redirect("~/insertexervariname");
            
        
    

所以我放入 SQL 行的变量是一个请求表单,所以它是一个用户输入,我想检查它是否存在于数据库中,如果它已经存在我不希望它被发布。以上是我在if ispost 中使用foreach 所尝试的。

如何实现这一目标? (c#razor/cshtml)

【问题讨论】:

【参考方案1】:

您的代码有竞争条件。

做你想做的最好的方法是让数据库使用唯一的索引/约束来强制执行约束:

create unique index unq_exerciseVariants_exerVariName on exerciseVariants(exerVariName);

如果您想避免更新错误,那么您也可以在更新时检查:

INSERT INTO exerciseVariants (exerVariName, exerVariNameID)
      SELECT exerVariName, exerVariNameID
      FROM (SELECT @0 as exerVariName, @1 as exerVariNameID
           ) x
      WHERE NOT EXISTS (SELECT 1
                        FROM exerciseVariants
                        WHERE ev.exerVariName = x.exerVariName
                       );

请注意,如果两个不同的线程尝试同时插入相同的名称,则由于竞争条件,此检查可能不够充分。这就是为什么最好让数据库强制执行唯一性。

【讨论】:

@PontusSvedberg 。 . .您将连接到数据库并运行一次。 不幸的是,我还没有编写我的数据库,它内置在 webmatrix 中,所以您只需单击并命名列,呵呵 您可以通过在列上添加唯一约束来执行相同的操作。我不知道如何在 Webmatrix 中做到这一点,但应该很容易。 哦,像检查'是身份'?【参考方案2】:

无论如何,我都不是 C# 人,但我确实看到了您当前代码的一个逻辑问题。目前,您的 EXISTSINSERT 查询是分开运行的,由几行 .NET 代码和可能更多的实际机器指令分隔。这样做的净(不是双关语)结果是,当存在检查显示为真但不再为真时,您最终可能会插入。为避免这种情况,存在性检查应出现在INSERTWHERE 子句中。像这样的东西应该可以工作:

INSERT INTO exerciseVariants (exerVariName, exerVariNameID)
VALUES (@0, @1)
WHERE EXISTS
(
    SELECT * exerVariName
    FROM exerciseVariants
    WHERE exerVariName = '" + exerVariName + "'";
)

现在INSERT 应该自动发生,这意味着您的检查和实际插入都将同时完成,而不管其他线程可能在做什么。

【讨论】:

我将 if ispost 中的代码更新为 var insertData = "INSERT INTO exerciseVariants (exerVariName, exerVariNameID) VALUES (@0, @1) WHERE EXISTS(SELECT * exerVariName FROM exerciseVariants WHERE exerVariName = '" + exerVariName + "')"; 并给出了这个错误(解析查询时出错。[ Token line number = 1,Token line offset = 77,Token in error = WHERE ]) 并突出显示这一行 db.Execute(insertData, exerVariName, exerciseID);

以上是关于SQL 检查记录是不是存在的主要内容,如果未能解决你的问题,请参考以下文章

检查PhoneGap的记录是不是存在SQL

Android SQL:检查数据库中的记录是不是存在

如何在SQL Server2005数据库中检查一个表是不是存在,如存在就删除表记录,如不存在就建表.

如何在将大量数据插入数据库之前检查记录是不是存在?

SQL检查是不是存在并插入[重复]

AX 插入一条记录提示表记录已经存在,但是该记录实际上是不存在的。