Программирование SQL Server – обновление всех дат на заданное количество дней

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

  •  21-08-2019
  •  | 
  •  

Вопрос

У меня есть демонстрационная база данных с парой сотен таблиц.Каждая таблица обычно имеет по крайней мере одно поле с именем tstamp, которое представляет собой тип данных smalldatetime.В некоторых таблицах есть и другие поля дат.Многие таблицы также имеют один или несколько триггеров.

Я написал сценарий (сложный способ — см. ниже), который увеличивает поля даты в каждой таблице на заданное количество дней.Идея состоит в том, чтобы сделать данные более «актуальными», обновляя все даты на одинаковое количество дней.

Я уверен, что есть более простой способ сделать это, пройдя по системной таблице, чтобы идентифицировать каждую пользовательскую таблицу в базе данных, отключить все триггеры на ней, изменить каждое поле smalldatetime, добавив к нему количество дней, повторно включив триггеры. и переходим к следующему столу.Я просто понятия не имею, как писать такой T-SQL.

Есть желающие?

Спасибо.Джо

Пример сценария:

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!

============================================================================= ================================================================== работает:

ОБЪЯВИТЬ @numDaysToAdd int

УСТАНОВИТЬ @numDaysToAdd = 1

ЕСЛИ @numDaysToAdd > 0

НАЧИНАТЬ

ОБЪЯВИТЬ @tablename varchar(100)

ОБЪЯВИТЬ @currtable varchar(100)

ОБЪЯВИТЬ @currcolumn varchar(100)

ОБЪЯВИТЬ @columnname varchar(100)

ОБЪЯВИТЬ @strSQL nvarchar(4000)

ОБЪЯВИТЬ tnames_cursor КУРСОР

ДЛЯ

ВЫБЕРИТЕ t.TABLE_NAME, c.COLUMN_NAME

FROM INFORMATION_SCHEMA.COLUMNS c присоединиться к INFORMATION_SCHEMA.TABLES t ON t.TABLE_NAME = c.TABLE_NAME

ГДЕ (c.DATA_TYPE = 'smalldatetime' ИЛИ ​​c.DATA_TYPE = 'datetime') И t.TABLE_TYPE<>'VIEW'

ORDER BY t.TABLE_NAME, c.COLUMN_NAME DESC

ОТКРЫТЬ tnames_cursor

ПОЛУЧИТЬ СЛЕДУЮЩИЙ ИЗ tnames_cursor В @tablename, @columnname

SET @currcolumn = @columnname

SET @currtable = @имя_таблицы

SET @strSQL = N'UPDATE ' + @tablename + CHAR(13)+CHAR(10) + 'SET ' + @columnname + ' = DATEADD(day, ' + CONVERT(varchar(10),@numDaysToAdd) + ', ' + @имя_столбца + ')'

ПОКА (@@FETCH_STATUS = 0)

НАЧИНАТЬ

ЕСЛИ (@currtable = @tablename)

BEGIN     

  IF @currcolumn <> @columnname

    SET @strSQL = @strSQL + N',' + CHAR(13)+CHAR(10) + @columnname + ' = DATEADD(day, ' + CONVERT(varchar(10),@numDaysToAdd) + ', ' + @columnname + ')'
END

ЕЩЕ

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

ПОЛУЧИТЬ СЛЕДУЮЩИЙ ИЗ tnames_cursor В @tablename, @columnname

КОНЕЦ

-Запустите окончательный оператор exec sp_executeql @strsql

ЗАКРЫТЬ tnames_cursor

DEALLOCATE tnames_cursor

КОНЕЦ

Это было полезно?

Решение

Ваше понимание правильное.Похоже, вам не хватает следующих частей:

  1. Как найти метаданные (какие таблицы у вас есть, и какие столбцы)
  2. Как построить SQL, чтобы пройти через столы.

Для № 1 см. представления системы. 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'

Для № 2 вы можете создать оператор SQL в виде строки, проходя по интересующим вас таблицам, а затем выполнить его с помощью sp_executesql.

Другие советы

Я согласен.Другой вариант — использовать системные таблицы для генерации SQL для всех 200 таблиц.Затем вы можете использовать sp_execsql для выполнения.Выполнение не изменится, но избавит вас от необходимости печатать, что всегда важно :)

Следующий запрос предоставит вам список пользовательских таблиц и их столбцов типа 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

здесь 58 — это system_type_id для типа данных — smallDateTime.Вы можете проверить это из таблицы sys.types.

Используя курсор, вы можете перебирать набор результатов, чтобы получить каждую таблицу, а затем отключить триггеры для этой таблицы.Проверьте это для отключения/включения триггера http://msdn.microsoft.com/en-us/library/ms189748.aspx

Затем обновите каждый столбец в наборе результатов, относящийся к каждой таблице, а затем включите триггеры.

ваше здоровье

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top