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# 人,但我确实看到了您当前代码的一个逻辑问题。目前,您的 EXISTS
和 INSERT
查询是分开运行的,由几行 .NET 代码和可能更多的实际机器指令分隔。这样做的净(不是双关语)结果是,当存在检查显示为真但不再为真时,您最终可能会插入。为避免这种情况,存在性检查应出现在INSERT
的WHERE
子句中。像这样的东西应该可以工作:
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 检查记录是不是存在的主要内容,如果未能解决你的问题,请参考以下文章