Como impedir que números inteiros sejam silenciosamente transformados em asteriscos no SQL Server?

8

Suponha que tenhamos uma conta de tabela, existe um campo acct_type varchar(2)

Insert into account(acct_type) values(888)

Resultado:

+-----------+
| acct_type |
+-----------+
| *         |
+-----------+

Espero que ele gere um erro ao inserir o gatilho de instrução. Por que está armazenando *valor na tabela?

Ankush
fonte
@Mor: ou talvez a tabela esteja definida incorretamente. Se o aplicativo quer armazenar números (inteiros) em lá, talvez a coluna deve ser definido como integerem vez devarchar
a_horse_with_no_name

Respostas:

11

Para o varchartipo de dados, um truncado intserá convertido como em *vez de gerar um erro (nesse caso, os três dígitos não se encaixam em a varchar(2)).

Isso não acontece com nvarchar

Não há como alterar esse comportamento, ele é preservado para compatibilidade com versões anteriores. Se esse é um problema real para você, você pode adicionar uma restrição de verificação de que o valor na coluna não é, *mas não consigo imaginar nenhuma situação em que isso realmente valha a pena.

A solução é simplesmente não fazer isso. Se você precisar inserir um INTe validar, ele estará no intervalo -9 to 99primeiro. Ou sempre use aspas em torno dos valores destinados a uma coluna de string em vez de confiar em conversões implícitas.

Martin Smith
fonte
Obrigado Martin! .. Como posso colocar uma restrição de verificação para evitar o valor inteiro no varchar arquivado ... você pode me ajudar a escrever a sintaxe?
Ankush em 31/03
ALTER TABLE account ADD CONSTRAINT CK_NoStar_acct_type CHECK (acct_type <> '*')mas você quase certamente não precisa fazer isso. Há uma tonelada de char/varcharcolunas na natureza com comprimento igual 10ou inferior a onde essa é uma possibilidade teórica que se dá muito bem sem isso. Obviamente, a restrição de verificação também bloqueia uma inserção explícita, *pois não há como distinguir entre como *foi recebida
Martin Smith
1
Muito obrigado Martin !! agora eu posso explicar corretamente ao meu desenvolvedor com sintaxe e efeitos colaterais disso
Ankush 31/03
4
Eu acho que a verdadeira questão é: se eles querem armazenar valores inteiros, por que isso é varcharpara começar?
a_horse_with_no_name 31/03
@a_horse_with_no_name Se você tiver uma pergunta para o OP, coloque-a na pergunta, não uma resposta. Eles não serão notificados aqui. Eu diria que não há nada na pergunta que indique que eles apenas pretendem armazenar números inteiros nesta coluna, embora "888" não seja um valor válido para o varchar(2)método. Tudo o que se pode inferir é que eles tentaram pelo menos uma vez e obtiveram um resultado inesperado que prefeririam ter cometido um erro do que falhar silenciosamente.
Martin Smith
-2

varchar aceita tipo de string. você pode inserir valor entre os símbolos ''. parece Insert into account(acct_type) values('888') Mas mostrará um erro porque o comprimento máximo é 2. comprimento do varchar de graxa ou seu valor máximo deve ser 2Insert into account(acct_type) values('88')

Əşrəf Cəfərli
fonte
Sua resposta vai em outra direção que a pergunta: Sami indica que não há erro e um valor inserido de '*'. O comentário que SMor fez é mais provável na direção da questão.
Mark