Select ... For Xml Auto, XmlSchema

  • Agradeceré mucho a quien me resuelva esta consulta.

    Tengo una tabla muy sencilla llamada DIVISAS y ejecuto lo siguiente:

    Declare @MyXmlXsd nvarchar(max)

    Set @MyXmlXsd = ( Select IdDivisa,

    Descripcion,

    Simbolo

    From Divisas

    For Xml Auto, xmlschema )

    Esto devuelve en @MyXmlXsd lo siguiente:

    <xsd:schema targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet3" xmlns:schema="urn:schemas-microsoft-com:sql:SqlRowSet3" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">

    <xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />

    <xsd:element name="Divisas">

    <xsd:complexType>

    <xsd:attribute name="IdDivisa" use="required">

    <xsd:simpleType sqltypes:sqlTypeAlias="[SipanRasa].[dbo].[Id2]">

    <xsd:restriction base="sqltypes:char" sqltypes:localeId="3082" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth">

    <xsd:maxLength value="2" />

    </xsd:restriction>

    </xsd:simpleType>

    </xsd:attribute>

    <xsd:attribute name="Descripcion" use="required">

    <xsd:simpleType sqltypes:sqlTypeAlias="[SipanRasa].[dbo].[String25]">

    <xsd:restriction base="sqltypes:varchar" sqltypes:localeId="3082" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth">

    <xsd:maxLength value="25" />

    </xsd:restriction>

    </xsd:simpleType>

    </xsd:attribute>

    <xsd:attribute name="Simbolo" use="required">

    <xsd:simpleType sqltypes:sqlTypeAlias="[SipanRasa].[dbo].[String3]">

    <xsd:restriction base="sqltypes:char" sqltypes:localeId="3082" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth">

    <xsd:maxLength value="3" />

    </xsd:restriction>

    </xsd:simpleType>

    </xsd:attribute>

    </xsd:complexType>

    </xsd:element>

    </xsd:schema>

    <Divisas xmlns="urn:schemas-microsoft-com:sql:SqlRowSet3" IdDivisa="01" Descripcion="Nuevos Soles" Simbolo="S/." />

    <Divisas xmlns="urn:schemas-microsoft-com:sql:SqlRowSet3" IdDivisa="02" Descripcion="Dólares Americanos" Simbolo="US$" />

    <Divisas xmlns="urn:schemas-microsoft-com:sql:SqlRowSet3" IdDivisa="03" Descripcion="Euros" Simbolo="Eur" />

    Como vemos tiene un esquema completo y los datos que existen en la tabla...

    La pregunta es como hago un SELECT a @MyXmlXsd para que me devuelva una tabla relacional si la necesidad de estar indicando como parsear cada campo, dado que ya tenemos una descripción completa de los datos Xml en el mismo @MyXmlXsd?

  • I don't know of an automated way to do that.

    You could however build your XML dynamically using the metadata in the schema.

    Here is a little something that could get you started.

    declare @sql nvarchar(max);

    with xmlnamespaces('http://www.w3.org/2001/XMLSchema' as xsd)

    select @sql =

    'with xmlnamespaces(default '''+@MyXmlXsd.value('xsd:schema[1]/@targetNamespace', 'nvarchar(max)')+''') '+

    'select '+

    (

    select ', T.N.value(''@'+T.N.value('@name', 'varchar(max)')+''', ''nvarchar(max)'') as '+T.N.value('@name', 'varchar(max)')

    from @MyXmlXsd.nodes('xsd:schema/xsd:element/xsd:complexType/xsd:attribute') as T(N)

    for xml path(''), type

    ).value('substring((./text())[1], 3)', 'nvarchar(max)')+' '+

    'from @MyXmlXsd.nodes(''/'+@MyXmlXsd.value('(/xsd:schema/xsd:element/@name)[1]', 'nvarchar(max)')+''') as T(N)';

    exec sp_executesql @sql, N'@MyXmlXsd xml', @MyXmlXsd

    This will work if your query only uses one table. I have not used the data types. Every columns is returned as nvarchar(max).

  • Gracias Mikael,

    Revisaré esto y comunicaré los resultados.

    Saludos cordiales,

    Hans

  • Hans MZ (10/26/2012)


    Gracias Mikael,

    Revisaré esto y comunicaré los resultados.

    Saludos cordiales,

    Hans

    La verdad es que hice la consulta con una tabla muy sencilla, pero el problema que tengo que resolver es con varios cientos de tablas...

    Hans

  • Hundreds of tables in one query? I hope not 🙂

    The code I provided will be the same regardless of what table you are using. It does however not support multiple tables in one query. Meaning that the source of information in one XML can only come from one table. I would guess it is possible to extend the code to handle multiple table as well but it might be a bit difficult and the code would get more complicated.

  • Mikael,

    Son cientos de tablas pero cada una se manejará por separado. Una tabla a la vez.

    Lo que no quiero es tener que personalizar la consulta para cada una de las tablas, que ademas pueden ser cambiantes en su estructura en el tiempo.

    Saludos,

    Hans

  • Ok, then you should be able to use the code above.

    Cheers!!

    /Micke

  • Hans MZ (10/26/2012)


    Mikael,

    Son cientos de tablas pero cada una se manejará por separado. Una tabla a la vez.

    Lo que no quiero es tener que personalizar la consulta para cada una de las tablas, que ademas pueden ser cambiantes en su estructura en el tiempo.

    Saludos,

    Hans

    Perhaps I am not fully underestanding the requirement, but I can get multiple tables into a single schema definition, using something like the following:

    Select top (1) *

    from Table1 pc_type,

    Table2 p_type,

    Table3 pv_type,

    Table4 pt_type

    where 1=0

    for xml auto, xmlschema

    This gives me a single schema file with the definitions for each of those tables, using the actual types for the actual columns.

    Now I suspect this might not work so well if you try to do that for hundreds of tables at a time, but it does work for quite a few.

    ----------------------------------------------------------------------------------
    Your lack of planning does not constitute an emergency on my part...unless you're my manager...or a director and above...or a really loud-spoken end-user..All right - what was my emergency again?

  • De una forma mas sencilla la pregunta es:

    Si tengo un campo/variable XML (en el cual hay datos de una sola tabla) y este ya tiene incluido el XMLSCHEMA, que camino automático y sencillo existe para conseguir una tabla relacional desde este.

    La idea es que cada fila de la tabla que tiene el campo XML tendrá los datos provenientes de una tabla diferente, por ejemplo, la primera fila tendrá los datos de CLIENTES, la segunda fila tendrá los datos de VENTAS, la tercera fila los datos de PERMISOS DE USUARIOS, etc.

    Entonces lo que quiero es leer estos datos y mostrarlos como una tabla relacional.

    Saludos,

    Hans

  • I can get multiple tables into a single schema definition

    Sure. The "problem" is only that I don't deal with multiple tables in the code I provided to fetch the data from the XML.

    The meta data for the extra tables ends up as separate element nodes and the data is added as child nodes to the first table. The dynamic query only uses the table name from the first element node and it only queries the root data nodes.

Viewing 10 posts - 1 through 9 (of 9 total)

You must be logged in to reply to this topic. Login to reply