T-SQL if语句错误

6
我正在尝试执行以下SQL 2008代码,但它提示“=”和“else”附近存在问题……我不明白这个代码有什么问题。
ALTER PROCEDURE dbo.LoginEmp @username NVARCHAR(10),
                             @password NVARCHAR(10),
                             @confirm  INT output,
                             @emp_name NVARCHAR(50) output,
                             @emp_id   BIGINT output
AS
    IF EXISTS (SELECT @emp_id = emp_id,
                      @emp_name = emp_name_ara
               FROM   Employee
               WHERE  ( emp_username LIKE @username
                        AND emp_password LIKE @password ))
      BEGIN
          SET @confirm=1

          INSERT INTO EmployeeLog
                      (log_emp_id,
                       log_act_id,
                       log_date,
                       log_data)
          VALUES      (@emp_id,
                       1,
                       GETDATE(),
                       -1)
      END
    ELSE
      BEGIN
          SET @confirm=0
      END

    RETURN 

2
你无法在 EXISTS(SELECT 内部分配变量。@Santosh 我使用 SQL Pretty Printer。在线版本在这里 http://www.dpriver.com/pp/sqlformat.htm - Martin Smith
@MarcelloRomani 我的朋友,这是一个nvarchar字段,所以最好使用LIKE运算符。 - Monir Tarabishi
@iceDragon - 给变量赋值的语句不会返回任何结果集,因此在 EXISTS 中使用没有意义。 - Martin Smith
2
在我看来,通过LIKE比较进行身份验证是一个重大的安全漏洞。此外,我认为SQL Server具有一个支持Unicode的=运算符http://msdn.microsoft.com/en-us/library/ms189863.aspx。 - Marcello Romani
@MarcelloRomani 是正确的。如果您知道用户名,那么您可以只输入“%”作为密码来使用“LIKE”进行身份验证。它应该使用“=”(在大多数情况下,密码也应该被哈希)。 - Martin Smith
显示剩余5条评论
5个回答

2

不要试图在EXISTS中分配输出参数,而是先进行赋值,然后检查@@rowcount以查看是否找到了任何匹配的行。

ALTER PROCEDURE dbo.LoginEmp @username NVARCHAR(10),
                             @password NVARCHAR(10),
                             @confirm  INT output,
                             @emp_name NVARCHAR(50) output,
                             @emp_id   BIGINT output
AS
    SELECT @emp_id = emp_id,
           @emp_name = emp_name_ara
    FROM   Employee
    WHERE  ( emp_username = @username
             AND emp_password = @password )

    IF @@ROWCOUNT = 1
      BEGIN
          SET @confirm=1

          INSERT INTO EmployeeLog
                      (log_emp_id,
                       log_act_id,
                       log_date,
                       log_data)
          VALUES      (@emp_id,
                       1,
                       GETDATE(),
                       -1)
      END
    ELSE
      BEGIN
          SET @confirm=0
      END

1
@iceDragon - 你可能更想使用 IF @@ROWCOUNT = 1 而不是 IF @@ROWCOUNT > 0。我只是使用第二个来尽可能地保留原始语义中的 EXISTS - Martin Smith

1

Exists操作符检查查询返回的结果集中是否存在任何行。在您的示例中,它只是将值分配给变量。有关更多参考,请查看此链接:在IF EXISTS子句中分配变量


0

试一下这个:

ALTER PROCEDURE dbo.LoginEmp
@username nvarchar(10),
@password nvarchar(10),
@confirm int output,
@emp_name nvarchar(50) output,
@emp_id bigint output
AS 
Begin
if exists (SELECT emp_id, emp_name_ara FROM Employee WHERE        (emp_username LIKE @username AND emp_password LIKE @password)) begin
  // Here Retrieve the Data into Variable again. Like You did Above Before.
set @confirm=1

INSERT INTO EmployeeLog (log_emp_id,log_act_id,log_date,log_data) VALUES (@emp_id,1,GETDATE(),-1)

end
else begin

set @confirm=0
end 
end
RETURN

这不影响结果。 - Monir Tarabishi

0

更改

SELECT @emp_id = emp_id,
                      @emp_name = emp_name_ara

SELECT emp_id, emp_name_ara

在WHERE子句中添加@emp_id@emp_name变量。
IF EXISTS (SELECT  emp_id, emp_name_ara
               FROM   Employee
               WHERE  ( emp_username LIKE @username
                        AND emp_password LIKE @password AND emp_id=@emp_id AND emp_name_ara = @emp_name  ))

但是我需要将这些值分配给输出变量。 - Monir Tarabishi
我不是使用变量来测试一个值,我需要通过它们返回一个值。 - Monir Tarabishi

0

你能把IF EXISTS放在BEGIN之后吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接