Dadas as seguintes tabelas:
CREATE TABLE #a
(
MyInt INT
)
INSERT INTO #a VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)
CREATE TABLE #b
(
MyVarchar VARCHAR(10)
)
INSERT INTO #b VALUES('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'),('ten')
Se eu executar a seguinte consulta;
SELECT *
FROM #a
LEFT JOIN #b
ON #a.MyInt = #b.MyVarchar
O SQL Server precisa executar uma conversão implícita, pois #a.MyInt
são #b.MyVarchar
tipos de dados incompatíveis. Devido à precedência do tipo de dados, a coluna com a precedência de tipo mais baixa (#b.MyVarchar) é convertida para o tipo de precedência mais alta (INT)
Isso significa que a consulta acima se torna equivalente a
SELECT *
FROM #a
LEFT JOIN #b
ON #a.MyInt = CONVERT(INT,#b.MyVarchar)
e ambos falham porque há um valor #b.MyVarchar
inválido para uma INT
coluna.
Minha pergunta é por que VARCHAR
tem uma precedência menor que INT
? se fosse o contrário, a conversão implícita seria bem-sucedida, mas em vez disso obteríamos uma consulta com erros. Por que um erro seria preferido a uma execução bem-sucedida? Meu palpite seria algo como este ser mais um mecanismo "defensivo" por parte do SQL Server - ele prefere um erro e, portanto, precisa que o usuário decida explicitamente o que deseja fazer, em vez de fornecer resultados de consulta talvez inesperados, sem que o usuário seja Cientes?
Como o SQL Server é um RDBMS, eles são otimizados para aplicativos que enviam consultas SQL em tabelas definidas corretamente.
A redução da precedência do tipo de dados de varchar permite que o mecanismo evite conversões implícitas nas expressões de coluna ao avaliar uma consulta que envia argumentos como strings literais ou parâmetros varchar:
ou
Em ambos os casos comuns, evitamos converter o valor de cada linha e habilitamos pesquisas indexadas com esta estratégia.
Temos dois cenários possíveis para comparar string com inteiro:
Podemos dizer que o primeiro cenário é mais rápido, pois existe apenas uma operação multi-tick.
É um caso muito raro quando precisamos de fazer tal comparação, por isso, mesmo que saibamos que o segundo cenário dá mais flexibilidade – a necessidade disso é muito rara. Portanto, a velocidade vence.
Além disso, o mecanismo SQL exibe
Strongly Typed
a natureza da programação. Ao definir o tipo de dados comodatetime
,INT
eleBIT
impõe restrições firmes aos dados edata integrity
mantémRDBMS
.Portanto, a consulta de amostra de dados acima definitivamente deve falhar.