O SQL Server tem um sinalizador de tipo chamado is_nullable
você pode vê-lo em sys.types
. Atualmente, (SQL Server 2019) está definido apenas para FALSE
dois tipos sys.timestamp
e sys.sysname
. Neste sys.timestamp
tipo parece aceitar null
. Nele sys.sysname
não. Existe alguma explicação para esse comportamento?
Você pode ver esses tipos com
SELECT * FROM sys.types WHERE is_nullable = 0;
SELECT TYPEPROPERTY('timestamp', 'AllowsNull'); -- returns 0
E você pode usar assim,
CREATE TABLE foo ( a sys.timestamp );
INSERT INTO foo (a) VALUES ( null );
Observe que isso não funcionará se você usarsys.sysname
Msg 515 Level 16 State 2 Line 1 Cannot insert the value NULL into column 'a', table 'dbo.foo'; column does not allow nulls. INSERT fails. Msg 3621 Level 0 State 0 Line 1 The statement has been terminated.
Também não funcionará se você criar um tipo de dados definido pelo usuário que seja NOT NULL
,
CREATE TYPE bar FROM int NOT NULL;
Isso é apenas uma dica para o usuário?
A resposta para sua pergunta é sim.
Essa coluna especifica a nulidade padrão de um tipo de dados, o que pode ser importante se o usuário não expressar uma preferência, por exemplo, em uma
CREATE TABLE
instrução com uma especificaçãoNULL
ou explícitaNOT NULL
. Infelizmente, essa informação está presente apenas na documentação da antiga visão de compatibilidadesys.systypes
:Por exemplo, pode-se substituir o
NOT NULL
comportamento padrão dosysname
tipo:O
timestamp
tipo (preferred namerowversion
) tem comportamentos especiais adicionais devido ao uso pretendido para detectar alterações de linha. Veja esta outra resposta para obter mais detalhes. Você ainda pode substituir sua nulidade da mesma maneira, mas não é possível armazenar um NULL para um atributo timestamp/rowversion.Existem várias camadas complexas para determinar a nulidade do atributo. Em vez de repetir alguns desses detalhes aqui, remeto para Por que você deve sempre especificar se uma coluna aceita nulos por Phil Factor para obter informações básicas e leitura adicional.
Deixe-me reformular a pergunta, para ter certeza de que estamos na mesma página:
Os metadados para o tipo timestamp dizem que ele não aceita NULL, mas se você criar uma tabela sem especificar a nulidade, poderá especificar NULL para essa coluna em INSERT. Por quê?
Se você SELECT da tabela, verá que o valor não é nulo após o INSERT. Você tem o "timestamp" gerado (ou rowversion, se preferir esse nome). Ou seja, NULL em INSERT não tem sentido, significa que o "default" (por assim dizer) é usado.
Pode-se discutir se essa propriedade de metadados para o tipo timestamp deve refletir se podemos especificar null em INSERT ou se podemos, no final, ter NULL nessa coluna.
Acho que teríamos que estar presentes quando a Sybase projetou as tabelas do sistema algumas décadas atrás para poder saber essa resposta. Eu não estava. :-)
Então, resumindo: a coluna do tipo timestamp não permite null na tabela, e com base nisso pode-se argumentar que os metadados estão corretos.
(Como um aparte, eu primeiro pensei que isso era uma coisa de compatibilidade com versões anteriores, então eu ativei uma versão 6.5 do SQL Server para testar. E eu quase ativei uma versão 4.2 também. Mas então eu fiz um SELECT e não foi t até então que notei que o valor não era NULL.)
Aqui está o T-SQL com o qual joguei (em 2019), FWIW: