programmazione SQL Server - aggiornare tutte le date da un determinato numero di giorni

StackOverflow https://stackoverflow.com/questions/1076359

  •  21-08-2019
  •  | 
  •  

Domanda

Ho un database demo con un paio di centinaia di tabelle in esso. Ogni tabella di solito ha almeno un campo denominato tstamp che è un tipo di dati smalldatetime. Alcune tabelle hanno altri datefields troppo. Molte tabelle hanno anche 1 o più trigger su di loro.

ho scritto uno script (nel modo più difficile - vedi sotto) per incrementare i campi della data in ogni tabella da un determinato numero di giorni. L'idea è quella di rendere i dati appaiono più "corrente" aggiornando tutte le date della stessa quantità di giorni.

Sono sicuro che ci sia un modo più semplice per fare questo ciclo su una tabella di sistema per identificare ogni tabella utente nel database, disattivare tutti i trigger su di esso, modificare ogni campo smalldatetime sommando il numero di giorni ad essa, ri- consentendo i trigger e lo spostamento al tavolo accanto. Solo che non ho idea di come scrivere come T-SQL.

Eventuali acquirenti?

Grazie. Joe

Script di esempio:

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!

=============================================== =========================================== Tralasciando la questione grilletto, ecco uno script che funziona:

DICHIARARE @numDaysToAdd int

SET @numDaysToAdd = 1

Se @numDaysToAdd> 0

BEGIN

DECLARE @tablename varchar (100)

DICHIARARE varchar @currtable (100)

DECLARE @currcolumn varchar (100)

DECLARE @columnname varchar (100)

DICHIARARE @strSQL nvarchar (4000)

DICHIARARE tnames_cursor CURSOR

per

SELEZIONARE t.TABLE_NAME, c.COLUMN_NAME

DA INFORMATION_SCHEMA.COLUMNS C Fai parte INFORMATION_SCHEMA.TABLES t ON t.TABLE_NAME = c.TABLE_NAME

WHERE (c.DATA_TYPE = 'smalldatetime' O c.DATA_TYPE = 'datetime') E t.TABLE_TYPE <> 'VIEW'

ORDER BY t.TABLE_NAME, c.COLUMN_NAME DESC

tnames_cursor Apri

FETCH AVANTI DA tnames_cursor IN @tablename, @columnname

SET @currcolumn = @columnname

SET @currtable = @tablename

SET @strSQL = N'UPDATE '+ @tablename + CHAR (13) + CHAR (10) + 'SET' + @columnname +' = DATEADD (giorno, '+ 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 AVANTI DA tnames_cursor IN @tablename, @columnname

FINE

- eseguire l'istruzione finale EXEC sp_executesql @strSQL

CLOSE tnames_cursor

DEALLOCATE tnames_cursor

FINE

È stato utile?

Soluzione

La vostra comprensione è corretta. Sembra che i pezzi che stai mancanti sono:

  1. Come trovare i metadati (quali le tabelle che hai, e quali colonne)
  2. come costruire lo SQL per camminare sopra le tabelle.

Per 1 #, vedere il punto di vista del sistema INFORMATION_SCHEMA.TABLES e 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'

Per 2 #, è possibile costruire un'istruzione SQL come una stringa, che cammina tra i tavoli a cui siete interessati, poi eseguirlo con sp_executesql.

Altri suggerimenti

Sono d'accordo. Un'altra opzione è quella di utilizzare le tabelle di sistema per generare l'SQL per tutti i 200 tavoli. È quindi possibile utilizzare sp_execsql a exec. Non cambierà l'esecuzione, ma farà risparmiare digitazione, che è sempre importante:)

La query seguente darebbe l'elenco delle tabelle utente e le loro colonne, che sono di 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

qui 58 è system_type_id per il tipo di dati - smalldatetime. È possibile verificare dalla tabella sys.types.

Utilizzando un cursore può essere possibile iterare il set di risultati per ottenere ogni tavolo e quindi disattivare trigger su quel tavolo. Controllare questo per innescare disabilitare / abilitare http://msdn.microsoft.com/en -us / library / ms189748.aspx

Poi andare avanti e aggiornare ogni colonna del set di risultati di pertinenza di ogni tavolo, seguita attivando il trigger.

applausi

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top