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