Нет соответствующего жестко запрограммированного ограничения (65 536 * Размер сетевого пакета 4 КБ составляет 268 МБ, а длина вашего сценария и близко не соответствует этому), хотя не рекомендуется использовать этот метод для большого количества строк.
Ошибка, которую вы видите, вызвана клиентскими инструментами, а не SQL Server. Если вы создаете строку SQL в динамической компиляции SQL, она может, по крайней мере, успешно начаться
DECLARE @SQL NVARCHAR(MAX) = '(100,200,300),
';
SELECT @SQL = 'SELECT * FROM (VALUES ' + REPLICATE(@SQL, 1000000) + '
(100,200,300)) tc (proj_d, period_sid, val)';
SELECT @SQL AS [processing-instruction(x)]
FOR XML PATH('')
SELECT DATALENGTH(@SQL) / 1048576.0 AS [Length in MB] --30.517705917
EXEC(@SQL);
Хотя я убил вышеприведенное после ~ 30 минут компиляции, и он все еще не создал строку. Буквенные значения должны храниться внутри самого плана в виде таблицы констант, и SQL Server тратит много времени, пытаясь также получить свойства о них.
SSMS — это 32-разрядное приложение, которое выдает исключение std::bad_alloc
при анализе пакета.
Он пытается поместить элемент в вектор маркера, который достиг емкости, и его попытка изменить размер терпит неудачу из-за недоступности достаточно большой непрерывной области памяти. Таким образом, оператор даже не доходит до сервера.
Емкость вектора увеличивается на 50 % каждый раз (т. е. в соответствии с этой последовательностью). Емкость, до которой должен расти вектор, зависит от того, как устроен код.
Следующие должны вырасти с вместимости 19 до 28.
SELECT * FROM
(VALUES
(100,200,300),
(100,200,300),
(100,200,300),
(100,200,300),
(100,200,300),
(100,200,300)) tc (proj_d, period_sid, val)
и следующему нужен только размер 2
SELECT * FROM (VALUES (100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300)) tc (proj_d, period_sid, val)
Для следующего требуется емкость > 63 и ‹= 94.
SELECT *
FROM (VALUES
(100,
200,
300),
(100,
200,
300),
(100,
200,
300),
(100,
200,
300),
(100,
200,
300),
(100,
200,
300)
) tc (proj_d, period_sid, val)
Для миллиона строк, расположенных, как в случае 1, емкость вектора должна вырасти до 3 543 306.
Вы можете обнаружить, что любое из следующих действий позволит успешно выполнить синтаксический анализ на стороне клиента.
- Уменьшите количество разрывов строк.
- Перезапуск SSMS в надежде, что запрос на большой объем непрерывной памяти будет выполнен успешно при меньшей фрагментации адресного пространства.
Однако даже если вы успешно отправите его на сервер, в любом случае это приведет только к остановке сервера во время генерации плана выполнения, как обсуждалось выше.
Вам будет гораздо лучше использовать мастер импорта-экспорта для загрузки таблицы. Если вам нужно сделать это в TSQL, вы обнаружите, что разбиваете его на более мелкие пакеты и / или используете другой метод, такой как измельчение XML, который будет работать лучше, чем конструкторы с табличным значением. Например, следующее выполняется за 13 секунд на моей машине (хотя при использовании SSMS вам все равно, вероятно, придется разбиваться на несколько пакетов, а не вставлять массивный строковый литерал XML).
DECLARE @S NVARCHAR(MAX) = '<x proj_d="100" period_sid="200" val="300" />
' ;
DECLARE @Xml XML = REPLICATE(@S,1000000);
SELECT
x.value('@proj_d','int'),
x.value('@period_sid','int'),
x.value('@val','int')
FROM @Xml.nodes('/x') c(x)
person
Martin Smith
schedule
07.11.2016
DECLARE @SQL NVARCHAR(MAX) = '(100,200,300),' ; SELECT @SQL = 'SELECT * FROM (VALUES ' + REPLICATE(@SQL,1000000) + '(100,200,300)) tc (proj_d, period_sid, val)';EXEC(@SQL)
- person Martin Smith   schedule 07.11.2016NULL
для обеих функций:/ - person Pரதீப்   schedule 07.11.2016TRY ... CATCH
ничего не поймать. Попробуйте выполнить меньший запрос (10 000–20 000 строк) и найдитеCompileMemory
иCachedPlanSize
в XML фактического плана. Вы получите представление о том, сколько памяти потребуется для 1 млн строк. - person Vladimir Baranov   schedule 07.11.2016