我正在使用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。单个存储过程执行数据库中的所有操作,然后返回原始查询结果集以供使用。
有什么想法吗?
答案 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 ....>