2011-01-18 3 views
2

Я унаследовал частично неполный код sql, который я не могу заставить работать.sql- превышает переменный размер в exec?

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

DECLARE @sql AS VARCHAR(8000) 
    SET @sql = 'INSERT INTO ['[email protected]+'].dbo.[customer] 
        (-- containing about 200 columns.) 
       VALUES(...)' 
PRINT @sql 
EXEC(@sql) 

я получил бы ошибки в середине имени столбца, иногда говорит, что это ожидает скобку или цитату. я начал удалять пустое пространство, чтобы, т. е. [имя], [фамилия] находились в одной строке, а не две разные строки, и это привело бы меня немного дальше к запросу. У меня нет намного больше пробелов, которые я могу удалить, и я просто попадаю в часть значений (...). странно. Я копирую и вставляю только часть столбцов и помещаю его в Word, и он составляет всего около 3000 символов, включая пробел.

Я что-то не хватает?
Если это что-то значит, я запускаю сервер Microsoft SQL Server 2005 и используя студию управления сервером sql для редактирования

спасибо!

+1

«Я что-то не хватает?» Правильная капитализация;) –

ответ

4

Смотрите здесь: SQL Server: When 8000 Characters Is Not Enough пар решений

+0

в вашей ссылке был раздел о том, как разделить запрос на несколько частей, с некоторыми играми вокруг, которые оказались моим решением. создавали @ sql1 @ sql2 и @ sql3 каждый как varchar (max), а затем разбивали вставку (...) и значение (...) среди этих 3.закончил с печатью @ sql1 + @ sql2 + @ sql3, а затем выполнил exec (@ sql1 + @ sql2 + @ sql3). Спасибо SQLMenace, извините, я не дошел до этого раньше. –

0

Используйте тип данных nvarchar (max) для @sql.

+0

Я тоже пробовал, без разницы. Спасибо хоть! –

+0

Nvarchar (max) - всего 4000 символов, один и тот же предел памяти, но с символами Unicode, по сравнению с 8000 обычного varchar (max). SQLMenace прав. Ваша переменная не может содержать все символы вашего запроса, поэтому она срезается посередине. Когда он распечатает его, вы должны увидеть это, не видите ли вы такое поведение? – GluedHands

+0

@GluedHands - гораздо более вероятно, что то, что вы видите, - это вывод на печать, который усечен, чем любое ограничение 'nvarchar (max)'! Он может хранить 2 ГБ данных, если доступно достаточное количество памяти. Каждый символ nchar - это 2 байта, которые вы делаете в математике! –

1

чрезвычайно сокращенный

Ну, это не помогает, так как у вас есть, вероятно, сокращенных прочь причина проблемы.

Если бы я предполагал, я видел случаи, когда были задействованы переменные/столбцы NCHAR или CHAR. Они расширяются до полной длины при использовании в конкатенации строк, и это приведет к тому, что окончательный оператор будет слишком длинным.

Для чего он нужен для стиля или иным образом, всегда используйте NVarchar (Max) для SQL Server 2005 и далее. Фактически, это ожидаемый тип, если вы используете sp_executesql.

Если вы проверите столбцы N/CHAR с фиксированной шириной и переключитесь на nvarchar (max), вы можете увидеть, что проблема исчезнет.

EDIT: Тест, показывающий NVarchar (Max), держащий скважину более 8000 байт.

declare @sql nvarchar(max) 

-- this CTE sets up the columns, 1 as field1, 2 as field2 etc 
-- it creates 2000 columns 
;with CTE(n, t) AS (
    select 1, convert(nvarchar(max),'1 as field1') 
    union all 
    select n+1, convert(nvarchar(max),RIGHT(n, 12) + ' as field'+RIGHT(n, 12)) 
    from cte 
    where N < 2000) 
select @sql = coalesce(@sql+',','') + t 
from CTE 
option (maxrecursion 2000) -- needed, the default of 100 is not nearly enough 

-- add the SELECT bit to make a proper SQL statement 
set @sql = 'select ' + @sql 

-- check the length : 33786 
select LEN(@sql) 

-- check the content 
print @sql 

-- execute to get the columns 
exec (@sql) 
+0

по ссылке SQLMenance дал мне, я разделил значения insert (...) (...) на 3 переменные максимального размера и выполнил их оттуда. проблема была встречена, хотя до того, как я даже достиг значений (...), только столбец таблицы с возвратом carraige и некоторый интервал был слишком большим, чтобы вписаться в одну переменную sql max. –

+0

вы уверены? 'слишком много, чтобы вписаться в одну переменную sql максимального размера. 'У вас есть sql-запрос размером более 2 ГБ в datalength? По 'max size' вы имеете в виду varchar (max) правильно? – RichardTheKiwi

+0

«переменная sql максимального размера». ... "varchar (max) правильно?" -yes, переменная, а не запрос. список имен столбцов был слишком длинным, чтобы соответствовать одной переменной, поэтому сначала я пытаюсь удалить пробелы и вижу, что i превышает лимит размера этой переменной. –