Как сделать столбец представления не нулевым
Я пытаюсь создать представление, в котором я хочу, чтобы столбец был только истинным или ложным. Однако кажется, что независимо от того, что я делаю, SQL Server (2008) считает, что мой столбец бит может каким-то образом быть нулевым.
у меня есть таблица под названием "Продукт" со столбцом "статус", которая составляет INT, NULL
. В представлении я хочу вернуть строку для каждой строки в продукте, с битовым столбцом, установленным в true, если продукт.Столбце "Состояние" равно 3, в противном случае битовое поле должно быть false.
пример SQL
SELECT CAST( CASE ISNULL(Status, 0)
WHEN 3 THEN 1
ELSE 0
END AS bit) AS HasStatus
FROM dbo.Product
если я сохраню этот запрос в виде представления и посмотрю столбцы в Обозревателе объектов, столбец HasStatus будет установлен в BIT, 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
одна из причин, по которой я на самом деле считаю это полезным, - это использование ОРМ и вы не хотите, чтобы результирующее значение отображалось на тип nullable. Это может сделать все проще, если ваше приложение видит, что значение никогда не может быть нулевым. Тогда вы не нужно написать код для обработки значений null исключения.
FYI, для людей, работающих в этом сообщении, добавление ISNULL() вокруг внешней стороны cast/convert может испортить оптимизатор на вашем представлении.
У нас было 2 таблицы, использующие то же значение, что и ключ индекса, но с различными типами числовой точности (плохо, я знаю), и наш взгляд объединялся с ними, чтобы получить окончательный результат. Но наш код промежуточного программного обеспечения искал определенный тип данных, и представление имело CONVERT () вокруг столбца returned
Я заметил, как OP сделал, что дескрипторы столбцов результата представления определили его как nullable, и я думал, что это первичный/внешний ключ в 2 таблицах; почему мы хотим, чтобы результат был определен как nullable?
Я нашел этот пост, бросил ISNULL () вокруг столбца и вуаля - больше не обнуляется.
проблема заключалась в том, что представление шло прямо в туалет, когда запрос фильтровался по этому столбцу.
по какой-то причине явное преобразование() в результате представления столбец не испортил оптимизатор (он должен был сделать это в любом случае из-за разных точности), но добавление избыточной оболочки ISNULL () сделало это в значительной степени.
Это код, который я использую, он сделает столбец ID не нулевым, а все остальные-нулевыми. Вы должны привести столбец 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
hth
все, что вы можете сделать в инструкции Select-это управлять данными, которые компонент database engine отправляет вам в качестве клиента. Инструкция Select не влияет на структуру таблицы. Для изменения структуры таблицы необходимо выполнить инструкцию Alter Table.
- сначала убедитесь, что в настоящее время нет нулей в этом битовом поле в таблице
- затем выполните следующую инструкцию ddl:
Alter Table dbo.Product Alter column status bit not null
Если ото всех вас пытаюсь контролировать выход смотреть, то что вы делаете вполне достаточно. Ваш синтаксис гарантирует, что вывод столбца HasStatus в наборе результатов представлений будет фактически никогда быть null. Это будет всегда быть либо битовое значение = 1 или битовое значение = 0. Не волнуйтесь, что говорит обозреватель объектов...