programmation SQL Server - mettre à jour toutes les dates par un certain nombre de jours
-
21-08-2019 - |
Question
J'ai une base de données de démonstration avec quelques centaines de tables en elle. Chaque table a généralement au moins un champ nommé tstamp qui est un type de données smalldatetime. Certains tableaux ont d'autres datefields aussi. De nombreux tableaux ont également 1 ou plusieurs déclencheurs sur eux.
J'ai écrit un script (la dure - voir ci-dessous) pour augmenter les champs de date dans chaque tableau par un nombre donné de jours. L'idée est de rendre les données apparaissent plus « courant » en mettant à jour toutes les dates par le même nombre de jours.
Je suis sûr qu'il ya un moyen plus facile de le faire en boucle sur une table de système pour identifier chaque table d'utilisateur dans la base de données, désactivez tous les déclencheurs sur elle, modifier chaque champ smalldatetime en ajoutant le nombre de jours à elle, re permettant aux déclencheurs et de passer à la table suivante. Je n'ai pas la moindre idée d'écrire ce T-SQL.
Les preneurs?
Merci. Joe
Exemple de script:
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!
=============================================== =========================================== Omettre la question de déclenchement, voici un script qui fonctionne:
DECLARE @numDaysToAdd int
SET @numDaysToAdd = 1
IF @numDaysToAdd> 0
BEGIN
DECLARE @tablename varchar (100)
DECLARE @currtable varchar (100)
DECLARE @currcolumn varchar (100)
DECLARE @columnname varchar (100)
DECLARE @strSQL nvarchar (4000)
DECLARE tnames_cursor CURSEUR
SELECT t.TABLE_NAME, c.COLUMN_NAME
DE INFORMATION_SCHEMA.COLUMNS c rejoindre INFORMATION_SCHEMA.TABLES t = ON t.TABLE_NAME c.TABLE_NAME
Où (c.DATA_TYPE = 'smalldatetime' OU c.DATA_TYPE = 'datetime') ET t.TABLE_TYPE <> 'VIEW'
ORDER BY t.TABLE_NAME, c.COLUMN_NAME DESC
OUVERT tnames_cursor
FETCH NEXT tnames_cursor EN @tablename, @columnname
SET @currcolumn = @columnname
SET @currtable = @tablename
SET @strSQL = N'UPDATE '+ @tablename + CHAR (13) + CHAR (10) + 'SET' + @columnname +' = DATEADD (jour, '+ CONVERT (varchar (10), @ numDaysToAdd) + '' + @columnname + ')'
WHILE (@@ FETCH_STATUS = 0)
BEGIN
IF (@currtable = @tablename)
BEGIN
IF @currcolumn <> @columnname
SET @strSQL = @strSQL + N',' + CHAR(13)+CHAR(10) + @columnname + ' = DATEADD(day, ' + CONVERT(varchar(10),@numDaysToAdd) + ', ' + @columnname + ')'
END
ELSE
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
FETCH NEXT tnames_cursor EN @tablename, @columnname
FIN
- exécuter la déclaration finale EXEC sp_executesql @strSQL
A tnames_cursor
DEALLOCATE tnames_cursor
FIN
La solution
Votre interprétation est correcte. On dirait que les pièces qui vous manquent sont:
- Comment trouver des métadonnées (quelles tables vous avez, et quelles colonnes)
- comment construire le SQL pour marcher les tables.
Pour # 1, voir le point de vue du système et INFORMATION_SCHEMA.TABLES
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'
Pour # 2, vous pouvez construire une instruction SQL comme une chaîne, la marche à travers les tables qui vous intéressent, puis l'exécuter avec sp_executesql
.
Autres conseils
Je suis d'accord. Une autre option consiste à utiliser les tables système pour générer le code SQL pour les 200 tables. Vous pouvez ensuite utiliser sp_execsql à exec. Ne changera pas l'exécution, mais vous permettra d'économiser frappe, ce qui est toujours important:)
La requête suivante vous donnera la liste des tables utilisateur et leurs colonnes sont de type « 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
ici 58 est system_type_id pour le type de données - SmallDateTime. Vous pouvez le vérifier à partir du tableau sys.types.
L'utilisation d'un curseur peut être vous pouvez parcourir le jeu de résultats pour obtenir chaque table, puis désactiver les déclencheurs sur cette table. Vérifiez cela pour désactiver déclencheur / activer http://msdn.microsoft.com/en -nous / bibliothèque / ms189748.aspx
Alors allez-y et mettre à jour chaque colonne dans le jeu de résultats se rapportant à chaque table, puis en permettant aux déclencheurs.
hourras