基于存储过程/ ColdFusion中的Select查询更新表

时间:2009-08-26 04:27:01

标签: sql-server tsql stored-procedures coldfusion

我正在使用ColdFusion进行项目,我有一个编写的查询,我认为使用存储过程可以更快,但我不是T-SQL人员,所以我不知道如何进行比较。

我正在运行一个初始查询,它根据动态构建的cfquery从表中选择多个字段。我想我知道如何将此查询转换为SQL Server存储过程。

然而,在此之后,我接着从该查询获取所有主键ID,并针对使用这些ID“锁定”记录的单独表运行另一个查询。锁是第二个表中的一个位字段(一个标志),它告诉系统该记录是“已检出”的。我已将cftransaction中的两个查询都包装起来,以便它们作为一个单元执行。

代码概述:

<cftransaction>
   <cfquery name="selectQuery">
      SELECT id, field2, field3
      FROM table1
      WHERE (bunch of conditions here)
   </cfquery>

   <cfquery name="updateQuery">
      UPDATE table2
      SET lockField = 1
      WHERE table2.id IN (#ValueList(selectQuery.id#)
   </cfquery>
</cftransaction>

然后我将selectQuery结果集返回到我的应用程序,该应用程序使用它来输出一些数据。如何在单个SQL Server 2008存储过程中完成相同的操作,我可以使用cfstoredproc调用?

同样,我认为本机CF方式(使用cfquery)不如存储过程有效,因为我必须将结果集检索回CF,然后再将另一个查询调回DB。单个存储过程执行数据库中的所有操作,然后返回原始查询结果集以供使用。

有什么想法吗?

4 个答案:

答案 0 :(得分:1)

你的问题是“一堆条件”。这些条件总是不变的吗?总是这样:( FOO = @x AND BAR = @y)?或者它是条件有时FOO根本不存在作为一个条件?

如果FOO并不总是存在,那么存储过程出现问题。 T-SQL不能做动态查询构建,实际上即使允许它也会有点否定proc的要点,即编译和预优化SQL。你当然可以这样做,但你最终只需要在proc体内构建一个SQL字符串,然后在最后执行它。使用CFQuery和cfqueryparams会更好。实际上你有没有考虑过这样做?

   <cfquery name="updateQuery">
      UPDATE table2
      SET lockField = 1
      WHERE table2.id IN (SELECT id
                          FROM table1
                          WHERE (bunch of conditions here))
   </cfquery>

答案 1 :(得分:1)

您可以向UPDATE语句添加OUTPUT子句以捕获更新的记录的ID,并将它们插入到表变量/临时表中。然后JOIN回到table1返回结果集。

DECLARE @UpdatedRecords TABLE ( ID INT )

UPDATE  t2
SET     t2.lockField = 1
OUTPUT  Inserted.ID INTO @UpdatedRecords ( ID )
FROM    table2 t2 INNER JOIN table1 t1  ON t2.id = t1.id
WHERE   (bunch of conditions for table1 here)

SELECT  t1.id, t1.field2, t1.field3
FROM    table1 t1 INNER JOIN @UpdatedRecords u ON t1.id = u.id

请记住,如果table1处于不断变化的状态,则其他值(“field2”和“field3”)不能保证在UPDATE发生时的值。但我认为您当前的方法也容易受到这个问题的影响。

答案 2 :(得分:0)

您可以通过将第一个查询作为子查询,然后使用单独的语句返回结果来在一个查询中执行更新。整个过程可能只是一个存储过程:

  CREATE PROCEDURE myUpdate
      @Variable [datatype], etc...
  AS
  BEGIN
    UPDATE table2
    SET lockField = 1
    WHERE table2.id IN (
        SELECT id
        FROM table1
        WHERE (bunch of conditions here)
    )
    SELECT id, field2, field3
    FROM table1
    WHERE (bunch of conditions here)
  END

您可能必须传入一些参数,但这是存储过程的基本结构。然后你可以像这样从ColdFusion中调用它:

<cfstoredproc procedure="myUpdate">
    <cfprocparam type="[CF SQL Type]" value="[CF Variable]">
    etc...
    <cfprocresult name="selectQuery" resultSet="1">
</cfstoredproc>

您可以像以前一样使用这些查询结果。

答案 3 :(得分:0)

不需要SPROC。

UPDATE table2
SET table2.lockField = 1
FROM table1 
WHERE table1.id = table2.id
  AND table1.field2 = <cfqueryparam ....> 
  AND table1.field3 = <cfqueryparam ....>