Ir al contenido principal

Trabajando con datos masivos SQL Server, VFP, XML, Stored procedures

 Trabajando con datos masivos SQL Server, VFP, XML, Stored procedures.


Introducción

En el mundo de la gestión de bases de datos, la eficiencia y la rapidez en la manipulación de datos son cruciales. Una técnica que ha ganado popularidad por su capacidad para manejar grandes volúmenes de datos de manera eficiente es el uso de XML para la inserción y modificación masiva de registros en SQL Server. Esta metodología no solo optimiza el rendimiento, sino que también simplifica el proceso de actualización de múltiples registros, lo que resulta en una mejora significativa en la productividad y la precisión de las operaciones.

Las bondades de trabajar con XML para la inserción y modificación masiva de registros

  1. Eficiencia en el manejo de datos masivos: Utilizar XML como parámetro permite enviar múltiples registros en una sola transacción. Esto reduce considerablemente el número de llamadas a la base de datos, minimizando el overhead asociado y acelerando el proceso de inserción o actualización de datos.

  2. Simplificación del código y mantenimiento: Al agrupar los datos en un solo documento XML, el código SQL necesario para manejar estas operaciones se simplifica. En lugar de escribir múltiples sentencias de inserción o actualización, se puede procesar el XML con un solo bloque de código, facilitando el mantenimiento y la escalabilidad de la aplicación.

  3. Reducción del tráfico de red: Al enviar un único documento XML que contiene todos los registros a insertar o actualizar, se disminuye significativamente el tráfico de red entre la aplicación y el servidor de bases de datos. Esto es especialmente beneficioso en entornos donde el ancho de banda es limitado o costoso.

  4. Mejora en la integridad de los datos: Al realizar inserciones o actualizaciones masivas dentro de una transacción única, se asegura que todas las operaciones se realicen de manera atómica. Esto significa que, en caso de error, se puede revertir toda la transacción, manteniendo la integridad de los datos.

  5. Flexibilidad y adaptabilidad: XML es un formato flexible que permite estructurar los datos de diversas maneras. Esto facilita la adaptación a diferentes tipos de esquemas de datos y permite manejar escenarios complejos sin necesidad de cambios significativos en la estructura de la base de datos.

Ejemplo: 

En el ejemplo a presentar, veremos una entidad-relación de un sistema de ventas de manera simplificada, a fin de explicar las ventajas de insertar masivamente en un conjunto de tablas de bases coherentes y de alta integración. Utilizando algunos esquemas y relaciones, este sistema destaca por su capacidad para manejar grandes volúmenes de datos de manera eficiente y mantener la integridad de la información. Aquí, las principales bondades de este enfoque:

Entidad relación:  


Principales Bondades

  1. Organización Modular por Esquemas:

    • Configuración: Agrupa tablas relacionadas con documentos, ubicaciones (Ubigeo), personas y monedas.
    • Comercial: Administra listas de precios, áreas de venta, clientes, condiciones de venta y las ventas mismas.
    • Producto: Maneja las unidades de manejo, familias de productos y los productos.
  2. Integridad y Relaciones de Datos:

    • Relaciones clave que aseguran la consistencia de los datos mediante claves foráneas, como las relaciones entre personas y sus ubicaciones (Ubigeo), y entre productos y sus familias.
    • Uso de restricciones para mantener la coherencia y validez de los datos.
  3. Jerarquías y Estructuras Flexibles:

    • Soporte para estructuras jerárquicas en ubicaciones (Ubigeo) y familias de productos, permitiendo una representación clara y detallada de relaciones parentales y dependencias.
    • Capacidad para asociar múltiples niveles de detalle en ventas, como áreas de venta y listas de precios.
  4. Escalabilidad y Crecimiento:

    • Diseño que facilita la expansión futura, permitiendo la incorporación de nuevos módulos o tablas sin afectar la integridad existente.
    • Identificadores automáticos (IDENTITY) que simplifican la gestión de registros y evitan conflictos de datos.
  5. Eficiencia en la Gestión de Clientes y Ventas:

    • Administración integral de clientes, incluyendo detalles personales y relaciones con áreas de venta y listas de precios.
    • Registro detallado de ventas y sus componentes, como productos, cantidades y condiciones de venta, optimizando el seguimiento y análisis de transacciones.
  6. Manejo de Productos Completo:

    • Gestión de productos a través de su identificación, clasificación por familias y unidades de manejo, y asignación de costos unitarios, facilitando el control de inventario y costos.

Script: Para recrear el escenario.

USE [master]

GO

Create database Sample01

go

use Sample01

go

Create schema Comercial

go

Create schema Configuracion

go

Create schema Producto

go

USE [MiDataEjemplo]

GO

CREATE TABLE [configuracion].[Tipo_Documento](

       [Id_TipoDoc] [int] IDENTITY(1,1) NOT NULL,

       [Nombre_TipoDoc] [varchar](50) NULL,

 CONSTRAINT [PK_Tipo_Documento_1] PRIMARY KEY CLUSTERED

([Id_TipoDoc] ASC))

go

CREATE TABLE [configuracion].[Ubigeo](

       [Id_Ubigeo] [int] IDENTITY(1,1) NOT NULL,

       [Nombre_Ubigeo] [varchar](100) NULL,

       [Id_Ubigeo_Padre] [int] NULL,

 CONSTRAINT [PK_Ubigeo] PRIMARY KEY CLUSTERED

([Id_Ubigeo] ASC))

ALTER TABLE [configuracion].[Ubigeo]  WITH CHECK ADD  CONSTRAINT [FK_Ubigeo_Ubigeo] FOREIGN KEY([Id_Ubigeo_Padre])

REFERENCES [configuracion].[Ubigeo] ([Id_Ubigeo])

GO

ALTER TABLE [configuracion].[Ubigeo] CHECK CONSTRAINT [FK_Ubigeo_Ubigeo]

GO

CREATE TABLE [configuracion].[Persona](

       [id_persona] [int] IDENTITY(1,1) NOT NULL,

       [Nombre_Persona] [varchar](50) NULL,

       [Apellido_Paterno] [varchar](50) NULL,

       [Apellido_Materno] [varchar](50) NULL,

       [Id_Ubigeo] [int] NULL,

       [Direccion] [varchar](254) NULL,

       [Telefono] [char](10) NULL,

       [Movil] [char](10) NULL,

       [Email] [varchar](254) NULL,

       [Id_TipoDoc] [int] NULL,

       [Nro_doc] [char](10) NULL,

 CONSTRAINT [PK_Persona] PRIMARY KEY CLUSTERED

([id_persona] ASC))

GO

 

ALTER TABLE [configuracion].[Persona]  WITH CHECK ADD  CONSTRAINT [FK_Persona_Tipo_Documento] FOREIGN KEY([Id_TipoDoc])

REFERENCES [configuracion].[Tipo_Documento] ([Id_TipoDoc])

GO

ALTER TABLE [configuracion].[Persona] CHECK CONSTRAINT [FK_Persona_Tipo_Documento]

GO

ALTER TABLE [configuracion].[Persona]  WITH CHECK ADD  CONSTRAINT [FK_Persona_Ubigeo] FOREIGN KEY([Id_Ubigeo])

REFERENCES [configuracion].[Ubigeo] ([Id_Ubigeo])

GO

ALTER TABLE [configuracion].[Persona] CHECK CONSTRAINT [FK_Persona_Ubigeo]

GO

CREATE TABLE [configuracion].[Moneda](

       [Id_Moneda] [int] IDENTITY(1,1) NOT NULL,

       [Nombre_Moneda] [varchar](30) NULL,

       [Abrev_Moneda] [char](5) NULL,

 CONSTRAINT [PK_Moneda] PRIMARY KEY CLUSTERED

([Id_Moneda] ASC))

GO

CREATE TABLE [comercial].[Lista_precios](

       [Id_Lprecio] [int] IDENTITY(1,1) NOT NULL,

       [Nombre_Lprecio] [varchar](50) NULL,

       [id_moneda] [int] NOT NULL,

 CONSTRAINT [PK_Lista_precios] PRIMARY KEY CLUSTERED

([Id_Lprecio] ASC))

GO

CREATE TABLE [comercial].[Area_Venta](

       [Id_Area] [int] IDENTITY(1,1) NOT NULL,

       [Nombre_Area] [varchar](50) NULL,

 CONSTRAINT [PK_Area_Venta] PRIMARY KEY CLUSTERED

([Id_Area] ASC))

GO

CREATE TABLE [comercial].[Cliente](

       [Id_Cliente] [int] IDENTITY(1,1) NOT NULL,

       [Id_Persona] [int] NULL,

       [Id_Area] [int] NULL,

       [Id_Lprecio] [int] NULL,

 CONSTRAINT [PK_Cliente] PRIMARY KEY CLUSTERED

([Id_Cliente] ASC))

GO

ALTER TABLE [comercial].[Cliente]  WITH CHECK ADD  CONSTRAINT [FK_Cliente_Area_Venta] FOREIGN KEY([Id_Area])

REFERENCES [comercial].[Area_Venta] ([Id_Area])

GO

ALTER TABLE [comercial].[Cliente] CHECK CONSTRAINT [FK_Cliente_Area_Venta]

GO

ALTER TABLE [comercial].[Cliente]  WITH CHECK ADD  CONSTRAINT [FK_Cliente_Lista_precios] FOREIGN KEY([Id_Lprecio])

REFERENCES [comercial].[Lista_precios] ([Id_Lprecio])

GO

ALTER TABLE [comercial].[Cliente] CHECK CONSTRAINT [FK_Cliente_Lista_precios]

GO

ALTER TABLE [comercial].[Cliente]  WITH CHECK ADD  CONSTRAINT [FK_Cliente_Persona] FOREIGN KEY([Id_Persona])

REFERENCES [configuracion].[Persona] ([id_persona])

GO

ALTER TABLE [comercial].[Cliente] CHECK CONSTRAINT [FK_Cliente_Persona]

GO

CREATE TABLE [comercial].[Condicion_Venta](

       [Id_Cond_Venta] [int] IDENTITY(1,1) NOT NULL,

       [Nombre_Cond_Venta] [varchar](50) NULL,

 CONSTRAINT [PK_Condicion_Venta] PRIMARY KEY CLUSTERED

([Id_Cond_Venta] ASC))

GO 

CREATE TABLE [comercial].[Venta](

       [Id_Venta] [int] IDENTITY(1,1) NOT NULL,

       [Id_Cliente] [int] NOT NULL,

       [Nro_Doc] [char](12) NULL,

       [Fecha_Venta] [datetime] NULL,

       [Obs_venta] [varchar](max) NULL,

       [Id_Area] [int] NULL,

       [Id_Moneda] [int] NOT NULL,

       [Id_Cond_Venta] [int] NULL,

       [id_lprecio] [int] NULL,

 CONSTRAINT [PK_Venta] PRIMARY KEY CLUSTERED

([Id_Venta] ASC))

GO

ALTER TABLE [comercial].[Venta]  WITH CHECK ADD  CONSTRAINT [FK_Venta_Area_Venta] FOREIGN KEY([Id_Area])

REFERENCES [comercial].[Area_Venta] ([Id_Area])

GO

ALTER TABLE [comercial].[Venta] CHECK CONSTRAINT [FK_Venta_Area_Venta]

GO

ALTER TABLE [comercial].[Venta]  WITH CHECK ADD  CONSTRAINT [FK_Venta_Cliente] FOREIGN KEY([Id_Cliente])

REFERENCES [comercial].[Cliente] ([Id_Cliente])

GO

ALTER TABLE [comercial].[Venta] CHECK CONSTRAINT [FK_Venta_Cliente]

GO

ALTER TABLE [comercial].[Venta]  WITH CHECK ADD  CONSTRAINT [FK_Venta_Condicion_Venta] FOREIGN KEY([Id_Cond_Venta])

REFERENCES [comercial].[Condicion_Venta] ([Id_Cond_Venta])

GO

ALTER TABLE [comercial].[Venta] CHECK CONSTRAINT [FK_Venta_Condicion_Venta]

GO

ALTER TABLE [comercial].[Venta]  WITH CHECK ADD  CONSTRAINT [FK_Venta_Lista_precios] FOREIGN KEY([id_lprecio])

REFERENCES [comercial].[Lista_precios] ([Id_Lprecio])

GO

ALTER TABLE [comercial].[Venta] CHECK CONSTRAINT [FK_Venta_Lista_precios]

GO

ALTER TABLE [comercial].[Venta]  WITH CHECK ADD  CONSTRAINT [FK_Venta_Moneda] FOREIGN KEY([Id_Moneda])

REFERENCES [configuracion].[Moneda] ([Id_Moneda])

GO

ALTER TABLE [comercial].[Venta] CHECK CONSTRAINT [FK_Venta_Moneda]

GO

CREATE TABLE [producto].[Unidad_Manejo](

       [Id_UM] [int] IDENTITY(1,1) NOT NULL,

       [Nombre_UM] [varchar](10) NULL,

 CONSTRAINT [PK_Unidad_Manejo_1] PRIMARY KEY CLUSTERED

([Id_UM] ASC))

GO

CREATE TABLE [producto].[Familia_Producto](

       [id_famprod] [int] IDENTITY(1,1) NOT NULL,

       [id_famprod_padre] [int] NULL,

       [nombre_familia] [varchar](100) NULL,

 CONSTRAINT [PK_Familia_Producto] PRIMARY KEY CLUSTERED

([id_famprod] ASC))

GO

ALTER TABLE [producto].[Familia_Producto]  WITH CHECK ADD  CONSTRAINT [FK_Familia_Producto_Familia_Producto] FOREIGN KEY([id_famprod_padre])

REFERENCES [producto].[Familia_Producto] ([id_famprod])

GO

ALTER TABLE [producto].[Familia_Producto] CHECK CONSTRAINT [FK_Familia_Producto_Familia_Producto]

GO

CREATE TABLE [producto].[Producto](

       [id_producto] [int] IDENTITY(1,1) NOT NULL,

       [Nombre_Producto] [varchar](150) NULL,

       [id_famprod] [int] NULL,

       [Id_UM] [int] NULL,

       [costo_unitario] [numeric](12, 2) NULL,

 CONSTRAINT [PK_Producto] PRIMARY KEY CLUSTERED

([id_producto] ASC))

GO

ALTER TABLE [producto].[Producto]  WITH CHECK ADD  CONSTRAINT [FK_Producto_Familia_Producto] FOREIGN KEY([id_famprod])

REFERENCES [producto].[Familia_Producto] ([id_famprod])

GO

ALTER TABLE [producto].[Producto] CHECK CONSTRAINT [FK_Producto_Familia_Producto]

GO

ALTER TABLE [producto].[Producto]  WITH CHECK ADD  CONSTRAINT [FK_Producto_Unidad_Manejo] FOREIGN KEY([Id_UM])

REFERENCES [producto].[Unidad_Manejo] ([Id_UM])

GO

ALTER TABLE [producto].[Producto] CHECK CONSTRAINT [FK_Producto_Unidad_Manejo]

GO

CREATE TABLE [comercial].[Venta_Detalle](

       [id_ventad] [int] IDENTITY(1,1) NOT NULL,

       [id_Venta] [int] NOT NULL,

       [id_producto] [int] NOT NULL,

       [Cantidad] [numeric](12, 3) NULL,

       [Precio_unitario] [numeric](12, 2) NULL,

       [Impuesto] [numeric](18, 6) NULL,

       [Tcambio] [numeric](12, 3) NULL,

 CONSTRAINT [PK_Venta_Detalle] PRIMARY KEY CLUSTERED

([id_ventad] ASC))

GO

ALTER TABLE [comercial].[Venta_Detalle]  WITH CHECK ADD  CONSTRAINT [FK_Venta_Detalle_Producto] FOREIGN KEY([id_producto])

REFERENCES [producto].[Producto] ([id_producto])

GO

ALTER TABLE [comercial].[Venta_Detalle] CHECK CONSTRAINT [FK_Venta_Detalle_Producto]

GO

ALTER TABLE [comercial].[Venta_Detalle]  WITH CHECK ADD  CONSTRAINT [FK_Venta_Detalle_Venta] FOREIGN KEY([id_Venta])

REFERENCES [comercial].[Venta] ([Id_Venta])

GO

ALTER TABLE [comercial].[Venta_Detalle] CHECK CONSTRAINT [FK_Venta_Detalle_Venta]

GO


Creando Nuestro Pimer Stored Procedure: Con este Query, recuperaremos una venta con su respectivo detalle.

create procedure comercial.select_venta

@id_venta int

as

SELECT [Id_Venta]

      ,[Id_Cliente]

      ,[Nro_Doc]

      ,[Fecha_Venta]

      ,[Obs_venta]

      ,[Id_Area]

      ,[Id_Moneda]

      ,[Id_Cond_Venta]

      ,[id_lprecio]

  FROM [Comercial].[Venta] where id_venta=@id_Venta

SELECT [id_ventad]

      ,[id_Venta]

      ,[id_producto]

      ,[Cantidad]

      ,[Precio_unitario]

      ,[Impuesto]

      ,[Tcambio]

  FROM [Comercial].[Venta_Detalle] where id_venta=@id_Venta

GO

grant execute on comercial.select_venta to public

 En VFP :

Creamos la conexión a la base de datos

ncon=SQLSTRINGCONNECT("Driver=SQL Server;Server=5CG13128K2;Database=sample01")

Ejecutamos el Stored Procedure

=SQLEXEC(ncon,"execute comercial.select_venta 1","venta")


Poblando datos a las tablas

INSERT INTO [configuracion].[Tipo_Documento] ([Nombre_TipoDoc]) VALUES

('DNI'), ('RUC'), ('Pasaporte'), ('Carnet de Extranjería'),

('Licencia de Conducir'), ('Otro Tipo 1'), ('Otro Tipo 2'),

('Otro Tipo 3'), ('Otro Tipo 4'), ('Otro Tipo 5');

INSERT INTO [configuracion].[Ubigeo] ([Nombre_Ubigeo], [Id_Ubigeo_Padre]) VALUES

('Perú', NULL),

('Lima', 1),

('Arequipa', 1),

('Cusco', 1),

('La Libertad', 1),

('Trujillo', 4),

('Chiclayo', 4),

('Piura', 4),

('Ica', 1),

('Tacna', 1);

INSERT INTO [configuracion].[Moneda] ([Nombre_Moneda], [Abrev_Moneda]) VALUES

('Nuevo Sol', 'PEN'),

('Dólar Americano', 'USD'),

('Euro', 'EUR'),

('Libra Esterlina', 'GBP'),

('Yen Japonés', 'JPY'),

('Franco Suizo', 'CHF'),

('Dólar Canadiense', 'CAD'),

('Dólar Australiano', 'AUD'),

('Real Brasileño', 'BRL'),

('Peso Mexicano', 'MXN');

INSERT INTO [configuracion].[Persona] ([Nombre_Persona], [Apellido_Paterno], [Apellido_Materno], [Id_Ubigeo], [Direccion], [Telefono], [Movil], [Email], [Id_TipoDoc], [Nro_doc]) VALUES

('Juan', 'Perez', 'Lopez', 2, 'Av. Siempre Viva 123', '0123456789', '0987654321', 'juan.perez@example.com', 1, '12345678'),

('Maria', 'Garcia', 'Sanchez', 2, 'Calle Falsa 456', '0234567890', '0897654321', 'maria.garcia@example.com', 2, '87654321'),

('Carlos', 'Rodriguez', 'Martinez', 3, 'Jiron Peru 789', '0345678901', '0796543210', 'carlos.rodriguez@example.com', 3, '34567890'),

('Ana', 'Fernandez', 'Gomez', 4, 'Pasaje Libertad 101', '0456789012', '0695432109', 'ana.fernandez@example.com', 4, '45678901'),

('Luis', 'Lopez', 'Diaz', 5, 'Plaza Mayor 202', '0567890123', '0594321098', 'luis.lopez@example.com', 5, '56789012'),

('Jose', 'Martinez', 'Perez', 6, 'Calle Real 303', '0678901234', '0493210987', 'jose.martinez@example.com', 6, '67890123'),

('Laura', 'Sanchez', 'Ramirez', 7, 'Av. Principal 404', '0789012345', '0392109876', 'laura.sanchez@example.com', 1, '78901234'),

('David', 'Ramirez', 'Vega', 8, 'Jiron Central 505', '0890123456', '0291098765', 'david.ramirez@example.com', 2, '89012345'),

('Elena', 'Gomez', 'Flores', 9, 'Pasaje Secundario 606', '0901234567', '0190987654', 'elena.gomez@example.com', 3, '90123456'),

('Jorge', 'Vega', 'Morales', 10, 'Calle Tercera 707', '1012345678', '0089876543', 'jorge.vega@example.com', 4, '01234567');

INSERT INTO [comercial].[Lista_precios] ([Nombre_Lprecio], [id_moneda]) VALUES

('Lista General', 1),

('Lista Promocional', 1),

('Lista Especial', 1),

('Lista VIP', 1),

('Lista Descuento', 1),

('Lista Exportación', 2),

('Lista Importación', 3),

('Lista Local', 4),

('Lista Nacional', 5),

('Lista Internacional', 6);

INSERT INTO [comercial].[Area_Venta] ([Nombre_Area]) VALUES

('Area Norte'),

('Area Sur'),

('Area Este'),

('Area Oeste'),

('Area Centro'),

('Area Lima'),

('Area Provincias'),

('Area Internacional'),

('Area Online'),

('Area Directa');

INSERT INTO [comercial].[Cliente] ([Id_Persona], [Id_Area], [Id_Lprecio]) VALUES

(1, 1, 1),

(2, 2, 2),

(3, 3, 3),

(4, 4, 4),

(5, 5, 5),

(6, 6, 6),

(7, 7, 7),

(8, 8, 8),

(9, 9, 9),

(10, 10, 10);

INSERT INTO [comercial].[Condicion_Venta] ([Nombre_Cond_Venta]) VALUES

('Contado'),

('Crédito 30 días'),

('Crédito 60 días'),

('Crédito 90 días'),

('Cheque'),

('Transferencia Bancaria'),

('Tarjeta de Crédito'),

('PayPal'),

('Efectivo'),

('Otro');

INSERT INTO [comercial].[Venta] ([Id_Cliente], [Nro_Doc], [Fecha_Venta], [Obs_venta], [Id_Area], [Id_Moneda], [Id_Cond_Venta], [id_lprecio]) VALUES

(1, '001-0001', '2024-01-01', 'Observación 1', 1, 1, 1, 1),

(2, '001-0002', '2024-01-02', 'Observación 2', 2, 2, 2, 2),

(3, '001-0003', '2024-01-03', 'Observación 3', 3, 3, 3, 3),

(4, '001-0004', '2024-01-04', 'Observación 4', 4, 4, 4, 4),

(5, '001-0005', '2024-01-05', 'Observación 5', 5, 5, 5, 5),

(6, '001-0006', '2024-01-06', 'Observación 6', 6, 6, 6, 6),

(7, '001-0007', '2024-01-07', 'Observación 7', 7, 7, 7, 7),

(8, '001-0008', '2024-01-08', 'Observación 8', 8, 8, 8, 8),

(9, '001-0009', '2024-01-09', 'Observación 9', 9, 9, 9, 9),

(10, '001-0010', '2024-01-10', 'Observación 10', 10, 10, 10, 10);

 INSERT INTO [producto].[Unidad_Manejo] ([Nombre_UM]) VALUES

('Unidad'),

('Caja'),

('Paquete'),

('Tonelada'),

('Gramo'),

('Kilogramo'),

('Metro'),

('Litro'),

('Botella'),

('Lata');

 INSERT INTO [producto].[Familia_Producto] ([id_famprod_padre], [nombre_familia]) VALUES

(NULL, 'Electrónicos'),

(1, 'Televisores'),

(1, 'Computadoras'),

(1, 'Smartphones'),

(NULL, 'Muebles'),

(5, 'Sillas'),

(5, 'Mesas'),

(NULL, 'Ropa'),

(8, 'Hombres'),

(8, 'Mujeres');

INSERT INTO [producto].[Producto] ([Id_Famprod], [Nombre_Producto], [Id_UM], [costo_unitario]) VALUES

(2, 'Televisor 32 pulgadas', 1, 1),

(2, 'Televisor 40 pulgadas', 1, 1),

(3, 'Laptop 14 pulgadas', 1, 1),

(3, 'PC de Escritorio', 1, 1),

(4, 'Smartphone 64GB', 1, 1),

(4, 'Smartphone 128GB', 1, 1),

(6, 'Silla de Oficina', 1, 1),

(7, 'Mesa de Comedor', 1, 1),

(9, 'Camisa Hombre', 1, 1),

(10, 'Blusa Mujer', 1, 1);

INSERT INTO [comercial].[Venta_Detalle] ([Id_Venta], [Id_Producto], [Cantidad], [Precio_unitario], tcambio) VALUES

(1, 1, 2, 1000.00, 1),

(2, 2, 1, 1200.00, 1),

(3, 3, 1, 1500.00, 1),

(4, 4, 3, 800.00, 1),

(5, 5, 2, 600.00, 1),

(6, 6, 1, 700.00, 1),

(7, 7, 5, 200.00, 1),

(8, 8, 1, 500.00, 1),

(9, 9, 4, 100.00, 1),

(10, 10, 3, 120.00, 1);

SQL Server, Stored Procedure de Inserción másiva.

create procedure [comercial].[venta_inserta_xml]

@id_venta int output,

@id_cliente int,

@nro_doc char(12),

@fecha_Venta datetime,

@obs_venta varchar(max),

@id_Area int,

@id_moneda int,

@id_cond_venta int,

@id_lprecio int,

@xmldetalle xml

as

declare @id_producto int , @Cantidad numeric(12,3), @Precio_unitario numeric(12,2), @Impuesto numeric(18,6),@Tcambio numeric(12,3),@id_ventad int

begin try

begin tran

       if @id_venta=0

       begin

             insert into comercial.Venta (Id_Cliente,Nro_Doc,Fecha_Venta,Obs_venta,Id_Area,Id_Moneda,Id_Cond_Venta,id_lprecio)

             values (@id_cliente,@nro_doc,@fecha_Venta,@obs_venta,@id_Area,@id_moneda,@id_cond_venta,@id_lprecio)

             set @id_Venta = (SELECT IDENT_CURRENT ('comercial.Venta'))

       end

       else

       begin

             update comercial.Venta set id_cliente=@id_cliente, nro_doc=@nro_doc, fecha_Venta=@fecha_Venta, obs_venta=@obs_venta,

             id_Area=@id_Area, id_moneda=@id_moneda, id_cond_venta=@id_cond_venta, @id_lprecio=@id_lprecio

             where id_venta=@id_venta

       end

 

             insert into comercial.Venta_Detalle (id_venta,id_producto,Cantidad,Precio_unitario,Impuesto,Tcambio)

             select @id_venta,

             id_producto=(ItmCnp.Item.value('@id_producto','int')),

             cantidad=(ItmCnp.Item.value('@cantidad','numeric(12,3)')),

             precio_unitario=(ItmCnp.Item.value('@precio_unitario','numeric(12,2)')),

             impuesto=(ItmCnp.Item.value('@impuesto','numeric(18,6)')),

             tcambio=(ItmCnp.Item.value('@tcambio','numeric(12,3)'))

             from @xmldetalle.nodes('ROOT/venta1') as ItmCnp(Item) where ItmCnp.Item.value('@id_ventad', 'int')=0

 

             UPDATE comercial.Venta_Detalle SET

             Venta_Detalle.Cantidad = ItmCnp.Item.value('@cantidad', 'numeric(12,3)'),

             Venta_Detalle.Precio_unitario = ItmCnp.Item.value('@precio_unitario', 'numeric(12,2)'),

             Venta_Detalle.Impuesto = ItmCnp.Item.value('@impuesto', 'numeric(18,6)'),

             Venta_Detalle.Tcambio = ItmCnp.Item.value('@tcambio', 'numeric(12,3)')

             FROM comercial.Venta_Detalle

             INNER JOIN @xmldetalle.nodes('ROOT/venta1') AS ItmCnp(Item)

             ON Venta_Detalle.id_ventad = ItmCnp.Item.value('@id_ventad', 'int') where ItmCnp.Item.value('@id_ventad', 'int')<>0

 

commit tran

end try

begin catch

ROLLBACK TRANSACTION

     DECLARE @ErrorMessage NVARCHAR(4000),@ErrorSeverity INT,@ErrorState INT;

     SELECT @ErrorMessage = ERROR_MESSAGE(),@ErrorSeverity = ERROR_SEVERITY(),@ErrorState = ERROR_STATE()

     RAISERROR (@ErrorMessage,@ErrorSeverity,@ErrorState)   

end catch

go

grant execute on [comercial].[venta_inserta_xml] to public

go


VFP PRG, Para generar de cursor a XML

Sintaxis:

_mixml = creaxml("Cursor")

LPARAMETERS tcAlias as String, tlClosealias as Logical

LOCAL XMLResult as String , oError as Exception

   XMLResult=''

    LcCabecera = "<?xml version=" + Chr(34) + "1.0" + Chr(34) +;

                 " encoding=" + Chr(34) + "iso-8859-1" + Chr(34) + "?>"

    XMLBody=''

  SELECT(tcAlias)

  LnColum = FCOUNT()

  GO top

  SCAN

      XMLBody = XMLBody+' <'+tcAlias

    FOR lncol=1 TO LnColum

          LcNameField = LOWER(FIELD(lncol))

          LvValor = &LcNameField

          LcValor=''

          DO Case

             CASE VARTYPE(LvValor)='D'

                 LcValor = DTOC(LvValor)

             CASE VARTYPE(LvValor)='T'

                 LcValor = TTOC(LvValor,3)                

             CASE VARTYPE(LvValor)='N'   && Numerico

                  LcValor = ALLTRIM(TRANSFORM(LvValor))

             CASE VARTYPE(LvValor)='X'   && NUll

                DO Case

                   CASE TYPE('LvValor')='N'

                        LcValor = "0"

                     CASE TYPE('LvValor')='D' OR TYPE('LvValor')='T'

                          LcValor = '01/01/1900'    

                     CASE TYPE('LvValor')='C' 

                          LcValor = ' '

                ENDCASE

             CASE VARTYPE(LvValor)='L'   && Logico

                LcValor = ICASE(LvValor,'1','0')              

             OTHERWISE

                LcValor = ALLTRIM(LvValor)

          ENDCASE       

          XMLBody=XMLBody+' '+LcNameField+'='+CHR(34)+LcValor+CHR(34)

    ENDFOR

      XMLBody=XMLBody+'></'+tcAlias+'>'              

  ENDSCAN

  XMLResult=LcCabecera + '<ROOT>'+;

                      XMLBody+;

                      '</ROOT>'

IF tlClosealias=.t.

endif

RETURN XMLResult

Llenando variables y Generando XML

Recuperando Registros de SQL Server
Actualizando datos en la cabecera y adiconando registros al detalle

=SQLEXEC(ncon,"execute comercial.select_venta 1","venta")


Actualizando datos en la cabecera y adiconando registros al detalle

Actualizando variables, generando XML y ejecutando Stored Procedure.

SELECT venta

SCATTER MEMVAR memo

SELECT venta1

_mixml = creaxml("venta1")

=SQLEXEC(ncon,"comercial.venta_inserta_xml ?@m.id_venta,?m.id_cliente,?m.nro_doc,?m.fecha_Venta,?m.obs_venta,?m.id_Area,?m.id_moneda,?m.id_cond_venta,?m.id_lprecio,?_mixml")

USE IN venta

USE IN venta1

=SQLEXEC(ncon,"execute comercial.select_venta 1","venta")


Validando en SQL Server

select * from comercial.venta where id_venta=1

select * from comercial.venta_detalle where id_venta=1



Conclusión

En resumen, la utilización de XML para la inserción y modificación masiva de registros en SQL Server es una estrategia poderosa que mejora la eficiencia, simplifica el mantenimiento, reduce el tráfico de red, mejora la integridad de los datos y ofrece una gran flexibilidad. Adoptar esta técnica puede transformar significativamente la forma en que se gestionan los datos en cualquier organización, contribuyendo a una mayor agilidad y precisión en las operaciones de bases de datos.



Comentarios

  1. Gracias por tu tiempo. Sólo tengo una duda. ¿Por qué crear una función que arme el XML "manualmente" cuando se puede usar la función CURSORTOXML() o la clase XMLAdapter que es más fácil de programar y ejecuta más rápido? Yo he usado la función CURSORTOXML() y me ha funcionado muy bien.

    ResponderEliminar
    Respuestas
    1. ¡Hola Skysurfer1967!
      He creado un programa (PRG) que genera un archivo XML más simplificado que el que proporciona la función cursortoxml(), con el fin de ofrecer una opción adicional . Este enfoque puede ser útil si buscas una estructura XML más sencilla y específica para tus datos.

      ¡Espero que te sea de ayuda!

      Saludos,

      Eliminar

Publicar un comentario

Entradas populares de este blog

  Control de Acceso en SQL Server: Logins y Usuarios de Aplicación En SQL Server, la gestión de accesos y permisos es fundamental para garantizar la seguridad de los datos. Un enfoque común es la creación de logins y usuarios con distintos niveles de acceso, asegurando que solo tengan las autorizaciones necesarias para sus funciones. En este artículo, exploraremos dos configuraciones comunes: 1. Usuarios con solo conexión, sin acceso a bases de datos 2. Usuarios de aplicación con acceso exclusivo a procedimientos almacenados (SP) mediante Application Roles 1. Creación de un Login sin acceso a ninguna base de datos Si necesitamos que un usuario pueda autenticarse en SQL Server pero sin acceso a ninguna base de datos, podemos seguir estos pasos: Creación del Login en el Servidor USE [master] GO CREATE LOGIN [user1] WITH PASSWORD =N'12345678', DEFAULT_DATABASE=[MiDataEjemplo], DEFAULT_LANGUAGE=[Español], CHECK_EXPIRATION= OFF , CHECK_POLICY= OFF GO Veri...
El Reto de Migrar de DBF a SQL Server: Un Viaje Emocional Migrar una base de datos de DBF a SQL Server no es simplemente una tarea técnica; es un viaje emocional que puede desencadenar una montaña rusa de sentimientos. Inspirado en las emociones de la película "Emociones 2", exploramos cómo nuestras emociones juegan un papel crucial en este proceso y cómo podemos afrontarlas para dar ese importante paso hacia la modernización. Alegría: La Emoción del Progreso Alegría es el motor que nos impulsa a ver las oportunidades y beneficios de migrar a SQL Server. Imagina la eficiencia, la seguridad y las capacidades avanzadas que ofrece SQL Server. Esta emoción nos llena de entusiasmo y optimismo, ayudándonos a visualizar un futuro más brillante para nuestros sistemas y procesos. Tristeza: El Desapego del Pasado Dejar atrás algo que ha sido parte de nuestro trabajo durante años puede generar tristeza. Es normal sentir nostalgia por la familiaridad y el confort de DBF, pero reconocer e...