2009-08-26 98 views
0

我正在使用ColdFusion作为项目,我写了一个查询,我认为使用存储过程可以更快,但我不是T-SQL人员,所以我不知道如何去做比较。基于存储过程中的Select查询更新表/ ColdFusion

我正在运行一个初始查询,该查询从基于动态构建的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。单个存储过程完成数据库中的所有操作,然后返回原始查询结果集以供使用。

任何想法?

回答

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> 

就像你之前使用它们,您可以使用这些查询结果。

+0

好的,我需要一个理智的检查这个答案。 table1的数据是不断变化的......它本质上是一个队列。因为这是在单个存储过程中,它本质上是作为单个事务运行的吗?意思是,因为我在表1上运行两次SELECT,所以我需要保证两次都得到相同的结果。由于许多用户会定期执行此功能,因此我需要确保“锁定”正常工作。 – 2009-08-26 05:38:43

+0

不,它并未作为单个事务运行。如果您在运行更新之前需要输出数据,则需要以不同的方式进行。我没有理解你问题中的全部问题。 – 2009-08-26 05:57:35

1

你的问题是“一堆条件在这里”。这些条件总是静态的吗?那么它总是:(FOO = @x和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> 
+0

问题是我需要从table1中返回select语句的结果集,而不仅仅是更新table2。 – 2009-08-26 13:56:46

1

您可以添加一个OUTPUT子句的UPDATE语句捕捉更新的记录的ID和它们插入到表变量/临时表。然后加入到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 

请记住,如果表1是在不断变化,其它的值​​(“场2”和“场3”)都不能保证他们在Update时有发生。但我认为你目前的方法也容易受到这个问题的影响。

0

不需要SPROC。

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

糟糕。刚刚意识到这是一个主要的巫术问题。 : - / – Shawn 2015-03-16 21:57:28