计数器函数用于插入查询

时间:2014-05-13 15:04:33

标签: sql sql-server sql-insert sql-function

我需要使用函数对表进行插入。我所做的是:

UPDATE  MyTable SET MyColumn = dbo.fncGetMyValue(MyParameter) where //some logic

这里MyParameter当然是MyTable中的一个专栏。问题是,只要我更新一行,函数的值就应该改变,因为它实际上是MyParemeter的计数器函数。但是查询为它更新的每一行插入了相同的第一个函数结果。我的意思是,它应该对每行进行15,16,17等更新,但它更新如15,15,15 ......我猜这是正常的,因为sql在插入过程之前看不到插入的值结束。

我的问题是,如果有办法解决这个问题而不使用while语句?

1 个答案:

答案 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;