SQL Server-Programmierung - Aktualisierte alle Daten von einer bestimmten Anzahl von Tagen
-
21-08-2019 - |
Frage
Ich habe eine Demo-Datenbank mit ein paar hundert Tabellen drin. Jeder Tisch hat in der Regel mindestens ein Feld mit dem Namen tstamp die ein smallDatenTyp ist. Einige Tabellen haben andere datefields auch. Viele Tabellen haben auch einen oder mehrere Trigger für sie.
Ich schrieb ein Skript (auf die harte Tour - siehe unten) von einer bestimmten Anzahl von Tagen der Datumsfelder in jeder Tabelle zu erhöhen. Die Idee ist, die Daten erscheinen „aktuelle“ durch die Aktualisierung aller Termine um den gleichen Betrag von Tagen zu machen.
Ich bin sicher, dass es ein einfacherer Weg, dies über eine Systemtabelle durch Schleifen zu tun, um jede Benutzer-Tabelle in der Datenbank zu identifizieren, deaktivieren Sie alle Trigger auf, verändert jedes Feld von small die Anzahl der Tage, um es dem Hinzufügen, Wieder- so dass die Auslöser und zum nächsten Tisch zu bewegen. Ich habe einfach keine Ahnung, wie solche T-SQL zu schreiben.
Jeder Abnehmer?
Danke. Joe
Beispielskript:
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!
=============================================== =========================================== Das Weglassen des Trigger-Problem, hier ist ein Skript, das funktioniert:
ERKLÄREN @numDaysToAdd int
SET @numDaysToAdd = 1
IF @numDaysToAdd> 0
BEGIN
DECLARE @tablename varchar (100)
ERKLÄREN @currtable varchar (100)
DECLARE @currcolumn varchar (100)
DECLARE @columnname varchar (100)
ERKLÄREN @strSQL nvarchar (4000)
ERKLÄREN tnames_cursor CURSOR
SELECT t.TABLE_NAME, c.COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS c verbinden INFORMATION_SCHEMA.TABLES t ON t.TABLE_NAME = c.TABLE_NAME
WHERE (c.DATA_TYPE = 'small' OR c.DATA_TYPE = 'Datetime') und t.TABLE_TYPE <> 'VIEW'
ORDER BY t.TABLE_NAME, c.COLUMN_NAME DESC
OPEN tnames_cursor
FETCH NEXT tnames_cursor INTO @tablename, @columnname
SET @currcolumn = @columnname
SET @currtable = @tablename
SET @strSQL = N'UPDATE '+ @tablename + CHAR (13) + CHAR (10) + 'SET' + @columnname +' = DATEADD (Tag, '+ 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 INTO @tablename, @columnname
END
- laufen die Endabrechnung EXEC Sp_executesql @strSQL
SCHLIEßEN tnames_cursor
AUFLöSEN tnames_cursor
END
Lösung
Ihr Verständnis ist richtig. Es klingt wie die Stücke Ihnen fehlt, sind:
- , wie Metadaten zu finden (was Tabellen bekam sie haben, und welche Spalten)
- , wie die SQL aufzubauen zu laufen über die Tische.
# 1 finden Sie in die Systemansichten INFORMATION_SCHEMA.TABLES
und 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 können Sie eine SQL-Anweisung als Zeichenfolge aufzubauen, zu Fuß durch die Tabellen, die Sie interessiert sind, dann führen Sie es mit sp_executesql
.
Andere Tipps
Ich bin damit einverstanden. Eine weitere Option ist die Systemtabellen zu verwenden, um die SQL für alle 200 Tabellen zu erzeugen. Sie können dann sp_execsql zu exec verwenden. Wird nicht die Ausführung ändern, sondern wird Sie mit der Eingabe sparen, was immer wichtig ist:)
Die folgende Abfrage würde Ihnen die Liste der Benutzertabellen und deren Spalten, die vom Typ sind ‚small‘.
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
hier 58 ist für den Datentyp system_type_id - small. Sie können es von sys.types Tabelle überprüfen.
einen Cursor zu verwenden sein können Sie einstellen, um das Ergebnis iterieren können jeden Tisch bekommen und dann deaktivieren Trigger für diese Tabelle. Aktivieren Sie diese Option für Trigger aktivieren / deaktivieren http://msdn.microsoft.com/en -US / library / ms189748.aspx
Dann voran gehen und jede Spalte in der Ergebnismenge aktualisieren, um jede Tabelle beziehen, gefolgt von dem Trigger ermöglicht wird.
cheers