(这是我今天早些时候发布的the answer by "onedaywhen" on a question的后续内容。)
大家好。假设我有一个表MyTable
,其中包含两个int
字段,PrimaryKey
和MyNumber
。 (和其他与此问题无直接关系的领域)。 MyNumber
具有唯一约束和检查约束,将其限制为BETWEEN 1 AND n
。 (现在让我们说n=5
。)
1,2
2,NULL
3,5
4,NULL
5,NULL
6,1
7,NULL
如何编写UPDATE
来更改PrimaryKey=2
的记录,以便MyNumber
具有非NULL
值?我不关心它有什么价值,只要它不是NULL
并且满足它的唯一和范围内的两个限制。
我正在使用MS SQL Server,但我希望有一个使用标准SQL的答案。
(我也希望不必有一个数字1到n作为内容的表。)
非常感谢。
答案 0 :(得分:0)
查找MS-SQL的@ROW_NUMBER函数,我现在无法想到代码,而且我不在我的数据库服务器附近做一些测试,但如果内存服务,@ ROW_NUMBER与“IS NOT NULL”检查相关联应该可以帮助您实现目标。
@ROW_NUMBER文档:http://msdn.microsoft.com/en-us/library/ms186734.aspx
对于其他SQL版本,我目前无法想到解决方案。
答案 1 :(得分:0)
WITH CTE AS (
SELECT 1 N
UNION ALL
SELECT N + 1 FROM CTE WHERE N < 5
)
UPDATE MyTable
SET MyNumber = (
SELECT TOP 1 N FROM CTE
WHERE NOT EXISTS (SELECT * FROM MyTable WHERE MyNumber = N)
)
WHERE PrimaryKey = 2
用简单的英语:
WITH CTE AS ...
)。SELECT TOP 1 ...
)中已存在不的第一个整数。UPDATE ...
)标识的行中将该整数分配给 MyNumber 。如果此查询无法找到合适的值,则只需将 MyNumber 设置为NULL。
警告:这可能仍然在并发环境中对 MyNumber 的UNIQUE约束进行调整(即,当两个并发执行的事务尝试并行运行同一查询时)。因此,您必须准备好在必要时重试查询。
答案 2 :(得分:0)
我不禁要指出,下一版本的SQL(代号Denali)将支持SEQUENCES,在这种情况下显然是理想的。
代码看起来像这样:
CREATE SEQUENCE Count1to5
START WITH 1
INCREMENT BY 1
MAX VALUE 5;
我不确定如何或者是否能够使用where来跳过更新的值,而我没有使用beta设置测试服务器,但似乎值得一提的是此解决方案将即将推出。