Pregunta

Para dar algunos antecedentes a este problema primero, estoy reescribiendo un código que actualmente recorre algunos xml, insertando en una tabla al final de cada ciclo, reemplazando con un solo sp que toma un parámetro xml y realiza el inserte de una vez, 'triturando' el xml en una tabla.

La trituración principal se realizó con éxito, pero actualmente una de las columnas se utiliza para almacenar todo el nodo. He podido resolver la consulta necesaria para esto (casi), pero pierde la parte raíz del nodo. Llegué a la conclusión de que mi consulta es tan buena como puedo obtenerla, y estoy buscando una manera de hacer una declaración de actualización para que el nodo raíz vuelva a estar allí.

Entonces mi xml tiene la forma;

<xml>
<Items>
<Item>
    <node1>...</node1><node2>..<node2>.....<noden>...<noden>
<Item>
<Item>
    <node1>...</node1><node2>..<node2>.....<noden>...<noden>
<Item>
<Item>
    <node1>...</node1><node2>..<node2>.....<noden>...<noden>
<Item>
......
<Items>
</xml>

Entonces, la trituración básica coloca el valor del nodo1 en la columna1, el nodo2 en la columna2, etc. La instrucción insert se parece a algo así;

INSERT INTO mytable col1, col2,...etc.....,wholenodecolumn
Select  
doc.col.value('node1[1]', 'int') column1,
doc.col.value('node2[1]', 'varchar(50)') column2,
....etc......,
doc.col.query('*')--this is the query for getting the whole node
FROM @xml.nodes('//Items/Item') doc(col)

El XML que termina en una columna completa es de la forma;

<node1>...</node1><node2>..<node2>.....<noden>...<noden>

pero necesito que tenga la forma

<Item><node1>...</node1><node2>..<node2>.....<noden>...<noden></Item>

Existe un código existente (mucho) que depende de que el xml en esta columna tenga la forma correcta.

Entonces, ¿alguien puede ver cómo modificar el doc.col.query('*') para obtener el resultado deseado?

De todos modos, dejé de modificar la consulta e intenté pensar en otras formas de lograr el resultado final. Lo que estoy viendo ahora es una actualización después de la inserción, algo así como;

update mytable set wholenodecolumn.modify('insert <Item> as first before * ')

Si pudiera hacer esto junto con

 .modify('insert </Item> as last after * ')  

eso estaría bien, pero hacer 1 a la vez no es una opción ya que el XML no es válido

XQuery [mytable.wholenodecolumn.modify()]: Expected end tag 'Item'  

y haciendo ambas cosas juntas, no sé si es posible, pero he probado varias sintaxis y no puedo ponerme a trabajar.

Cualquier otro enfoque del problema también se agradece

¿Fue útil?

Solución 2

¡Respondiendo mi propia pregunta aquí! - Esto se desprende de los comentarios a uno de los otros intentos de respuesta donde dije:

  

Actualmente estoy investigando FLWOR   Construcciones Xquery en la consulta.
      col.query('for $item in * return <Item> {$item} </item>') es casi   allí, pero se pone   cada nodo, en lugar de alrededor de todos los   nodos

Casi estaba allí con la sintaxis, un pequeño ajuste me dio lo que necesitaba;

doc.col.query('<Item> { for $item in * return $item } </item>'

Gracias a todos los que ayudaron. Tengo más problemas relacionados ahora, pero lo publicaré como preguntas separadas

Otros consejos

Creo que puede especificar el nombre del nodo raíz utilizando la cláusula FOR.

Por ejemplo:

select top 1 *
from HumanResources.Department
for XML AUTO, ROOT('RootNodeName')

Eche un vistazo a los libros en línea para obtener más detalles:

http://msdn.microsoft.com/en-us/library/ ms190922.aspx

¿No podría simplemente agregar '' / '' como textos fijos en su selección? Algo así como:

Select  
  '<Item>',
  doc.col.value('node1[1]', 'int') column1,
  doc.col.value('node2[1]', 'varchar(50)') column2,
  ....etc......,
  doc.col.query('*'),
  '</Item>'      --this is the query for getting the whole node
FROM @xml.nodes('//Items/Item') doc(col)

Marc

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top