我需要使用函数对表进行插入。我所做的是:
UPDATE MyTable SET MyColumn = dbo.fncGetMyValue(MyParameter) where //some logic
这里MyParameter当然是MyTable中的一个专栏。问题是,只要我更新一行,函数的值就应该改变,因为它实际上是MyParemeter的计数器函数。但是查询为它更新的每一行插入了相同的第一个函数结果。我的意思是,它应该对每行进行15,16,17等更新,但它更新如15,15,15 ......我猜这是正常的,因为sql在插入过程之前看不到插入的值结束。
我的问题是,如果有办法解决这个问题而不使用while语句?
答案 0 :(得分:0)
好的,你已经相当节俭了,所以我不得不猜测你的一些逻辑,但如果我按照你的逻辑说你的函数得到最大的记录+ 1,你仍然应该能够做到这一点基于集合的方式:
首先我将解释一下SELECT,它应该适应UPDATE,本质上你遇到的问题是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 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;