#sql-server #xml #xquery
#sql-сервер #xml #xquery
Вопрос:
Есть ли какой-либо способ создать своего рода «альтернативную группу», как в регулярных выражениях, в пути XQuery в SQL Server?
У меня есть этот запрос…
SELECT Q.ROWID QUEUEID, Q.DOCUMENTPACKAGETYPE,
B.R.value('@_ID', 'NAME') PARTYID,
B.R.value('@_BorrowerID', 'NAME') BORROWERID,
B.R.value('@_Name', 'NAME') NAME,
B.R.value('@_EmailAddress', 'NAME') EMAILADDRESS
FROM docutech.QUEUE_EX Q
CROSS APPLY Q.DATA.nodes('LOAN_PUSHBACK_PACKAGE/EVENT_DATA/ESIGN/PARTY') AS B(R)
WHERE Q.REASONFORPUSHBACK = 'DocumentDistribution' AND B.R.value('@_Type', 'NAME') = 'Borrower'
Но что мне нужно, так это то, что CROSS APPLY
узел ESIGN в пути на самом деле может быть либо ESIGN, либо ECLOSE. Итак, я хочу сделать что-то вроде следующего (думая в терминах регулярных выражений)…
CROSS APPLY Q.DATA.nodes('LOAN_PUSHBACK_PACKAGE/EVENT_DATA/(ESIGN)|(ECLOSE)/PARTY') AS B(R)
Есть ли какой-либо способ сделать что-то подобное? Мне бы очень не хотелось повторять один и тот же запрос дважды, просто из-за этого простого различия, хотя, возможно, XQuery
не поддерживает подобные параметры?
На самом деле, я только что обнаружил, что могу использовать звездочку, которая будет соответствовать обоим, но я ХОТЕЛ бы иметь возможность ограничить ее этими известными значениями узла, если это возможно. Если нет, я думаю, это подойдет.
Комментарии:
1. Было бы здорово, если бы вы могли предоставить минимально воспроизводимый пример: (1) DDL и выборку данных, т.Е. Создать таблицу (ы) плюс инструкции INSERT, T-SQL. (2) Что вам нужно сделать, т.Е. логика, и ваша попытка реализовать ее в T-SQL. (3) Желаемый результат на основе образца данных в # 1 выше. (4) Ваша версия SQL Server (ВЫБЕРИТЕ @@version;)
Ответ №1:
Думаю, я понял, что вам нужно. Вот концептуальный пример для вас.
Выражение предиката XPath проверяет, принадлежат ли имена элементов на определенном уровне последовательности указанных имен. <SomethingElse>
Элемент не является членом последовательности, поэтому его данные не извлекаются.
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata XML);
INSERT INTO @tbl (xmldata) VALUES
(N'<LOAN_PUSHBACK_PACKAGE>
<EVENT_DATA>
<ESIGN>
<PARTY _Name="one"/>
</ESIGN>
<ECLOSE>
<PARTY _Name="two"/>
</ECLOSE>
<SomethingElse>
<PARTY _Name="three"/>
</SomethingElse>
</EVENT_DATA>
</LOAN_PUSHBACK_PACKAGE>');
-- DDL and sample data population, end
SELECT c.value('@_Name','VARCHAR(20)') AS [Name]
FROM @tbl
CROSS APPLY xmldata.nodes('/LOAN_PUSHBACK_PACKAGE/EVENT_DATA/*[local-name(.)=("ESIGN","ECLOSE")]/PARTY') AS t(c);
Вывод
------
| Name |
------
| one |
| two |
------
Комментарии:
1. Это сделало это! И бонус, он исключил несколько строк из
*
, которые отображали другие типы записей, которые мы получаем из стороннего источника данных. (Они предоставляют очень мало документации!) … На что ссылается этот синтаксис в мире XQuery? Я пробовал поискать в Googlereg ex
,options
,alternates
optional groups
и несколько других, но не смог этого понять. Знание правильных имен в области XQuery может помочь разобраться в любых дальнейших вопросах, которые у меня могут возникнуть.2. Хех … выяснил, как определить, чему он соответствует, добавив следующее поле в мой
SELECT
список полей:B.R.value('local-name(..)', 'NAME') PARENT
, которое возвращает либо ESIGN , либо ECLOSE .3. @eidylon, рад слышать, что предложенное решение работает для вас. «… На что ссылается этот синтаксис в мире XQuery?..» На языке XQuery это последовательность. Пожалуйста, свяжитесь со мной в LinkedIn.