Principales respuestas
Insertar Maestro Detalle en c# con XMl

Pregunta
-
amigos tengo ese problema que no se como pasar el archivo xml al procedimiento almancenado.
el xml lo genero con este codigo
protected void BtonRegistrarOferta_Click(object sender, EventArgs e) { string path = Server.MapPath("~/OfertaMarcas.xml"); using (XmlTextWriter writer = new XmlTextWriter(path, Encoding.UTF8)) { writer.Formatting = Formatting.Indented; writer.WriteStartDocument(); writer.WriteStartElement("ROOt"); writer.WriteStartElement("OfertaEcoTec"); writer.WriteAttributeString("USUARIOID", (Convert.ToString(Session["IdUsuario"]); writer.WriteAttributeString("LICITACIONID", Convert.ToString(this.ddLicitacion.SelectedValue)); writer.WriteAttributeString("PROVEEDORID", Convert.ToString(this.lblProveedorId.Text)); writer.WriteAttributeString("REQID", Convert.ToString(this.ddclave.SelectedValue)); writer.WriteAttributeString("GPO", Convert.ToString(this.txtgpo.Text)); writer.WriteAttributeString("GEN", Convert.ToString(this.txtgen.Text)); writer.WriteAttributeString("ESP", Convert.ToString(this.txtesp.Text)); writer.WriteAttributeString("DIF", Convert.ToString(this.txtdif.Text)); writer.WriteAttributeString("VAR", Convert.ToString(this.txtvar.Text)); writer.WriteAttributeString("PRECIOOFER",this.txtofertado.Text); writer.WriteAttributeString("DESCUENTOOFER", Convert.ToString(this.txtdescuento.Text)); writer.WriteAttributeString("PRECIONETO", Convert.ToString(this.txtdescuento.Text)); writer.WriteAttributeString("CANTMAXOFER", Convert.ToString(this.txtmaxofer.Text)); //foreach (GridViewRow row in this.GridMarcas.Rows) foreach (GridViewRow row in GridMarcas.Rows) { writer.WriteStartElement("MARCASOFER"); Label MARCA = (Label)row.FindControl("lblItemClase"); Label OFICIO = (Label)row.FindControl("lblItemOficio"); Label INCLUSION = (Label)row.FindControl("lblItemTramite"); Label ORIGEN = (Label)row.FindControl("lblOrigen"); Label FABRICANTE = (Label)row.FindControl("lblItemFabricante"); Label RFCFAB = (Label)row.FindControl("lblItemRfc"); writer.WriteAttributeString("MARCA",HttpUtility.HtmlEncode( MARCA.Text)); writer.WriteAttributeString("OFICIO", HttpUtility.HtmlEncode(OFICIO.Text)); writer.WriteAttributeString("INCLUSION", HttpUtility.HtmlEncode(INCLUSION.Text)); writer.WriteAttributeString("ORIGEN", HttpUtility.HtmlEncode(ORIGEN.Text)); writer.WriteAttributeString("FABRICANTE", HttpUtility.HtmlEncode(FABRICANTE.Text)); writer.WriteAttributeString("RFCFAB", HttpUtility.HtmlEncode(RFCFAB.Text)); writer.WriteEndElement(); } writer.WriteEndElement(); writer.Close(); } }
ahora como le hago para pasar este archivo al procedimiento almacenado.
y poder guardarlo en las tablas definitivas.
muchas gracias.
Horacio Xochitemol Bautista
Respuestas
-
Gracias amigo ya lo pude pasarlo al SP; ahora bien en mi tabla tengo columnas que debe ser unicas; el SP no inserta la informacion en la tabla 1(columnas con campos unicos) pero si en la tabla 2, es decir no captura el error podrian echarme una mano por favor el SP es el siguiente.
USE [MCCUR] GO /****** Object: StoredProcedure [dbo].[PGUARDA_OFERTA_ECO_MAESTRO_DETALLE] Script Date: 10/09/2015 06:18:04 p.m. ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER Procedure [dbo].[PGUARDA_OFERTA_ECO_MAESTRO_DETALLE] @xml text as DECLARE @hDoc int Begin TRANSACTION DECLARE @Error int EXEC sp_xml_preparedocument @hDoc OUTPUT, @xml Declare @IdOferta int Insert into OFERTAS (USUARIOID,LICITACIONID,MREQUERIMIENTOID,PROVEEDORID,GPO,GEN,ESP,DIF,VAR,PRECIO_OFERTADO,CANT_MAX,DESCUENTO,PRECIO_NETO) SELECT * FROM OPENXML(@hDoc, N'/ROOT/OfertaEcoTec') with (USUARIOID INT,LICITACIONID int,REQID int, PROVEEDORID int,GPO char(3),GEN char(3),ESP char(4),DIF char(2),[VAR] char(2),PRECIOOFER float,CANTMAXOFER int,DESCUENTOOFER float,PRECIONETO float) Select @IdOferta =@@identity --almacendo el error por si no se ejecuta la instruccion correctamente SET @Error=@@ERROR --si la variable de error es diferente de cero ejecuto el codigo para cancelar la transaccion if (@Error<>0) GOTO TratarError --si el primer inset se realiza con exito pasamos al segundo insert de marcas Insert into MARC_OFERT (OFERTAID,MARCA,OFICIO_EXIME,TRAMITE_INCLUSION,ORIGEN,FABRICANTE,RFC_FABRICANTE) SELECT @IdOferta,* FROM OPENXML(@hDoc, N'/ROOT/OfertaEcoTec/MARCASOFER') with (MARCA VARCHAR(200),OFICIO VARCHAR(200), INCLUSION VARCHAR(200), ORIGEN VARCHAR(200),FABRICANTE VARCHAR(200),RFCFAB VARCHAR(30)) EXEC sp_xml_removedocument @hDoc SET @Error=@@ERROR if (@Error<>0) GOTO TratarError COMMIT TRANSACTION TratarError: if @@ERROR <>0 BEGIN PRINT 'Ocurrio un error durante la transaccion' ROLLBACK TRANSACTION END
Horacio Xochitemol Bautista
- Marcado como respuesta Xochitemol martes, 15 de septiembre de 2015 0:36
Todas las respuestas
-
Hola Horacio,
Para pasar un XML a un procedimiento almacenado como parámetro, en primer lugar debes definir el procedimiento para recibir un parámetro de tipo XML.
CREATE PROCEDURE [dbo].[XYZ] @xml XML AS BEGIN ... END
Una vez definido el procedimiento, el proceso para enviar el XML en C# es muy similar al envío de cualquier otro parámetro. Puedes probar lo siguiente:
//Leemos el contenido del fichero en una variable var xml = File.ReadAllText(path); //Creamos la conexión y el comando using (SqlConnection con = new SqlConnection(ConnStr)) { using (SqlCommand cmd = new SqlCommand("XYZ")) { //Asignamos la conexión y pasamos el parámetro cmd.Connection = con; cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@xml", xml); con.Open(); cmd.ExecuteNonQuery(); con.Close(); } }
Para más información echa un vistazo a los siguientes enlaces:
http://www.codeproject.com/Questions/209223/Passing-XML-to-stored-procedure
http://www.aspsnippets.com/Articles/Pass-XML-parameter-to-Stored-Procedure-in-C-and-VBNet.aspx
When an answer is helpful, please vote as helpful, propose as answer and/or mark as answer
-
Gracias por la pronta respuesta, pero tengo una duda aquí genero el xml en un archivo de la aplicación; que pasaría con el archivo xml si están 2 o mas usuarios usando la aplicación en el mismo Proceso?; seria mejor guardar el archivo xml en una variable de tipo texto para después pasarla como parámetro al SP; como guardo ese archivo en la una variable de tipo string?
por su ayuda muchas gracias.
Horacio Xochitemol Bautista
-
Haber amigos no he podido mandar el xml como parámetroal SP hice algunas modificaciones al codigo y quedo de la siguiente manera.
para generar el xml y pasarlo al sp.
protected void BtonRegistrarOferta_Click(object sender, EventArgs e) { using (StringWriter str = new StringWriter()) using (XmlTextWriter writer = new XmlTextWriter(str)) { writer.Formatting = Formatting.Indented; writer.WriteStartDocument(); writer.WriteStartElement("ROOT"); writer.WriteStartElement("OfertaEcoTec"); writer.WriteAttributeString("USUARIOID", (Convert.ToString(Session["IdUsuario"]))); writer.WriteAttributeString("LICITACIONID", Convert.ToString(this.ddLicitacion.SelectedValue)); writer.WriteAttributeString("REQID", Convert.ToString(this.ddclave.SelectedValue)); writer.WriteAttributeString("PROVEEDORID", Convert.ToString(this.lblProveedorId.Text)); writer.WriteAttributeString("GPO", Convert.ToString(this.txtgpo.Text)); writer.WriteAttributeString("GEN", Convert.ToString(this.txtgen.Text)); writer.WriteAttributeString("ESP", Convert.ToString(this.txtesp.Text)); writer.WriteAttributeString("DIF", Convert.ToString(this.txtdif.Text)); writer.WriteAttributeString("VAR", Convert.ToString(this.txtvar.Text)); writer.WriteAttributeString("PRECIOOFER",this.txtofertado.Text); writer.WriteAttributeString("DESCUENTOOFER", Convert.ToString(this.txtdescuento.Text)); writer.WriteAttributeString("PRECIONETO", Convert.ToString(this.txtdescuento.Text)); writer.WriteAttributeString("CANTMAXOFER", Convert.ToString(this.txtmaxofer.Text)); //foreach (GridViewRow row in this.GridMarcas.Rows) foreach (GridViewRow row in GridMarcas.Rows) { writer.WriteStartElement("MARCASOFER"); Label MARCA = (Label)row.FindControl("lblItemClase"); Label OFICIO = (Label)row.FindControl("lblItemOficio"); Label INCLUSION = (Label)row.FindControl("lblItemTramite"); Label ORIGEN = (Label)row.FindControl("lblOrigen"); Label FABRICANTE = (Label)row.FindControl("lblItemFabricante"); Label RFCFAB = (Label)row.FindControl("lblItemRfc"); writer.WriteAttributeString("MARCA",HttpUtility.HtmlEncode( MARCA.Text).Trim()); writer.WriteAttributeString("OFICIO", HttpUtility.HtmlEncode(OFICIO.Text).Trim()); writer.WriteAttributeString("INCLUSION", HttpUtility.HtmlEncode(INCLUSION.Text).Trim()); writer.WriteAttributeString("ORIGEN", HttpUtility.HtmlEncode(ORIGEN.Text).Trim()); writer.WriteAttributeString("FABRICANTE", HttpUtility.HtmlEncode(FABRICANTE.Text).Trim()); writer.WriteAttributeString("RFCFAB", HttpUtility.HtmlEncode(RFCFAB.Text).Trim()); writer.WriteEndElement(); } writer.WriteEndElement(); writer.Close(); Response.Write(str); //conexion a la base de datos conexion cn = new conexion(); // SqlConnection cnx = cn.conectar(); using (SqlConnection cnx = cn.conectar()) { using (SqlCommand cmd = new SqlCommand("RegistroOfertaEcoTec")) { try {//Asignamos la conexión y pasamos el parámetro cmd.Connection = cnx; cmd.Parameters.AddWithValue("@xml", str); cmd.CommandType = CommandType.StoredProcedure; cnx.Open(); cmd.ExecuteNonQuery(); cnx.Close(); } catch (Exception Err) { errorgral = Err.Message.ToString() + " - " + Err.Source.ToString(); MessageBoxShow(this, errorgral); } } } } }
ahora el procedimiento almacenado
alter Procedure RegistroOfertaEcoTec @xml text as DECLARE @hDoc int Begin transaction EXEC sp_xml_preparedocument @hDoc OUTPUT, @xml Declare @IdOferta int Insert into OFERTAS (USUARIOID,LICITACIONID,MREQUERIMIENTOID,PROVEEDORID,GPO,GEN,ESP,DIF,VAR,PRECIO_OFERTADO,CANT_MAX,DESCUENTO) SELECT * FROM OPENXML(@hDoc, N'/ROOT/OfertaEcoTec') with (USUARIOID INT,LICITACIONID int,REQID int, PROVEEDORID int,GPO char(3),GEN char(3),ESP char(4),DIF char(2),[VAR] char(2),PRECIOOFER float,CANTMAXOFER int,DESCUENTOOFER float) Select @IdOferta =@@identity If @@error <>0 Rollback Tran Else Insert into MARC_OFERT (OFERTAID,MARCA,OFICIO_EXIME,TRAMITE_INCLUSION,ORIGEN,FABRICANTE,RFC_FABRICANTE) SELECT @IdOferta,* FROM OPENXML(@hDoc, N'/ROOT/OfertaEcoTec/MARCASOFER') with (MARCA VARCHAR(200),OFICIO VARCHAR(200), INCLUSION VARCHAR(200), ORIGEN VARCHAR(200),FABRICANTE VARCHAR(200),RFCFAB VARCHAR(30)) EXEC sp_xml_removedocument @hDoc If @@error <>0 Begin Rollback Tran Return End Else Commit Tran
pero al momento de hacer la conexion y mandar el parametro al SP me manda el siguiente error:
No hay ninguna asignación de tipo de objecto system.IO.StringWriter a un tipo nativo de un proveedor administrado conocido.- System.Data
Alguien podría ayudarme con este error, de antemano muchas gracias.
Horacio Xochitemol Bautista
-
Hola, buenas.
No puedes pasar el StringWriter str como parámetro al procedimiento almacenado. En lugar de pasar la variable str tal cuál, debes pasar el contenido, invocando al método ToString. El método ToString del StringWriter recupera el contenido del mismo en formato cadena.
https://msdn.microsoft.com/en-us/library/system.io.stringwriter.tostring(v=vs.110).aspx
Prueba a hacer el siguiente cambio:
... cmd.Parameters.AddWithValue("@xml", str.ToString()); ...
Un saludo.
When an answer is helpful, please vote as helpful, propose as answer and/or mark as answer
- Editado ohawari viernes, 11 de septiembre de 2015 8:10
-
Gracias amigo ya lo pude pasarlo al SP; ahora bien en mi tabla tengo columnas que debe ser unicas; el SP no inserta la informacion en la tabla 1(columnas con campos unicos) pero si en la tabla 2, es decir no captura el error podrian echarme una mano por favor el SP es el siguiente.
USE [MCCUR] GO /****** Object: StoredProcedure [dbo].[PGUARDA_OFERTA_ECO_MAESTRO_DETALLE] Script Date: 10/09/2015 06:18:04 p.m. ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER Procedure [dbo].[PGUARDA_OFERTA_ECO_MAESTRO_DETALLE] @xml text as DECLARE @hDoc int Begin TRANSACTION DECLARE @Error int EXEC sp_xml_preparedocument @hDoc OUTPUT, @xml Declare @IdOferta int Insert into OFERTAS (USUARIOID,LICITACIONID,MREQUERIMIENTOID,PROVEEDORID,GPO,GEN,ESP,DIF,VAR,PRECIO_OFERTADO,CANT_MAX,DESCUENTO,PRECIO_NETO) SELECT * FROM OPENXML(@hDoc, N'/ROOT/OfertaEcoTec') with (USUARIOID INT,LICITACIONID int,REQID int, PROVEEDORID int,GPO char(3),GEN char(3),ESP char(4),DIF char(2),[VAR] char(2),PRECIOOFER float,CANTMAXOFER int,DESCUENTOOFER float,PRECIONETO float) Select @IdOferta =@@identity --almacendo el error por si no se ejecuta la instruccion correctamente SET @Error=@@ERROR --si la variable de error es diferente de cero ejecuto el codigo para cancelar la transaccion if (@Error<>0) GOTO TratarError --si el primer inset se realiza con exito pasamos al segundo insert de marcas Insert into MARC_OFERT (OFERTAID,MARCA,OFICIO_EXIME,TRAMITE_INCLUSION,ORIGEN,FABRICANTE,RFC_FABRICANTE) SELECT @IdOferta,* FROM OPENXML(@hDoc, N'/ROOT/OfertaEcoTec/MARCASOFER') with (MARCA VARCHAR(200),OFICIO VARCHAR(200), INCLUSION VARCHAR(200), ORIGEN VARCHAR(200),FABRICANTE VARCHAR(200),RFCFAB VARCHAR(30)) EXEC sp_xml_removedocument @hDoc SET @Error=@@ERROR if (@Error<>0) GOTO TratarError COMMIT TRANSACTION TratarError: if @@ERROR <>0 BEGIN PRINT 'Ocurrio un error durante la transaccion' ROLLBACK TRANSACTION END
Horacio Xochitemol Bautista
- Marcado como respuesta Xochitemol martes, 15 de septiembre de 2015 0:36