Есть ли способ предотвратить молча усечение SQL Server данных в локальных переменных и параметрах хранимых процедур? - PullRequest
7 голосов
/ 31 января 2011

Недавно я столкнулся с проблемой при переносе приложения на SQL Server.Оказалось, что эта проблема была вызвана тем, что параметр хранимой процедуры был объявлен слишком коротким для передаваемых ему данных: параметр был объявлен как VARCHAR(100), но в одном случае передавалось более 100 символов данных.Что меня удивило, так это то, что SQL Server не сообщал об ошибках или предупреждениях - он просто молча урезал данные до 100 символов.

Следующий сеанс SQLCMD демонстрирует это:

1> create procedure WhereHasMyDataGone (@data varchar(5)) as
2> begin
3>     print 'Your data is ''' + @data + '''.';
4> end;
5> go
1> exec WhereHasMyDataGone '123456789';
2> go
Your data is '12345'.

LocalПеременные также проявляют то же поведение:

1> declare @s varchar(5) = '123456789';
2> print @s;
3> go
12345

Можно ли включить параметр, позволяющий в таких ситуациях сообщать об ошибках (или хотя бы предупреждениях) SQL Server?Или я должен просто объявить все локальные переменные и параметры хранимой процедуры как VARCHAR(MAX) или NVARCHAR(MAX)?

Ответы [ 5 ]

3 голосов
/ 31 января 2011

SQL Server не имеет такой опции.Вам придется либо вручную проверять длину строк в вашей хранимой процедуре и каким-то образом обрабатывать более длинные строки, либо использовать опцию nvarchar (max).Если дисковое пространство не является проблемой, тогда опция nvarchar (max), безусловно, является самым простым и быстрым решением.

3 голосов
/ 06 декабря 2012

Вам не нужно использовать nvarchar (max), просто используйте nvarchar (длина + 1) [например, если длина вашего столбца равна 50, то вы должны установить для параметра значение nvarchar (51)]. Смотрите ответ от DavidHyogo - SQL Server молча обрезает varchar в хранимых процедурах .

1 голос
/ 31 января 2011

Я не знаю, как заставить сервер сделать это, но я использовал функцию проектов SQL Server в Visual Studio Team System Developer Edition.Он включает в себя анализ кода, который обнаружил мою проблему усечения: использование параметра int для вставки в столбец smallint.

0 голосов
/ 12 марта 2018

Хотя это неудобно, вы можете динамически проверять длину параметра перед вызовом, например,

CREATE FUNCTION MyFunction(@MyParameter varchar(10))
RETURNS int
AS 
BEGIN
RETURN LEN(@MyParameter)
END
GO

DECLARE @MyValue varchar(15) = '123456789012345'
DECLARE @ParameterMaxLength int

SELECT @ParameterMaxLength = CHARACTER_MAXIMUM_LENGTH
       FROM INFORMATION_SCHEMA.PARAMETERS
       WHERE SPECIFIC_SCHEMA = 'dbo' AND
                 SPECIFIC_name   = 'MyFunction' AND
                 PARAMETER_NAME  = '@MyParameter'

IF @ParameterMaxLength <> -1 AND
   LEN(@MyValue) > @ParameterMaxLength
    PRINT 'It''s too looooooooooooooooooong'

Я пропустил имя базы данных вызываемой функции в запросе и в ссылке на INFORMATION_SCHEMA.PARAMETERS, чтобы мой образец работал без изменений.

Я не обязательно защищаю это, но я хотел бы отметить, что информация может быть доступна для динамического обнаружения неизбежного усечения, если в какой-то критической ситуации это необходимо.

0 голосов
/ 07 мая 2015

Вы можете использовать LEFT в SQL и указать длину, которую вы хотите вставить. например.

CREATE TABLE Table1 ( тестовый varchar (10) )

вставить в значения таблицы 1 (LEFT ('abcdefghijklmnopqrstuvwxyz', 10))

Это будет вставить только

abcdefghij на столе

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...