加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

sql-server – SQL Server行使与界说不匹配的数据添补PERSISTED

发布时间:2021-01-10 06:33:02 所属栏目:编程 来源:网络整理
导读:我正在跟踪 this question关于PERSISTED计较列中的稀疏值.哪里的谜底会对这种举动怎样发生一些揣摩. 我问以下题目:这不是一个彻头彻尾的错误吗?是否应承PERSISTED列以这种方法运行? DECLARE @test TABLE ( Col1 INT,Contains2 AS CASE WHEN 2 IN (Col1) TH

我正在跟踪 this question关于PERSISTED计较列中的稀疏值.哪里的谜底会对这种举动怎样发生一些揣摩.

我问以下题目:这不是一个彻头彻尾的错误吗?是否应承PERSISTED列以这种方法运行?

DECLARE @test TABLE (
    Col1 INT,Contains2 AS CASE WHEN 2 IN (Col1) THEN 1 ELSE 0 END PERSISTED) --depends on Col1

INSERT INTO @test (Col1) VALUES
    (ABS(CHECKSUM(NEWID()) % 5)),(ABS(CHECKSUM(NEWID()) % 5)),(ABS(CHECKSUM(NEWID()) % 5))

SELECT * FROM @test --shows impossible data

UPDATE @test SET Col1 = Col1*1 --"fix" the data by rewriting it

SELECT * FROM @test --observe fixed data

/*
Col1    Contains2
2   0
2   0
0   1
4   0
3   0

Col1    Contains2
2   1
2   1
0   0
4   0
3   0
*/

请留意,数据看起来“不行能”,由于计较列的值与其界说差池应.

众所周知,查询中的非确定性函数也许示意得很稀疏,但这里好像违背了耐久计较列的约定,因此应该是犯科的.

插入随机数也许是一小我私人为假想的场景,但假如我们插入NEWID()值或SYSUTCDATETIME()会怎么样?我以为这是一个也许现实示意出来的相干题目.

办理要领

这虽然是一个错误. col1值刚好是涉及随机数的表达式的功效,这一究竟显然不会改变col2的正确值应该是什么.假如对永世表运行此呼吁,DBCC CHECKDB将返回错误.
create table test (
    Col1 INT,Contains2 AS CASE WHEN 2 IN (Col1) THEN 1 ELSE 0 END PERSISTED);

INSERT INTO test (Col1) VALUES
    (ABS(CHECKSUM(NEWID()) % 5)),(ABS(CHECKSUM(NEWID()) % 5));

DBCC CHECKDB

给(我的测试运行有一个“不行能”的行)

Msg 2537,Level 16,State 106,Line 17
Table error: object ID 437576597,index ID 0,partition ID 72057594041008128,alloc unit ID 72057594046251008 (type In-row data),page (1:121),row 0. The record check (valid computed column) failed. The values are 2 and 0.
DBCC results for 'test'.
There are 5 rows in 1 pages for object "test".
CHECKDB found 0 allocation errors and 1 consistency errors in table 'test' (object ID 437576597).

它也陈诉了这一点

repair_allow_data_loss is the minimum repair level for the errors
found by DBCC CHECKDB

假如回收修复选项,则会绝不客套地删除整行,由于它无法确定哪个列已破坏.

附加调试器表现每个插入行评估NEWID()两次.在评估CASE表达式之前和之后一次.

也许的办理要领也许是行使

INSERT INTO @test
            (Col1)
SELECT ( ABS(CHECKSUM(NEWID()) % 5) )
FROM   (VALUES (1),(1),(1)) V(X);

出于某种缘故起因,这可以停止该题目,而且每行仅评估一次表达式.

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读