2010-07-07 79 views
1

我试图用如下语句在INT列中的所有NULL值更改为一个递增值:更新与价值功能似乎只评价函数一次

UPDATE [TableName] SET [ColumnName] = dbo.FunctionName() WHERE [ColumnName] IS NULL 

在函数看起来像这样的:

CREATE FUNCTION FunctionName() RETURNS INT AS 
BEGIN 
    RETURN (select MAX(ColumnName) + 1 from TableName) 
END 

,但这样做的结果是,所有的都是NULL值现在设置为相同的值(即低于最高之前被称为声明1时)。

这是预期的行为?如果是这样,我将如何去获得我所追求的结果?

我想避免使用自动增量列作为所有我真的想要的是唯一性,增量只是一种到达那里的方式。

+0

您将获得通过使用自动增量列之后是结果。你不想使用它的原因同样适用于你的黑客,因为它对实际工作的自动增量很有用。 – 2010-07-07 03:41:56

+0

@Anon:此列中的值是我们系统外定义的唯一标识符,它绝对不是自动递增的。我只想要增加现有的未知行为。 – Eltariel 2010-07-07 04:40:42

回答

4

是的,这是通过设计,它被称为Halloween protection。为了实现你想要的(这是一个一次)使用可更新的CTE:

with cte as (
SELECT Column, 
ROW_NUMBER() OVER() as rn 
FROM Table 
WHERE Column IS NULL) 
UPDATE t 
SET t.Column = m.max + t.rn 
FROM cte t 
JOIN (
SELECT MAX(Column) as max 
FROM Table) m; 
+0

谢谢你。 SQL2008抱怨了一些关于语法的问题,但是它们解决了一些小问题:'ROW_NUMBER()OVER()' - >'ROW_NUMBER()OVER(ORDER BY col)'和'JOIN(...)m' - >'JOIN(...)m ON 1 = 1' – Eltariel 2010-07-07 04:35:19