【问题标题】:Searching in XML using another XML data使用另一个 XML 数据在 XML 中搜索
【发布时间】:2018-05-22 19:52:06
【问题描述】:

我有这两张桌子:

表1:

IDt1    |    XML
1123         xml
1457         xml

表2:

ID     |    Name    |    XML
01           A           xml
02           B           xml

我想在 table1 XML 中搜索,如果数据存在,则使用 IDt1 并在 table2 XML 中搜索,如果存在,然后从 table2 返回 ID 和名称 这是每个表的 XML。

表 1 xml:

<t>
  <ts>
    <sc>
      <rn>445</rn>
      <am>Name1</am>
    </sc>
    <sc>
      <rn>555/rn>
      <am>Name2</am>
    </sc>
  </ts>
</t>

表 2 xml:

<t>
  <ts>
    <d>
      <n>01123</n>
    </d>
    <d>
      <n>04344</n>
    </d>
  </ts>
</t>

我想要的数据:

ID   |   Name
01        a

我能够从表 1 中检索包含我要查找的内容的 ID,但后来我无法使用这些 ID 在其他 xml 中进行搜索。 这是我所拥有的:

SELECT IDt1 as table1IDs
  FROM [Table1]
  WHERE [XML].exist ('/t/ts/sc/am[contains(., "Name1")]') > 0

它返回一个包含 Name1 的 ID 表,现在问题是如何使用 ID 并在 table2 的 xml 中搜索它们,然后返回 table2 的名称和 ID 现在的问题是我必须使用不能接受变量的 xml.exist [contain table1IDs]

有没有办法做到这一点?

【问题讨论】:

  • 感谢您简化的示例和您自己的努力,我这边 +1!

标签: mysql sql sql-server xml select


【解决方案1】:

你的解决方案非常接近,虽然我不会使用LIKE...你可以试试这个:

DECLARE @dummy1 TABLE(IDt1 INT, xml1 XML);
INSERT INTO @dummy1 VALUES
 (1123,N'<t>
  <ts>
    <sc>
      <rn>445</rn>
      <am>Name1</am>
    </sc>
    <sc>
      <rn>555</rn>
      <am>Name2</am>
    </sc>
  </ts>
</t>')
,(1457,N'<t />'); --you provided only one example...

DECLARE @dummy2 TABLE(ID INT, [Name] VARCHAR(100), [XML] XML);
INSERT INTO @dummy2 VALUES
 (1,'A',N'<t>
  <ts>
    <d>
      <n>01123</n>
    </d>
    <d>
      <n>04344</n>
    </d>
  </ts>
</t>')
,(2,'B',N'<t />'); --you provided only one example...

DECLARE @searchFor NVARCHAR(100)=N'Name1'
SELECT *
FROM @dummy1 AS t1 
INNER JOIN @dummy2 AS t2 ON t2.[XML].exist(N'/t/ts/d/n[text()[1]=sql:column("t1.IDt1")]')=1
WHERE t1.xml1.exist(N'/t/ts/sc/am[text()[1]=sql:variable("@searchFor")]')=1

【讨论】:

  • 如何忽略exist(N'/t/ts/d/n[text()[1]=sql:column("t1.IDt1")]' 中的大小写或使其上/下?
  • 我试过N'fn:lower-case/t/ts/d/n[text()[1]=sql:column("t1.IDt1")]' return 0,所以我不确定这个答案是否正确
  • @FrankoT,我是否理解正确:即使使用“name1”或“nAmE1”,您也想找到“Name1”?目前无法对其进行测试,但使用XQuery-function 需要像lower-case(SomeXPathSingleton) 这样的括号。我假设你会将这个 within 放在像.../am[lower-case(text())=lower-case(sql:variable(blah))] 这样的谓词中。 Hth
  • 不,我的意思是当我执行 t1.IDt1 时,因为我的 ID 实际上是一个 guid。在内部连接之后,我能够使它工作,t2 ON t2.[XML].query(N'/t/ts/d/n').value('.', 'varchar(max)') = CAST(t1.IDt1 as varchar(36)) 使它工作,但它仍然错过了一些行,没有像我的解决方案那样返回。
  • 想通了,我的确实包含而不是精确。你的搜索完全形成 Name1。谢谢Shnugo
【解决方案2】:

经过多次测试,我认为这是可行的

DECLARE @searchFor NVARCHAR(max)=N'Name1'
SELECT t2.ID as ID, t2.Name as Name
FROM table1 AS t1 
JOIN table2 AS t2 ON t2.xml.query(N'/t/ts/d/n').value('.', 'VARCHAR(max)') = CAST(t1.ID as varchar(max))
WHERE t1.xml.exist(N'/t/ts/sc/am[text()[1]=sql:variable("@searchFor")]')=1 order by ID

返回

ID   |   Name
01        a

【讨论】:

  • 只是作为一个提示(由您的 cmets 在我的回答下方引起):如果这有效或不区分大小写取决于您的字符串的 COLLATION... 您不应隐含地依赖此
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多