programação SQL Server - atualizar todas as datas por um determinado número de dias

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

  •  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

Foi útil?

Solução

O seu entendimento está correto. Parece que as peças que você está faltando são:

  1. como encontrar metadados (quais tabelas você tem, e que colunas)
  2. 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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top