2016-01-29 5 views
2

В чем разница между типом данных SQL variable и таблицей column.Разница между типом данных переменной SQL и типом столбца таблицы столбца

Рассмотрим следующий пример:

DECLARE @variable CHAR(1) 

SET @variable = 'quarter' 

SELECT @variable --works 

Результат: Q

Но когда я делаю то же самое в таблице я получаю ошибку

DECLARE @table TABLE 
    (
    col CHAR(1) 
) 

INSERT INTO @table 
VALUES  ('quarter') --Fails 

Msg 8152, уровень 16, состояние 14, строка 9 Строковые или двоичные данные будут усечены.

Я прошел через MSDN около DECLARE @local_variable, пока не получил никакого ответа. Может ли кто-нибудь сказать мне, в чем причина.

+0

нет различий в типах, но в операторах (установить vs insert) –

+0

@ Lashane -Спасибо, вы можете объяснить подробно –

ответ

3

основное отличие состоит в том, как предупреждения в SET против INSERT работы, вот SET ANSI_WARNINGS documentation

Если установлено значение ON, то деление на ноль и арифметические ошибки переполнения вызывают заявление откат и ошибка сообщение генерируется. Если установлено значение «ВЫКЛ», ошибки «перерыв на ноль» и «арифметическое переполнение» приводят к возврату нулевых значений. Поведение, при котором ошибка возврата к нулю или арифметическая ошибка переполнения приводит к возврату нулевых значений, if an INSERT or UPDATE is tried on a character, Unicode, or binary column in which the length of a new value exceeds the maximum size of the column. If SET ANSI_WARNINGS is ON, the INSERT or UPDATE is canceled as specified by the ISO standard.. Заканчивающиеся пробелы игнорируются для столбцов символов, а конечные значения NULL игнорируются для двоичных столбцов. Когда ВЫКЛ, данные усекаются до размера столбца, и утверждение выполняется успешно.

, но это не влияет на SET заявления:

ANSI_WARNINGS не соблюдается при передаче параметров в хранимой процедуре, определенной пользователем функции, или при объявлении и setting variables в пакетном заявлении. Например, if a variable is defined as char(3), and then set to a value larger than three characters, the data is truncated to the defined size и инструкция INSERT или UPDATE успешно завершены.

поэтому, вы можете отключить предупреждения ansi, и ваш запрос на вставку будет работать. Но я бы предпочел иметь предупреждения, но сделать валидацию данных/усечение на стороне приложения.

+1

+1 Это прекрасный ответ, но с практической точки зрения было бы плохо сделать что, на мой взгляд. Правильно было бы подстроить/оставить поле при его вставке. – UnhandledExcepSean

+0

@Ghost Я не вижу ничего плохого в том, что у меня есть _option_, чтобы сделать то или другое. Можете ли вы честно сказать, что в каждой единственной ситуации, что усечение тихо - это «правильная» вещь? Если что-нибудь, что я сказал бы _consistency_ между 'SET' и' INSERT' (при сохранении опциональности), было бы лучше. –

+0

@ DStanley Я утверждаю, что в каждой ситуации было бы лучше, чтобы код явно обрезал данные, чем параметр, который неявно усекает данные. – UnhandledExcepSean