ORDER BY sintaxe com uma coluna XML no SQL 2005

votos
2

Eu tenho um perfil de usuário (mais de um perfil com base no tipo de usuário) que eu estou armazenando em uma coluna DB (xml).

I pode consultar esta usando XPATH no meu procedimento armazenado, mas estou sem saber como, em seguida, executar um 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/property[contains(.,sql:variable(@cLookup))]') = 1

Exemplo 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>

E

<Properties>
            <property id=FirstName name=First Name></property>
            <property id=LastName name=Last Name></property>
        </Properties>

Gostaria de ORDER BY BusinessName

Publicado 23/01/2009 em 02:51
fonte usuário
Em outras línguas...                            


2 respostas

votos
0

Considere esta resposta um trabalho em progresso, porque eu não sei com certeza que esta é a consulta à direita.

A resposta reside na utilização dos .nodes () função combinada com .value () para que você possa puxar o valor para o atributo "name" para fora do elemento com "BusinessName", como o valor do atributo "id".

Há um pouco de um guia para usar .nodes () para substituir a sintaxe OPENXML velho aqui .

Enfim, aqui é a consulta, tal como está. Experimente-o em seus dados e vamos ver se podemos ajustá-lo até que ele funciona.

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)')
Respondeu 23/01/2009 em 05:06
fonte usuário

votos
0

Outra opção que você pode querer olhar é colunas computadas, especialmente se você tem uma ou algumas colunas que você precisa com freqüência.

A coluna computada, em geral, é apenas isso - uma coluna que tem um valor calculado de outra coisa, e que é atualizado a qualquer momento sem que você precise atualizá-lo o tempo todo.

Em conjunto com XML, você pode escrever uma pequena função armazenada e usar isso para criar uma coluna computada em sua mesa "base", para que você possa consultar e fim por essa coluna sem ter que "chegar no" XML o tempo todo.

No seu caso aqui, você poderia escrever uma função armazenada para recuperar o "BusinessName" e torná-lo disponível em sua tabela UserProfile assim:

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

Isto define uma função armazenada que terá o seu XML perfil e ir olhar para a "propriedade" com o "id" de "Business Name" e retorna seu "nome" atributo de volta.

Para adicionar este à sua mesa UserProfile, use este código SQL:

ALTER TABLE UserProfile
    ADD BusinessName AS dbo.GetBusinessName(Profile) PERSISTED

Com isso, você adicionar um novo campo calculado chamado "BusinessName" para a sua mesa, e de agora em diante, você pode selecionar e ordem usando este novo campo, por exemplo,

SELECT ID, BusinessName FROM UserProfiles ORDER BY BusinessName

Apreciar!

PS: Uma palavra sobre o desempenho: Eu encontrei em muitos casos, isso é muito mais rápido do que manter constantemente para consultar o XML em um campo XML. Então se você tem certos elementos em seu XML que precisam de acesso a freqüência, ou que podem aparecer em uma instrução ORDER BY, utilizando uma coluna computada pode realmente acelerar as coisas consideravelmente.

Respondeu 28/01/2009 em 07:17
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more