Нужна часть строки в столбце

У меня есть такие значения, как показано ниже, в столбце таблицы 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, но не получил нужного значения.

Я ожидаю, что значение между и будет в отдельном столбце. Мне нужно это значение, чтобы сравнить его с другими таблицами.

Пожалуйста, покажите нам предпринятую вами попытку, чтобы мы могли помочь вам ее исправить.

Dale K 04.09.2024 11:35

Являются ли ваши значения действительными в формате XML?

Dale K 04.09.2024 11:37

Это похоже на XML; SQL Server поддерживает XQuery, так почему бы не использовать его? Не рассматривайте свои данные как строку, если это XML, рассматривайте их как xml.

Thom A 04.09.2024 11:38
between and что это значит? Можете ли вы указать реальную ценность, которую вы ожидаете получить?
siggemannen 04.09.2024 11:40

Из примера мне нужно значение: 2011284 Пробовал этот SELECT id, url, SUBSTRING (cast(url as text), CHARINDEX('</artikel>',10),5) AS подстроку FROM job

Tom Zaugg 04.09.2024 11:45

Я не знаю, если это неверный XML, может быть, что-то вроде SELECT SUBSTRING(yourcolumn, charindex('<artikel>', yourcolumn) + 9, charindex('</artikel>', yourcolumn) - charindex('<artikel>', yourcolumn) - 9) from yourtable в противном случае есть много ответов на анализ XML.

siggemannen 04.09.2024 11:52

Задавая вопрос, вам необходимо предоставить минимальный воспроизводимый пример: (1) DDL и образец набора данных, т. е. таблицы CREATE плюс инструкции INSERT T-SQL. (2) Что вам нужно сделать, т. е. логику и попытку реализации вашего кода в T-SQL. (3) Желаемый результат, основанный на примере данных в пункте 1 выше. (4) Версия вашего SQL-сервера (ВЫБЕРИТЕ @@version;).

Yitzhak Khabinsky 04.09.2024 14:45
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
7
66
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Во-первых, давайте посмотрим, как это должно работать с 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
  • ЧАРИНДЕКС тоже основан на 1
  • 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 значения. Это недопустимо, если подзапрос следует за =, !=, <, <= , >, >= или когда подзапрос используется как выражение. что я сделал не так?

Tom Zaugg 04.09.2024 14:08

@TomZaugg, у тебя в записи url несколько записей, и у каждой есть SUBSTRING. Когда вы присваиваете результат этого запроса как значение вашей переменной $url, вы рассматриваете его как скаляр, то есть как одно значение. Однако множественность ваших результатов не позволит вам этого сделать. Можете ли вы объяснить простыми словами, как вы хотите использовать его позже url? Нужны ли вам все подстроки или только одна из них? Как бы вы позже использовали @url? Можете ли вы показать код, в котором вы пытаетесь использовать его в качестве редактирования своего вопроса?

Lajos Arpad 04.09.2024 14:46

@TomZaugg, отредактируйте свой вопрос и укажите тип данных столбца URL-адреса и более полные образцы данных для него.

Yitzhak Khabinsky 04.09.2024 15:15
Ответ принят как подходящий

Минимального воспроизводимого примера не предоставлено, поэтому снимаю от бедра.

Ответ следует тому же минимально воспроизводимому примеру. Просто скопируйте его в 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);

Выход

идентификатор статья 1 702440 2 2010622

Отлично 👍 Большое спасибо, Ицхак.

Tom Zaugg 05.09.2024 16:45

Мне приятно быть полезным.

Yitzhak Khabinsky 05.09.2024 16:46

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