7/07/2023 10:17:00 p. m.
Share:
Blog Informático sobre Análisis y Desarrollo de Software.
MERGE <table_destino> [AS TARGET]
USING <table_origen> [AS SOURCE]
ON <condicion_compara_llaves>
[WHEN MATCHED THEN
<accion cuando coinciden> ]
[WHEN NOT MATCHED [BY TARGET] THEN
<accion cuando no coinciden por destino> ]
[WHEN NOT MATCHED BY SOURCE THEN
<accion cuando no coinciden por origen> ];
Analizando la instrucción, podemos desglosar su funcionamiento:
--Sincronizar la tabla TARGET con
--los datos actuales de la tabla SOURCE
MERGE Alumno AS TARGET
USING AlumnoActual AS SOURCE
ON (TARGET.Codigo = SOURCE.Codigo)
--Cuandos los registros concuerdan con por la llave
--se actualizan los registros si tienen alguna variación
WHEN MATCHED AND TARGET.Nombre <> SOURCE.Nombre
OR TARGET.Promedio <> SOURCE.Promedio THEN
UPDATE SET TARGET.Nombre = SOURCE.Nombre,
TARGET.Promedio = SOURCE.Promedio
--Cuando los registros no concuerdan por la llave
--indica que es un dato nuevo, se inserta el registro
--en la tabla TARGET proveniente de la tabla SOURCE
WHEN NOT MATCHED BY TARGET THEN
INSERT (Codigo, Nombre, Promedio)
VALUES (SOURCE.Codigo, SOURCE.Nombre, SOURCE.Promedio)
--Cuando el registro existe en TARGET y no existe en SOURCE
--se borra el registro en TARGET
WHEN NOT MATCHED BY SOURCE THEN
DELETE
--Seccion opcional e informativa
--$action indica el tipo de accion
--en OUTPUT retorna cualquiera de las 3 acciones
--'INSERT', 'UPDATE', or 'DELETE',
OUTPUT $action,
DELETED.Codigo AS TargetCodigo,
DELETED.Nombre AS TargetNombre,
DELETED.Promedio AS TargetPuntos,
INSERTED.Codigo AS SourceCodigo,
INSERTED.Nombre AS SourceNombre,
INSERTED.Promedio AS SourcePuntos;
SELECT @@ROWCOUNT;
GO
SELECT * FROM Alumno
SELECT * FROM AlumnoActual
CREATE LOGIN [LoginFinanciera] WITH PASSWORD = N'Protect2020' GO CREATE LOGIN [LoginFinanciera] WITH PASSWORD = N'Protect2020', DEFAULT_DATABASE=[FinancieraDemoBD] -- creación de login desde Windows CREATE LOGIN [LoginFinanciera] FROM WINDOWS WITH DEFAULT_DATABASE=[FinancieraDemoBD]Asignación de Roles a Login
-- Agregar rol dbcreator al login EXEC sp_addsrvrolemember 'LoginFinanciera', 'dbcreator'
USE FinancieraDemoBD GO CREATE USER [UsuarioBDFinanciera] FOR LOGIN [LoginFinanciera] GO -- conceder permisos al usuario para que realice Select sobre una tabla de la BD. GRANT SELECT ON dbo.CLIENTE TO UsuarioBDFinanciera GO
-- Eliminar Login y Usuario drop login LoginFinanciera drop user UsuarioBDFinanciera
-- CREACION DE LOGIN USE [master] GO IF NOT EXISTS (SELECT name FROM sys.server_principals WHERE name = N'LoginFinanciera') CREATE LOGIN [LoginFinanciera] WITH PASSWORD = N'Protect2020', DEFAULT_DATABASE=[FinancieraDemoBD] -- CREACION DE USUARIO DE BASE DE DATOS USE [FinancieraDemoBD] GO IF NOT EXISTS(SELECT name FROM sys.sysusers WHERE name = 'UsuarioBDFinanciera') CREATE USER [UsuarioBDFinanciera] FOR LOGIN [LoginFinanciera] GO
-- ASIGNACION DE PERMISOS EXEC sp_addrolemember N'db_datareader', N'UsuarioBDFinanciera' GO EXEC sp_addrolemember N'db_datawriter', N'UsuarioBDFinanciera' GO GRANT EXECUTE TO [UsuarioBDFinanciera] -- DAR PERMISOS AL USUARIO DE BASE DE DATOS SOBRE PROCEDIMIENTOS ALMACENADOS Y TABLAS USE [FinancieraDemoBD] GO GRANT EXECUTE ON [spListar_Clientes] TO [UsuarioBDFinanciera]; GRANT EXECUTE ON [spInsertar_Cliente] TO [UsuarioBDFinanciera]; GRANT EXECUTE ON [spListar_Proveedor] TO [UsuarioBDFinanciera]; GRANT EXECUTE ON [spInsertar_Proveedor] TO [UsuarioBDFinanciera]; GRANT SELECT,INSERT,UPDATE,DELETE ON [CLIENTE] TO [UsuarioBDFinanciera]; GRANT SELECT,INSERT,UPDATE,DELETE ON [PROVEEDOR] TO [UsuarioBDFinanciera]; GRANT SELECT,INSERT,UPDATE,DELETE ON "dbo"."COLABORADOR" TO "UsuarioBDFinanciera"; -- PERMISO ESPECIAL --> EVALUAR CONSIDERACIONES DE SEGURIDAD GRANT ALTER ON "dbo"."CLIENTE" TO "UsuarioBDFinanciera"; GO
-- *** Ver los Inicios de Sesión de la Instancia de SQL Server *** select sid, name, dbname, password, loginname from master..syslogins
-- Ver los inicios de Sesion select * from sys.server_principals
-- *** Ver los Usuarios de la Base de Datos actual de SQL Server *** use FinancieraDemoBD GO select uid, name, sid, * from sysusers where islogin=1
select * from sys.database_principals
USE FinancieraDemoBD GO -- sacaremos una copia de seguridad de la DMK BACKUP MASTER KEY TO FILE = 'D:\BACKUP\PERSONAL\DMK.dat' ENCRYPTION BY PASSWORD = 'TopSecret2020MK'; GO -- Sacaremos una copia de seguridad del certificado BACKUP CERTIFICATE FinancieraCertificado TO FILE = 'D:\BACKUP\PERSONAL\FinancieraCertificadoCS.cer' WITH PRIVATE KEY ( FILE = 'D:\BACKUP\PERSONAL\FinancieraCertificadoCS.key' , ENCRYPTION BY PASSWORD = 'TopSecret2020C' ); GOAhora borraremos la llave simetrica, el certificado y la master key
DROP SYMMETRIC KEY FINANCIERA_KEY_SYMMETRIC GO -- Ahora perderemos el certificado. DROP CERTIFICATE FinancieraCertificado GO -- Ahora perderemos la DMK DROP MASTER KEY GO
RESTORE MASTER KEY FROM FILE = 'D:\BACKUP\PERSONAL\DMK.dat' DECRYPTION BY PASSWORD = 'TopSecret2020MK' ENCRYPTION BY PASSWORD = 'TopSecret2020MKN' GO -- Ahora abrimos la DMK sino no podremos restaurar el certificado OPEN MASTER KEY DECRYPTION BY PASSWORD = 'TopSecret2020MKN' GO -- Ahora restauramos el certificado CREATE CERTIFICATE FinancieraCertificado FROM FILE = 'D:\BACKUP\PERSONAL\FinancieraCertificadoCS.cert' WITH PRIVATE KEY (FILE = 'D:\BACKUP\PERSONAL\FinancieraCertificadoCS.key', DECRYPTION BY PASSWORD = 'TopSecret2020C'); GO -- Ahora recreamos la llave simetrica CREATE SYMMETRIC KEY FINANCIERA_KEY_SYMMETRIC WITH KEY_SOURCE = 'ClaveSimetrica2020', IDENTITY_VALUE = 'MiValorIdentidad', ALGORITHM = AES_256 ENCRYPTION BY CERTIFICATE FinancieraCertificado GO
OPEN SYMMETRIC KEY FINANCIERA_KEY_SYMMETRIC DECRYPTION BY CERTIFICATE FinancieraCertificado; -- Ahora seleccionamos los datos pero antes los desencriptamos con la llave simetrica SELECT MATRICULACOLABORADOR, CONVERT(VARCHAR(100),DECRYPTBYKEY(NOMBRES)) AS NOMBRES, CONVERT(VARCHAR(100),DECRYPTBYKEY(APELLIDOS)) AS APELLIDOS FROM dbo.COLABORADOR /* MATRICULACOLABORADOR NOMBRES APELLIDOS CAR001 CESAR ANTONIO AVILA ROBLES */ -- Y ahora volvemos a cerrar la llave simetrica CLOSE SYMMETRIC KEY FINANCIERA_KEY_SYMMETRIC
IF (DATABASEPROPERTY('FinancieraDemoBD','version') > 0)
BEGIN
USE MASTER
ALTER DATABASE FinancieraDemoBD SET single_user WITH ROLLBACK IMMEDIATE
DROP DATABASE FinancieraDemoBD
END
-- Creamos la Base de Datos de prueba
use master
GO
create database FinancieraDemoBD
GO
-- Usamos la Base de Datos de Prueba
use FinancieraDemoBD
GO
-- Creamos una tabla cliente con las columnas Nombre y NombreCorto
-- de tipo varbinary para que contenga la informacion encriptada
CREATE TABLE [dbo].[CLIENTE](
[IDCLIENTE] [int] IDENTITY(1,1) NOT NULL,
[FECING] [datetime] NULL,
[USUING] [varchar](6) NULL,
[FECACT] [datetime] NULL,
[USUACT] [varchar](6) NULL,
[NOMBRE] [varbinary](max) NOT NULL,
[NOMBRECORTO] [varbinary](max) NULL,
PRIMARY KEY CLUSTERED
(
[IDCLIENTE] ASC
)
) ON [PRIMARY]
GO
-- Crear una Database Master Key
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'ClaveSecretaINFO2020'
GO
-- Crear el Certificado
CREATE CERTIFICATE FinancieraCertificado WITH SUBJECT='INFOTACTICAS Certificate',
EXPIRY_DATE = '20211231'
GO
-- Consultar los certificados creados en la base de datos
SELECT name, pvt_key_encryption_type_desc, subject, expiry_date
FROM sys.certificates
/*
name pvt_key_encryption_type_desc subject expiry_date
FinancieraCertificado ENCRYPTED_BY_MASTER_KEY INFOTACTICAS Certificate 2021-12-31 00:00:00.000
*/
-- Insertar un valor
INSERT INTO dbo.CLIENTE (FECING, USUING, NOMBRE, NOMBRECORTO)
VALUES (getdate(), 'IRE001', ENCRYPTBYCERT(CERT_ID('FinancieraCertificado'),'CARLOS FLORES RIOS'), ENCRYPTBYCERT(CERT_ID('FinancieraCertificado'),'CARLOS FLORES'))
GO
-- Select convencional
SELECT IDCLIENTE, NOMBRE, NOMBRECORTO, FECING
FROM dbo.CLIENTE
/*
IDCLIENTE NOMBRE NOMBRECORTO FECING
1 0xC118457BFAA... 0xEF308BFC78424F717... 2020-10-08 23:47:39.520
*/
-- Select desencriptando los datos con el certificado correcto
SELECT IDCLIENTE, CONVERT(VARCHAR(100), DECRYPTBYCERT(CERT_ID('FinancieraCertificado'),NOMBRE)) as 'NOMBRE',
CONVERT(VARCHAR(70), DECRYPTBYCERT(CERT_ID('FinancieraCertificado'),NOMBRECORTO)) as 'NOMBRECORTO',
FECING
FROM dbo.CLIENTE
/*
IDCLIENTE NOMBRE NOMBRECORTO FECING
1 CARLOS FLORES RIOS CARLOS FLORES 2020-10-08 23:47:39.520
*/
USE FinancieraDemoBD GO -- Sacar una copia de seguridad del certificado BACKUP CERTIFICATE FinancieraCertificado TO FILE = 'D:\BACKUPS\PERSONAL\FinancieraCertificado.cer' WITH PRIVATE KEY ( FILE = 'D:\BACKUPS\PERSONAL\FinancieraCertificado.key' , ENCRYPTION BY PASSWORD = 'TopSecretINFO2020' ); GOSe borrará el certificado para simular su pérdida en escenarios donde se hace un backup de la base de datos y se restaurá en otro servidor y dicho certificado no se guardó con el backup.
-- Eliminar el certificado.
DROP CERTIFICATE FinancieraCertificado
GO
-- Podemos confirmar que nuestro certificado no esta y no podemos desencriptar nuestra informacion
SELECT name, pvt_key_encryption_type_desc, subject, expiry_date
FROM sys.certificates
SELECT IDCLIENTE, CONVERT(VARCHAR(100), DECRYPTBYCERT(CERT_ID('FinancieraCertificado'),NOMBRE)) as 'NOMBRE',
CONVERT(VARCHAR(70), DECRYPTBYCERT(CERT_ID('FinancieraCertificado'),NOMBRECORTO)) as 'NOMBRECORTO',
FECING
FROM dbo.CLIENTE
/*
IDCLIENTE NOMBRE NOMBRECORTO FECING
1 NULL NULL 2020-10-08 23:47:39.520
*/
Probaremos a crear nuevamente el certificado a ver si todo funcionara nuevamente.
-- Creamos el certificado
CREATE CERTIFICATE FinancieraCertificado WITH SUBJECT='INFOTACTICAS Certificate',
EXPIRY_DATE = '20211231'
GO
-- Probamos desencriptar la informacion
SELECT IDCLIENTE, CONVERT(VARCHAR(100), DECRYPTBYCERT(CERT_ID('FinancieraCertificado'),NOMBRE)) as 'NOMBRE',
CONVERT(VARCHAR(70), DECRYPTBYCERT(CERT_ID('FinancieraCertificado'),NOMBRECORTO)) as 'NOMBRECORTO',
FECING
FROM dbo.CLIENTE
/*
IDCLIENTE NOMBRE NOMBRECORTO FECING
1 NULL NULL 2020-10-08 23:47:39.520
*/
Sin embargo, no funcionó debido a que el certificado que se usó no es el mismo que encripto la información, a pesar de que se creó el certificado con la misma instrucción.
Volveremos a eliminar el certificado y restaurarlo desde el backup.
-- Volvemos a eliminar el certificado
DROP CERTIFICATE FinancieraCertificado
GO
-- Ahora restauramos el certificado desde nuestra copia de seguridad
CREATE CERTIFICATE FinancieraCertificado
FROM FILE = 'D:\BACKUPS\PERSONAL\FinancieraCertificado.cer'
WITH PRIVATE KEY (FILE = 'D:\BACKUPS\PERSONAL\FinancieraCertificado.key',
DECRYPTION BY PASSWORD = 'TopSecretINFO2020');
GO
-- Finalmente volvemos a consultar la informacion
SELECT IDCLIENTE, CONVERT(VARCHAR(100), DECRYPTBYCERT(CERT_ID('FinancieraCertificado'),NOMBRE)) as 'NOMBRE',
CONVERT(VARCHAR(70), DECRYPTBYCERT(CERT_ID('FinancieraCertificado'),NOMBRECORTO)) as 'NOMBRECORTO',
FECING
FROM dbo.CLIENTE