DECLARE @result NVARCHAR(max);
SET @result = (SELECT * FROM table
FOR JSON AUTO, ROOT('Data'))
SELECT @result;
Это возвращает строку json из ~ 43000 символов с усечением некоторых результатов.
SET @result = (SELECT * FROM table
FOR JSON AUTO, ROOT('Data'))
Это возвращает строку json из ~ 2000 символов. Есть ли способ предотвратить усечение? Даже при работе с некоторыми большими данными и строкой из миллионов и миллионов символов?
@Surendra ну, ни один запрос не работает, один просто возвращает больше данных, данные идентичны. Так, например, второй запрос возвращает 2000 ~ символов, и эти первые ~ 2000 символов идентичны первым ~ 2000 символам первого запроса. Однако даже первый запрос сильно урезается. Я просто пытаюсь вернуть строку json со всеми данными для таблицы, даже если это безумно массивно.
@Surendra Я бы предпочел не предоставлять тестовые данные, так как мне пришлось бы потратить время на их дезинфекцию и не вижу, насколько это будет полезно, но я могу, если нужно
Когда вы говорите «усечение», вы имеете в виду, что вся строка не возвращается в вашем окне SSMS?
@dfundako Правильно, он просто обрезан в середине столбца. Я пробовал использовать SSMS, запрашивая через dotnet и node, все имеют одинаковый результат. Так что это не проблема SSMS.
@ jayjay93 Попробуйте перейти в Инструменты, Параметры, Результаты запроса, SQL Server, Результаты в сетку и установите для данных, отличных от XML, максимальное количество (я думаю, 65535)
Вы пробовали запустить SELECT DATALENGTH(@result); и посмотреть, что у вас получится? Я почти уверен, что это просто проблема с отображением в SSMS - сами данные внутри переменной должны быть в порядке


Трудно точно определить, в чем проблема, не отправляя данные, но у меня была аналогичная проблема, когда я пытался экспортировать запрос в формате JSON. Решение, которое сработало для меня, заключалось в том, чтобы перейти в Query / Query Options / Results / Text / Set «Максимальное количество символов, отображаемых в каждом столбце:» до 8192 (максимальное значение AFAIK).
Это, вероятно, не сильно поможет с вашим первым запросом, но потенциально он может быть разбит на более мелкие запросы и успешно выполнен. Я ожидал, что вы сможете эффективно выполнить второй запрос после изменения этого параметра.
Я не нашел «официального» ответа, но похоже, что это ошибка нового оператора FOR JSON, который разбивает результат на строки длиной 2033 символа. Как рекомендовано здесь, пока лучший вариант - перебирать результаты, объединяя возвращенные строки:
string result = "";
while (reader.Read())
{
result += Convert.ToString(reader[0]);
}
Кстати, похоже, что в последних версиях SSMS уже применяется какой-то обходной путь, подобный этому, чтобы представить результат в одной строке.
tbh, объединение такой строки требует очень больших ресурсов. Лучше использовать StringBuilder, как указано в документации.
Мы видели аналогичные проблемы в SSMS без использования усечения переменной SSMS в 2033 году.
С переменной запрос действительно работает нормально, когда вы используете переменную nvarcahr (max), но он обрезает вывод в представлении результатов запроса на 43697.
Возможное решение, которое я тестировал, - это вывод результатов запроса в файл с помощью BCP:
bcp "DECLARE @result NVARCHAR(max); SET @result = (SELECT * FROM table FOR JSON AUTO, ROOT('Data')); SELECT @result as Result;" queryout "D:\tmp\exportOutput.txt" -S SQL_SERVER_NAME -T -w
См. Документацию BCP для определения имени сервера \ экземпляра и параметров аутентификации.
Мне удалось получить полную, необрезанную строку, используя print вместо select в SQL Server 2017 (версия 14.0.2027):
DECLARE @result NVARCHAR(max);
SET @result = (SELECT * FROM table
FOR JSON AUTO, ROOT('Data'))
PRINT @result;
Другой вариант - загрузить и использовать Студия данных Azure, который, как мне кажется, является многоплатформенным переписыванием SSMS (аналогично тому, как Visual Studio была переписана как VS Code). Кажется, он выплевывает всю необрезанную строку json, как и ожидалось из коробки!
Примечание: PRINT ничего не возвращает, если вам нужно использовать его в вашей системе. SELECT сделает это.
Если ваша длина данных меньше 65535, вам следует использовать предложение @dfundako, который прокомментировал в первом сообщении:
Try going to Tools, Options, Query Results, SQL Server, Results to Grid, and set Non-XML data to the max amount (I think 65535)
В моем случае длина данных составляла 21 тыс. Символов, поэтому после экспорта в сетку я скопировал значение, и оно было в порядке, а не усечено. Тем не менее, это не решает проблему для тех, у кого большой объем данных.
Я знаю, что это старый поток, но мне удалось решить эту проблему, отправив результат в переменную XML. Преимущество использования переменной XML заключается в том, что размер указывается не как длина символа, а как размер строки в памяти, который можно изменить в параметрах. Поэтому ответ Брэда Си теперь будет выглядеть так ...
DECLARE @result XML
SET @result = (SELECT * FROM table
FOR JSON AUTO, ROOT('Data'))
SELECT @result
or...
PRINT @result;
Пробовал, но получаю ошибку преобразования «Неявное преобразование из типа данных xml в nvarchar недопустимо. Используйте функцию CONVERT для выполнения этого запроса».
Это также будет работать, если вы вставите в временную таблицу - без представления не применяется усечение SSMS. Может быть полезно, если вам нужно рассчитать несколько значений.
declare @json table (j nvarchar(max));
insert into @json select * from(select* from Table where Criteria1 for json auto)a(j)
insert into @json select * from(select* from Table where Criteria2 for json auto)a(j)
select * from @json
Вот ответ на усечение JSON:
SQL делит результат JSON на куски размером 2 КБ (по крайней мере, в моей установке SQL 2016), по одному фрагменту в первом столбце каждой строки в наборе результатов. Чтобы получить полный результат, ваш клиентский код должен пройти через набор результатов и объединить первый столбец каждой записи. Когда вы дойдете до конца строк, вуаля, будет получен весь ваш результат JSON без вырезок.
Когда я впервые столкнулся с проблемой усечения, я был сбит с толку и списал ДЛЯ JSON на несколько лет как несерьезную функцию, подходящую только для самых маленьких наборов данных. Я узнал, что мне нужно прочитать весь набор записей только из документации ДЛЯ XML, и никогда не видел, чтобы он упоминался в документации ДЛЯ JSON.
Можете ли вы добавить тестовые данные, чтобы посмотреть, и оба запроса выглядят одинаково, разницы быть не должно