【问题标题】:Insert new rows when item is added to another table SQL将项目添加到另一个表 SQL 时插入新行
【发布时间】:2021-05-04 16:29:09
【问题描述】:

必须要桌子。一个包含项目的维度表和一个包含项目、价值和期间(月)的事实表。

当一个新项目添加到维度表中时,希望在我的事实表中添加 12 行项目 ID 新行。这 12 行应该是接下来的 12 个月。 (总是在当前月份之后)

我知道添加新行时它应该是一个创建触发器,那部分很好。 我遇到的问题是如何编写可以与触发器一起使用的 SQL 语句来完成这项工作。我在 INSERT INTO 上尝试了一些版本,但我没有足够的经验知道必须编写此语句。

示例:项目 2 已添加到暗表中。

project status
1 A
2 B

然后创建一个触发器,将这 12 个新行添加到我的事实表中

project status Period Value
2 B 6/1/2021 NULL
2 B 7/1/2021 NULL
2 B 8/1/2021 NULL
2 B 9/1/2021 NULL
2 B 10/1/2021 NULL
2 B 11/1/2021 NULL
2 B 12/1/2021 NULL
2 B 1/1/2022 NULL
2 B 2/1/2022 NULL
2 B 3/1/2022 NULL
2 B 4/1/2022 NULL
2 B 5/1/2022 NULL

对如何写这个语句有什么建议吗?

非常感谢!

【问题讨论】:

    标签: sql-server triggers


    【解决方案1】:

    这是一种方法:

     --==== Test 'inserted' table
    Declare @inserted Table (Project int, Status char(1));
     Insert Into @inserted (Project, Status)
     Values (1, 'A'), (2, 'B');
    
     --==== Test 'facttable'
    Declare @factTable Table (Project int, Status char(1), Period date, Value varchar(50));
    
     --==== Example code for trigger
       With periods (Period)
         As (
     Select dateadd(month, p.num, dateadd(month, datediff(month, 0, getdate()), 0))
       From (Values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12) ) As p(num)
            )
     Insert Into @factTable (Project, [Status], [Period], [Value])
     Select i.Project
          , i.[Status]
          , p.[Period]
          , Value = Null
       From periods                 p
      Cross Join @inserted          i;
    
     --==== Show resulting fact table
     Select *
       From @factTable;
    

    触发器的示例代码是解决方案,并假设您不会有重复的项目条目。我们不必使用 row_number 生成数字 - 只需使用 VALUES 并指定 1 到 12。

    【讨论】:

      【解决方案2】:

      您可以使用 CTE 即时生成数字列表,然后无条件地加入 inserted 表以生成您的行:

      with months as (
          select top (12)  Row_Number() over(order by (select null)) as m from sys.sysobjects
      )
      select i.Project, i.Status,
        DateAdd(month,m,DateAdd(month, DateDiff(month, 0, GetDate()), 0)) as Period
      from months join inserted i on 1=1
      

      【讨论】:

      • 与其不必要地查询sysobjects,不如使用(VALUES(0),(0),(0),(0),(0)...)
      • 是的,你当然可以这样做,我倾向于使用它来即时模拟,尤其是当它超过几位数字时 - 当然在一个完整的解决方案中,我既不会使用,也不会使用可用于此类事物的永久数字表。
      猜你喜欢
      • 2020-06-03
      • 2019-05-24
      • 1970-01-01
      • 2013-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多