У меня есть такие значения, как показано ниже, в столбце таблицы SQL Server 2022.
Мне нужно захватить с помощью оператора select значение между <artikel>
и </artikel>
.
Название таблицы: JOB
Столбец: URL-адрес
..<ersatzteilOperations><mode>V</mode><artikel>2011284</artikel><belegticket>je mapelle velogstell</belegticket><artaugabeneingang>V</artaugabeneingang></ersatzteilOperations>
Кто-нибудь может мне помочь? Я видел те же объяснения, но не понял.
Я пробовал использовать подстроку и charindex, но не получил нужного значения.
Я ожидаю, что значение между и будет в отдельном столбце. Мне нужно это значение, чтобы сравнить его с другими таблицами.
Являются ли ваши значения действительными в формате XML?
Это похоже на XML; SQL Server поддерживает XQuery, так почему бы не использовать его? Не рассматривайте свои данные как строку, если это XML, рассматривайте их как xml
.
between and
что это значит? Можете ли вы указать реальную ценность, которую вы ожидаете получить?
Из примера мне нужно значение: 2011284 Пробовал этот SELECT id, url, SUBSTRING (cast(url as text), CHARINDEX('</artikel>',10),5) AS подстроку FROM job
Я не знаю, если это неверный XML, может быть, что-то вроде SELECT SUBSTRING(yourcolumn, charindex('<artikel>', yourcolumn) + 9, charindex('</artikel>', yourcolumn) - charindex('<artikel>', yourcolumn) - 9) from yourtable
в противном случае есть много ответов на анализ XML.
Задавая вопрос, вам необходимо предоставить минимальный воспроизводимый пример: (1) DDL и образец набора данных, т. е. таблицы CREATE плюс инструкции INSERT T-SQL. (2) Что вам нужно сделать, т. е. логику и попытку реализации вашего кода в T-SQL. (3) Желаемый результат, основанный на примере данных в пункте 1 выше. (4) Версия вашего SQL-сервера (ВЫБЕРИТЕ @@version;).
Во-первых, давайте посмотрим, как это должно работать с XQuery:
DECLARE @XML XML = '<root><ersatzteilOperations><mode>V</mode><artikel>2011284</artikel><belegticket>je mapelle velogstell</belegticket><artaugabeneingang>V</artaugabeneingang></ersatzteilOperations></root>';
SELECT @XML.query('/root/mode/artikel')
Я инкапсулировал ваш XML в тег root
и ожидаю, что он сработает. Мне не удалось это проверить, потому что на данный момент у меня нет доступного SQL-сервера, а онлайн-рабочий пример не удалась из-за
Выполнение SELECT не удалось, поскольку следующие параметры SET имеют неправильные настройки: «QUOTED_IDENTIFIER». Убедитесь, что параметры SET подходят для использования с индексированными представлениями и/или индексами вычисляемых столбцов и/или отфильтрованными индексами и/или уведомлениями о запросах и/или методами типа данных XML и/или операциями с пространственным индексом.
То есть, если вы претендуете на это решение, убедитесь, что QUOTED_IDENTIFIER
правильно установлен в вашей СУБД.
Что касается вашей попытки
SELECT SUBSTRING(yourcolumn, charindex('<artikel>', yourcolumn) + 9, charindex('</artikel>', yourcolumn) - charindex('<artikel>', yourcolumn) - 9)
from yourtable
Давайте немного поразмыслим над этим:
expression
, start
и length
, то есть из вашего expression
, то есть yourcolumn
, вы указываете индекс start
подстроки, которую вы хотите получить (индекс на основе 1), и количество персонажи как length
start
был указан как charindex('<artikel>', yourcolumn) + 9
, где вы искали <artikel>
в строке, и хотя технически правильно передать 9 в качестве количества символов, через которые вы хотите перепрыгнуть, я настоятельно рекомендую использовать LEN
, поэтому при следующем повторном использовании этого кода будет искать внутренний текст какого-то другого поля, тогда вам не придется подсчитывать количество символов, чтобы перепрыгнуть, поэтому лучше вместо этого сделать что-то вроде charindex('<artikel>', yourcolumn) + LEN('<artikel>')
charindex('</artikel>', yourcolumn) - charindex('<artikel>', yourcolumn) - 9)
как length
, и это правильно, потому что вы получаете разницу между позициями начала и закрытия тега и вычитаете длину начального тега, чтобы получить только внутренний текст, опять же, я рекомендую использовать из LEN
вместо 9, которые вы использовалиЯ проверил ваш запрос на скрипке, через
declare @yourcolumn varchar(4096) = '<ersatzteilOperations><mode>V</mode><artikel>2011284</artikel><belegticket>je mapelle velogstell</belegticket><artaugabeneingang>V</artaugabeneingang></ersatzteilOperations>';
SELECT SUBSTRING(@yourcolumn, charindex('<artikel>', @yourcolumn) + 9, charindex('</artikel>', @yourcolumn) - charindex('<artikel>', @yourcolumn) - 9);
и это правильно дало ожидаемый результат 2011284, как вы также можете видеть на скриншоте:
Теперь, если это не сработало для вас, причина вашей проблемы может быть миллион разной природы. Вам нужно будет убедиться, что ваше соединение правильное и другие запросы выполняются успешно. Вам нужно будет убедиться, что вы правильно ввели имена столбцов, имя таблицы и имена функций и передали нужные параметры. Если у вас есть ошибка, внимательно изучите, что вам говорит эта ошибка. Подумайте о случаях, когда yourcolumn
является null
, не имеет тега artikel
или имеет несколько тегов artikel
. Убедитесь, что ваш код дает ожидаемые результаты для всех этих возможных входных данных.
Я изменил вашу строку следующим образом: объявите @url varchar(4096) = (выберите URL-адрес из задания, где URL-адрес типа '%<artikel>%'); SELECT SUBSTRING(@url, charindex('<artikel>', @url) + 9, charindex('</artikel>', @url) - charindex('<artikel>', @url) - 9); Результат: сообщение 512, уровень 16, состояние 1, строка 1. Подзапрос возвратил более 1 значения. Это недопустимо, если подзапрос следует за =, !=, <, <= , >, >= или когда подзапрос используется как выражение. что я сделал не так?
@TomZaugg, у тебя в записи url
несколько записей, и у каждой есть SUBSTRING
. Когда вы присваиваете результат этого запроса как значение вашей переменной $url
, вы рассматриваете его как скаляр, то есть как одно значение. Однако множественность ваших результатов не позволит вам этого сделать. Можете ли вы объяснить простыми словами, как вы хотите использовать его позже url
? Нужны ли вам все подстроки или только одна из них? Как бы вы позже использовали @url
? Можете ли вы показать код, в котором вы пытаетесь использовать его в качестве редактирования своего вопроса?
@TomZaugg, отредактируйте свой вопрос и укажите тип данных столбца URL-адреса и более полные образцы данных для него.
Минимального воспроизводимого примера не предоставлено, поэтому снимаю от бедра.
Ответ следует тому же минимально воспроизводимому примеру. Просто скопируйте его в SSMS как есть, запустите и посмотрите результаты.
SQL
-- DDL and sample data population, start
DECLARE @tbl_job TABLE (id INT IDENTITY PRIMARY KEY, URL NVARCHAR(MAX));
INSERT INTO @tbl_job (URL) VALUES
(N'../masterdata/artikel.asmx anp_ErsatzteilOperationsMail() <ersatzteilOperations><mode>erledigt</mode><artikel>702440</artikel></ersatzteilOperations>'),
(N'../masterdata/artikel.asmx anp_ErsatzteilOperations() <ersatzteilOperations><mode>V</mode><artikel>2010622</artikel><belegticket>CWU-DiesDas</belegticket><artaugabeneingang>V</artaugabeneingang></ersatzteilOperations>');
-- DDL and sample data population, end
SELECT id
, c.value('(artikel/text())[1]', 'VARCHAR(20)') AS artikel
FROM @tbl_job AS t
CROSS APPLY (SELECT TRY_CAST(SUBSTRING(URL, CHARINDEX('() ', URL) + 3, 4096) AS XML)) AS t1(x)
CROSS APPLY x.nodes('/ersatzteilOperations') AS t2(c);
Выход
Отлично 👍 Большое спасибо, Ицхак.
Мне приятно быть полезным.
Пожалуйста, покажите нам предпринятую вами попытку, чтобы мы могли помочь вам ее исправить.