programação SQL Server - atualizar todas as datas por um determinado número de dias
-
21-08-2019 - |
Pergunta
Eu tenho um banco de dados de demonstração com um par de centenas de tabelas nele. Cada mesa tem geralmente pelo menos um campo chamado tstamp que é um tipo de dados smalldatetime. Algumas tabelas têm outras DateFields também. Muitas tabelas também têm 1 ou mais gatilhos sobre eles.
Eu escrevi um script (da maneira mais difícil - veja abaixo) para incrementar os campos de data em cada tabela por um determinado número de dias. A idéia é fazer com que os dados aparecem mais "atual", atualizando todas as datas pela mesma quantidade de dias.
Eu tenho certeza que há uma maneira mais fácil de fazer isso por looping sobre uma tabela de sistema para identificar cada tabela de usuários no banco de dados, desativar todos os gatilhos nele, modificar cada campo smalldatetime adicionando o número de dias para ele, re- permitindo que os gatilhos e passar para a próxima mesa. Eu só não têm qualquer idéia de como escrever tais T-SQL.
Algum comprador?
Graças. Joe
Exemplo 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!
=============================================== =========================================== Omitindo a questão gatilho, aqui é um script que funciona:
DECLARE @numDaysToAdd int
SET @numDaysToAdd = 1
Se @numDaysToAdd> 0
BEGIN
DECLARE @TableName varchar (100)
DECLARE varchar @currtable (100)
DECLARE @currcolumn varchar (100)
DECLARE @columnname varchar (100)
nvarchar DECLARE @strSQL (4000)
DECLARE tnames_cursor CURSOR
FOR
SELECIONAR t.TABLE_NAME, c.COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS c juntar INFORMATION_SCHEMA.TABLES t ON t.TABLE_NAME = c.TABLE_NAME
WHERE (c.DATA_TYPE = 'smalldatetime' OR c.DATA_TYPE = 'datetime') E t.TABLE_TYPE <> 'Ver'
ORDER BY t.TABLE_NAME, c.COLUMN_NAME DESC
tnames_cursor ABERTO
Obter PRÓXIMO DE @TableName tnames_cursor INTO, @columnname
SET @currcolumn = @columnname
SET @currtable = @TableName
= SET @strSQL N'UPDATE '+ + @TableName CHAR (13) + CHAR (10) + 'SET' + @columnname +' = DATEADD (dia, '+ CONVERTER (VARCHAR (10), @ numDaysToAdd) + '' + @columnname + ')'
ENQUANTO (@@ 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
Obter PRÓXIMO DE @TableName tnames_cursor INTO, @columnname
END
- executar a declaração final EXEC sp_executesql @strSQL
close tnames_cursor
DEALLOCATE tnames_cursor
END
Solução
O seu entendimento está correto. Parece que as peças que você está faltando são:
- como encontrar metadados (quais tabelas você tem, e que colunas)
- como construir o SQL de andar sobre as tabelas.
Para # 1, ver a vista do 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'
Para # 2, você pode construir uma instrução SQL como uma corda, andar por entre as mesas você está em interessado, então executá-lo com sp_executesql
.
Outras dicas
Eu concordo. Outra opção é usar tabelas do sistema para gerar o SQL para todas as 200 mesas. Você pode então usar sp_execsql para exec. não mudará execução, mas você vai economizar digitação, que é sempre importante:)
A consulta a seguir lhe daria a lista de tabelas de usuário e suas colunas que são do 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
aqui 58 é system_type_id para o tipo de dados - smalldatetime. Você pode verificá-lo da tabela sys.types.
Usando um cursor pode ser que você pode iterar sobre o conjunto de resultados para obter cada mesa e gatilhos, em seguida, desativar nessa tabela. Verifique isso para desativar gatilho / ativar http://msdn.microsoft.com/en -us / library / ms189748.aspx
Em seguida, vá em frente e atualizar cada coluna no conjunto de resultados referentes a cada tabela, seguido por permitindo que os gatilhos.
aplausos