我需要使用一个函数对一个表进行插入。我所做的是:
UPDATE MyTable SET MyColumn = dbo.fncGetMyValue(MyParameter) where //some logic
当然,这里的MyParameter是MyTable中的一个列。问题是,只要我更新一行,函数的值就应该改变,因为它实际上是MyParemeter的计数器函数。但是查询会为它更新的每一行插入函数的第一个相同的结果。我是说,它应该更新15,16,17...每一行,但它会更新15,15,15,...我想这是正常的,因为sql在插入过程结束之前看不到插入的值。
我的问题是,是否有一种方法可以在不使用while语句的情况下解决这个问题?
发布于 2014-05-14 22:57:51
好的,你在细节上相当节俭,所以我不得不猜测你的一些逻辑,但如果我遵循你的逻辑,你的函数获得最好的记录+ 1,你应该仍然能够以基于集合的方式做到这一点:
首先,我将使用SELECT来解释,实际上,您遇到的问题是MaxRecord +1对于所有行都是相同的,就像下面的SELECT一样:
SELECT t.ID,
t.MyColumn,
t.MyParamter,
MaxRecord = MaxT.MyColumn + 1
FROM MyTable AS t
INNER JOIN
( SELECT MyParameter, MyColumn = MAX(MyColumn)
FROM MyTable
WHERE SomeLogic
GROUP BY MyParamter
) AS MaxT
ON MaxT.MyParamter = t.MyParamter
WHERE SomeLogic;
您可以通过删除+1并添加ROW_NUMBER()
来避免此问题:
MaxRecord = MaxT.MyColumn + ROW_NUMBER() OVER(PARTITION BY t.MyParameter ORDER BY t.ID)
最后,您还可以使用分析函数删除子查询,因此您的最终select将是:
SELECT t.ID,
t.MyParameter,
t.MyColumn,
MyNewColumn = MAX(t,MyColumn) OVER(PARTITION BY t.MyParameter) +
ROW_NUMBER() OVER(PARTITION BY t.MyParameter
ORDER BY t.ID)
FROM MyTable t
WHERE SomeLogic;
然后,要进行更新,您可以将所有这些都包装在一个CTE中,然后更新它:
WITH CTE AS
( SELECT t.ID,
t.MyParameter,
t.MyColumn,
MyNewColumn = MAX(t,MyColumn) OVER(PARTITION BY t.MyParameter) +
ROW_NUMBER() OVER(PARTITION BY t.MyParameter
ORDER BY t.ID)
FROM MyTable t
WHERE SomeLogic
)
UPDATE CTE
SET MyColumn = MyNewColumn;
https://stackoverflow.com/questions/23634939
复制相似问题