【问题标题】:TSQL How do I update a Temp Table column multiple timesTSQL如何多次更新临时表列
【发布时间】:2016-02-25 22:40:05
【问题描述】:

我有一个需要从不同数据库中提取的临时表。原因是每个数据库都在一组单独的员工中保存信息,我们正在尝试创建一个报告,将它们全部放入一个文件中。为此,当我创建临时表时,我会说:

Select ...
       ,...
       ,CAST(NULL AS int) AS 'FedExemptions'
       ,...
INTO #TaxInfo
FROM #....

然后我像这样更新 FedExemptions 列:

UPDATE #TaxInfo
set FedExemptions = (SELECT ISNULL(FEDERAL_EXEMPTIONS, 0)
                 FROM <db1>.EMPS
                 WHERE CONVERT(int, <db1>.EMPS.EMP) = #TaxInfo.EmpNo)
UPDATE #TaxInfo
set FedExemptions = (SELECT ISNULL(FEDERAL_EXEMPTIONS, 0)
                 FROM <db2>.EMPS
                 WHERE CONVERT(int, <db2>.EMPS.EMP) = #TaxInfo.EmpNo)
UPDATE #TaxInfo
set FedExemptions = (SELECT ISNULL(FEDERAL_EXEMPTIONS, 0)
                 FROM <db3>.EMPS
                 WHERE CONVERT(int, <db3>.EMPS.EMP) = #TaxInfo.EmpNo)
UPDATE #TaxInfo
set FedExemptions = (SELECT ISNULL(FEDERAL_EXEMPTIONS, 0)
                 FROM <db4>.EMPS
                 WHERE CONVERT(int, <db4>.EMPS.EMP) = #TaxInfo.EmpNo)

但是,最后一次更新(db4)会覆盖之前的其他 3 次更新,将前三组的 Fedexemptions 设置为 0

我不明白为什么。我可以发誓:

WHERE CONVERT(int, <db4>.EMPS.EMP) = #TaxInfo.EmpNo

这样当 emp 编号不匹配时,SSMS 不会触及行。

作为旁注,我正在对 Emp 编号进行 CONVERT,因为其中一个 #TaxInfo Emp 编号是 INT,而 数据库是 varchars。

【问题讨论】:

    标签: sql sql-server tsql sql-update temp-tables


    【解决方案1】:

    让我重新格式化那个查询:

    UPDATE #TaxInfo
    SET FedExemptions = (
        SELECT ISNULL(FEDERAL_EXEMPTIONS, 0)
        FROM <db4>.EMPS
        WHERE CONVERT(int, <db4>.EMPS.EMP) = #TaxInfo.EmpNo
    )
    

    所以现在您可以看到 outer 查询中没有 WHERE 子句。对于每一行,值将设置为内部查询返回的值。

    我认为你想做更多这样的事情:

    UPDATE t SET FedExemptions = ISNULL(e.FEDERAL_EXEMPTIONS, 0)
    FROM #TaxInfo t
    JOIN <db4>.EMPS e ON CONVERT(int, e.EMPS.EMP) = t.EmpNo    
    

    【讨论】:

    • 谢谢你。似乎我需要一个橡皮鸭,因为它看起来很直接,我的大脑只是拒绝去想那个......
    【解决方案2】:

    好吧,这里发生了很多没有意义的事情。

    首先,相关子查询是一种糟糕的更新方式。如果您仍然进行更新,而这对我来说实际上没有任何意义,请使用联接。

    接下来,从您的代码看来,您希望将任何值为 null 的记录更新为 0 并获取 EMPS 表中的值,那么为什么不将它们最初插入到临时表中呢?类似:

    INsert into   #TaxInfo ( put fields here) 
    Select ...
               ,...
               ,ISNULL(FEDERAL_EXEMPTIONS, 0) AS 'FedExemptions'
               ,...
    
        FROM #....
    

    您可能需要根据实际的初始查询向 EMPS 表添加连接。在临时表和插入中专门定义列也是一种最佳实践。如果有人更改了您的数据库结构会怎样?

    此外,由于您从不同数据库中的多个表中获取 empno,您确定它们不会重复吗? empno 200 是否可以是数据库 A 中的一个人和数据库 b 中的其他人?你真的需要检查这种事情。

    您还可以考虑是否值得创建一个由所有这些表组成的视图,然后查询该视图。如果还有其他查询也需要访问所有这些表,这是最好的选择。如果您有机会添加另一个数据库和另一个需要添加到所有这些查询的 EMPS 表,则删除并重新创建视图比查找引用这些表的 1000 个不同查询更简单。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-29
      • 2018-03-02
      • 1970-01-01
      • 1970-01-01
      • 2016-07-19
      • 2012-07-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多