从单行中提取以特定字符开头的多个字符串

问题描述 投票:0回答:1

我有一个表,其中一列包含大量 XML 数据。我想提取以 SAP(大写)开头的字符串(例如:SAP-PTS-RSK-SEC-A-006-GFC)。这些字符串出现在多个实例中,并且始终前面有 ,后面有 。这是该专栏中文本的一小部分摘录。我已经突出显示了我之前提到的文本部分。

No</entity_number><form_value>Form Value</form_value><is_data_limited>FALSE</is_data_limited></headers><entities><entity_number>GPSCAPSA</entity_number><detection_value>Financial Services - Money Services Business</form_value><drills_data><drill_context>***<form_id>SAP-PTS-RSK-SEC-A-006-GFC</form_id>***<alert_date>2023-07-11</alert_date><entity_type_cd>1</entity_type_cd><entity_key>63111179</entity_key><entity_sk>63111149</entity_sk><is_external_party>0</is_external_party><start_date>2023-07-11</start_date><end_date>2023-07-

我的期望是有一列列出中间有逗号的字符串

SAP-PTS-RSK-SEC-A-006-GFC,
SAP-PTS-FUI-SEC-A-006-SLA,
SAP-VCR-RSK-KGB-A-006-GFC

非常感谢任何帮助,谢谢!

sql-server t-sql substring
1个回答
0
投票

您提供的样本不明确。请 - 对于将来的问题 - 尝试提供工作数据。

XML 片段似乎有一个开始

<detection_value>
而没有结束标记。如果您的 XML 无效,您就会遇到麻烦...

但是:如果表中的 XML 有效/有效,这非常简单:

从从 XML 片段中提取的工作示例开始:

DECLARE @tbl TABLE (ID INT IDENTITY, YourXml XML);
INSERT INTO @tbl(YourXml) VALUES
(N'
<drills_data>
  <drill_context>   
    <form_id>SAP-PTS-RSK-SEC-A-006-GFC</form_id>
    <alert_date>2023-07-11</alert_date>
  </drill_context>
</drills_data>
<drills_data>
  <drill_context>
    <form_id>SAP-SomeOtherCode</form_id>
    <alert_date>2023-07-11</alert_date>
  </drill_context>
</drills_data>
<drills_data>
  <drill_context>
    <form_id>Blub-OneWithoutSAP</form_id>
    <alert_date>2023-07-11</alert_date>
  </drill_context>
</drills_data>
');

--查询

SELECT SAP.formId.value('.','nvarchar(max)')
FROM @tbl t
CROSS APPLY t.YourXml.nodes('//form_id[substring(text()[1],1,3)="SAP"]') SAP(formId);

简而言之,这个想法:

  • 我们使用
    CROSS APPLY
    来使用 XML 函数
    nodes()
  • XQuery 执行深度搜索(它将找到任何
    <form_id>
    )。
  • 它将仅过滤前 3 个字符为 SAP 的条目。
  • XQuery 区分大小写,仅适用于大写“SAP”。
  • SELECT
    中我们使用
    .value()
    来阅读内容。

结果(第三个带“Blub”的不返回)。

SAP-PTS-RSK-SEC-A-006-GFC
SAP-SomeOtherCode

提示:如果 XML 不是 XML 而是字符串,您可以使用以下内容:

SELECT SAP.formId.value('.','nvarchar(max)')
FROM @tbl t
CROSS APPLY (SELECT CAST(t.YourXml AS XML)) A(Casted)
CROSS APPLY A.Casted.nodes('//form_id[substring(text()[1],1,3)="SAP"]') SAP(formId);

提示2:不执行深度搜索(使用

//form_id
)而是指定通向那里的路径更快更好。但我们不知道您实际的 XML。

© www.soinside.com 2019 - 2024. All rights reserved.