Как сделать столбец представления NOT NULL
Я пытаюсь создать представление, в котором я хочу, чтобы столбец был только true или false. Однако, похоже, что независимо от того, что я делаю, SQL Server (2008) полагает, что мой битовый столбец может как-то быть нулевым.
У меня есть таблица под названием "Продукт" со столбцом "Статус", которая INT, NULL
, В представлении я хочу вернуть строку для каждой строки в Product, причем для столбца BIT установлено значение true, если столбец Product.Status равен 3, в противном случае битовое поле должно быть ложным.
Пример SQL
SELECT CAST( CASE ISNULL(Status, 0)
WHEN 3 THEN 1
ELSE 0
END AS bit) AS HasStatus
FROM dbo.Product
Если я сохраню этот запрос как представление и посмотрю на столбцы в обозревателе объектов, для столбца HasStatus будет установлено значение BIT, NULL
, Но это никогда не должно быть NULL. Есть ли какой-то магический трюк SQL, который я могу использовать, чтобы заставить этот столбец быть NOT NULL
,
Обратите внимание, что если я удалю CAST()
вокруг CASE
столбец правильно установлен как NOT NULL
, но тогда тип столбца устанавливается на INT
что не то, что я хочу. Я хочу чтобы это было BIT
,:-)
4 ответа
Вы можете достичь того, чего хотите, немного изменив порядок запроса. Хитрость в том, что ISNULL
должно быть снаружи, прежде чем SQL Server поймет, что полученное значение никогда не может быть NULL
,
SELECT ISNULL(CAST(
CASE Status
WHEN 3 THEN 1
ELSE 0
END AS bit), 0) AS HasStatus
FROM dbo.Product
Одна из причин, по которой я нахожу это полезным, - использование ORM, и вы не хотите, чтобы полученное значение отображалось в обнуляемый тип. Это может упростить ситуацию, если ваше приложение увидит, что значение никогда не будет нулевым. Тогда вам не нужно писать код для обработки нулевых исключений и т. Д.
К вашему сведению, для людей, сталкивающихся с этим сообщением, добавление ISNULL() за пределы приведения / преобразования может испортить оптимизатор в вашем представлении.
У нас было 2 таблицы, в которых использовалось то же значение, что и в ключе индекса, но с разными числовыми значениями точности (я знаю, что это плохо), и наше представление объединялось с ними для получения окончательного результата. Но наш код промежуточного программного обеспечения искал определенный тип данных, и представление возвращало CONVERT() вокруг столбца
Как и OP, я заметил, что дескрипторы столбцов результата представления определили его как обнуляемый, и я подумал, что это первичный / внешний ключ для 2 таблиц; почему мы хотим, чтобы результат был определен как обнуляемый?
Я нашел этот пост, бросил ISNULL() вокруг колонки и вуаля - больше не обнуляется.
Проблема заключалась в том, что при просмотре запроса по этому столбцу производительность представления сразу шла по унитазу.
По какой-то причине явный CONVERT() в столбце результатов представления не испортил оптимизатор (он все равно должен был сделать это из-за разной точности), но добавление избыточной оболочки ISNULL() сделало, в большой путь.
Это код, который я использую, он сделает столбец идентификатора NOT NULL, а все остальные - NULL. Вы должны привести столбец bit или varchar и сравнить столбец int с NULL.
CREATE TABLE [dbo].[aTestTable](
[ID] [int] NOT NULL,
[varcharCol] [varchar](50) NOT NULL,
[nullvarcharCol] [varchar](50) NULL,
[bitCol] [bit] NOT NULL,
[nullbitCol] [bit] NULL,
[intCol] [int] NOT NULL,
[nullintCol] [int] NULL,
CONSTRAINT [PK_aTestTable] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE VIEW [dbo].[aTestView]
AS
SELECT ID ,
NULLIF(varcharCol , '') AS varcharCol ,
NULLIF(CAST(varcharCol AS VARCHAR), null) AS varcharCol1, --better
nullvarcharCol ,
NULLIF(CAST(bitCol AS INT), null) AS bitCol ,
nullbitCol ,
NULLIF(CAST(intCol AS INT), NULL) AS intCol ,
nullintCol
FROM dbo.aTestTable
Sample Data:
ID varcharCol nullvarcharCol bitCol nullbitCol intCol nullintCol
1 1 1 1 1 1 1
2 0 0 0 0 0 0
3 0 NULL 0 NULL 0 NULL
4 a a 1 1 2 2
НТН
Все, что вы можете сделать в операторе Select, это управлять данными, которые ядро базы данных отправляет вам как клиенту. Оператор выбора не влияет на структуру базовой таблицы. Чтобы изменить структуру таблицы, необходимо выполнить инструкцию Alter Table.
- Сначала убедитесь, что в этом битовом поле в таблице нет нулей.
- Затем выполните следующую инструкцию ddl:
Alter Table dbo.Product Alter column status bit not null
Если, ооо, все, что вы пытаетесь сделать, это контролировать вывод представления, то то, что вы делаете, достаточно. Ваш синтаксис гарантирует, что вывод столбца HasStatus в результирующем наборе представлений фактически никогда не будет нулевым. Это всегда будет либо битовое значение = 1, либо битовое значение = 0. Не беспокойтесь о том, что говорит проводник объектов...