Requeria enviar programaticamente emails, pero no cuento con un servidor de email (SMTP), así que busque si se podia hacer a través de mi cuenta de GMAIL y encontré este fabuloso post con un ejemplo, lo probé y funciona a la perfección.
http://geeks.ms/blogs/jalarcon/archive/2007/06/23/c-243-mo-enviar-correo-electr-243-nico-por-c-243-digo-usando-cuentas-de-gmail.aspx
enero 30, 2011
enero 29, 2011
Auditoria de instrucciones DDL
Con DDL Triggers apartir de SQL Server 2005 podemos auditar todos las operaciones de DDL a la BD
USE pruebas
--La tabla de auditoria
Create Table DDL_Auditoria(
Id int Not Null identity,
FechaEvento datetime not null,
TipoEvento SYSNAME not null,
UsuarioEvento SYSNAME not null,
NombreObjeto SYSNAME not null,
NombreObjetoObjetivo SYSNAME not null
)
--disparador
Create TRIGGER DDL_AuditoriaDML ON DATABASE FOR DDL_DATABASE_LEVEL_EVENTS
As
Declare @EV as XML
SET @EV = EVENTDATA()
INSERT INTO DDL_Auditoria
VALUES(
CAST(@EV.query('data(//PostTime)') as varchar(23)),
CAST(@EV.query('data(//EventType)') as Sysname),
CAST(@EV.query('data(//LoginName)') as Sysname),
CAST(@EV.query('data(//ObjectName)') as Sysname),
CAST(@EV.query('data(//TargetObjectName)') as Sysname)
)
go
--Probamos el disparador con 2 operaciones DDL y consultamos las entradas de auditoria en nuestra tabla
Create Table TablaNueva (Cve int)
go
Alter Table TablaNueva ADD Col2 int
go
Select * FROM DDL_Auditoria
go
USE pruebas
--La tabla de auditoria
Create Table DDL_Auditoria(
Id int Not Null identity,
FechaEvento datetime not null,
TipoEvento SYSNAME not null,
UsuarioEvento SYSNAME not null,
NombreObjeto SYSNAME not null,
NombreObjetoObjetivo SYSNAME not null
)
--disparador
Create TRIGGER DDL_AuditoriaDML ON DATABASE FOR DDL_DATABASE_LEVEL_EVENTS
As
Declare @EV as XML
SET @EV = EVENTDATA()
INSERT INTO DDL_Auditoria
VALUES(
CAST(@EV.query('data(//PostTime)') as varchar(23)),
CAST(@EV.query('data(//EventType)') as Sysname),
CAST(@EV.query('data(//LoginName)') as Sysname),
CAST(@EV.query('data(//ObjectName)') as Sysname),
CAST(@EV.query('data(//TargetObjectName)') as Sysname)
)
go
--Probamos el disparador con 2 operaciones DDL y consultamos las entradas de auditoria en nuestra tabla
Create Table TablaNueva (Cve int)
go
Alter Table TablaNueva ADD Col2 int
go
Select * FROM DDL_Auditoria
go
DDL Triggers apartir de SQL Server 2005
En versiones anteriores sólo existian disparadores para operaciones DML para intrucciones INSERT, UPDATE y DELETE apartir de SQL Server 2005 es posible implementar disparadores para DDL
Por ejemplo:
USE pruebas
--Disparador que impediara modificar cualquier tabla de la BD.
Create Trigger DDL_1 ON DATABASE FOR ALTER_TABLE AS
RAISERROR('No se puede alterar tablas en esta Base de Datos', 16, 1)
ROLLBACK
Go
--Para probar que no se puede alterar la tabla, intentaremos una intrucción DDL a la tabla.
Alter table T1 ADD COLUMNA3 Varchar(10)
go
Por ejemplo:
USE pruebas
--Disparador que impediara modificar cualquier tabla de la BD.
Create Trigger DDL_1 ON DATABASE FOR ALTER_TABLE AS
RAISERROR('No se puede alterar tablas en esta Base de Datos', 16, 1)
ROLLBACK
Go
--Para probar que no se puede alterar la tabla, intentaremos una intrucción DDL a la tabla.
Alter table T1 ADD COLUMNA3 Varchar(10)
go
enero 28, 2011
Funcionalidad de CDC (Change Data Capture) en SQL Server 2008
SQL Server 2008 incluye una nueva configuración que nos sirve muy bien para el control de la auditoria sobre las operaciones DML (Update, Insert y Delete)
http://jcgonzalezmartin.wordpress.com/2008/04/21/sql-server-2008-change-data-capture-o-cdc/
http://weblogs.sqlteam.com/derekc/archive/2008/01/28/60469.aspx
http://jcgonzalezmartin.wordpress.com/2008/04/21/sql-server-2008-change-data-capture-o-cdc/
http://weblogs.sqlteam.com/derekc/archive/2008/01/28/60469.aspx
enero 17, 2011
Patrón de diseño: Estrategia
Utilizaremos el patrón stretegy porque se requiere implementar un mecanismo dinámico para el calculo de impuesto de acuerdo al país a donde se va a facturar, por ejemplo Europa, EE.UU y México y quizás otros paises más.
Proposito: De comportamiento
Alcance: Objeto
A continuación el diagrama de clases que representa a este patrón.
Ahora el diagrama de clases del calculo de impuestos de acuerdo al país
El código en C#
La clase contexto:
La interface que de acuerdo al tipo de objeto selecciona la clase concreta para realizar el calculo del impuesto.
las clases concretas, que implementan a la interface con el calculo del impuesto correspondiente a cada país
y finalmente el cliente
Asi si en el futuro de factura a otro país, sólo tenemos que implementar la interface con una clase concreta que realice el calculo correspondiente.
http://es.wikipedia.org/wiki/Strategy_(patr%C3%B3n_de_dise%C3%B1o)
Proposito: De comportamiento
Alcance: Objeto
A continuación el diagrama de clases que representa a este patrón.
Ahora el diagrama de clases del calculo de impuestos de acuerdo al país
El código en C#
La clase contexto:
La interface que de acuerdo al tipo de objeto selecciona la clase concreta para realizar el calculo del impuesto.
las clases concretas, que implementan a la interface con el calculo del impuesto correspondiente a cada país
y finalmente el cliente
Asi si en el futuro de factura a otro país, sólo tenemos que implementar la interface con una clase concreta que realice el calculo correspondiente.
http://es.wikipedia.org/wiki/Strategy_(patr%C3%B3n_de_dise%C3%B1o)
Patrón de diseño: Método Plantilla
Utilizaremos el patrón Template Method porque queremos crear una clase que nos permita trabajar cierta funcionalidad independientemente del manjeador de base de datos, acontinuación veremos su representación en el diagrama de clases:
Ahora el diagrama de clases de lo que nosotros queremos (ejecución de operaciones independientes del manejador de base datos).
Y ahora el código en C#
Esta es la clase que contiene el método plantilla. Observemos que los métodos que tienen que ver con el manejador de base de datos se han definido abstractos (sin implementar) pues estos deberán ser implementados por cada clase que represente al manejador de base de datos que queremos trabajar.
Las clases concretas que se casan con el manejador de Base de Datos
Otra clase concreta que implementa a la clase ConectividadBD, ahora para Oracle
Y el código cliente:
Ahora el diagrama de clases de lo que nosotros queremos (ejecución de operaciones independientes del manejador de base datos).
Y ahora el código en C#
Esta es la clase que contiene el método plantilla. Observemos que los métodos que tienen que ver con el manejador de base de datos se han definido abstractos (sin implementar) pues estos deberán ser implementados por cada clase que represente al manejador de base de datos que queremos trabajar.
Las clases concretas que se casan con el manejador de Base de Datos
Otra clase concreta que implementa a la clase ConectividadBD, ahora para Oracle
Y el código cliente:
Y así si queremos utilizar Informix, DB2 y los que sean.
enero 16, 2011
Herencia entre Interfaces
Las interfaces no pueden heredar de clases, pero si de otras interfaces. En la siguiente imagen vemos como IVehiculoVolador hereda de IVehiculo, porque un VehiculoVolador también es un Vehiculo y al implementar la interface IVehiculoVolador tenemos que implementar las dos interfaces.
Ahora el mismo diagrama, pero con los métodos implementados de las interfaces que utilizan:
Ahora el mismo diagrama, pero con los métodos implementados de las interfaces que utilizan:
enero 15, 2011
enero 14, 2011
Invocar al Constructor de la clase Base en C#
Tenemos una clase que hereda de otra y sabemos que los constructores no son heredados, entonces podemos desde la clase que hereda invocar al constructor de la clase base, en este caso para no volver a escribirlo o quizas en su cuerpo agregar alguna otra inicialización.
Lista de parámetros dinámica a una función C#
Requerimos hacer una función que reciba un número de parámetros desconcido desde 1 hasta N valores para tratarlos a todos.
//Los parámetros dinámicos se definene en la firma del método como un arreglo sin tamaño.
public static int Suma(params int[] argumentosN)
{
int total = 0;//el acumulador
for (int i = 0; i < argumentosN.Length; i++){
total += argumentosN[i];
}
return total;
}
Al llamar a la funcion pasamos el # de parametros que queramos, en este caso siempre los sumara todos
Console.WriteLine("valor : " + Suma (4,5,5,5,6));
Console.WriteLine("valor : " + Suma (4,5,5,5,6,3,4,5,33,45,2,3,44,5,1,12,4));
//Los parámetros dinámicos se definene en la firma del método como un arreglo sin tamaño.
public static int Suma(params int[] argumentosN)
{
int total = 0;//el acumulador
for (int i = 0; i < argumentosN.Length; i++){
total += argumentosN[i];
}
return total;
}
Al llamar a la funcion pasamos el # de parametros que queramos, en este caso siempre los sumara todos
Console.WriteLine("valor : " + Suma (4,5,5,5,6));
Console.WriteLine("valor : " + Suma (4,5,5,5,6,3,4,5,33,45,2,3,44,5,1,12,4));
Algunas Consideraciones en el Uso de las Variables: Locales, de Instancia y Estáticas en .NET
Así, las variables locales siempre deberan ser inicializadas antes de utilizarlas sino el compilador marcará un error. Los campos o variables de clase sino so inicializadas, éstas serán inicialzadas a sus valores defaul correspondientes, los tipo númericos a cero y los tipos de datos referencia a null para ello tenga presente el uso de constructores.
enero 13, 2011
Clasificación de tamaño de los proyectos en el desarrollo sistemas
Comenzaremos por la definición de proyecto que por ahi encontré.
Proyecto: Conjunto o secuencia de actividades que se desarrollan durante un tiempo por un equipo de personas para obtener un resultado u objetivo concreto. Así un proyecto siempre tendrá:
* Un objetivo concreto por alcanzar
* Una linea de tiempo con un principio y un final
* Un equipo de personas
* Recursos limitados (dinero, equipos, licencias...)
Y cómo podemos clasificar a los proyectos de software de acuerdo a su tamaño? bueno considero que n función de dos factores: tiempo y número de personas:
* Chicos: tienen una duración menor o igual a 6 meses con la participación de un equipo de personas de 1-5
* Medianos: tienen una duración mayor a 6 meses y menor o igual 36 meses con la participación de un equipo de personas de 5 a 15
* Grandes: tienen una duración de más de 36 meses y con un equipo de personas mayor a 15
Proyecto: Conjunto o secuencia de actividades que se desarrollan durante un tiempo por un equipo de personas para obtener un resultado u objetivo concreto. Así un proyecto siempre tendrá:
* Un objetivo concreto por alcanzar
* Una linea de tiempo con un principio y un final
* Un equipo de personas
* Recursos limitados (dinero, equipos, licencias...)
Y cómo podemos clasificar a los proyectos de software de acuerdo a su tamaño? bueno considero que n función de dos factores: tiempo y número de personas:
* Chicos: tienen una duración menor o igual a 6 meses con la participación de un equipo de personas de 1-5
* Medianos: tienen una duración mayor a 6 meses y menor o igual 36 meses con la participación de un equipo de personas de 5 a 15
* Grandes: tienen una duración de más de 36 meses y con un equipo de personas mayor a 15
¿Cuáles son hoy las habilidades necesarias para la construcción del Software?
* Análisis de Requisitos
* Análisis y Diseño Orientado a Objetos
* Programación Orientada a Objetos
* Ingenieria de usabilidad
* Diseño de Interfaces de usuario
* Diseño de Base de Datos
(Referencia: UML y Patrones. Craig Larman)
* Análisis y Diseño Orientado a Objetos
* Programación Orientada a Objetos
* Ingenieria de usabilidad
* Diseño de Interfaces de usuario
* Diseño de Base de Datos
(Referencia: UML y Patrones. Craig Larman)
enero 09, 2011
Múltiples referencias al mismo objeto (Referencias entre objetos)
Definción de referencia: Una referencia es un valor en tiempo de ejecución que está: o vacío o conectado.
Caso ejemplo:
Tenemos una clase que nos permite almacenar libros, es así que un libro se compone de la siguiente información:
-Titulo
-Año de publicación
-No paginas
-Autor
-Fecha Nacimiento
-Pais de Origen
De tal modo que cuando necesitamos crear más de un objeto Libro para los cuales se trata del mismo autor se veria de la siguiente forma:
Asi que por ello es la referencia entre objetos, es decir; en el objeto Libro habrá un apuntador que referncia al objeto Autor:
En el Diagrama de Clases lo podemos ver en la navegación, en donde la clase Libro tiene un apuntador a la case Autor:
Y en la implemantación en C# como una aplicación de consola:
using System;
class Libro
{
public string Titulo;
public Int16 AñoPublicacion;
public Int16 NoPaginas;
public Autor AutorLibro; //esta es la variable para hacer la refencia la objeto Autor
}
using System;
class Autor
{
public string Nombre;
public string FechaNacimiento;
public string PaisOrigen;
}
Y el programa cliente que hace uso de las clases y las relaciona através de referencias entre objetos:
using System;
class Program
{
static void Main(string[] args)
{
//creamos 2 libros que tienen mismo autor
Libro Libro1 = new Libro();
Libro1.Titulo = "Ensayo de la ceguera";
Libro1.AñoPublicacion = 1998;
Libro1.NoPaginas = 234;
Libro Libro2 = new Libro();
Libro2.Titulo = "El Evangelio Segun Jesucristo";
Libro2.AñoPublicacion = 1992;
Libro2.NoPaginas = 334;
//genereamos el autor
//Cuando se realiza una instancia de una clase (mediante new) se reserva en la memoria un espacio
//para un conjunto de datos como el que definen los atributos de la clase que se indica en la instanciación.
//A este conjunto de variables se le denomina variables de instancia.
Autor Autorlibro = new Autor();
Autorlibro.Nombre = "José Saramago";
Autorlibro.FechaNacimiento = "22/07/1948";
Autorlibro.PaisOrigen = "Portugal";
//Los 2 libros los escribió el mismo autor de tal modo que la referencia es al mismo objeto autor.
//las variables AutorLibro de cada Libro apuntan ambas al mismo Autor que es la variable de instancia creada arriba con new.
Libro1.AutorLibro = Autorlibro;
Libro2.AutorLibro = Autorlibro;
//Ahora vamos a imprimir los libros con su respectivo autor para identificar que se trata del mismo.
Console.WriteLine("Impresión del libro 1:");
Console.WriteLine("Titulo: " + Libro1.Titulo);
Console.WriteLine("Año de Publicación: " + Libro1.AñoPublicacion);
//ahora exponemos los datos del autor que apuntan desde el objeto libro al objeto autor.
Console.WriteLine("Autor : " + Libro1.AutorLibro.Nombre);
Console.WriteLine("Fecha de Nacimiento : " + Libro1.AutorLibro.FechaNacimiento);
Console.WriteLine("Pais de Origen: : " + Libro1.AutorLibro.PaisOrigen);
Console.WriteLine("");
Console.WriteLine("Impresión del libro 2:");
Console.WriteLine("Titulo: " + Libro2.Titulo);
Console.WriteLine("Año de Publicación: " + Libro2.AñoPublicacion);
//ahora exponemos los datos del autor que apuntan desde el objeto libro al objeto autor.
Console.WriteLine("Autor : " + Libro2.AutorLibro.Nombre);
Console.WriteLine("Fecha de Nacimiento : " + Libro2.AutorLibro.FechaNacimiento);
Console.WriteLine("Pais de Origen: : " + Libro2.AutorLibro.PaisOrigen);
Console.WriteLine("");
Console.WriteLine("Enter para terminar");
Console.ReadLine();//espera un Enter para continuar.
}
}
La salida:
Y asi, si el mismo autor tiene 100 libros todos los objetos Libro tendrán una refencia al mimo objeto Autor. Y este mismo esquema aplica para muchos casos por ejemplo tenemos muchas Facturas expedidas al mismo Cliente, no tenderemos un objeto Cliente por cada objeto Factura, habrá muchas Facturas todas apuntando al mismo Cliente.
Caso ejemplo:
Tenemos una clase que nos permite almacenar libros, es así que un libro se compone de la siguiente información:
-Titulo
-Año de publicación
-No paginas
-Autor
-Fecha Nacimiento
-Pais de Origen
De tal modo que cuando necesitamos crear más de un objeto Libro para los cuales se trata del mismo autor se veria de la siguiente forma:
Asi que por ello es la referencia entre objetos, es decir; en el objeto Libro habrá un apuntador que referncia al objeto Autor:
En el Diagrama de Clases lo podemos ver en la navegación, en donde la clase Libro tiene un apuntador a la case Autor:
Y en la implemantación en C# como una aplicación de consola:
using System;
class Libro
{
public string Titulo;
public Int16 AñoPublicacion;
public Int16 NoPaginas;
public Autor AutorLibro; //esta es la variable para hacer la refencia la objeto Autor
}
using System;
class Autor
{
public string Nombre;
public string FechaNacimiento;
public string PaisOrigen;
}
Y el programa cliente que hace uso de las clases y las relaciona através de referencias entre objetos:
using System;
class Program
{
static void Main(string[] args)
{
//creamos 2 libros que tienen mismo autor
Libro Libro1 = new Libro();
Libro1.Titulo = "Ensayo de la ceguera";
Libro1.AñoPublicacion = 1998;
Libro1.NoPaginas = 234;
Libro Libro2 = new Libro();
Libro2.Titulo = "El Evangelio Segun Jesucristo";
Libro2.AñoPublicacion = 1992;
Libro2.NoPaginas = 334;
//genereamos el autor
//Cuando se realiza una instancia de una clase (mediante new) se reserva en la memoria un espacio
//para un conjunto de datos como el que definen los atributos de la clase que se indica en la instanciación.
//A este conjunto de variables se le denomina variables de instancia.
Autor Autorlibro = new Autor();
Autorlibro.Nombre = "José Saramago";
Autorlibro.FechaNacimiento = "22/07/1948";
Autorlibro.PaisOrigen = "Portugal";
//Los 2 libros los escribió el mismo autor de tal modo que la referencia es al mismo objeto autor.
//las variables AutorLibro de cada Libro apuntan ambas al mismo Autor que es la variable de instancia creada arriba con new.
Libro1.AutorLibro = Autorlibro;
Libro2.AutorLibro = Autorlibro;
//Ahora vamos a imprimir los libros con su respectivo autor para identificar que se trata del mismo.
Console.WriteLine("Impresión del libro 1:");
Console.WriteLine("Titulo: " + Libro1.Titulo);
Console.WriteLine("Año de Publicación: " + Libro1.AñoPublicacion);
//ahora exponemos los datos del autor que apuntan desde el objeto libro al objeto autor.
Console.WriteLine("Autor : " + Libro1.AutorLibro.Nombre);
Console.WriteLine("Fecha de Nacimiento : " + Libro1.AutorLibro.FechaNacimiento);
Console.WriteLine("Pais de Origen: : " + Libro1.AutorLibro.PaisOrigen);
Console.WriteLine("");
Console.WriteLine("Impresión del libro 2:");
Console.WriteLine("Titulo: " + Libro2.Titulo);
Console.WriteLine("Año de Publicación: " + Libro2.AñoPublicacion);
//ahora exponemos los datos del autor que apuntan desde el objeto libro al objeto autor.
Console.WriteLine("Autor : " + Libro2.AutorLibro.Nombre);
Console.WriteLine("Fecha de Nacimiento : " + Libro2.AutorLibro.FechaNacimiento);
Console.WriteLine("Pais de Origen: : " + Libro2.AutorLibro.PaisOrigen);
Console.WriteLine("");
Console.WriteLine("Enter para terminar");
Console.ReadLine();//espera un Enter para continuar.
}
}
La salida:
Y asi, si el mismo autor tiene 100 libros todos los objetos Libro tendrán una refencia al mimo objeto Autor. Y este mismo esquema aplica para muchos casos por ejemplo tenemos muchas Facturas expedidas al mismo Cliente, no tenderemos un objeto Cliente por cada objeto Factura, habrá muchas Facturas todas apuntando al mismo Cliente.
enero 04, 2011
Cursores FAST-FORWARD en SQL Server
If you have no choice but to use a server-side cursor in your application, try to use a FORWARD-ONLY or FAST-FORWARD, READ-ONLY cursor. When working with unidirectional, read-only data, use the FAST_FORWARD option instead of the FORWARD_ONLY option, as it has some internal performance optimizations to speed performance. This type of cursor produces the least amount of overhead on SQL Server.
http://www.sql-server-performance.com/tips/cursors_p1.aspx
EJEMPLO de uso:
--Declaramos las variables
Declare @cod as int
Declare CURSOR1 cursor FAST_FORWARD for
select Valor from tabla1
Open CURSOR1
-- Avanzamos un registro y cargamos en las variables los valores encontrados en el primer registro
fetch next from CURSOR1
into @cod
while @@fetch_status = 0
Begin
--intruccion: la necesidad de implementar el cursor.
print convert(varchar(10), @cod)
-- Avanzamos otro registro
fetch next from CURSOR1
into @cod
End
-- cerramos el cursor
close CURSOR1
deallocate CURSOR1
http://www.sql-server-performance.com/tips/cursors_p1.aspx
EJEMPLO de uso:
--Declaramos las variables
Declare @cod as int
Declare CURSOR1 cursor FAST_FORWARD for
select Valor from tabla1
Open CURSOR1
-- Avanzamos un registro y cargamos en las variables los valores encontrados en el primer registro
fetch next from CURSOR1
into @cod
while @@fetch_status = 0
Begin
--intruccion: la necesidad de implementar el cursor.
print convert(varchar(10), @cod)
-- Avanzamos otro registro
fetch next from CURSOR1
into @cod
End
-- cerramos el cursor
close CURSOR1
deallocate CURSOR1
Store Procedure con lecturas sucias
Ventajas: no hay bloqueos.
Desventajas: los select no obtienen valores al 100% vs lo que inserta, actualiza o elimina la concurrencia.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE dbo.spuX
AS
BEGIN
SET NOCOUNT ON;
--especiifcacion de nivel de aislamiento (equivalente a usar NoLock
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT 1
END
GO
Desventajas: los select no obtienen valores al 100% vs lo que inserta, actualiza o elimina la concurrencia.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE dbo.spuX
AS
BEGIN
SET NOCOUNT ON;
--especiifcacion de nivel de aislamiento (equivalente a usar NoLock
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT 1
END
GO
¿Cuando usar Cursores?
Los cursores son buenos cuando estamos hablando de menos de 300 registros, las tablas temporales seria la mejor opción, pero si sabemos que la tabal temporal podria tener unos 1000 registros mejor utilecemos una variable de tipo table en lugar de la tabla temporal que se crea en el disco en la bd de Tempdb.
Los cursores reservan recursos en el servidor, como por ejemplo locks, packages,
procesos, almacenamiento temporal, etc. Por ejemplo, Microsoft SQL Server implementa los cursores creando una tabla temporal y rellenándola con los datos de la consulta.
Si un cursor no se cierra de manera correcta, el recurso no será liberado hasta que la sesión SQL (conexión) sea cerrada. Este desperdicio de recursos en el servidor puede llevar no sólo a una degradación del rendimiento, sino también a fallos más graves.
Los cursores reservan recursos en el servidor, como por ejemplo locks, packages,
procesos, almacenamiento temporal, etc. Por ejemplo, Microsoft SQL Server implementa los cursores creando una tabla temporal y rellenándola con los datos de la consulta.
Si un cursor no se cierra de manera correcta, el recurso no será liberado hasta que la sesión SQL (conexión) sea cerrada. Este desperdicio de recursos en el servidor puede llevar no sólo a una degradación del rendimiento, sino también a fallos más graves.
Variables Tabla (CursorLess) SQL Server
Un ejemplo de utilizar variables tabla en SQL Server
http://www.eggheadcafe.com/articles/20010823.asp
Algunas ventajas: son que todo se trabaja en memoria no hay I/O como es el caso de tablas temporal.
USE NORTHWIND
--1. Declaracion de la variable tabla
declare @SpecialCustomers TABLE (
CustomerID nchar (5) NOT NULL ,
OrderID int NOT NULL ,
ShipVia int NOT NULL,
Freight money NOT NULL)
--2. poblamos la variable tabla con la informacion de la tabla Orders
insert into @SPecialCustomers select CustomerID, OrderID, ShipVia, Freight
from dbo.Orders where ShipVia =1 AND Freight >50.25
--3. Actualizamos datos con el uso de la informacion en la variable tabla
UPDATE ORDERS SET ShipVia=4, Freight =21.00
where ORDERS.OrderID IN (SELECT ORDERID FROM @SpecialCustomers)es o cursores.
http://www.eggheadcafe.com/articles/20010823.asp
Algunas ventajas: son que todo se trabaja en memoria no hay I/O como es el caso de tablas temporal.
USE NORTHWIND
--1. Declaracion de la variable tabla
declare @SpecialCustomers TABLE (
CustomerID nchar (5) NOT NULL ,
OrderID int NOT NULL ,
ShipVia int NOT NULL,
Freight money NOT NULL)
--2. poblamos la variable tabla con la informacion de la tabla Orders
insert into @SPecialCustomers select CustomerID, OrderID, ShipVia, Freight
from dbo.Orders where ShipVia =1 AND Freight >50.25
--3. Actualizamos datos con el uso de la informacion en la variable tabla
UPDATE ORDERS SET ShipVia=4, Freight =21.00
where ORDERS.OrderID IN (SELECT ORDERID FROM @SpecialCustomers)es o cursores.
Suscribirse a:
Entradas (Atom)