Stored procedure error: int is incompatible with uniqueidentifier
Stored procedure error: int is incompatible with uniqueidentifier
我正在尝试解决客户站点上的登录问题。我的公司没有建立网站,但我们只是在客户需要时进行更新。我尝试在浏览器中登录时遇到的错误是:
"Operand type clash: int is incompatible with 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
这是tmsCommon.Authenticate代码:
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.Authenticate:
调用的存储过程 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
这是在 sp_authenticate:
中调用的存储过程 spGetUserIDByName
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
Table dbo.aspnet_Membership 的定义:
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
Table dbo.aspnet_Users 的定义:
ApplicationId uniqueidentifier
UserId uniqueidentifier
UserName nvarchar(256)
LoweredUserName nvarchar(256)
MobileAlias nvarchar(16)
IsAnonymous bit
LastActivityDate datetime
sp_authenticate 在 SQL Server Management Studio 中执行:
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
执行返回错误:
消息 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_authenticate 程序进行了更改:
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 时,我现在得到这个错误:
消息 201,级别 16,状态 4,过程 dbo.spGetUserIDByName,第 0 行 [批处理开始第 2 行]
过程或函数 'spGetUserIDByName' 需要未提供的参数“@UserId”。
这是问题所在:
EXEC @UserId = dbo.spGetUserIDByName @UserName
在被调用的存储过程中,您声明并填充了一个 GUID 变量:
DECLARE @UserId uniqueidentifier
-- select user ID from aspnet_users table
SELECT TOP 1 @UserId = u.UserId
FROM ...
但是您永远不会将该变量用作存储过程的输出。
在该过程的末尾添加这个可能会解决问题:
RETURN @UserID;
一个更规范的修复方法是将 @UserID
变成一个 OUTPUT
参数并在调用过程中相应地捕获它。
sp_getuseridbyname returns "key" 通过输出参数。您没有正确调用该过程。您必须 "pass" 一个 UID 变量作为参数才能访问该过程设置的值。
exec dbo.spGetUserIDByName @UserName, @UserID OUTPUT;
您在身份验证过程中声明了变量但没有使用它们。专注于您的代码。停止添加更多的东西,尝试一些东西,让自己感到困惑。
我正在尝试解决客户站点上的登录问题。我的公司没有建立网站,但我们只是在客户需要时进行更新。我尝试在浏览器中登录时遇到的错误是:
"Operand type clash: int is incompatible with 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
这是tmsCommon.Authenticate代码:
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.Authenticate:
调用的存储过程 sp_authenticateUSE [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
这是在 sp_authenticate:
中调用的存储过程 spGetUserIDByNameUSE [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
Table dbo.aspnet_Membership 的定义:
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
Table dbo.aspnet_Users 的定义:
ApplicationId uniqueidentifier
UserId uniqueidentifier
UserName nvarchar(256)
LoweredUserName nvarchar(256)
MobileAlias nvarchar(16)
IsAnonymous bit
LastActivityDate datetime
sp_authenticate 在 SQL Server Management Studio 中执行:
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
执行返回错误: 消息 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_authenticate 程序进行了更改:
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 时,我现在得到这个错误:
消息 201,级别 16,状态 4,过程 dbo.spGetUserIDByName,第 0 行 [批处理开始第 2 行] 过程或函数 'spGetUserIDByName' 需要未提供的参数“@UserId”。
这是问题所在:
EXEC @UserId = dbo.spGetUserIDByName @UserName
在被调用的存储过程中,您声明并填充了一个 GUID 变量:
DECLARE @UserId uniqueidentifier
-- select user ID from aspnet_users table
SELECT TOP 1 @UserId = u.UserId
FROM ...
但是您永远不会将该变量用作存储过程的输出。
在该过程的末尾添加这个可能会解决问题:
RETURN @UserID;
一个更规范的修复方法是将 @UserID
变成一个 OUTPUT
参数并在调用过程中相应地捕获它。
sp_getuseridbyname returns "key" 通过输出参数。您没有正确调用该过程。您必须 "pass" 一个 UID 变量作为参数才能访问该过程设置的值。
exec dbo.spGetUserIDByName @UserName, @UserID OUTPUT;
您在身份验证过程中声明了变量但没有使用它们。专注于您的代码。停止添加更多的东西,尝试一些东西,让自己感到困惑。