SQL 2005中带有XML列的按语法排序
我有一个用户配置文件(基于用户类型的多个配置文件),存储在DB列(xml)中 我可以在存储过程中使用XPATH对此进行查询,但是我不确定接下来如何执行ORDER BYSQL 2005中带有XML列的按语法排序,sql,xml,xpath,Sql,Xml,Xpath,我有一个用户配置文件(基于用户类型的多个配置文件),存储在DB列(xml)中 我可以在存储过程中使用XPATH对此进行查询,但是我不确定接下来如何执行ORDER BY SELECT U.UserId, UP.Profile, UP.UserParentID FROM aspnet_Users U LEFT OUTER JOIN UserProperties UP ON U.UserId = UP.UserId WHERE UP.Profile.exist('/Properties/propert
SELECT U.UserId, UP.Profile, UP.UserParentID
FROM aspnet_Users U
LEFT OUTER JOIN UserProperties UP ON U.UserId = UP.UserId
WHERE
UP.Profile.exist('/Properties/property[contains(.,sql:variable("@cLookup"))]') = 1
XML示例:
<Properties>
<property id="BusinessName" name="Business Name"></property>
<property id="AccountNumber" name="Account Number"></property>
<property id="Address" name="Address"></property>
<property id="Phone" name="Phone"></property>
<property id="Fax" name="Fax"></property>
<property id="Web" name="Web"></property>
<property id="ABN" name="ABN"></property>
<property id="Logo" name="Logo"></property>
<property id="Photos" name="Photos"></property>
<property id="Map" name="Location Map"></property>
</Properties>
及
如果您想按BusinessName下单,请将此答案视为正在进行的工作,因为我不确定这是否是正确的查询 答案在于将.nodes()函数与.value()结合使用,这样您就可以从元素中提取“name”属性的值,并将“BusinessName”作为“id”属性的值 这里有一些使用.nodes()替换旧OPENXML语法的指南 不管怎么说,现在的问题是这样的。在您的数据上尝试一下,看看我们是否可以调整它,直到它起作用
SELECT U.UserId, UP.Profile, UP.UserParentID
FROM aspnet_Users U
LEFT OUTER JOIN UserProperties UP ON U.UserId = UP.UserId
OUTER APPLY UP.Profile.nodes('/Properties/property') p(prof)
WHERE UP.Profile.exist('/Properties/property[contains(.,sql:variable("@cLookup"))]') = 1
AND p.prof.value('@id', 'nvarchar(20)') = 'BusinessName'
ORDER BY p.prof.value('@name', 'nvarchar(100)')
将此答案视为正在进行的工作,因为我不确定这是否是正确的查询 答案在于将.nodes()函数与.value()结合使用,这样您就可以从元素中提取“name”属性的值,并将“BusinessName”作为“id”属性的值 这里有一些使用.nodes()替换旧OPENXML语法的指南 不管怎么说,现在的问题是这样的。在您的数据上尝试一下,看看我们是否可以调整它,直到它起作用
SELECT U.UserId, UP.Profile, UP.UserParentID
FROM aspnet_Users U
LEFT OUTER JOIN UserProperties UP ON U.UserId = UP.UserId
OUTER APPLY UP.Profile.nodes('/Properties/property') p(prof)
WHERE UP.Profile.exist('/Properties/property[contains(.,sql:variable("@cLookup"))]') = 1
AND p.prof.value('@id', 'nvarchar(20)') = 'BusinessName'
ORDER BY p.prof.value('@name', 'nvarchar(100)')
您可能希望查看的另一个选项是计算列,特别是当您有一个或几个经常需要的列时 一般来说,计算列就是这样的—一个列,它的值是从其他内容计算出来的,并且在任何时候都是最新的,而不必一直刷新它 结合XML,您可以编写一个小的存储函数,并使用它在“base”表上创建一个计算列,这样您就可以按该列进行查询和排序,而无需一直“接触”XML 在这里的例子中,您可以编写一个存储函数来检索“BusinessName”,并使其在UserProfile表中可用,如下所示:
CREATE FUNCTION dbo.GetBusinessName(@input XML)
RETURNS VARCHAR(50)
WITH SCHEMABINDING
AS BEGIN
DECLARE @Result VARCHAR(50)
SELECT
@Result = @input.value('(Properties/property[@id="BusinessName"]/@name)[1]', 'VARCHAR(50)')
RETURN @Result
END
这定义了一个存储函数,该函数将获取您的配置文件XML并查找“id”为“Business Name”的“property”,然后返回其“Name”属性
要将其添加到UserProfile表中,请使用以下SQL代码:
ALTER TABLE UserProfile
ADD BusinessName AS dbo.GetBusinessName(Profile) PERSISTED
这样,您就可以在表中添加一个名为“BusinessName”的新计算字段,从现在起,您可以使用这个新字段进行选择和排序,例如
SELECT ID, BusinessName FROM UserProfiles ORDER BY BusinessName
享受吧
PS:关于性能的一句话:我发现在很多情况下,这比在XML字段中不断查询XML要快得多。因此,如果您的XML中有某些元素需要经常访问,或者可能以ORDER BY语句的形式出现,那么使用计算列实际上可以大大加快速度。您可能希望查看的另一个选项是计算列,特别是当您有一个或几个经常需要的列时 一般来说,计算列就是这样的—一个列,它的值是从其他内容计算出来的,并且在任何时候都是最新的,而不必一直刷新它 结合XML,您可以编写一个小的存储函数,并使用它在“base”表上创建一个计算列,这样您就可以按该列进行查询和排序,而无需一直“接触”XML 在这里的例子中,您可以编写一个存储函数来检索“BusinessName”,并使其在UserProfile表中可用,如下所示:
CREATE FUNCTION dbo.GetBusinessName(@input XML)
RETURNS VARCHAR(50)
WITH SCHEMABINDING
AS BEGIN
DECLARE @Result VARCHAR(50)
SELECT
@Result = @input.value('(Properties/property[@id="BusinessName"]/@name)[1]', 'VARCHAR(50)')
RETURN @Result
END
这定义了一个存储函数,该函数将获取您的配置文件XML并查找“id”为“Business Name”的“property”,然后返回其“Name”属性
要将其添加到UserProfile表中,请使用以下SQL代码:
ALTER TABLE UserProfile
ADD BusinessName AS dbo.GetBusinessName(Profile) PERSISTED
这样,您就可以在表中添加一个名为“BusinessName”的新计算字段,从现在起,您可以使用这个新字段进行选择和排序,例如
SELECT ID, BusinessName FROM UserProfiles ORDER BY BusinessName
享受吧
PS:关于性能的一句话:我发现在很多情况下,这比在XML字段中不断查询XML要快得多。因此,如果XML中有某些元素需要经常访问,或者可能以ORDER BY语句的形式出现,那么使用计算列实际上可以大大加快速度