Как сделать столбец представления не нулевым


Я пытаюсь создать представление, в котором я хочу, чтобы столбец был только истинным или ложным. Однако кажется, что независимо от того, что я делаю, 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 67

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.

  1. сначала убедитесь, что в настоящее время нет нулей в этом битовом поле в таблице
  2. затем выполните следующую инструкцию ddl: Alter Table dbo.Product Alter column status bit not null

Если ото всех вас пытаюсь контролировать выход смотреть, то что вы делаете вполне достаточно. Ваш синтаксис гарантирует, что вывод столбца HasStatus в наборе результатов представлений будет фактически никогда быть null. Это будет всегда быть либо битовое значение = 1 или битовое значение = 0. Не волнуйтесь, что говорит обозреватель объектов...