Sql server 存储过程错误:int与uniqueidentifier不兼容

Sql server 存储过程错误:int与uniqueidentifier不兼容,sql-server,int,uniqueidentifier,Sql Server,Int,Uniqueidentifier,我正在尝试修复客户端站点上的登录问题。我的公司没有建立网站,但我们只是在客户需要时进行更新。尝试在浏览器中登录时遇到的错误是: “操作数类型冲突:int与uniqueidentifier不兼容” 下面是堆栈跟踪和代码片段。我希望下面的内容足够全面,因为我很难弄清楚我在这里遗漏了什么。我不是.NET开发人员,所以这不是我经常使用的东西 这是堆栈跟踪: [SqlException (0x80131904): Operand type clash: int is incompatible with u

我正在尝试修复客户端站点上的登录问题。我的公司没有建立网站,但我们只是在客户需要时进行更新。尝试在浏览器中登录时遇到的错误是:

“操作数类型冲突:int与uniqueidentifier不兼容”

下面是堆栈跟踪和代码片段。我希望下面的内容足够全面,因为我很难弄清楚我在这里遗漏了什么。我不是.NET开发人员,所以这不是我经常使用的东西

这是堆栈跟踪:

[SqlException (0x80131904): Operand type clash: int is incompatible with uniqueidentifier]
   System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +1960506
   System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +4890731
   System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) +194
   System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2412
   System.Data.SqlClient.SqlDataReader.ConsumeMetaData() +59
   System.Data.SqlClient.SqlDataReader.get_MetaData() +83
   System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +293
   System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +954
   System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162
   System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +32
   System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +141
   System.Data.SqlClient.SqlCommand.ExecuteReader() +89
   TMSTrade.tmsCommon.Authenticate(String ps_login, String ps_password) +187
   TMSTrade._Default.Login1_Authenticate(Object sender, AuthenticateEventArgs e) +215
   System.Web.UI.WebControls.Login.OnAuthenticate(AuthenticateEventArgs e) +108
   System.Web.UI.WebControls.Login.AttemptLogin() +115
   System.Web.UI.WebControls.Login.OnBubbleEvent(Object source, EventArgs e) +101
   System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +37
   System.Web.UI.WebControls.ImageButton.OnCommand(CommandEventArgs e) +111
   System.Web.UI.WebControls.ImageButton.RaisePostBackEvent(String eventArgument) +176
   System.Web.UI.WebControls.ImageButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565
这是常见的。身份验证代码:

Public Function Authenticate(ps_login As String, ps_password As String) As Object
    Dim sqlConnection As SqlConnection = New SqlConnection(Conversions.ToString(RuntimeHelpers.GetObjectValue(Me.GetConnString())))
    sqlConnection.Open()
    Dim sqlCommand As SqlCommand = New SqlCommand("sp_Authenticate", sqlConnection)
    Dim num As Integer = 0
    sqlCommand.CommandType = CommandType.StoredProcedure
    sqlCommand.Parameters.Add("@username", SqlDbType.VarChar, 255).Value = ps_login
    sqlCommand.Parameters.Add("@password", SqlDbType.VarChar, 255).Value = ps_password
    Dim sqlDataReader As SqlDataReader = sqlCommand.ExecuteReader()
    If sqlDataReader.Read() Then
        num = Conversions.ToInteger(RuntimeHelpers.GetObjectValue(sqlDataReader("auth")))
    End If
    sqlConnection.Close()
    Return num
End Function
这是从tmsCommon调用的存储过程sp_authenticate。authenticate:

USE [tmstradedb]
GO
/****** Object:  StoredProcedure [dbo].[sp_authenticate]    Script Date: 7/27/2018 12:31:28 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- sp_authenticate 'neal','blue96'
ALTER PROCEDURE [dbo].[sp_authenticate]
    ( @UserName             varchar(255),
    @password       varchar(255))
AS
BEGIN
    DECLARE @UserId uniqueidentifier
    declare @result int
    set @result=0

    declare @appdate datetime
    declare @guestmember int
    Declare @isapproved int
    declare @islockedout int
    EXEC @UserId = dbo.spGetUserIDByName @UserName



        SELECT @result=1,@guestmember=guestmember,@appdate=approveddate,@islockedout=islockedout,@isapproved=isapproved 
        FROM    dbo.aspnet_Membership m 
        WHERE  m.password=@password and m.userid=@UserId and deleted=0 and archived=0 


        IF (@result >0) -- Username  found

        begin



            UPDATE   dbo.aspnet_Users SET LastActivityDate = getdate() WHERE    @UserId = UserId
            if (@isapproved=0) and (datediff(dd,@appdate,getdate())>31) 
            begin
                select @result=2 
            end
            if (@isapproved=2)
            begin
                select @result=3
            end
            if (@islockedout=1)
            begin
                select @result=4
            end



    end

    select @result as Auth
END
USE [tmstradedb]
GO
/****** Object:  StoredProcedure [dbo].[spGetUserIDByName]    Script Date: 7/27/2018 1:03:09 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--select dbo.[spGetUserIDByName]('neal')
ALTER PROCEDURE [dbo].[spGetUserIDByName]
    @UserName             nvarchar(256)
AS
BEGIN
        DECLARE @UserId uniqueidentifier

         -- select user ID from aspnet_users table
        SELECT TOP 1 @UserId = u.UserId
        FROM    dbo.aspnet_Applications a, dbo.aspnet_Users u, dbo.aspnet_Membership m
        WHERE    LOWER('/') = a.LoweredApplicationName AND
                u.ApplicationId = a.ApplicationId    AND
                LOWER(@UserName) = u.LoweredUserName AND u.UserId = m.UserId

END
这是存储过程spGetUserIDByName,它在sp_authenticate中调用:

USE [tmstradedb]
GO
/****** Object:  StoredProcedure [dbo].[sp_authenticate]    Script Date: 7/27/2018 12:31:28 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- sp_authenticate 'neal','blue96'
ALTER PROCEDURE [dbo].[sp_authenticate]
    ( @UserName             varchar(255),
    @password       varchar(255))
AS
BEGIN
    DECLARE @UserId uniqueidentifier
    declare @result int
    set @result=0

    declare @appdate datetime
    declare @guestmember int
    Declare @isapproved int
    declare @islockedout int
    EXEC @UserId = dbo.spGetUserIDByName @UserName



        SELECT @result=1,@guestmember=guestmember,@appdate=approveddate,@islockedout=islockedout,@isapproved=isapproved 
        FROM    dbo.aspnet_Membership m 
        WHERE  m.password=@password and m.userid=@UserId and deleted=0 and archived=0 


        IF (@result >0) -- Username  found

        begin



            UPDATE   dbo.aspnet_Users SET LastActivityDate = getdate() WHERE    @UserId = UserId
            if (@isapproved=0) and (datediff(dd,@appdate,getdate())>31) 
            begin
                select @result=2 
            end
            if (@isapproved=2)
            begin
                select @result=3
            end
            if (@islockedout=1)
            begin
                select @result=4
            end



    end

    select @result as Auth
END
USE [tmstradedb]
GO
/****** Object:  StoredProcedure [dbo].[spGetUserIDByName]    Script Date: 7/27/2018 1:03:09 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--select dbo.[spGetUserIDByName]('neal')
ALTER PROCEDURE [dbo].[spGetUserIDByName]
    @UserName             nvarchar(256)
AS
BEGIN
        DECLARE @UserId uniqueidentifier

         -- select user ID from aspnet_users table
        SELECT TOP 1 @UserId = u.UserId
        FROM    dbo.aspnet_Applications a, dbo.aspnet_Users u, dbo.aspnet_Membership m
        WHERE    LOWER('/') = a.LoweredApplicationName AND
                u.ApplicationId = a.ApplicationId    AND
                LOWER(@UserName) = u.LoweredUserName AND u.UserId = m.UserId

END
表dbo.aspnet_成员的定义:

ApplicationId   uniqueidentifier
UserId  uniqueidentifier
Password    nvarchar(128)
PasswordFormat  int
PasswordSalt    nvarchar(128)
MobilePIN   nvarchar(16)
Email   nvarchar(256)
LoweredEmail    nvarchar(256)
PasswordQuestion    nvarchar(256)
PasswordAnswer  nvarchar(128)
IsApproved  int
IsLockedOut bit
CreateDate  datetime
LastLoginDate   datetime
LastPasswordChangedDate datetime
LastLockoutDate datetime
FailedPasswordAttemptCount  int
FailedPasswordAttemptWindowStart    datetime
FailedPasswordAnswerAttemptCount    int
FailedPasswordAnswerAttemptWindowStart  datetime
Comment ntext
ApprovedDate    datetime
GuestMember bit 
Quest   varchar(MAX)
passbkup    nvarchar(128)
QuestVisible    bit
Archived    bit
表dbo.aspnet_用户的定义:

ApplicationId   uniqueidentifier
UserId  uniqueidentifier
UserName    nvarchar(256)
LoweredUserName nvarchar(256)
MobileAlias nvarchar(16)
IsAnonymous bit
LastActivityDate    datetime
SQL Server Management Studio中的sp_身份验证执行:

USE [tmstradedb]
GO

DECLARE @return_value int

EXEC    @return_value = [dbo].[sp_authenticate]
        @UserName = N'123-456', --fake user name
        @password = N'2345' -- fake password

SELECT  'Return Value' = @return_value

GO
执行时返回的错误: Msg 206,级别16,状态2,过程dbo.spGetUserIDByName,第0行[批处理起始行2] 操作数类型冲突:int与uniqueidentifier不兼容

******更新***** 根据我得到的反馈,我尝试了几件事。我将spGetUserIDByName过程修改为以下内容:

USE [tmstradedb]
GO
/****** Object:  StoredProcedure [dbo].[spGetUserIDByName]    Script Date: 7/27/2018 2:12:18 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--select dbo.[spGetUserIDByName]('neal')
ALTER PROCEDURE [dbo].[spGetUserIDByName]
    @UserName             nvarchar(256),
    @UserId uniqueidentifier OUTPUT
AS
BEGIN
        --DECLARE @UserId uniqueidentifier

         -- select user ID from aspnet_users table
        SELECT TOP 1 @UserId = u.UserId
        FROM    dbo.aspnet_Applications a, dbo.aspnet_Users u, dbo.aspnet_Membership m
        WHERE    LOWER('/') = a.LoweredApplicationName AND
                u.ApplicationId = a.ApplicationId    AND
                LOWER(@UserName) = u.LoweredUserName AND u.UserId = m.UserId

    RETURN;

END
我还更改了sp_身份验证过程:

USE [tmstradedb]
GO
/****** Object:  StoredProcedure [dbo].[sp_authenticate]    Script Date: 7/27/2018 2:13:12 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- sp_authenticate 'neal','blue96'
ALTER PROCEDURE [dbo].[sp_authenticate]
    ( @UserName             varchar(255),
    @password       varchar(255))
AS
BEGIN
    DECLARE @UserId uniqueidentifier
    declare @result int
    set @result=0

    declare @appdate datetime
    declare @guestmember int
    Declare @isapproved int
    declare @islockedout int
    --EXEC @UserId = dbo.spGetUserIDByName @UserName
    EXEC dbo.spGetUserIDByName @UserName



        SELECT @result=1,@guestmember=guestmember,@appdate=approveddate,@islockedout=islockedout,@isapproved=isapproved 
        FROM    dbo.aspnet_Membership m 
        WHERE  m.password=@password and m.userid=@UserId and deleted=0 and archived=0 


        IF (@result >0) -- Username  found

        begin



            UPDATE   dbo.aspnet_Users SET LastActivityDate = getdate() WHERE    @UserId = UserId
            if (@isapproved=0) and (datediff(dd,@appdate,getdate())>31) 
            begin
                select @result=2 
            end
            if (@isapproved=2)
            begin
                select @result=3
            end
            if (@islockedout=1)
            begin
                select @result=4
            end



    end

    select @result as Auth
END
我知道我仍然在做一些错误的事情,因为当我像上面的例子一样执行sp_authenticate时,我现在得到这个错误:

Msg 201,级别16,状态4,过程dbo.spGetUserIDByName,第0行[批处理起始行2] 过程或函数“spGetUserIDByName”需要未提供的参数“@UserId”。

这就是问题所在:

EXEC @UserId = dbo.spGetUserIDByName @UserName
RETURN @UserID;
在被调用的存储过程中,声明并填充GUID变量:

 DECLARE @UserId uniqueidentifier

         -- select user ID from aspnet_users table
        SELECT TOP 1 @UserId = u.UserId
        FROM   ...
但是,永远不要将该变量用作存储过程的输出

在该过程结束时添加此选项可能会解决问题:

EXEC @UserId = dbo.spGetUserIDByName @UserName
RETURN @UserID;

更为规范的修复方法是将
@UserID
转换为
输出
参数,并在调用过程中相应地捕获它。

sp_getuseridbyname通过输出参数返回“key”。您没有正确调用该过程。必须将UID变量作为参数“传递”才能访问过程设置的值

exec dbo.spGetUserIDByName @UserName, @UserID OUTPUT;

您在身份验证过程中声明了变量,但未使用它们。关注你的代码。停止添加更多的东西,尝试一些东西,迷惑自己

谢谢你这么快的回复。我尝试将RETURN@UserId添加到spGetUserIDByName过程的末尾,但当我尝试执行更新时,我得到了“Msg 206,级别16,状态2,过程spGetUserIDByName,第15行[Batch Start Line 7]操作数类型冲突:uniqueidentifier与int不兼容”太多无法破译。在SSMS的查询窗口中运行时,sp_authenticate是否执行无误?如果是这样,问题在于调用代码。如果不是,那么只关注sql逻辑,而忽略从应用程序调用它的方式。你需要把问题分成更小的部分来找出真正的问题。TBH,您的sql代码需要一些认真的工作和最佳实践的应用。您应该使用SET not select分配变量。你应该终止你的陈述。还有其他问题。旁注:您不应该在存储过程中使用
sp_
前缀。微软已经这样做了,而且你确实有可能在将来的某个时候发生名称冲突。最好只是简单地避免使用
sp.
并使用其他东西作为前缀,或者根本不使用前缀!不相关的提示:
SqlConnection
SqlCommand
SqlDataReader
都是
IDisposable
,因此每个都应该在
使用块中。一旦你完成了,关闭是多余的,因为隐式释放(在退出块时)会帮你完成。谢谢你的反馈。更改exec行可以消除我所遇到的错误。