2010-12-08 30 views
3

J'ai une table appelée People avec une colonne de type xml appelée properties. Je l'ai utilisé pour stocker des informations aléatoires sur chaque personne, ce qui permet essentiellement aux gens de stocker des données supplémentaires qui seront ajoutées à l'avenir sans une refonte de la base de données. Tous les gens n'auront pas les mêmes éléments dans leur XML.SQL Server 2005 Recherche dans la colonne XML Données

CREATE TABLE [dbo].[Person](
[PersonID] [bigint] IDENTITY(1,1) NOT NULL, 
[PersonType] [nvarchar](50) NULL, 
[Title] [nvarchar](5) NULL, 
[Forename] [nvarchar](60) NULL, 
[Surname] [nvarchar](60) NULL, 
[Company] [nvarchar](60) NULL, 
[Properties] [xml] NULL 
) 

Un exemple de xml est:

<PropertyList xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Property Name="Class">Class A</Property> 
    <Property Name="CarRegistration">123456</Property> 
    <Property Name="MedicalNotes">None</Property> 
</PropertyList> 

première question est que je ne peux pas sembler trouver une requête SQL qui va me permettre d'obtenir une liste d'enregistrements qui correspondent aux critères stockés dans la xml.

Par exemple, comment puis-je obtenir tous les enregistrements où Class="Class A". J'ai essayé:

SELECT 
    PersonID, 
    Properties.value('/PropertyList/Property[@Name="Class"][1]','nvarchar(50)') 
FROM Person 

Je sais que cela est inexact, mais je reçois l'erreur « nécessite un singleton (ou une séquence vide) » et je ne suis pas tout à fait sûr ce qui est mal passé.

Et deuxième question est que j'ai combiné plusieurs bases de données plus anciennes dans une liste de personnes seule, mais les anciennes interfaces de base de données doivent encore accéder à leur bit des données. Mon plan était de créer une vue pour chaque frontend de base de données avec une mise en page spécifique à ses besoins tout reliant à la table des personnes principale. Cependant certains de leurs champs sont maintenant stockés dans le XML. Existe-t-il un moyen de créer une vue pour mettre à jour le XML sans voir le xml c'est-à-dire pour qu'il ressemble et agisse comme une vue sur n'importe quelle autre table. J'espère que j'ai expliqué cela correctement. Pour chaque vue, je vais avoir un ensemble spécifique de propriétés XML dont j'ai besoin pour éditer et tous les enregistrements les auront donc pas si aléatoire.

Merci pour toute aide.

Répondre

5

Votre XQuery devrait être:

SELECT PersonID, 
     Properties.value('(/PropertyList/Property[@Name="Class"])[1]','NVARCHAR(50)') 
FROM dbo.Person 

Est-ce que l'aide ??

Mise à jour: pour le rendre plus clair pour les autres - j'ai ajouté des parenthèses autour de l'expression /PropertyList/Property[@Name="Class"], de sorte que cette évaluera potentiellement une liste de valeurs, puis la [1] après la parenthèse choisira la première (et le plus souvent uniquement) valeur (en tant que singleton) de cette liste afin qu'il puisse être converti en une chaîne NVARCHAR(50).

value('(/PropertyList/Property[@Name="Class"])[1]','NVARCHAR(50)') 
     !          ! 

est pas le même que

value('/PropertyList/Property[@Name="Class"][1]','NVARCHAR(50)') 

Mise à jour 2: si vous voulez créer une vue - que, aucune raison de ne pas! ;-)

Vous pouvez certainement créer quelque chose comme:

CREATE VIEW dbo.YourViewName 
AS 
    SELECT 
     PersonID, PersonType, Title, 
     ForeName, Surname, Company, 
     Properties.value('(/PropertyList/Property[@Name="Class"])[1]','NVARCHAR(50)') AS 'Class', 
     Properties.value('(/PropertyList/Property[@Name="CarRegistration"])[1]','NVARCHAR(50)') AS 'CarRegistration', 
     Properties.value('(/PropertyList/Property[@Name="MedicalNotes"])[1]','NVARCHAR(50)') AS 'MedicalNotes' 

de votre table et « casser » XML en colonnes sur votre point de vue. Est-ce ce que vous cherchez ??

+0

N'est-ce pas exactement ce qu'ils ont déjà essayé? –

+0

@Ash Burlaczenko: ** NON !! ** J'ai ajouté des parenthèses à l'expression XQuery (qui sont essentielles dans ce cas!) Sans la parenthèse (message original), cela ne fonctionne pas et donne une erreur - avec ma parenthèse, cela fonctionne - vérifiez de près !! –

+0

@marc_s: pouvez-vous expliquer pourquoi les parens devraient faire la différence? Bien sûr, en théorie, si une valeur de colonne Propriétés peut être un fragment de document XML avec plusieurs éléments/PropertyList, alors la parens signifierait la différence entre "la première propriété nommée Class" et "la première propriété nommée Class de chaque PropertyList". Mais en supposant que chaque valeur de la colonne Propriétés n'a qu'un seul élément/PropertyList, il n'y a pas de différence, n'est-ce pas? En fait, dans son exemple, il n'y a qu'une seule propriété nommée "Class", donc le '[1]' ne devrait pas faire de différence du tout. – LarsH