SQL存储过程无法识别列名称

时间:2016-02-10 07:15:16

标签: sql-server tsql if-statement stored-procedures visual-studio-2015

我有一个非常基本的登录学校管理系统。存储过程需要使用用户名和密码。它在' Person'上查找用户ID。表并确定用户是教师还是管理员。然后,它会相应地查找Teacher或Administrator表以匹配密码。我遇到的问题是它似乎无法识别列名称" Type"在Person表中,也没有"密码"其他2个表中的列名。这是我的SQL命令。 (注意:只有IF语句中提到的列名称才能识别。其他一切似乎都很好)。感谢您提供的任何帮助。非常感谢。

CREATE PROCEDURE Login
(@ID INT, @PW TEXT)
AS
BEGIN
DECLARE @USERTYPE INT
SET @USERTYPE = 0
SELECT Type FROM dbo.Person WHERE @ID = ID
IF (Type = 'Teacher')
BEGIN
    (SELECT Password FROM dbo.Teacher WHERE @ID = TID)
    IF (@PW = Password)
    BEGIN
        SET @USERTYPE = 1
        END
        END
ELSE IF (Type = 'Administrator')
BEGIN
    (SELECT Password FROM dbo.Administartion WHERE @ID = AID)
    IF (@PW = Password)
    BEGIN
        SET @USERTYPE = 2
        END
        END
ELSE 
BEGIN
    SET @USERTYPE = 0
END
END

2 个答案:

答案 0 :(得分:2)

我猜你是SQL的新手,不是吗?因为这不是查询的工作方式:

SELECT Type FROM dbo.Person WHERE @ID = ID

选择Type值,但返回作为存储过程的一个结果集。它不会存储它。

这就是以下不起作用的原因:

IF (Type = 'Teacher')

SQL无法定义变量Type以了解如何处理它(除了它是一个保留字)。您需要将查询结果存储在变量中。

SET @type = (SELECT TOP 1 [Type] FROM dbo.Person WHERE @ID = ID)

TOP 1子句对于避免返回多个记录的问题非常重要。如果ID是主键,那么这是不可能的,但最好是安全而不是抱歉。

你需要重组整个事情。一个例子可能是:

DECLARE @USERTYPE INT
SET @USERTYPE = 0

DECLARE @type NVARCHAR(128)
SET @type = (SELECT TOP 1 [Type] FROM dbo.Person WHERE @ID = ID)

IF (@type = 'Teacher')
BEGIN
    IF EXISTS (SELECT 1 FROM dbo.Teacher WHERE @ID = TID AND [Password] = @PW)
        SET @USERTYPE = 1
END ELSE IF (@type = 'Administrator') 
BEGIN
    IF EXISTS (SELECT 1 FROM dbo.Administartion WHERE @ID = AID AND [Password] = @PW)
        SET @USERTYPE = 2
END

话虽如此,我想你也应该重组你的数据库,让一个公共表存储有关教师和管理员的信息。有两个单独的表是什么原因?将公共信息(如登录数据,姓名,地址等)放入人员表中,只将特定信息(如教师教授的科目)放入单独的表格中,并按人员ID连接。

在您目前的计划中,如果您的某个人既是教师又是管理员,会发生什么?

你说没有人同时是教师和管理员,所以你可以简化一下整个查询:

DECLARE @USERTYPE INT
SET @USERTYPE = 0

SELECT @USERTYPE = UserType FROM
(
    SELECT 1 AS UserType FROM dbo.Teacher WHERE @ID = TID AND [Password] = @PW)
    UNION
    SELECT 2 AS UserType FROM dbo.Administartion WHERE @ID = AID AND [Password] = @PW)
) tmp

请注意,这只适用于ID在两个表中都是唯一的。

答案 1 :(得分:0)

TypeSQL中的保留关键字,因此请使用方括号。

此外,您需要在变量中取值[Type],以便稍后可以引用它。

DECLARE @Type NVARCHAR(50)

SELECT @Type=[Type] FROM dbo.Person WHERE @ID = ID

IF (@Type = 'Teacher')