2016-12-09 2 views
6

Недавно я столкнулся с проблемой в SQL-скрипте, где оператор insert (который вставлял несколько строк) имел столбец типа varchar (10), а строки данных, которые он вставлял, проходили в ints.SQL молча преобразует int в varchar, но затем выдает ошибку, когда он встречается с varchar?

Однако, когда я добавил новую строку данных для вставки, и использовать VARCHAR в колонке VARCHAR, SQL попытался преобразовать его в Int, даже если столбец имеет тип VARCHAR (10)

Вот пример, который вы можете запустить локально.

CREATE TABLE dbo.TestTable 
    (
    VarcharColumn varchar(10) NOT NULL 
    ) ON [PRIMARY] 

insert into TestTable(VarcharColumn) 
Values (1) 

При запуске этого, он вставляет просто отлично, SQL должен молча преобразовать это целое значение в VARCHAR за кулисами.

Однако тогда, если вы попытаетесь это сделать:

insert into TestTable(VarcharColumn) 
Values (1),(2),('Hello') 

SQL выбросит следующее сообщение об ошибке:

Conversion failed when converting the varchar value 'Hello' to data type int.

Кто-нибудь может предложить объяснение в внутреннюю работу SQL в этом случае? В частности:

  1. Почему SQL позволяет вставлять целые числа в VARCHAR столбцов
  2. Почему когда SQL молчаливо преобразования этих значений, если он работает по фактической VARCHAR он будет пытаться преобразовать его в целое.

Я понимаю, как исправить эту проблему и как ее избежать в первую очередь, но я ищу объяснение, почему SQL работает таким образом.

+2

пройти через [документации] (https://msdn.microsoft.com/en-us/library/ms191530.aspx) –

+0

Что является объяснить? Ваши вопросы показывают, что вы точно понимаете ситуацию. Ответ таков: так работает SQL Server. –

+0

@ GordonLinoff, это не то, что я спросил. Я задал два вопроса: почему он допускает неявное преобразование (которое, по-видимому, объясняет ссылка vkp на документацию) и как неявное преобразование работает во вставке операторов с несколькими строками. «Вот как это работает» - это ужасное, ничего не сделанное утверждение. –

ответ

7

Это то, что произошло. Когда SQL Server работал, он прошел через строки

(1),(2),('Hello') 

и понял, что существует более одного типа данных. Следовательно, он преобразовал его в тот, который имеет наивысший приоритет (int vs varchar).

Вот почему вы получили сообщение об ошибке.

Подробнее о типе данных старшинства здесь

https://msdn.microsoft.com/en-us/library/ms190309.aspx

+0

@ GordonLinoff Я думаю, что ты прав. Я отредактировал ответ. – DVT

+0

. , Я думаю, что он определяет типы во время компиляции. Это может привести к ошибке в компиляции; он может генерировать ошибку во время выполнения. Если вы знаете ошибку компиляции, то описание в порядке. –

+0

@GordonLinoff Я попробовал запустить тест с INSERT ... VALUES (1), (2). Я получил план запроса (справа налево) из Constant Scan -> Compute Scalar -> Table Insert -> INSERT. Поэтому я предполагаю, что Constant Scan был выполнен первым, преобразовывая все в int, а затем Table Insert convert int в varchar. – DVT

Смежные вопросы