Sql server 如何在select语句中设置2个计算输出参数

Sql server 如何在select语句中设置2个计算输出参数,sql-server,tsql,Sql Server,Tsql,我正在SQL Server 2016中创建一个存储过程,基本上我将验证用户和密码组合,以了解用户是否有效,如果是,我想设置两个输出参数,其中一个包含表示用户有效的布尔值(因为稍后在我的应用程序中,我想检查该布尔值)另一个包含用户的ID 我的存储过程是这样的 ALTER PROCEDURE [dbo].[uspLogin] ( @Email AS VARCHAR(200), @Password AS VARCHAR(200), @IsValid AS BIT OUTPUT,

我正在SQL Server 2016中创建一个存储过程,基本上我将验证用户和密码组合,以了解用户是否有效,如果是,我想设置两个输出参数,其中一个包含表示用户有效的布尔值(因为稍后在我的应用程序中,我想检查该布尔值)另一个包含用户的ID

我的存储过程是这样的

ALTER PROCEDURE [dbo].[uspLogin]
(
    @Email AS VARCHAR(200),
    @Password AS VARCHAR(200),
    @IsValid AS BIT OUTPUT,
    @UserId AS INT OUTPUT
)
AS
BEGIN

    SET NOCOUNT ON;

    BEGIN TRY


        BEGIN TRANSACTION;

        SELECT 
        @IsValid = (CASE WHEN COUNT(*) > 0 THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END),
        @UserId = (CASE WHEN COUNT(*) > 0 THEN CAST(U.UserId AS INT) ELSE CAST(-1 AS INT) END)
        FROM [dbo].[User] AS U
        INNER JOIN [dbo].[UserEnabled] AS UE ON U.UserId = UE.UserId
        WHERE U.Email = @Email AND U.Password = @Password

        COMMIT TRANSACTION;

    END TRY
    BEGIN CATCH

        IF @@TRANCOUNT > 0
            ROLLBACK TRANSACTION;

        DECLARE @ErrorMessage nvarchar(4000) = 'Error: [' + ERROR_MESSAGE() + '] in line [' + CAST(ERROR_LINE() AS varchar(1000)) + '] of procedure [' + ERROR_PROCEDURE() + ']';

        RAISERROR(@Errormessage, 18, 0);

    END CATCH;

END
一旦执行,我就会出现以下错误:

列“dbo.User.UserId”在选择列表中无效,因为它未包含在聚合函数或GROUP BY子句中


您只需获取@UserId并检查其值。如果为NULL,则表示无效

SELECT @UserId  = U.UserId 
FROM   [dbo].[User] AS U
       INNER JOIN [dbo].[UserEnabled] AS UE ON U.UserId = UE.UserId
WHERE  U.Email = @Email AND U.Password = @Password

SELECT @IsValid = CASE WHEN @UserId IS NULL THEN 0 ELSE 1 END
或者,您可以将
@IsValid
初始化为false,并在查询中设置为
TRUE

SELECT @IsValid  = 0

SELECT @UserId  = U.UserId,
       @IsValid = 1
FROM   [dbo].[User] AS U
       INNER JOIN [dbo].[UserEnabled] AS UE ON U.UserId = UE.UserId
WHERE  U.Email = @Email AND U.Password = @Password

您只需获取@UserId并检查其值。如果为NULL,则表示无效

SELECT @UserId  = U.UserId 
FROM   [dbo].[User] AS U
       INNER JOIN [dbo].[UserEnabled] AS UE ON U.UserId = UE.UserId
WHERE  U.Email = @Email AND U.Password = @Password

SELECT @IsValid = CASE WHEN @UserId IS NULL THEN 0 ELSE 1 END
或者,您可以将
@IsValid
初始化为false,并在查询中设置为
TRUE

SELECT @IsValid  = 0

SELECT @UserId  = U.UserId,
       @IsValid = 1
FROM   [dbo].[User] AS U
       INNER JOIN [dbo].[UserEnabled] AS UE ON U.UserId = UE.UserId
WHERE  U.Email = @Email AND U.Password = @Password

我建议修改存储过程以简单地输出userid,当用户无效时,返回userid=null?它们将在使用合适的salt进行单向散列后存储,并且验证需要对输入密码进行散列以进行比较。@HABO密码字段是一个已经进行了salt的密码字段group by error应该是明显的-您使用的是count(*),但也引用了单个值。Add
groupbyu.UserId
我建议修改存储过程,只输出UserId,当用户无效时,返回UserId=null。旁白:当然,真实世界的应用程序永远不会以明文形式存储密码,对吗?它们将在使用合适的salt进行单向散列后存储,并且验证需要对输入密码进行散列以进行比较。@HABO密码字段是一个已经进行了salt的密码字段group by error应该是明显的-您使用的是count(*),但也引用了单个值。添加
按U.UserId分组