TSQL如何多次更新Temp Table列

时间:2016-02-25 22:40:06

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

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

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,而&lt; db&gt;数据库是varchars。

2 个答案:

答案 0 :(得分:3)

让我重新格式化该查询:

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

现在您可以看到外部查询中没有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    

答案 1 :(得分:2)

好的,这里有很多事情没有意义。

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

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

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

    FROM #....

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

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

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