SQL Server 2016 - 当条件未满足时,IF 语句中的 WHILE 循环仍然发生



根据这个问题,我使用以下代码将 3 行数据插入表 PeopleStatusCodes。

--declare temporary tables
DECLARE @peopleStatus TABLE (peopleStatusID INT)
DECLARE @data TABLE (FirstName VARCHAR (100), LastName VARCHAR (100), Codename VARCHAR (100))
--insert data into @data
INSERT INTO @data(
    [FirstName]
   ,[LastName]
   ,[Codename]
)
VALUES(
    'John'
   ,'Smith'
   ,'02 - Code2'
)
--check if entry exists inside PeopleStatus and insert into @peopleStatus based on that
IF NOT EXISTS (SELECT [ps].[PersonCode] FROM PeopleStatus [ps], People [p], @data [d]
WHERE [ps].[PersonCode] = [p].[PersonCode]
AND [p].[FirstName] = [d].[FirstName]
AND [p].[LastName] = [d].[LastName])
    INSERT INTO PeopleStatus (
           [PersonCode]
          ,[Status]
    )
    OUTPUT inserted.[ID]
    INTO @peopleStatus
    SELECT
           [p].[PersonCode]
          ,1
    FROM [People] [p], @data [d]
    WHERE [p].[FirstName] = [d].[FirstName]
      AND [p].[LastName] = [d].[LastName]
ELSE INSERT INTO @peopleStatus (peopleStatusID)
SELECT [ps].[ID]
FROM PeopleStatus [ps], People [p], @data [d]
WHERE [ps].[PersonCode] = [p].[PersonCode]
AND [p].[FirstName] = [d].[FirstName]
AND [p].[LastName] = [d].[LastName]
--insert into PeopleStatusCodes a row of data for each Code in the Codes table with Result defaulting to 0
IF NOT EXISTS (SELECT [psc].ID
FROM PeopleStatusCodes [psc], @peopleStatus [temp]
WHERE [psc].PeopleStatusID = [temp].peopleStatusID)
    DECLARE @IDColumn VARCHAR (10)
    SELECT @IDColumn = MIN(c.ID)
    FROM Codes [c]
    WHILE @IDColumn IS NOT NULL
    BEGIN
        INSERT INTO [dbo].[PeopleStatusCodes] (
             [PeopleStatusID]
            ,[CodeID]
            ,[Result]
        )
        SELECT
             [temp].[peopleStatusID]
            ,@IDColumn
            ,0
        FROM @peopleStatus [temp]
        SELECT @IDColumn = MIN(c.ID)
        FROM Codes [c]
        WHERE c.ID > @IDColumn
    END
--Checks if the data matching row has not had Result changed to 1 already, and if so, update that row.
IF NOT EXISTS (SELECT [psc].ID
FROM PeopleStatusCodes [psc], @peopleStatus [temp]
WHERE [psc].PeopleStatusID = [temp].peopleStatusID 
AND [psc].CodeID = (SELECT [c].ID FROM Codes [c], @data [d] WHERE [c].CodeNumber + ' - ' + [c].Name = [d].[Codename])
AND [psc].Result = 1)
UPDATE [dbo].[PeopleStatusCodes] SET Result = 1 WHERE CodeID = (SELECT [c].ID FROM Codes [c], @data [d] WHERE [c].CodeNumber + ' - ' + [c].Name = [d].[Codename])

结果如下,是我想要的:

+----+----------------+--------+--------+
| ID | PeopleStatusID | CodeID | Result |
+----+----------------+--------+--------+
|  1 |              1 |      1 |      0 |
|  2 |              1 |      2 |      1 |
|  3 |              1 |      3 |      0 |
+----+----------------+--------+--------+

然后我决定插入第二组数据:我希望 John Smith 也拥有 Code3 并取得成功的结果。所以我再次运行代码,只需将 @data[Codename]列更改为值"03 - Code3"。我想要的结果是:

+----+----------------+--------+--------+
| ID | PeopleStatusID | CodeID | Result |
+----+----------------+--------+--------+
|  1 |              1 |      1 |      0 |
|  2 |              1 |      2 |      1 |
|  3 |              1 |      3 |      1 |
+----+----------------+--------+--------+

在上述方案中,仅更新了一行。但是,当我运行代码时,每个代码都会得到一组新行:

+----+----------------+--------+--------+
| ID | PeopleStatusID | CodeID | Result |
+----+----------------+--------+--------+
|  1 |              1 |      1 |      0 |
|  2 |              1 |      2 |      1 |
|  3 |              1 |      3 |      0 |
|  4 |              1 |      1 |      0 |
|  5 |              1 |      2 |      0 |
|  6 |              1 |      3 |      1 |
+----+----------------+--------+--------+

似乎 IF 语句的条件SELECT [psc].ID FROM PeopleStatusCodes [psc], @peopleStatus [temp] WHERE [psc].PeopleStatusID = [temp].peopleStatusID被忽略了,但我不确定为什么。我尝试在 WHILE 语句周围加上括号,以便它仅在满足上述条件时才运行,但 SQL Server 认为括号在语法上是错误的。

你需要使用 BEGIN ...结束 IF 条件

如果某物=某物开始

结束

否则,IF 仅适用于 IF 条件之后的第一个语句

最新更新