试图将一个不可为 NULL 的列的值设置为 NULL

Attempting to set a non-NULL-able column's value to NULL

在使用 SQL Server 2014 的 ISNULL() 功能时,我在客户端数据库上遇到了一个奇怪的问题。在线搜索让我看到其他人遇到了同样的错误,但是当 INSERTing。 运行 一个简单的 SELECT:

时出现以下错误
Msg 681, Level 16, State 3, Line 1
Attempting to set a non-NULL-able column's value to NULL.

以下查询会产生该错误:

SELECT
    ISNULL( [t2].[date_update], GETDATE() )
FROM
    [dbo].[t1]
INNER JOIN
    [dbo].[t2] ON [t1].[a] = [t2].[id];

我已经删除了表格以简化我的解释,但受影响的列定义如下:

CREATE TABLE [dbo].[t1] (
    [id]          INT           NOT NULL PRIMARY KEY,
    [a]           NVARCHAR(100) NOT NULL
);

CREATE TABLE [dbo].[t2] (
    [id]          BIGINT        NOT NULL PRIMARY KEY,
    [date_update] DATETIME      NULL
);

非常感谢任何帮助或见解!

编辑:

在故障排除中,我能够使用以下 INSERT:

在客户端系统上重现相同的错误消息
CREATE TABLE #t2 ([id] BIGINT NOT NULL PRIMARY KEY NONCLUSTERED, [date_update] DATETIME NULL);

INSERT INTO #t2 ([id], [date_update)
SELECT [id], [date_update]
FROM [dbo].[t2];

编辑2:

更多故障排除表明 SELECT 使用的索引有问题。尝试重建索引时出现同样的错误!

Rebuild failed for Index xxx
Attempting to set a non-NULL-able column's value to NULL.

由于在包含 NOT NULL 列定义的 table 中存在完全为 NULL 的行,因此显示错误消息。

在这种情况下,损坏的原因未知,但错误可以解释为 SELECT 查询正在创建散列 table 以便于连接,它试图插入 NULL进入主键列。

这可以通过创建具有相同定义但所有列 NULL 可用的 table 来测试,从损坏的 table 插入它,然后查询 NULLs 在假定的 NOT NULL 列中。

有时候我打电话的时候 select * from sys.dm_exec_query_stats 我收到此错误,但我不知道如何捕获它。 TRY CATCH 没有捕捉到这个错误。