SQL Server concat

У меня есть 3 переменные:

declare @A NVARCHAR(MAX), @B NVARCHAR(MAX), @C NVARCHAR(MAX)

@A заполнен 40000 символами, а @B заполнен 50000.

Теперь я хочу объединить @a и @b в @c следующим образом:

@c = @a + @b

И обновите колонку с @c. Но когда я их объединяю, я теряю часть данных.

Как я могу это исправить?

Поделитесь кодом / tsql, с которым у вас возникли проблемы, чтобы мы смогли помочь.

Shiham 21.07.2018 20:36

Вы пробовали использовать CONCAT вместо +?

Larnu 21.07.2018 20:40

Вы теряете данные при вставке или объединении? Можете ли вы воспроизвести ошибку, указав LEN () всех трех переменных?

Stuart Ainsworth 21.07.2018 20:40

Я пробую CONCAT, но теряю данные в concatatio

A30 21.07.2018 20:52

Возможно, у вас проблемы с отображением. Этот может помочь.

Hossein Golshani 21.07.2018 22:25

@ A30 Не могли бы вы взглянуть на мой ответ? Вероятно, это не конкат. Как вы на самом деле заполняете переменные?

LukStorms 21.07.2018 22:34

Я действительно могу это воспроизвести. DECLARE @a nvarchar(MAX) = REPLICATE('@',40000); DECLARE @b nvarchar(MAX) = REPLICATE('@',50000); DECLARE @c nvarchar(MAX) = CONCAT(@A,@B); SELECT LEN(@C); возвращает 16000. Это означает, что @a и @b усекаются, а не @c.

Larnu 21.07.2018 22:35

это было полезно

A30 22.07.2018 08:01
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
8
123
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблема, похоже, не в самой конкатенации.

Вы можете проверить это с помощью этого фрагмента SQL:

declare @A NVARCHAR(MAX), @B NVARCHAR(MAX), @C NVARCHAR(MAX);
set @A = replicate(N'A',4000);
set @A = @A + @A + @A + @A + @A;
set @A = @A + @A;
set @B = replicate(N'B',2500);
set @B = @B + @B + @B + @B + @B;
set @B = @B + @B;
set @B = @B + @B;

-- CONCAT(@A,@B) gives the same result as @A+@B. 
-- But @A+@B would return NULL if @A or @B is NULL.
set @C = CONCAT(@A, @B);

select len(@A) as sizeA, len(@B) as sizeB, len(@C) as sizeC;

Возврат:

sizeA   sizeB   sizeC
-----   -----   -----
40000   50000   90000

И NVARCHAR (MAX) может содержать до 2 ^ 30-1 символов. Так что 1073741823 символов - это ... много. Ссылка здесь
И даже если это ограничено максимальным размером хранилища 2 гигабайта. Тогда он все еще может содержать 1000000000 2-байтовых символов Юникода. Другими словами, около 3333,3 книг, каждая из которых содержит в среднем 300000 знаков. Многие библиотеки, вероятно, могли бы хранить все свои романы в одном NVARCHAR (MAX).

Проблема может быть вызвана заполнением @A и / или @B.

Например, если вы используете REPLICATE.
Он может заполнить NVARCHAR только до 4000 символов.

Пример:

declare @X NVARCHAR(MAX);
set @X = replicate(N'X',10000);
select len(@X) as sizeX;

Возврат:

sizeX
-----
4000

Итак, один вопрос, который нужно задать:

How were @A and/or @B filled up, and is the length of their data as expected?

А если @A или @B действительно содержат ожидаемое количество символов?
Но скопировать и вставить ячейку в текстовый редактор не все символы?

Оказывается, из ячейки с данными в формате, отличном от XML, в буфер обмена можно скопировать не более 43679 символов. И есть также этот предел для данных Non-Xml в OPTIONS SSMS.
Смотрите скриншот ниже. Так что попытка скопировать и вставить 90000 символов все равно будет усечена.

ssms grid options

Одним из обходных путей может быть приведение NVARCHAR (MAX) к типу XML в выбранном элементе. Поскольку XML имеет ограничение по умолчанию в 2 МБ.

Пример фрагмента:

declare @X NVARCHAR(MAX);
set @X = replicate(N'0123456789',333); -- 3330
set @X = @X + @X + @X + @X + @X; -- 16650
set @X = @X + @X + @X + @X; -- 66600

select len(@X) as sizeX, cast(N'<X><![CDATA['+ @X +N']]></X>' as XML) as XasXml;

Хорошая уловка, я (по глупости) предполагал, что REPLICATE будет жаловаться, если у него будет значение больше, чем он может обработать, однако это «особенность» documentrd: ПОВТОР (Transact-SQL)

Larnu 21.07.2018 22:56

@Larnu Вы правы. Хорошая находка этой .. "особенности". 8000 символов - это когда вы используете VARCHAR. Так как тогда это 1 байт на символ. С NVARCHAR это меньше: 4000 символов, если у вас есть только 2-байтовые символы Unicode. Я надеюсь, что ОП проливает свет на то, как он заполнял свои переменные. Может быть, у источника его проблемы есть простое решение.

LukStorms 21.07.2018 23:00
Ответ принят как подходящий

Не удается вставить более 43679 символов в одну ячейку SQL-сервера?

это было полезно

Выясните, что мои данные сохранены полностью, но SSMS - не может вставить более 43679 символов из столбца в режиме сетки

Вместо того, чтобы просто размещать ссылку, включите в свой ответ соответствующие части сообщения. Только ссылка Андерс не одобряет SO, как будто ссылка когда-нибудь станет мертвой, так же как и ваш ответ; и тогда это никому не помогает. Спасибо.

Larnu 22.07.2018 11:12

Другие вопросы по теме