Sql 选择是否存在,否则选择0是否查询两次?

Sql 选择是否存在,否则选择0是否查询两次?,sql,Sql,我正在做这样的密码验证查询 if exists(select UserID from users where UserName=@UserName and Password=@Password) select UserID from users where UserName=@UserName and Password=@Password else select 0 但在我看来,对于一个单一的结果,我要查询两次 我可以这样做吗 Select UserID Where Use

我正在做这样的密码验证查询

if exists(select UserID from users where UserName=@UserName and Password=@Password) 
    select UserID from users where UserName=@UserName and Password=@Password
else 
    select 0
但在我看来,对于一个单一的结果,我要查询两次 我可以这样做吗

Select UserID Where Username = @UserName and Password = @Password
当我得到我的结果时,只需查看阅读器中的结果数量

if (!myReader.HasRows)
    MessageBox.Show("UserName not found or Password invalid");
else
    //do login stuff
猜猜我想问的是,哪一个更好,或者它们是一样的?

使用这个:

SELECT  ISNULL
        (
        (
        SELECT  userId
        FROM    users
        WHERE   userName = @userName
                AND password = @password
        ),
        0
        )
当然,检查记录数量的解决方案也会起作用

请注意,它将始终只返回一条记录,如果用户名不唯一且存在@userName的重复项,则将失败

正如@Andriy M所指出的,COALESCE在这里没有帮助,因为它在内部被重写成一个容易出现相同问题的案例

回答您的问题:是的,原始批将访问用户两次。

使用以下方法:

SELECT  ISNULL
        (
        (
        SELECT  userId
        FROM    users
        WHERE   userName = @userName
                AND password = @password
        ),
        0
        )
当然,检查记录数量的解决方案也会起作用

请注意,它将始终只返回一条记录,如果用户名不唯一且存在@userName的重复项,则将失败

正如@Andriy M所指出的,COALESCE在这里没有帮助,因为它在内部被重写成一个容易出现相同问题的案例



回答您的问题:是的,原始批将访问用户两次。

关于在数据库中存储可重构密码的标准警告适用。@Quassnoi您介意解释一下这个所谓的标准警告吗?我自己研究过它,我认为这是指向Quassnoi所说内容的一个很好的链接,如果你正在读这篇文章,并想知道,请检查一下,这不是一个大阅读,但它是一个优秀的文章存储在数据库中的密码在纯文本或任何其他索引搜索条件被认为是不安全的。您的查询表明,可以仅从通过网络传输的值构造存储在数据库中的值。如果您的数据库泄漏,对每个用户来说都是一种安全风险。而是存储盐渍散列值。谢谢你,我从来不知道这是个问题。该死的笨蛋!!关于在数据库中存储可重构密码的标准警告适用。@Quassnoi您介意解释一下这个所谓的标准警告吗?我自己研究过它,我认为这是一个很好的链接,指向Quassnoi所说的内容,如果您正在阅读此文并想知道,请查看它,这不是一篇大文章,但它是一篇优秀的文章,将密码以纯文本形式存储在数据库中,或者任何其他索引搜索条件都被认为是不安全的。您的查询表明,可以仅从通过网络传输的值构造存储在数据库中的值。如果您的数据库泄漏,对每个用户来说都是一种安全风险。而是存储盐渍散列值。谢谢你,我从来不知道这是个问题。该死的笨蛋!!我肯定比第一个更喜欢这个。我必须阅读它,但是它选择了第一个带有非空数据的选项,所以如果第一个选择不起作用,它将转到下一个选项。在这种情况下,这是一个常数,并且始终有效。这太完美了,非常感谢。对于标量子查询,它代替了COALESCE,因为使用COALESCE,子查询将执行两次,这并不能解决OP的问题。@AndriyM:这里是一个单子查询,在列表中排在第一位。它将只执行一次。验证不会花费太多时间。尝试此操作并比较两个选择的计划:DECLARE@t TABLE ID int,Value int;从@t中选择COALESCESELECT值,其中ID=1,0;从@t中选择ISNULLSELECT值,其中ID=1,0;。在SQLServer2008R2上,它们对我来说是不同的。@AndriyM:你说得对,很抱歉贬低了我。从最左边嵌套循环中的IsFalseOrNull判断,COALESCE很可能被重写为解析阶段的CASE。我肯定比第一个更喜欢它。我必须阅读它,但是它选择了第一个带有非空数据的选项,所以如果第一个选择不起作用,它将转到下一个选项。在这种情况下,这是一个常数,并且始终有效。这太完美了,非常感谢。对于标量子查询,它代替了COALESCE,因为使用COALESCE,子查询将执行两次,这并不能解决OP的问题。@AndriyM:这里是一个单子查询,在列表中排在第一位。它将只执行一次。验证不会花费太多时间。尝试此操作并比较两个选择的计划:DECLARE@t TABLE ID int,Value int;从@t中选择COALESCESELECT值,其中ID=1,0;从@t中选择ISNULLSELECT值,其中ID=1,0;。在SQLServer2008R2上,它们对我来说是不同的。@AndriyM:你说得对,很抱歉贬低了我。从最左边嵌套循环中的IsFalseOrNull判断,COALESCE很可能被重写为解析阶段的CASE。