1

我有以下查询,它使用 cfspreadsheet 从读取的数据中更新引用数据的表。(大约 600 行)并被称为 qry1。SQL 运行大约需要 2 分钟才能完成。我可以改进 SQL 以改进更新时间吗?products 表中有 1360000 行。此示例更新其中的 600 行。Oracle 版本是 11g Coldfusion 版本是 9.1

<cfloop from="1" to="#qry1.recordcount#" index="i">
    <cfquery name="qry2" datasource="db1">
        UPDATE PRODUCTS P
        SET P.QTY = <cfqueryparam value="#qry1.ITEM_NEW_INCOMING_QUOTE_QTY#" cfsqltype="cf_sql_numeric" />
        WHERE P.PRODUCT= <cfqueryparam value="#qry1.PRODUCT#" cfsqltype="cf_sql_varchar"  />
        AND EXISTS(
            SELECT QUOTE_ID
            FROM QUOTE Q
            WHERE P.QUOTE_ID = Q.QUOTE_ID
                AND Q.QUOTE_NUMBER = <cfqueryparam value="#Val(qry1.QUOTE_NUMBER)#" cfsqltype="cf_sql_numeric" /> 
            )
    </cfquery>
</cfloop>
4

2 回答 2

3

更新 不幸的是,由于 OP 之前省略了一些新信息,此解决方案无效。


原始答案

我认为您不需要使用甚至应该使用 ColdFusion 来执行此操作。这将进行 600 次数据库调用,这可能是您花费大量时间的地方。最多您只需要 CF 发送 where 子句来告诉查询您需要更新哪些 600 行。

您可以使用直接 SQL 从另一个表更新 oracle 中的表。看看这个较旧的 SO 帖子是否对您有帮助。Oracle SQL:用另一个表中的数据更新一个表

如果此链接发生问题,评分最高的答案的要点是:

UPDATE table1 t1
   SET (name, desc) = (SELECT t2.name, t2.desc
                         FROM table2 t2
                        WHERE t1.id = t2.id)
 WHERE EXISTS (
    SELECT 1
      FROM table2 t2
     WHERE t1.id = t2.id 
     AND  -- your where clause from your first cfquery here
 )
于 2013-02-07T15:18:34.713 回答
0

无论如何,600 个单独的更新都需要相当长的时间。如果您不希望用户必须坐在那里等待,您可以使用 cfthread 进行更新并感谢用户在您的主线程上提供的文件。

或者,您可以简单地上传文件并将其保存在服务器上的某个位置。然后设置一个查找这些文件并处理它们的计划作业。

无论你做什么,都不要为了速度而牺牲良好的实践。由于上传的文件是用户输入,因此您必须验证收到的数据。

于 2013-02-07T17:46:07.510 回答