我试图创建一个SQL视图,该视图将从表中的列中返回子串的连接值。
在我的示例中,有一个标题为“DefDetails'在名为' TrebuchetSettings'的表中,它包含我需要连接在一起的XML值列表。
DefDetails列将保存一个类似下面的值,每条记录:
<Trebuchet>
<FolderSetDef ID="9365da81288308c9c57aba483f83d2469a5da9ecba" Name="ReportDef" Version="1.0" SubType="" Scope="Global" Culture="Invariant" View="(None)">
<Alias />
<Description />
<Owner>934ec7a1701c451ce57f2c43bfbbe2e46fe4843f81</Owner>
<FolderList>
<FolderDef ID="93af31dc1b3238241be33549ba8f8239b377767680" Name="Yearly Reports" ParentID="93af31a36cf8232f44265b40f9a1cd14d1e7000813" Scope="Core" />
<FolderDef ID="93af31a36cf8232f44265b40f9a1cd14d1e7000813" Name="CSM Management Reports" ParentID="Root" Scope="Core" />
</FolderList>
</FolderSetDef>
</Trebuchet>
使用SQL语句,我需要查询TrebuchetSettings表并返回&#39; Name&#39;的串联列表。 “FolderDef”中的字段&#39;上面的XML中的节点,由&#39; /&#39;分隔开使用FolderDef的字符,其ID与字符串开头列出的后续FolderDef的ParentID匹配,以便连接结构表示文件夹结构。
由于此表中还有其他类型的记录,因此我的查询当前包含以下内容,以识别从以下位置提取这些子字符串所需的记录:
SELECT *
FROM TrebuchetSettings
WHERE DefType = 'FolderSetDef'
AND DefDetails LIKE '%(Folder ID)%'
在上面的示例SQL中,Folder ID是一个42个字符的ID,将与另一个表中的值进行比较,以匹配XML中某个Folder Defs的ID。
不幸的是,我没有一套启动代码,因为我没有使用SQL中的列子串的经验,也不知道从哪里开始。
答案 0 :(得分:1)
如果有大量数据,您尝试做的事情可能非常慢 ...在这种情况下,管理一个(触发?)边桌是一个很好的建议将您的ParentID保存在索引列中,同时保存包含XML行的键。换句话说,就像自我完成的索引......
只是为了清楚说明:你有一个包含多个ID(长字符串)的表。然后,您必须找到包含此值的所有XML条目为&#34; ParentID&#34;在&#34; / FolderDef&#34;。如果找到一个,则需要连接特定DefDetails的所有名称。这意味着:对于第二个表格中的任何ID,您必须一遍又一遍地扫描所有DefDetail ...一开始LIKE
搜索%
将非常慢即可。 XML方法.exist()
应该更快......
你可以试试这个:
我声明了一个表变量,用两个条目模拟你的设置表:
DECLARE @TrebuchetSettings TABLE(DefDetails XML);
INSERT INTO @TrebuchetSettings VALUES
(N'<Trebuchet>
<FolderSetDef ID="9365da81288308c9c57aba483f83d2469a5da9ecba" Name="ReportDef" Version="1.0" SubType="" Scope="Global" Culture="Invariant" View="(None)">
<Alias />
<Description />
<Owner>934ec7a1701c451ce57f2c43bfbbe2e46fe4843f81</Owner>
<FolderList>
<FolderDef ID="93af31dc1b3238241be33549ba8f8239b377767680" Name="Yearly Reports" ParentID="93af31a36cf8232f44265b40f9a1cd14d1e7000813" Scope="Core" />
<FolderDef ID="93af31a36cf8232f44265b40f9a1cd14d1e7000813" Name="CSM Management Reports" ParentID="Root" Scope="Core" />
</FolderList>
</FolderSetDef>
</Trebuchet>')
,(N'<Trebuchet>
<FolderSetDef ID="SomeOther" Name="ReportDef" Version="1.0" SubType="" Scope="Global" Culture="Invariant" View="(None)">
<Alias />
<Description />
<Owner>OtherOwner</Owner>
<FolderList>
<FolderDef ID="Other first ID" Name="Yearly Reports" ParentID="Other ParentID" Scope="Core" />
<FolderDef ID="Other second ID" Name="CSM Management Reports" ParentID="Root" Scope="Core" />
</FolderList>
</FolderSetDef>
</Trebuchet>');
使用一个现有的ParentID和一个不存在的
定义您的第二个表DECLARE @YourOtherTable TABLE(FolderID VARCHAR(42));
INSERT INTO @YourOtherTable VALUES
('93af31a36cf8232f44265b40f9a1cd14d1e7000813')
,('Some not existing');
现在找到具有给定FolderDef-ParentID的所有记录,并将所有Name属性列为/
- 分隔列表
SELECT ot.FolderID
,concatenated.Names
FROM @YourOtherTable AS ot
CROSS JOIN @TrebuchetSettings AS s
CROSS APPLY
(
SELECT STUFF(
(
SELECT '/' + A.NameAttr.value('@Name','varchar(max)')
FROM DefDetails.nodes('/Trebuchet/FolderSetDef/FolderList/FolderDef') AS A(NameAttr)
FOR XML PATH('')
),1,1,'')
) AS concatenated(Names)
WHERE s.DefDetails.exist('/Trebuchet/FolderSetDef/FolderList/FolderDef[@ParentID=sql:column("ot.FolderID")]')=1
结果如下:
93af31a36cf8232f44265b40f9a1cd14d1e7000813 Yearly Reports/CSM Management Reports
答案 1 :(得分:0)
SQL没有一种简单的方法可以在字符串中查找多个vales ...但它确实具有将xml转换为可以正常查询的表的功能。