我正在编写一个自动化任务的更新,该任务用于同步来自不同应用程序的同一数据库中两个不同表的数据。该脚本的原始版本是用ColdFusion编写的,并且工作得非常好,但是我想在SQL中重写一部分代码以提高性能。原始代码脚本位于ColdFusion中,如下所示:
<cfquery name="getIMSIToUpdate" datasource="mydsn">
SELECT DISTINCT a.imsi, b.esn, b.parentId
FROM table_a a
INNER JOIN table_b b ON a.imsi = b.termPhone
WHERE (a.parentID IS NULL OR a.parentID = '')
</cfquery>
<cfloop query="getIMSIToUpdate">
<cfquery name="updtIMSIParentIdEsn" datasource="mydsn">
UPDATE table_a
SET esn = <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(getIMSIToUpdate.esn)#" null="#NOT Len(Trim(getIMSIToUpdate.esn))#" />
,parentId = <cfqueryparam cfsqltype="cf_sql_integer" value="#Trim(getIMSIToUpdate.parentId)#" null="#NOT Len(Trim(getIMSIToUpdate.parentId))#" />
WHERE imsi = <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(getIMSIToUpdate.imsi)#" />
</cfquery>
所以我从表A中查询记录,然后循环遍历返回的每个记录,并根据原始查询中从表B中检索到的值对表A的值执行更新。这是我用来替换这段代码的SQL查询:
BEGIN
DECLARE @update_table TABLE (imsi VARCHAR(25), esn VARCHAR(25), parentId INT);
DECLARE @localimsi VARCHAR(25);
DECLARE @localesn VARCHAR(25);
DECLARE @localparentid INT;
SELECT a.imsi, b.esn, b.parentId
INTO "dbo"."@update_table"
FROM dbo.table_a A
INNER JOIN table_b B ON A.imsi = B.termPhone
WHERE (A.parentID IS NULL OR A.parentID = '');
WHILE (SELECT COUNT(*) FROM @update_table) <> 0
SELECT TOP 1
@localimsi = imsi,
@localesn = esn,
@localparentid = parentid
FROM @update_table;
UPDATE table_a A
SET esn = @localesn,
parentId = @localparentid
WHERE imsi = @localimsi;
DELETE FROM @update_table WHERE imsi = @localimsi;
END
DROP TABLE "dbo"."@update_table";
我确信有一种方法可以自行解决这个问题,但我不熟悉SQL Server调试器的工作方式,所以我不是百分之百确定实际发生了什么,只是我认为应该发生的事情。查询会选择适当的行和值并将它们插入到临时表中,但它不会更新任何选定的记录。关于如何编写此SQL脚本以获得更高效的其他输入将不胜感激,但不会单独获得答案奖。
答案 0 :(得分:1)
如果没有架构,这有点难,但我认为你正在做的是更新表A以使用表B中的ESN和parentID,其中a.IMSI = b.termPhone并且表a上的parentid为null或为空
您可以使用单个查询执行此操作:
update table_a
set esn = b.esn,
parentid = b.termphone
from table_a a,
table_b b
where a.imsi = b.termphone
and (a.parentid is null
or a.parentid = '')