SQL循环更新

时间:2011-02-16 19:21:24

标签: sql sql-server tsql hierarchical-data

所以这是交易。我得到了我们所谓的“ProjectIDs”,这是我们数据库中的一个字段(主键)我们有2个字段需要根据项目ID中的信息进行更新。例如:

我可能有一个项目ID

00068:

这个projectID不会有我们称之为“阶段”......但是我可能有另一个项目,其中“阶段”将有多个记录(即所有单独的作业),但是由差异字段绑定在一起。

0174:
0174-A-SEG-64:
0174-A-SEG-86:
0174-A-DEF-64:
0174-A-DEF-86:

例如:0174-A-SEG-64,将绑定到0174-A-SEG0174-A-SEG-64的记录会更新2个字段。

ProjectIsPhase = -1 and ParentProjectID = 0174-A-SEG:

所以棘手的部分发挥作用。一些像0174-A-SEG这样的“主要”工作可能不存在。所以他们必须在飞行中创建。理想情况下,您可以从给出0174-A的示例项目中看到:0174-A-SEG:或0174-A-DEF也不存在:所以最后项目结构需要如下所示:

ProjectID           ProjectIsPhase               Parent ProjectID
0174: 
0174-A:             -1                           0174:
0174-A-SEG:         -1                           0174-A:
0174-A-DEF:         -1                           0174-A:
0174-A-SEG-64:      -1                           0174-A-SEG:

因此当它在树视图中结束时,它看起来像下面的

0174:
  0174-A:
    0174-A-SEG:
       0174-A-SEG-64:
    0174-A-DEF:

这一切都需要通过SQL或T-SQL

来完成

1 个答案:

答案 0 :(得分:0)

我不确定你想要用ProjectIsPhase完成什么,但我怀疑这是你问题的重要部分。

给定ProjectID,您可以按如下方式派生ParentProjectID :(可能需要几个+ -1调整来考虑分隔符。)

LEFT(ProjectID, LEN(ProjectID) - CHARINDEX('-', REVERSE(ProjectID))

然后插入不存在的父项目:

INSERT INTO Projects(ProjectID)
SELECT  LEFT(ProjectID, LEN(ProjectID) - CHARINDEX('-', REVERSE(ProjectID))
FROM    Projects p
WHERE   LEFT(ProjectID, LEN(ProjectID) - CHARINDEX('-', REVERSE(ProjectID)) 
        NOT IN (
        SELECT  ProjectID
        FROM    Projects
        )
-- You might need to double-check the best condition to not insert a "parent" for a root project
AND     LEFT(ProjectID, LEN(ProjectID) - CHARINDEX('-', REVERSE(ProjectID)) <> ''

您可以运行上述操作,直到不再有父母遗失为止。您还可以使用WHILE @@ROWCOUNT > 0循环。

插入所有父项目后,您可以同时更新所有项目的ParentProjectID。

UPDATE  Projects
SET ParentProjectID = LEFT(ProjectID, LEN(ProjectID) - CHARINDEX('-', REVERSE(ProjectID))

修改 阅读评论后,您似乎想要为特定项目执行此操作。 然后调整上面的内容并使用局部变量应该可以解决问题:

DECLARE @CurrentProjectID varchar, 
        @ParentProjectID varchar
SET @CurrentProjectID = @InputProjectID
SET @ParentProjectID = LEFT(@CurrentProjectID, LEN(@CurrentProjectID) - CHARINDEX('-', REVERSE(@CurrentProjectID))

WHILE @ParentProjectID <> ''
BEGIN
  IF NOT EXISTS (
    SELECT  *
    FROM    Projects
    WHERE   ProjectID = @ParentProjectID
  )
  BEGIN
    INSERT INTO Projects (ProjectID)
    VALUES (@ParentProjectID)
  END
  UPDATE  Projects
  SET     ParentProjectID = @ParentProjectID
  WHERE   ProjectID = @CurrentProjectID
    SET @CurrentProjectID = @ParentProjectID
    SET @ParentProjectID = LEFT(@CurrentProjectID, LEN(@CurrentProjectID) - CHARINDEX('-', REVERSE(@CurrentProjectID))
END

您还可以选择确保在存储过程中允许递归调用,并使用当前ProjectID的父级调用存储过程调用本身。