SQL 服务器 '=' returns 当行存在时没有行

SQL Server '=' returns no rows when rows exist

我想弄清楚为什么 SQL 服务器存储过程为一列存储了错误的 ID 值,这使得存储过程 return 存在两行时为零行。

当在存储过程之外执行 select 语句时,我得到了我正在寻找的结果,但这正被另一个应用程序使用,我不想硬编码 select 语句,我想使用存储过程,因为该过程在应用程序的许多部分中使用。

IF OBJECT_ID('GET_ENABLE_OBJ_SP') IS NOT NULL
    DROP PROC GET_ENABLE_OBJ_SP
GO

CREATE PROC GET_ENABLE_OBJ_SP   
    @COURSE VARCHAR(10) = NULL,
    @OBJ    VARCHAR(10) = NULL,
    @DEPT_DES VARCHAR(10) = NULL
AS
BEGIN 
    DECLARE @COURSE_ID INT;
    DECLARE @OBJ_ID INT;
    DECLARE @DEPT_ID INT;

    IF EXISTS (SELECT DEPT_ID FROM DEPARTMENT 
               WHERE DEPT_DESIGNATOR = @DEPT_DES)
    BEGIN 
        SELECT @DEPT_ID = DEPT_ID 
        FROM DEPARTMENT 
        WHERE DEPT_DESIGNATOR = @DEPT_DES;
    END

    PRINT 'DEPARTMENT ID: ' + CONVERT(VARCHAR,@DEPT_ID);
    PRINT 'DEPT DESIGNAT: ' + @DEPT_DES;

    IF @COURSE IS NULL
        RAISERROR('MUST SUPPLY A COURSE DESIGNATOR', 11, 1);

    IF @OBJ IS NULL
        RAISERROR ('MUST SUPPLY AN OBJECTIVE DESIGNATOR', 11, 1);

    -- FIND THE COURSE
    IF EXISTS (SELECT COURSE_ID FROM COURSE 
               WHERE COURSE_DESIGNATOR = @COURSE AND DEPT_ID = @DEPT_ID)
    BEGIN 
        SELECT @COURSE_ID = COURSE_ID 
        FROM COURSE 
        WHERE COURSE_DESIGNATOR = @COURSE AND DEPT_ID = @DEPT_ID;
    END

    PRINT 'COURSE_ID:  ' + CONVERT(VARCHAR, @COURSE_ID);
    PRINT 'COURSE DES:  ' + @COURSE;

    IF @COURSE_ID IS NULL
        RAISERROR('COURSE DOES NOT EXISTS', 11, 1);

    IF EXISTS (SELECT CTO_ID FROM COURSE_TERMINAL_OBJECTIVE 
               WHERE COURSE_ID = @COURSE_ID)
    BEGIN 
        SELECT @OBJ_ID = CTO_ID 
        FROM COURSE_TERMINAL_OBJECTIVE 
        WHERE COURSE_ID = @COURSE_ID AND DEPT_ID = @DEPT_ID;
    END

    PRINT 'OBJECTIVE ID: ' + CONVERT(VARCHAR, @OBJ_ID);
    PRINT 'OBJ DESIGNAT: ' + @OBJ;

    IF @OBJ_ID IS NULL
        RAISERROR('OBJECTIVE IS INVALID OR DOES NOT EXIST', 11, 1);
    ELSE
        IF EXISTS (SELECT CEO_ID FROM COURSE_ENABLE_OBJECTIVE 
                   WHERE CTO_ID = @OBJ_ID AND COURSE_ID = @COURSE_ID)
        BEGIN 
            SELECT 
               E.CEO_DESIGNATOR, E.CEO_DESCRIPTION
            FROM 
               COURSE_ENABLE_OBJECTIVE E
            JOIN 
               COURSE_TERMINAL_OBJECTIVE T ON E.COURSE_ID = T.COURSE_ID 
                                           AND E.CTO_ID = T.CTO_ID
            WHERE 
               E.COURSE_ID = @COURSE_ID 
               AND T.CTO_ID = @OBJ_ID;
         END
END
GO

这是我用来调用它的执行语句和 select table 的所有值的语句 selected "department" 和 "course"

begin try
    exec GET_ENABLE_OBJ_SP '201', '1.0.0', 'CIS'
    EXEC GET_OBJECTIVES '201', 'CIS'

    SELECT * 
    FROM COURSE_TERMINAL_OBJECTIVE 
    WHERE COURSE_ID = 6

    SELECT * 
    FROM COURSE_ENABLE_OBJECTIVE 
    WHERE COURSE_ID = 6
end try
begin catch
    PRINT  'ERROR' + CONVERT(VARCHAR, ERROR_NUMBER());
    PRINT 'MESSAGE: ' + ERROR_MESSAGE();
end catch

我可以 return 使用 select 语句的所有值并对值进行硬编码,但它 return 不属于的行,这是屏幕截图值 returned 和存储过程中的 'print' 语句。由于某种原因,它 return 将 @obj_id(CTO_ID) 设为 4,而它应该是 1。我的 objective 是 return 正确的 CEO_ID 下面结果集中的列,其中 CTO_ID = 1 和 COURSE_ID = 6。正如您在消息中看到的那样,存储过程标记了我传入的指示符 ('1.0 .0') 属于 ID 4,从结果集中很明显它在 ID 1 而不是 4,这是什么原因?

此声明

SELECT @OBJ_ID = CTO_ID 
FROM COURSE_TERMINAL_OBJECTIVE 
WHERE COURSE_ID = @COURSE_ID AND DEPT_ID = @DEPT_ID;

匹配您的 COURSE_TERMINAL_OBJECTIVE table 中的 4 行。如果您只想匹配 CTO_ID = 1,那么您需要缩小 WHERE 子句的范围。

应该是

SELECT @OBJ_ID = CTO_ID 
FROM COURSE_TERMINAL_OBJECTIVE 
WHERE COURSE_ID = @COURSE_ID AND DEPT_ID = @DEPT_ID 
  AND CTO_DESIGNATOR = @OBJ;

我觉得是这个原因:

SELECT 
  @OBJ_ID = CTO_ID 
FROM 
  COURSE_TERMINAL_OBJECTIVE 
WHERE
  COURSE_ID = @COURSE_ID AND
  DEPT_ID = @DEPT_ID;

您有 4 行,其中 course_id 6 和 dept_id 1。结果是 select 中的最后一个 ID 保留在变量中。

也许您错过了 cto_designator?或者如果你想拥有第一个,你应该拥有 select top 1 + order by 以保证你实际需要拥有哪个。

你对 "if exists" 的逻辑也很奇怪,你那里只有 course_id,但你也在用 dept_id 获取数据。