SQL-Server: при создании представления с подстрокой в столбце подстрока возвращает ноль при наличии данных
Я создаю представление, чтобы получить подстроку столбца с именем ScopeContent в базе данных X, у него есть тип данных ntext. Когда я смотрю на значение ScopeContent в представлении, некоторые данные являются нулевыми, в то время как другие имеют данные. Например, первая запись имеет длину данных 33000, но в представлении, которое я создал, она отображается как (NULL), а для второй записи она имеет длину данных 91578 и показывает данные в представлении. Ниже мое заявление sql.
Если я правильно понимаю, как работает подстрока (имя столбца, начальная позиция, длина до)
CREATE VIEW ScopeContent2 (CatId, ScopeContent)
AS
SELECT CatId, SUBSTRING(ScopeContent,32001,32000) AS ScopeContent
FROM X
WHERE datalength(ScopeContent)>32000
Например
CatId ScopeContent
----- ------------
1 (NULL)
2 rem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed arcu posuere, pellentesque elit sit amet, ultricies mauris. Curabitur nec metus hendreri
3 ответа
Datalength
считает байты, а не символы. В этом случае 2 байта =1 символ.
SUBSTRING
занимает позиции символов, а не позиции байтов.
В этом свете ваше заявление
Например, первая запись имеет длину данных 33000, но в представлении, которое я создал, она отображается как (NULL), а для второй записи она имеет длину данных 91578 и показывает данные в представлении...
СОЗДАТЬ ПРОСМОТР ScopeContent2 (CatId, ScopeContent) КАК ВЫБРАТЬ CatId, SUBSTRING(ScopeContent,32001,32000) AS ScopeContent ОТ X ГДЕ длина данных (ScopeContent)>32000
и запрос несовместимы. Как вы пытаетесь извлечь с помощью substring
Функциональные данные с позиции 64002 байта (32001 символа), где ваши данные, очевидно, меньше, чем 64002 байта (но больше, чем 32000 байтов согласно вашей WHERE
оговорка)
Вероятно, вы хотите, чтобы вам потребовалась подстрока запроса после 32000 символов, если длина текста> 32000
В этом случае ваш запрос должен быть
CREATE VIEW ScopeContent2 (CatId, ScopeContent)
AS
SELECT
CatId,
SUBSTRING(ScopeContent,32001,32000) AS ScopeContent
FROM X
WHERE datalength(ScopeContent)>64000 --- double of original value
Я думаю, смешивание подстроки и длины данных может быть проблемой. Длина данных возвращает байты (см. https://msdn.microsoft.com/de-de/library/ms173486%28v=sql.120%29.aspx и http://www.sqlservercentral.com/Forums/Topic431183-8-1.aspx), в то время как подстрока afaik работает с символами. Один символ не обязательно один байт. Поэтому вы можете столкнуться с проблемами, так как длина данных превышает 32000, но значение String составляет всего 20000 символов (если 1 символ равен 2 байта, строка 20000 символов будет 40000 байтов).
Я думаю, что dnoeth может быть прав в этом, он был немного быстрее:)
Ты можешь попробовать:
CREATE VIEW ScopeContent2 (CatId, ScopeContent)
AS
SELECT CatId, SUBSTRING(ScopeContent,32001,32000) AS ScopeContent
FROM X
WHERE LEN(CAST(ScopeContent AS NVARCHAR(MAX))) > 32000
Или же
CREATE VIEW ScopeContent2 (CatId, ScopeContent)
AS
SELECT CatId, SUBSTRING(ScopeContent,32001,32000) AS ScopeContent
FROM X
WHERE DataLength(ScopeContent) > 64000
Функция Len возвращает количество символов в строке, datalenght - количество байтов, что в два раза больше количества символов.