Pop

Curso SQL SERVER - 7 Comando UPDATE y uso de Encriptación


7. Curso SQL SERVER -Comando UPDATE  y uso de Encriptación


  • Como acostumbro os dejo también  el esquema de la base de datos para que tengáis claro a que campo me refiero:
  • Os dejo el vídeo con la explicación del uso de comando UPDATE. Además os explico como encriptar una columna de una tabla, para el caso que no queramos que los valores se muestren por pantalla de una manera legible.

  • Como  acostumbro os dejo las  consultas de la parte de cifrado hechas durante este capítulo:
USE master; 
GO 
SELECT * FROM sys.symmetric_keys WHERE name = '##MS_ServiceMasterKey##'; 
GO 


 CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'ClaveCurso'; 
 CREATE CERTIFICATE Certificado WITH SUBJECT = 'Pruebas'; 
CREATE SYMMETRIC KEY MiClave   WITH ALGORITHM = AES_256   ENCRYPTION BY CERTIFICATE Certificado; 


--CONSULTAS UPDATE
OPEN SYMMETRIC KEY MiClave DECRYPTION BY CERTIFICATE Certificado; 

UPDATE USUARIOS SET Pass = EncryptByKey (Key_GUID('MiClave'),'PASS1') FROM dbo.USUARIOS WHERE idusuario=1; 
UPDATE USUARIOS SET Pass = EncryptByKey (Key_GUID('MiClave'),'PASS2') FROM dbo.USUARIOS WHERE idusuario=2; 
UPDATE USUARIOS SET Pass = EncryptByKey (Key_GUID('MiClave'),'PASS3') FROM dbo.USUARIOS WHERE idusuario=3; 
UPDATE USUARIOS SET Pass = EncryptByKey (Key_GUID('MiClave'),'PASS4') FROM dbo.USUARIOS WHERE idusuario=4; 
UPDATE USUARIOS SET Pass = EncryptByKey (Key_GUID('MiClave'),'PASS5') FROM dbo.USUARIOS WHERE idusuario=5; 

CLOSE SYMMETRIC KEY MiClave; 

-- Leer los datos 
OPEN SYMMETRIC KEY MiClave DECRYPTION BY CERTIFICATE Certificado; 
GO 

SELECT Nombre,Email ,Pass AS 'encriptado', CONVERT(varchar, DecryptByKey(Pass)) AS 'sin encriptar' FROM dbo.USUARIOS;    
-- Close the symmetric key 
CLOSE SYMMETRIC KEY MiClave; 


Curso SQL SERVER - 6 Añadiendo tabla a nuestro diseño para guardar sesiones


6. Curso SQL SERVER -Añadiendo tabla a nuestro diseño para guardar sesiones


  • Hola a todos , en esta ocasión vamos continuar  con nuestro curso sobre SQL SERVER. En este capítulo del curso vamos a resolver la pregunta que os deje en la anterior entrada del blog. La cuestión era la siguiente :¿Qué debemos modificar en nuestro diseño de base de datos para poder almacenar las sesiones de usuario?


  • Para poder almacenar las sesiones es necesario añadir un campo password a la tabla usuarios. Ya que se supone que para poder iniciar sesión el cliente a tenido que logar en nuestro sitio.Además debemos añadir una tabla de SESIONES que este relaccionada por el campo idusuario  con la tabla USUARIOS. En esta nueva tabla almacenaremos  que usuario inicio sesión en nuestro sitio y a que hora lo hizo, ademas de un token que idetificará de manera única cada sesión. Os dejo una imagen de como quedaría el diagrama de base de datos después de añadir esta tabla:




  • - En el vídeo podéis ver los pasos necesarios para agregar este nueva tabla a nuestro esquema. Además genero algunas sesiones ficticias para tener datos en nuestra tabla: 




  • Os dejo el script de creación de la tabla sesiones y una sentencia que añade un registro a la tabla para tener datos con los que hacer las futuras consultas:
--PARA CREAR LA TABLA

CREATE TABLE [dbo].[SESIONES](
[IdSesion] [int] IDENTITY(1,1) NOT NULL,
[IdUsuario] [int] NOT NULL,
[Token] [varchar](50) NOT NULL,
[FechaInicio] [datetime] NOT NULL,
[FechaFin] [datetime] NULL,
 CONSTRAINT [PK_SESIONES] PRIMARY KEY CLUSTERED 
(
[IdSesion] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[SESIONES]  WITH CHECK ADD  CONSTRAINT [FK_SESIONES_USUARIOS] FOREIGN KEY([IdUsuario])
REFERENCES [dbo].[USUARIOS] ([IdUsuario])
GO

ALTER TABLE [dbo].[SESIONES] CHECK CONSTRAINT [FK_SESIONES_USUARIOS]


--PARA HACER INSERT
INSERT INTO dbo.SESIONES(IdUsuario,Token,FechaInicio,FechaFin)
VALUES(1,NEWID(),GETDATE(),NULL)

Curso SQL SERVER - 5 Funciones de agregado (SUM,AVG,MIN,MAX...)


5. Curso SQL SERVER - 5 Funciones de agregado (SUM,AVG,MIN,MAX...)

 -  Hola a todos , en esta ocasión vamos continuar  con nuestro curso sobre SQL SERVER. En este capítulo del curso muestro en el vídeo algunas de las funciones de agregado.Estas funciones son de uso común cuando queremos obtener totales o valores calculados de algunas de las columnas que tenemos en nuestras tablas.

-Un función de agregado realiza un cálculo sobre un conjunto de valores y devuelve un solo valor. Las funciones de agregado se suelen usar con la cláusula GROUP BY de la instrucción SELECT. En la documentación de Microsoft podéis ver una información más completa:
En nuestro ejemplo utilizamos estas funciones  calculando valores sobre los datos de las tablas que vemos en este esquema:



  • Os dejo el vídeo donde podéis ver unos ejemplos del uso de estas funciones:




  • Como acostumbro os dejo las consultas vistas durante  este capítulo:


--TOTAL USUARIOS GUARDADOS
SELECT count(*) FROM USUARIOS

--USO DE LA FUNCION AVG
SELECT USUARIOS.IdUsuario, AVG(Cantidad*Precio)   FROM USUARIOS
INNER JOIN  PEDIDOS ON PEDIDOS.IdUsuario = USUARIOS.IdUsuario
INNER JOIN  PEDIDOS_LINEAS ON PEDIDOS.IdPedido = PEDIDOS_LINEAS.IdPedido
INNER JOIN PRODUCTOS ON PEDIDOS_LINEAS.IdProducto = PRODUCTOS.IdProducto
group by USUARIOS.IdUsuario

--MENOR PRECIO DE UN PRODUCTO
SELECT MIN(PRECIO) FROM PRODUCTOS

--MAYOr PRECIO DE UN PRODUCTO
SELECT MAX(PRECIO) FROM PRODUCTOS

  • Para el siguiente capítulo os planteo la siguiente pregunta. Supongamos que queremos almacenar las sesiones de usuario en nuestra pagina web. ¿Qué tendríamos que añadir en nuestro diseño de BBDD para que esto sea posible?

Curso SQL SERVER - 4 Tipos de datos y consultas con claúsulas group by y Having


4. Curso SQL SERVER -  Tipos de datos y consultas con claúsulas group by y Having 

 -  Hola a todos , en esta ocasión vamos continuar  con nuestro curso sobre SQL SERVER. En este capítulo del curso muestro en el vídeo los diferentes tipos de datos que tenemos disponibles y además practicamos  con algunas querys de SQL añadiendo a nuestras consultas las claúsulas group by y having.


  • En la segunda parte del vídeo practicamos haciendo algunas consultas.La idea es realizar querys agregando cada vez más clausulas y condicionantes.En esta ocasión practicamos con las claúsulas WHERE,HAVING y GRUOP BY  en las tablas que tenemos definidas tal cual vemos en el esquema:

  • En el vídeo que añado con cada capítulo os hablo sobre los tipos de datos y os muestro como hacer las consultas:





  • Os dejo las consultas hechas durante el vídeo:

-- Consulta que nos devuelva todos los pedidos y los usuario que los hicieron

SELECT USUARIOS.IdUsuario,nombre,FechaPedido FROM PEDIDOS
INNER JOIN  USUARIOS ON PEDIDOS.IdUsuario = USUARIOS.IdUsuario

-- Consulta que nos devuelva todos los pedidos de los usuarios 1 y 2 ordenados por fecha

SELECT USUARIOS.IdUsuario,nombre,FechaPedido FROM PEDIDOS
INNER JOIN  USUARIOS ON PEDIDOS.IdUsuario = USUARIOS.IdUsuario
where
--USUARIOS.IdUsuario=1 or USUARIOS.IdUsuario=2
--USUARIOS.Email ='email1@mail.com' or USUARIOS.Email ='email2@mail.com'
--USUARIOS.Email like '%email4%'
order by FechaPedido desc


-- Consulta que nos devuelva el total de ventas de todos los productos menos el  1 y que su suma total sea mayor que 100

SELECT PRODUCTOS.idproducto, SUM(precio*cantidad) as total  FROM PRODUCTOS
INNER JOIN dbo.PEDIDOS_LINEAS ON PRODUCTOS.IdProducto = PEDIDOS_LINEAS.IdProducto
where PRODUCTOS.IdProducto<>1
group by Productos.IdProducto
having SUM(precio*cantidad)>100

Curso SQL SERVER - 3 Sentencia select e Insert Into


3. Curso SQL SERVER -  Sentencia select e Insert Into

 -  Hola a todos , en esta ocasión vamos continuar  con nuestro curso sobre SQL SERVER. En este capítulo del curso vamos a ver la sentencia SELECT y  la sentencia  INSERT INTO.  El entorno sobre el que vamos a trabajar es un Sql server express.

- Os dejo el esquema de tablas sobre el que trabajamos, que siempre es bueno tenerlo presente:




  • La sentencia SELECT   se utiliza principalmente para recuperar datos de una o varias tablas. También se suele utilizar con encabezados que requieren cálculos o para crear tablas mediante la sentencia SELECT INTO. En la siguiente entrada del blog profundizaremos más en la sentencia SELECT.  De momento en el vídeo, os muestro como insertar datos en una tabla ya existente mediante una sentencia INSERT INTO [TABLA]  SELECT:

  • Os dejo los enlaces  a la documentación oficial de SQL de Microsoft  sobre estas dos sentencias:

https://docs.microsoft.com/es-es/sql/t-sql/queries/select-examples-transact-sql?view=sql-server-2017

https://docs.microsoft.com/es-es/sql/t-sql/statements/insert-transact-sql?view=sql-server-2017


  • También os dejo la consulta que hemos creado paso a paso en el vídeo:

INSERT INTO dbo.FACTURAS
SELECT PEDIDOS.IdPedido ,SUM(Cantidad*Precio),GETDATE() 
FROM PEDIDOS
INNER JOIN PEDIDOS_LINEAS ON PEDIDOS.IdPedido = PEDIDOS_LINEAS.IdPedido
INNER JOIN PRODUCTOS ON PEDIDOS_LINEAS.IdProducto = PRODUCTOS.IdProducto
--WHERE PEDIDOS.idPedido =1
GROUP BY PEDIDOS.IdPedido

Curso SQL SERVER - 2 Sentencia Insert


2. Curso SQL SERVER - 2 Sentencia Insert

 -  Hola a todos , en esta ocasión vamos continuar  con nuestro curso sobre SQL SERVER. En este capítulo del curso vamos a ver la sentencia INSERT.  El entorno sobre el que vamos a trabajar es un Sql server express.

- Os recuerdo el esquema de tablas que estamos utilizando:




  • La sentencia INSERT se utiliza para agregar una o varias filas a una tabla o una vista en SQL Server. En el vídeo lo podéis ver claramente:



  • Toda la documentación sobre esta instrucción la tenemos en:
 https://docs.microsoft.com/es-es/sql/t-sql/statements/insert-transact-sql?view=sql-server-2017
  • Os dejo las sentencias que hemos visto en el vídeo para rellenar con datos las tablas que utilizaremos durante el curso.Os dejo las sentencias necesarias para llenar con algunos datos la tabla productos:


INSERT INTO  dbo . PRODUCTOS ( CodigoProducto , Precio , FechaAlta ) VALUES('PROD1',10,GETDATE())
INSERT INTO  dbo . PRODUCTOS ( CodigoProducto , Precio , FechaAlta ) VALUES('PROD2',20,GETDATE())
INSERT INTO  dbo . PRODUCTOS ( CodigoProducto , Precio , FechaAlta ) VALUES('PROD3',30,GETDATE())
INSERT INTO  dbo . PRODUCTOS ( CodigoProducto , Precio , FechaAlta ) VALUES('PROD4',40,GETDATE())
INSERT INTO  dbo . PRODUCTOS ( CodigoProducto , Precio , FechaAlta ) VALUES('PROD5',50,GETDATE())
INSERT INTO  dbo . PRODUCTOS ( CodigoProducto , Precio , FechaAlta ) VALUES('PROD6',60,GETDATE())
INSERT INTO  dbo . PRODUCTOS ( CodigoProducto , Precio , FechaAlta ) VALUES('PROD7',70,GETDATE())
INSERT INTO  dbo . PRODUCTOS ( CodigoProducto , Precio , FechaAlta ) VALUES('PROD8',80,GETDATE())
INSERT INTO  dbo . PRODUCTOS ( CodigoProducto , Precio , FechaAlta ) VALUES('PROD9',90,GETDATE())
INSERT INTO  dbo . PRODUCTOS ( CodigoProducto , Precio , FechaAlta ) VALUES('PROD10',100,GETDATE())
INSERT INTO  dbo . PRODUCTOS ( CodigoProducto , Precio , FechaAlta ) VALUES('PROD11',110,GETDATE())
INSERT INTO  dbo . PRODUCTOS ( CodigoProducto , Precio , FechaAlta ) VALUES('PROD12',120,GETDATE())



  • Para llenar la tabla usuarios:


INSERT INTO  dbo . USUARIOS ( Nombre , Email , Moroso , FechaAlta , FechaBaja ) VALUES ('Usuario1','email1@mail.com',0,GETDATE(),NULL)
INSERT INTO  dbo . USUARIOS ( Nombre , Email , Moroso , FechaAlta , FechaBaja ) VALUES ('Usuario2','email2@mail.com',0,GETDATE(),NULL)
INSERT INTO  dbo . USUARIOS ( Nombre , Email , Moroso , FechaAlta , FechaBaja ) VALUES ('Usuario3','email3@mail.com',0,GETDATE(),NULL)
INSERT INTO  dbo . USUARIOS ( Nombre , Email , Moroso , FechaAlta , FechaBaja ) VALUES ('Usuario4','email4@mail.com',0,GETDATE(),NULL)
INSERT INTO  dbo . USUARIOS ( Nombre , Email , Moroso , FechaAlta , FechaBaja ) VALUES ('Usuario5','email5@mail.com',0,GETDATE(),NULL)


  • Para llenar la tabla PEDIDOS:


INSERT INTO [dbo].[PEDIDOS]([IdUsuario],[Anulado],[FechaPedido])VALUES (1,0,GETDATE())
INSERT INTO [dbo].[PEDIDOS]([IdUsuario],[Anulado],[FechaPedido])VALUES (2,0,GETDATE())
INSERT INTO [dbo].[PEDIDOS]([IdUsuario],[Anulado],[FechaPedido])VALUES (3,0,GETDATE())
INSERT INTO [dbo].[PEDIDOS]([IdUsuario],[Anulado],[FechaPedido])VALUES (4,0,GETDATE())
INSERT INTO [dbo].[PEDIDOS]([IdUsuario],[Anulado],[FechaPedido])VALUES (5,0,GETDATE())


  • Para llenar la tabla PEDIDOS_LINEAS:


INSERT INTO [dbo].[PEDIDOS_LINEAS]([IdPedido],[Cantidad],[IdProducto]) VALUES(4,1,7)
INSERT INTO [dbo].[PEDIDOS_LINEAS]([IdPedido],[Cantidad],[IdProducto]) VALUES(4,13,8)
INSERT INTO [dbo].[PEDIDOS_LINEAS]([IdPedido],[Cantidad],[IdProducto]) VALUES(4,4,9)

INSERT INTO [dbo].[PEDIDOS_LINEAS]([IdPedido],[Cantidad],[IdProducto]) VALUES(5,1,4)
INSERT INTO [dbo].[PEDIDOS_LINEAS]([IdPedido],[Cantidad],[IdProducto]) VALUES(5,4,2)
INSERT INTO [dbo].[PEDIDOS_LINEAS]([IdPedido],[Cantidad],[IdProducto]) VALUES(5,6,3)

INSERT INTO [dbo].[PEDIDOS_LINEAS]([IdPedido],[Cantidad],[IdProducto]) VALUES(4,1,4)
INSERT INTO [dbo].[PEDIDOS_LINEAS]([IdPedido],[Cantidad],[IdProducto]) VALUES(4,1,5)
INSERT INTO [dbo].[PEDIDOS_LINEAS]([IdPedido],[Cantidad],[IdProducto]) VALUES(4,1,5)

INSERT INTO [dbo].[PEDIDOS_LINEAS]([IdPedido],[Cantidad],[IdProducto]) VALUES(5,1,4)
INSERT INTO [dbo].[PEDIDOS_LINEAS]([IdPedido],[Cantidad],[IdProducto]) VALUES(5,1,5)
INSERT INTO [dbo].[PEDIDOS_LINEAS]([IdPedido],[Cantidad],[IdProducto]) VALUES(5,1,5)

INSERT INTO [dbo].[PEDIDOS_LINEAS]([IdPedido],[Cantidad],[IdProducto]) VALUES(2,1,4)
INSERT INTO [dbo].[PEDIDOS_LINEAS]([IdPedido],[Cantidad],[IdProducto]) VALUES(2,1,5)
INSERT INTO [dbo].[PEDIDOS_LINEAS]([IdPedido],[Cantidad],[IdProducto]) VALUES(3,1,5)

Curso SQL SERVER - 1 Definiendo nuestra base de datos


1. Curso SQL SERVER -  Definiendo nuestra base de datos 

 -  Hola a todos , en esta ocasión vamos comenzar un curso sobre SQL SERVER. En este capítulo del curso vamos a comenzar definiendo la base de datos sobre la que vamos a trabajar. El entorno sobre el que vamos a trabajar será un Sql server express.

- Para nuestros ejemplos utilizaremos esta diseño de tablas:
Para llegar a este diseño hemos supuesto que tenemos una tienda en la que vendemos productos a usuarios. Cada pedido puede tener 1 o n productos, puede tener factura o o no y debe estar asociado a un usuario. En el vídeo os lo cuento:


  • Os dejo también los scripts de creación de las tablas por si no queréis hacer el diseño siguiendo los pasos del video:

USE [PruebasCurso]
GO

/****** Object:  Table [dbo].[FACTURAS]    Script Date: 04/07/2018 20:27:59 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[FACTURAS](
[IdFactura] [int] IDENTITY(1,1) NOT NULL,
[IdPedido] [int] NOT NULL,
[TotalFactura] [float] NOT NULL,
[Fecha] [datetime] NOT NULL,
 CONSTRAINT [PK_FACTURAS] PRIMARY KEY CLUSTERED 
(
[IdFactura] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

/****** Object:  Table [dbo].[PEDIDOS]    Script Date: 04/07/2018 20:27:59 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[PEDIDOS](
[IdPedido] [int] IDENTITY(1,1) NOT NULL,
[IdUsuario] [int] NOT NULL,
[Anulado] [bit] NOT NULL,
[FechaPedido] [datetime] NOT NULL,
 CONSTRAINT [PK_PEDIDOS] PRIMARY KEY CLUSTERED 
(
[IdPedido] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

/****** Object:  Table [dbo].[PEDIDOS_LINEAS]    Script Date: 04/07/2018 20:27:59 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[PEDIDOS_LINEAS](
[IdPedidoLinea] [int] IDENTITY(1,1) NOT NULL,
[IdPedido] [int] NOT NULL,
[Cantidad] [int] NOT NULL,
[IdProducto] [int] NOT NULL,
 CONSTRAINT [PK_PEDIDOS_LINEAS] PRIMARY KEY CLUSTERED 
(
[IdPedidoLinea] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

/****** Object:  Table [dbo].[PRODUCTOS]    Script Date: 04/07/2018 20:27:59 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[PRODUCTOS](
[IdProducto] [int] IDENTITY(1,1) NOT NULL,
[CodigoProducto] [varchar](50) NOT NULL,
[Precio] [float] NOT NULL,
[FechaAlta] [datetime] NOT NULL,
 CONSTRAINT [PK_PRODUCTOS] PRIMARY KEY CLUSTERED 
(
[IdProducto] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

/****** Object:  Table [dbo].[USUARIOS]    Script Date: 04/07/2018 20:27:59 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[USUARIOS](
[IdUsuario] [int] IDENTITY(1,1) NOT NULL,
[Nombre] [varchar](250) NOT NULL,
[Email] [varchar](250) NOT NULL,
[Moroso] [bit] NOT NULL,
[FechaAlta] [datetime] NOT NULL,
[FechaBaja] [datetime] NULL,
 CONSTRAINT [PK_USUARIOS] PRIMARY KEY CLUSTERED 
(
[IdUsuario] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[FACTURAS]  WITH CHECK ADD  CONSTRAINT [FK_FACTURAS_PEDIDOS] FOREIGN KEY([IdPedido])
REFERENCES [dbo].[PEDIDOS] ([IdPedido])
GO

ALTER TABLE [dbo].[FACTURAS] CHECK CONSTRAINT [FK_FACTURAS_PEDIDOS]
GO

ALTER TABLE [dbo].[PEDIDOS]  WITH CHECK ADD  CONSTRAINT [FK_PEDIDOS_USUARIOS] FOREIGN KEY([IdUsuario])
REFERENCES [dbo].[USUARIOS] ([IdUsuario])
GO

ALTER TABLE [dbo].[PEDIDOS] CHECK CONSTRAINT [FK_PEDIDOS_USUARIOS]
GO

ALTER TABLE [dbo].[PEDIDOS_LINEAS]  WITH CHECK ADD  CONSTRAINT [FK_PEDIDOS_LINEAS_PEDIDOS_LINEAS] FOREIGN KEY([IdPedido])
REFERENCES [dbo].[PEDIDOS] ([IdPedido])
GO

ALTER TABLE [dbo].[PEDIDOS_LINEAS] CHECK CONSTRAINT [FK_PEDIDOS_LINEAS_PEDIDOS_LINEAS]
GO

ALTER TABLE [dbo].[PEDIDOS_LINEAS]  WITH CHECK ADD  CONSTRAINT [FK_PEDIDOS_LINEAS_PRODUCTOS] FOREIGN KEY([IdProducto])
REFERENCES [dbo].[PRODUCTOS] ([IdProducto])
GO

ALTER TABLE [dbo].[PEDIDOS_LINEAS] CHECK CONSTRAINT [FK_PEDIDOS_LINEAS_PRODUCTOS]
GO




Curso programación C# - 82. Inteligencia Artificial con C# (11)- Visual Studio 2017


81. Inteligencia Artificial (11). Tres en raya con Minimax

 -  En este capítulo del curso de programación en c# con visual studio 2017 vamos a continuar con nuestra serie de entradas relacionadas con un tema de moda: la inteligencia artificial. En la entrada anterior vimos como implementar la parte gráfica de este nuevo ejemplo.

- En esta entrada os muestro la implementación de la clase  TresEnRaya.cs  En esta clase tendremos una serie de métodos necesarios para dotar a nuestro agente de inteligencia artificial de una cierta lógica, así como métodos para comprobar si la partida a finalizado o si quedan posiciones en la matriz por ocupar.

- En el vídeo os cuento todo esto con más detalles:




  • Como acostumbro os dejo el código de la clase vista en el vídeo:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TresEnRaya
{
    class TresEnRaya
    {

        private int[,] matriz = new int[3, 3];
        private int ganador = -1;
     
        private int[] ultimoMovimientoMaquina = new int[3];

        public int[,] Matriz { get => matriz; set => matriz = value; }
        public int Ganador { get => ganador; set => ganador = value; }
        public int[] UltimoMovimientoMaquina { get => ultimoMovimientoMaquina; set => ultimoMovimientoMaquina = value; }

        //inicialmente todas las caillas de la matriz tendran -1
        public void inicializarPartida()
        {
            for (int i = 0; i < matriz.GetLength(0); i++)
                for (int j = 0; j < matriz.GetLength(1); j++)
                    matriz[i,j] = -1;
            Ganador = -1;
        }

        public void seleccionarPosicion(int x, int y)
        {
            if (x >= 0 && x < 3 && y >= 0 && y < 3 && matriz[x, y] == -1 && Ganador == -1)
            {
                matriz[x, y] = 0;
                Ganador = ganaPartida();
                mueveMaquina();
            }
        }

        //Miramos si alguan combinacion gana
        public int ganaPartida()
        {
            int aux = -1;

            //Diagonales
            if (matriz[0, 0] != -1 && matriz[0, 0] == matriz[1, 1] && matriz[0, 0] == matriz[2, 2])
                aux = matriz[0, 0];

            if (matriz[0, 2] != -1 && matriz[0, 2] == matriz[1, 1] && matriz[0, 2] == matriz[2, 0])
                aux = matriz[0, 2];

            //horizontal y vertical
            for (int i = 0; i < matriz.GetLength(0); i++)
            {
                if (matriz[i, 0] != -1 && matriz[i, 0] == matriz[i, 1] && matriz[i, 0] == matriz[i, 2])
                    aux = matriz[i, 0];

                if (matriz[0, i] != -1 && matriz[0, i] == matriz[1, i] && matriz[0, i] == matriz[2, i])
                    aux = matriz[0, i];
            }


            return aux;
        }

        public bool tableroLleno()
        {
            bool tableroCompleto = true;
            for (int i = 0; i < matriz.GetLength(0); i++)
                for (int j = 0; j < matriz.GetLength(1); j++)
                    if (matriz[i, j] == -1)
                        tableroCompleto = false;


            return tableroCompleto;
        }

        public bool finJuego()
        {
            bool fin = false;
            if (tableroLleno() || ganaPartida() != -1)
                fin = true;

            return fin;

        }

        public void mueveMaquina()
        {

            if (!finJuego())
            {
                int f = 0;
                int c = 0;
                int v = -99999999;
                int aux;

                for (int i = 0; i < matriz.GetLength(0); i++)
                    for (int j = 0; j < matriz.GetLength(1); j++)
                        if (matriz[i, j] == -1)
                        {
                            matriz[i, j] = 1;
                            aux = minimo();
                            if (aux > v)
                            {
                                v = aux;
                                f = i;
                                c = j;
                            }

                            matriz[i, j] = -1;
                        }
                matriz[f, c] = 1;
                ultimoMovimientoMaquina[0] = f;
                ultimoMovimientoMaquina[1] = c;
            }


        }


        private int maximo()
        {
            if (finJuego())
            {
                if (ganaPartida() != -1)
                    return -1;
                else
                    return 0;
            }

            int v = -99999999;
            int aux;
            for (int i = 0; i < matriz.GetLength(0); i++)
                for (int j = 0; j < matriz.GetLength(1); j++)
                    if (matriz[i, j] == -1)
                    {
                        matriz[i, j] = 1;
                        aux = minimo();
                        if (aux > v)
                            v = aux;

                        matriz[i, j] = -1;
                    }

            return v;
        }

        private int minimo()
        {
            if (finJuego())
            {
                if (ganaPartida() != -1)
                    return 1;
                else
                    return 0;
            }

            int v = 99999999;
            int aux;
            for (int i = 0; i < matriz.GetLength(0); i++)
                for (int j = 0; j < matriz.GetLength(1); j++)
                    if (matriz[i, j] == -1)
                    {
                        matriz[i, j] = 0;
                        aux = maximo();
                        if (aux < v)
                            v = aux;

                        matriz[i, j] = -1;
                    }

            return v;
        }
    }
}


  • Como el ejemplo está finalizado os dejo el código del proyecto al completo en este  enlace:

Curso programación C# - 81. Inteligencia Artificial con C# (10)- Visual Studio 2017


81. Inteligencia Artificial (10). Tres en raya con Minimax

 -  En este capítulo del curso de programación en c# con visual studio 2017 vamos a continuar con nuestra serie de entradas relacionadas con un tema de moda: la inteligencia artificial. En la entrada anterior vimos la lógica del algortimo minimax necesaria para aplicarla al juego del tres en raya.

- En esta entrada os muestro el inicio de la implementación de nuestro ejemplo. Para hacer este desarrollo hemos creado una aplicación windows forms. El tablero donde calcularemos los movimientos es una matriz, igual que en el ejemplo del ajedrez, aunque bastante más pequeña. Sera una matriz de este  tipo: private int[,] matriz = new int[2, 2] .

- Este ejemplo consta de dos clases principales. Una de las clases es la que muestra la representación del juego en pantalla y la otra clase es la que calcula el mejor movimiento de nuestra IA. En el vídeo os lo cuento con más detalles.


- Para finalizar os dejo el código de la clase Forms vista en el vídeo. En la siguiente entrada del blog finalizaremos el ejemplo y os dejare código de la clase que falta y un enlace para descargar el proyecto al completo.

  • Form1.Designer.cs:
namespace TresEnRaya
{
    partial class Form1
    {
        /// <summary>
        /// Variable del diseñador necesaria.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Limpiar los recursos que se estén usando.
        /// </summary>
        /// <param name="disposing">true si los recursos administrados se deben desechar; false en caso contrario.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Código generado por el Diseñador de Windows Forms

        /// <summary>
        /// Método necesario para admitir el Diseñador. No se puede modificar
        /// el contenido de este método con el editor de código.
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.button3 = new System.Windows.Forms.Button();
            this.button4 = new System.Windows.Forms.Button();
            this.button5 = new System.Windows.Forms.Button();
            this.button6 = new System.Windows.Forms.Button();
            this.button7 = new System.Windows.Forms.Button();
            this.button8 = new System.Windows.Forms.Button();
            this.button9 = new System.Windows.Forms.Button();
            this.button10 = new System.Windows.Forms.Button();
            this.label1 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button1.Location = new System.Drawing.Point(12, 12);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(106, 104);
            this.button1.TabIndex = 0;
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // button2
            // 
            this.button2.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button2.Location = new System.Drawing.Point(155, 12);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(106, 104);
            this.button2.TabIndex = 1;
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // 
            // button3
            // 
            this.button3.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button3.Location = new System.Drawing.Point(302, 12);
            this.button3.Name = "button3";
            this.button3.Size = new System.Drawing.Size(106, 104);
            this.button3.TabIndex = 2;
            this.button3.UseVisualStyleBackColor = true;
            this.button3.Click += new System.EventHandler(this.button3_Click);
            // 
            // button4
            // 
            this.button4.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button4.Location = new System.Drawing.Point(302, 152);
            this.button4.Name = "button4";
            this.button4.Size = new System.Drawing.Size(106, 104);
            this.button4.TabIndex = 3;
            this.button4.UseVisualStyleBackColor = true;
            this.button4.Click += new System.EventHandler(this.button4_Click);
            // 
            // button5
            // 
            this.button5.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button5.Location = new System.Drawing.Point(155, 152);
            this.button5.Name = "button5";
            this.button5.Size = new System.Drawing.Size(106, 104);
            this.button5.TabIndex = 4;
            this.button5.UseVisualStyleBackColor = true;
            this.button5.Click += new System.EventHandler(this.button5_Click);
            // 
            // button6
            // 
            this.button6.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button6.Location = new System.Drawing.Point(12, 152);
            this.button6.Name = "button6";
            this.button6.Size = new System.Drawing.Size(106, 104);
            this.button6.TabIndex = 5;
            this.button6.UseVisualStyleBackColor = true;
            this.button6.Click += new System.EventHandler(this.button6_Click);
            // 
            // button7
            // 
            this.button7.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button7.Location = new System.Drawing.Point(302, 290);
            this.button7.Name = "button7";
            this.button7.Size = new System.Drawing.Size(106, 104);
            this.button7.TabIndex = 6;
            this.button7.UseVisualStyleBackColor = true;
            this.button7.Click += new System.EventHandler(this.button7_Click);
            // 
            // button8
            // 
            this.button8.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button8.Location = new System.Drawing.Point(155, 290);
            this.button8.Name = "button8";
            this.button8.Size = new System.Drawing.Size(106, 104);
            this.button8.TabIndex = 7;
            this.button8.UseVisualStyleBackColor = true;
            this.button8.Click += new System.EventHandler(this.button8_Click);
            // 
            // button9
            // 
            this.button9.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.button9.Location = new System.Drawing.Point(12, 290);
            this.button9.Name = "button9";
            this.button9.Size = new System.Drawing.Size(106, 104);
            this.button9.TabIndex = 8;
            this.button9.UseVisualStyleBackColor = true;
            this.button9.Click += new System.EventHandler(this.button9_Click);
            // 
            // button10
            // 
            this.button10.Location = new System.Drawing.Point(127, 465);
            this.button10.Name = "button10";
            this.button10.Size = new System.Drawing.Size(197, 38);
            this.button10.TabIndex = 9;
            this.button10.Text = "Nueva Partida";
            this.button10.UseVisualStyleBackColor = true;
            this.button10.Click += new System.EventHandler(this.button10_Click);
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(449, 31);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(0, 13);
            this.label1.TabIndex = 10;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(602, 537);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.button10);
            this.Controls.Add(this.button9);
            this.Controls.Add(this.button8);
            this.Controls.Add(this.button7);
            this.Controls.Add(this.button6);
            this.Controls.Add(this.button5);
            this.Controls.Add(this.button4);
            this.Controls.Add(this.button3);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Name = "Form1";
            this.Text = "Tres en raya";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.Button button3;
        private System.Windows.Forms.Button button4;
        private System.Windows.Forms.Button button5;
        private System.Windows.Forms.Button button6;
        private System.Windows.Forms.Button button7;
        private System.Windows.Forms.Button button8;
        private System.Windows.Forms.Button button9;
        private System.Windows.Forms.Button button10;
        private System.Windows.Forms.Label label1;
    }
}


  • Forms.cs: 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TresEnRaya
{
    public partial class Form1 : Form
    {

        TresEnRaya tresEnRaya = new TresEnRaya();
        private int[,] matriz = new int[2, 2];
        private int ganador = -1;

        public Form1()
        {
            InitializeComponent();
            tresEnRaya.inicializarPartida();
            matriz = tresEnRaya.Matriz;

        }

        private void comprobarGanador()
        {
            int[] ultMov = tresEnRaya.UltimoMovimientoMaquina;

            if (ultMov[0] == 0 && ultMov[1] == 0)
                button1.Text = "0";
            if (ultMov[0] == 0 && ultMov[1] == 1)
                button2.Text = "0";
            if (ultMov[0] == 0 && ultMov[1] == 2)
                button3.Text = "0";

            if (ultMov[0] == 1 && ultMov[1] == 0)
                button6.Text = "0";
            if (ultMov[0] == 1 && ultMov[1] == 1)
                button5.Text = "0";
            if (ultMov[0] == 1 && ultMov[1] == 2)
                button4.Text = "0";


            if (ultMov[0] == 2 && ultMov[1] == 0)
                button9.Text = "0";
            if (ultMov[0] == 2 && ultMov[1] == 1)
                button8.Text = "0";
            if (ultMov[0] == 2 && ultMov[1] == 2)
                button7.Text = "0";

            if (ganador == 0) MessageBox.Show("GANASTE");
             

            if (ganador == 1) MessageBox.Show("PERDISTE");
        

            if(ganador==-1 && tresEnRaya.tableroLleno())
                MessageBox.Show("EMPATE"); 


        }

        private void eventoBotones( int x, int y,Button boton)
        {
            if (matriz[x, y] == -1)
            {
                tresEnRaya.seleccionarPosicion(x,y);
                ganador = tresEnRaya.ganaPartida();
                comprobarGanador();
                boton.Text = "X";
               

            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            eventoBotones(0, 0, button1);
       }

        private void button2_Click(object sender, EventArgs e)
        {
            eventoBotones(0, 1, button2);
           
        }

        private void button3_Click(object sender, EventArgs e)
        {
            eventoBotones(0, 2, button3);
   
        }

        private void button6_Click(object sender, EventArgs e)
        {
            eventoBotones(1, 0, button6);
     
        }

        private void button5_Click(object sender, EventArgs e)
        {
            eventoBotones(1, 1, button5);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            eventoBotones(1,2, button4);
        }

        private void button9_Click(object sender, EventArgs e)
        {
            eventoBotones(2, 0, button9);
        }

        private void button8_Click(object sender, EventArgs e)
        {
            eventoBotones(2, 1, button8);
        }

        private void button7_Click(object sender, EventArgs e)
        {
        eventoBotones(2, 2, button7);
        }

        private void button10_Click(object sender, EventArgs e)
        {
            tresEnRaya = new TresEnRaya();
            tresEnRaya.inicializarPartida();
            matriz = tresEnRaya.Matriz;
            ganador = -1;

            label1.Text = button1.Text = button2.Text = button3.Text = button4.Text = button5.Text = button6.Text = button7.Text = button8.Text = button9.Text = String.Empty;
            
        }
    }

}

Curso programación C# - 80. Inteligencia Artificial con C# (9)- Visual Studio 2017


80. Inteligencia Artificial (9). Minimax aplicado al juego 3 en raya

 -  En este capítulo del curso de programación en c# con visual studio 2017 vamos a continuar con nuestra serie de entradas relacionadas con un tema de moda: la inteligencia artificial. En la entrada anterior vimos una introducción al algoritmo minimax.

- En esta entrada nos centraremos en explicar al detalle el funcionamiento de este algortimo. Como ya comentamos en la entrada anterior este  algoritmo se resume en cómo elegir el mejor movimiento suponiendo que tu oponente escogerá el peor para ti. Una vez supuesto esto recorremos todo el árbol de soluciones del juego a partir de un estado dado, es decir, según las casillas que ya han sido rellenadas. Minimax se ejecutará cada vez que le toque mover a la IA.

- Podemos implementar el algoritmo minimax en diferentes pasos y de diferentes maneras pero hay que tener  una idea clara de su funcionamiento.


  • Partimos de un estado inicial, que es el estado en que se encuentra el juego. Para el caso que nos ocupa puede ser por ejemplo:

  • Buscamos las posibles jugadas legales a partir del estado inicial.En el caso que nos ocupa todas las posibles jugadas son las siguientes:

  •  Asignamos un determinado valor para el caso de empate,victoria o derrota
  • Lo que  hará el algoritmo Minimax cuando vaya regresando hacia atrás, será comunicarle a la llamada recursiva superior cuál es el mejor nodo hoja alcanzado hasta el momento. 
  • Cada llamada recursiva tiene que saber a quién le toca jugar, para analizar si el movimiento realizado pertenece a la inteligencia artificial o al otro jugador, ya que cuando sea el turno de la IA nos interesa MAXIMIZAR el resultado, y cuando sea el turno del rival MINIMIZAR su resultado.
  • El algoritmo nos devolverá la jugada que debe realizar la máquina para maximizar sus posibilidades y bloquear las posibilidades del rival.

- En la siguiente entrada del blog veremos el código necesario para implementar esta lógica.De momento os dejo el vídeo con lo explicado en este capítulo:







Curso programación C# - 79. Inteligencia Artificial con C# (8)- Visual Studio 2017

79. Inteligencia Artificial (8).Algoritmo minimax

 -  En este capítulo del curso de programación en c# con visual studio 2017 vamos a continuar con nuestra serie de entradas relacionadas con un tema de moda: la inteligencia artificial. En la entradas anterior enseñamos a nuestro agente mecanismos para evitar el jaque de nuestro adversario.

- En esta ocasión finalizamos nuestro ajedrez validando en que situaciones finaliza el juego por producirse jaque mate . Además os dejo las nociones teóricas para la implementación del algoritmo minimax.

-  Minimax lo que hace informalmente es considerar todos los casos que se pueden dar desde donde estás y en base a esto,  elegir el movimiento que te lleve a un resultado mejor asumiendo que el contrario hará el movimiento que más te perjudique.El algoritmo Minimax es el algoritmo más conocido (y utilizado) para juegos de 2 adversarios, movimientos alternos (“ahora tú, ahora yo”). No se puede utilizar en juegos donde hay “azar”, sino perfectamente definido como las tres en raya y el ajedrez.  El problema de Minimax es que el árbol de estados que crea es muy grande para juegos como el ajedrez. Os dejo la imagen del posible  de movimientos de una posible jugada y el vídeo donde lo explico:



Explicación:




-Minimax es un algoritmo recursivo (https://es.wikipedia.org/wiki/Minimax). El funcionamiento de minimax puede resumirse como elegir el mejor movimiento para ti mismo suponiendo que tu contrincante escogerá el peor para ti.

-  Pasos del algoritmo minimax:

  • Generación del árbol de juego. Se generarán todos los nodos hasta llegar a un estado terminal.
  • Cálculo de los valores de la función de utilidad para cada nodo terminal. 
  • Calcular el valor de los nodos superiores a partir del valor de los inferiores. Según nivel si es MAX o MIN se elegirán los valores mínimos y máximos representando los movimientos del jugador y del oponente, de ahí el nombre de minimax. 
  • Elegir la jugada valorando los valores que han llegado al nivel superior. El algoritmo explorará los nodos del árbol asignándoles un valor numérico mediante una función de evaluación, empezando por los nodos terminales y subiendo hacia la raíz. La función de utilidad definirá lo buena que es la posición para un jugador cuando la alcanza. 
  • En el caso del ajedrez los posibles valores son (+1, 0 ,-1) que se corresponden con ganar, empatar y perder respectivamente. 

* Finalmente os dejo el código  del proyecto completo  en visual studio en este archivo rar:




Curso .NET Core en C# - 34.Creamos nuestro propio log

34.Creamos nuestro propio log Hola a todos. En este curso, analizaremos todos los conceptos básicos, intermedios y avanzados de  ASP.NET...