Programación de SQL Server: actualice todas las fechas en un número determinado de días
-
21-08-2019 - |
Pregunta
Tengo una base de datos de demostración con un par de cientos de tablas.Cada tabla suele tener al menos un campo llamado tstamp, que es un tipo de datos de fecha y hora pequeña.Algunas tablas también tienen otros campos de fecha.Muchas mesas también tienen 1 o más activadores.
Escribí un script (de la manera más difícil, ver más abajo) para incrementar los campos de fecha en cada tabla en una cantidad determinada de días.La idea es hacer que los datos parezcan más "actuales" actualizando todas las fechas con la misma cantidad de días.
Estoy seguro de que hay una manera más fácil de hacer esto al recorrer una tabla del sistema para identificar cada tabla de usuario en la base de datos, deshabilitar todos los activadores, modificar cada campo pequeño de fecha y hora agregando la cantidad de días y volver a habilitar los activadores. y pasar a la siguiente mesa.Simplemente no tengo idea de cómo escribir ese tipo de T-SQL.
¿Ningún arrendatario?
Gracias.José
Guión de muestra:
DECLARE @numDaysToAdd int
SET @numDaysToAdd = 100
ALTER TABLE someTableDISABLE TRIGGER someTrigger
UPDATE someTable
SET tstamp = DATEADD(day, @numDaysToAdd, tstamp)
-- update any other smalldatetime field in the table too.
ALTER TABLE someTable ENABLE TRIGGER someTrigger
-- same pattern for 200 more tables!
==================================================== ========================================= omitiendo el problema del activador, aquí hay un script que obras:
DECLARAR @numDaysToAdd int
ESTABLECER @numDaysToAdd = 1
SI @numDaysToAdd > 0
COMENZAR
DECLARAR @tablename varchar(100)
DECLARAR @currtable varchar(100)
DECLARAR @currcolumn varchar(100)
DECLARAR @columnname varchar(100)
DECLARAR @strSQL nvarchar(4000)
DECLARAR tnames_cursor CURSOR
PARA
SELECCIONE t.TABLE_NAME, c.COLUMN_NAME
FROM INFORMACIÓN_SCHEMA.COLUMNS c unirse INFORMACIÓN_SCHEMA.TABLES t ON t.TABLE_NAME = c.TABLE_NAME
DONDE (c.DATA_TYPE = 'smalldatetime' OR c.DATA_TYPE = 'datetime') AND t.TABLE_TYPE<>'VIEW'
ORDENAR POR t.TABLE_NAME, c.COLUMN_NAME DESC
ABRIR tnames_cursor
BUSCAR SIGUIENTE DESDE tnames_cursor EN @tablename, @columnname
SET @currcolumn = @columnname
SET @currtable = @nombretabla
SET @strSQL = N'UPDATE ' + @tablename + CHAR(13)+CHAR(10) + 'SET ' + @columnname + ' = DATEADD(día, ' + CONVERT(varchar(10),@numDaysToAdd) + ', ' + @nombredecolumna + ')'
MIENTRAS (@@FETCH_STATUS = 0)
COMENZAR
SI (@currtable = @tablename)
BEGIN
IF @currcolumn <> @columnname
SET @strSQL = @strSQL + N',' + CHAR(13)+CHAR(10) + @columnname + ' = DATEADD(day, ' + CONVERT(varchar(10),@numDaysToAdd) + ', ' + @columnname + ')'
END
DEMÁS
BEGIN
SET @currtable = @tablename
SET @currcolumn = @columnname
EXEC sp_executesql @strSQL
SET @strSQL = N'UPDATE ' + @tablename + CHAR(13)+CHAR(10) + 'SET ' + @columnname + ' = DATEADD(day, ' + CONVERT(varchar(10),@numDaysToAdd) + ', ' + @columnname + ')'
END
BUSCAR SIGUIENTE DESDE tnames_cursor EN @tablename, @columnname
FIN
--cuente la declaración final exec sp_executesql @strsql
CERRAR tnames_cursor
DEASIGNAR tnames_cursor
FIN
Solución
Su comprensión es correcta.Parece que las piezas que te faltan son:
- cómo encontrar metadatos (qué tablas tienes, y qué columnas)
- Cómo construir el SQL para caminar sobre las mesas.
Para el punto 1, consulte las vistas del sistema. INFORMATION_SCHEMA.TABLES
y INFORMATION_SCHEMA.COLUMNS
:
-- add your own additional criteria
select t.TABLE_NAME, c.COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS c
join INFORMATION_SCHEMA.TABLES t ON t.TABLE_NAME = c.TABLE_NAME
WHERE c.DATA_TYPE = 'datetime'
° 2, puede crear una declaración SQL como una cadena, recorrer las tablas que le interesan y luego ejecutarla con sp_executesql
.
Otros consejos
Estoy de acuerdo. Otra opción es utilizar tablas del sistema para generar el SQL para todas las 200 mesas. A continuación, puede utilizar sp_execsql al ejecutivo. No cambiará la ejecución, pero te salvará de escribir, que siempre es importante:)
La siguiente consulta le daría la lista de tablas de usuario y sus columnas, que son del tipo 'SMALLDATETIME'.
SELECT sys.columns.name as tableName, sys.tables.name as columnName from sys.columns,sys.tables
where sys.columns.object_id=sys.tables.object_id and sys.columns.system_type_id=58 order by tableName
58 aquí se system_type_id para el tipo de datos - SMALLDATETIME. Puede verificarlo sys.types de la mesa.
Uso de un cursor puede ser usted puede iterar sobre el conjunto de resultados a obtener cada mesa y luego desactivar los disparadores en esa tabla. Compruebe esto para desactivar el gatillo / activar http://msdn.microsoft.com/en -us / biblioteca / ms189748.aspx
A continuación, seguir adelante y actualizar cada columna del conjunto de resultados correspondiente a cada tabla, seguido por permitiendo a los factores desencadenantes.
aplausos