Постоянный выброс столбца недетерминированной ошибки при использовании преобразования - PullRequest
0 голосов
/ 28 июня 2018

Используя SQL Server 2016, я столкнулся с небольшой проблемой.

Вот мой вариант использования, который вызывает у меня проблемы ...

create table dbo.Example (
    Id int identity (1, 1) not null,
    [Name] nvarchar(100) not null,
    Email nvarchar(255) not null,
    DOB datetime2(7) not null,
    RowHash as convert(nvarchar(66), hashbytes('SHA1', coalesce(
        convert(nvarchar(max), [Name]), 
        convert(nvarchar(max), Email), 
        convert(nvarchar(max), DOB)
    ))) persisted
    constraint [PK_Example] primary key clustered (Id asc)
);
drop table dbo.Example;

Я получаю сообщение:

Сообщение 4936, уровень 16, состояние 1, строка 1 Вычисляемый столбец 'RowHash' в таблице 'Пример' не может быть сохранен, поскольку столбец недетерминирован.

Когда я установил, что столбец не будет сохранен, тип данных будет правильно интерпретирован как nvarchar (66), однако я бы хотел, чтобы он сохранялся. Эта проблема, похоже, связана со столбцом datetime2, однако в таблице есть несколько типов данных.

Таким образом, цель состоит в том, чтобы использовать постоянный столбец хеш-байтов для хранения хеша всех значений в моей таблице.

Есть идеи?

Thx!

Ответы [ 3 ]

0 голосов
/ 28 июня 2018

Это можно исправить, указав формат для преобразования даты:

create table dbo.Example (
    Id int identity (1, 1) not null,
    [Name] nvarchar(100) not null,
    Email nvarchar(255) not null,
    DOB date not null,  -- I figure date is good enough
    RowHash as convert(nvarchar(66), hashbytes('SHA1', concat(
        convert(nvarchar(max), [Name]), 
        convert(nvarchar(max), Email),
        convert(nvarchar(max), DOB, 121)
    ))) persisted
    constraint [PK_Example] primary key clustered (Id asc)
);

Проблема в том, что преобразование даты в строку по умолчанию зависит от системных параметров, поэтому оно не является детерминированным. Для постоянного столбца все компоненты должны быть детерминированными.

Я хотел бы сказать, что документация охватывает этот экзотический момент в хорошо сбалансированных деталях. Не совсем. Вы можете получить представление из этой документации . Просто простите - это также относится к date, datetime2 и другим типам данных.

0 голосов
/ 28 июня 2018

Вот окончательный результат, который представляет собой комбинацию обоих ответов выше. Большое спасибо за помощь.

create table dbo.Example (
    Id int identity (1, 1) not null,
    [Name] nvarchar(100) not null,
    Email nvarchar(255) not null,
    DOB datetime2(7) null,
    RowHash as convert(nvarchar(66), hashbytes('SHA1', concat(
        convert(nvarchar(max), [Name]),
        convert(nvarchar(max), Email),
        convert(nvarchar(max), DOB, 121)
    ))) persisted
    constraint [PK_Example] primary key clustered (Id asc)
);
drop table dbo.Example;
0 голосов
/ 28 июня 2018

Почему coalesce(), а не concat()?

Пример

create table dbo.Example (
    Id int identity (1, 1) not null,
    [Name] nvarchar(100) not null,
    Email nvarchar(255) not null,
    DOB datetime2(7) not null,
    RowHash as convert(nvarchar(66), hashbytes('SHA1', concat(
        [Name], 
        Email, 
        DOB
    ))) persisted
    constraint [PK_Example] primary key clustered (Id asc)
);

Select * from [dbo].[Example]
--drop table dbo.Example;

Результаты

enter image description here

...