Как вы усекаете все таблицы в базе данных, используя TSQL? - PullRequest
191 голосов
/ 01 октября 2008

У меня есть тестовая среда для базы данных, которую я хочу перезагрузить с новыми данными в начале цикла тестирования. Я не заинтересован в перестройке всей базы данных, просто в «переустановке» данных.

Каков наилучший способ удалить все данные из всех таблиц с помощью TSQL? Существуют ли системные хранимые процедуры, представления и т. Д., Которые можно использовать? Я не хочу вручную создавать и поддерживать операторы усеченной таблицы для каждой таблицы - я бы предпочел, чтобы она была динамической.

Ответы [ 17 ]

2 голосов
/ 12 августа 2009

Намного проще (и, возможно, даже быстрее) составить сценарий для вашей базы данных, а затем просто удалить ее и создать из сценария.

2 голосов
/ 01 октября 2008

Это один способ сделать это ... вероятно, есть еще 10, которые лучше / эффективнее, но, похоже, это делается очень редко, так что вот так ...

получить список tables из sysobjects, затем выполнить цикл с курсором, вызывая sp_execsql('truncate table ' + @table_name) для каждого iteration.

0 голосов
/ 04 июля 2018

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

  1. Сохранить все ограничения во временной таблице
  2. Отбросить все ограничения
  3. Усечение всех таблиц, за исключением некоторых таблиц, которые не требуют усечения
  4. Воссоздать все ограничения.

Я перечислил это в своем блоге здесь

0 голосов
/ 02 июля 2009

Я не понимаю, почему очистка данных была бы лучше, чем сценарий для удаления и повторного создания каждой таблицы.

Это или сохранить резервную копию вашей пустой БД и восстановить ее поверх старой

0 голосов
/ 30 января 2014

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

Вы можете изменить это, если хотите сделать все таблицы, просто поместите в SELECT имя INTO #TruncateList FROM sys.tables. Однако вы обычно не хотите делать их все.

Кроме того, это повлияет на все внешние ключи в базе данных, и вы также можете изменить это, если это слишком сильно для вашего приложения. Это не для моих целей.

/*
CREATE TABLE _ScriptLog 
(
    ID Int NOT NULL Identity(1,1)
    , DateAdded DateTime2 NOT NULL DEFAULT GetDate()
    , Script NVarChar(4000) NOT NULL
)

CREATE UNIQUE CLUSTERED INDEX IX_ScriptLog_DateAdded_ID_U_C ON _ScriptLog
(
    DateAdded
    , ID
)

CREATE TABLE _TruncateList
(
    TableName SysName PRIMARY KEY
)
*/
IF OBJECT_ID('TempDB..#DropFK') IS NOT NULL BEGIN
    DROP TABLE #DropFK
END

IF OBJECT_ID('TempDB..#TruncateList') IS NOT NULL BEGIN
    DROP TABLE #TruncateList
END

IF OBJECT_ID('TempDB..#CreateFK') IS NOT NULL BEGIN
    DROP TABLE #CreateFK
END

SELECT Scripts = 'ALTER TABLE ' + '[' + OBJECT_NAME(f.parent_object_id)+ ']'+
' DROP  CONSTRAINT ' + '[' + f.name  + ']'
INTO #DropFK
FROM .sys.foreign_keys AS f
INNER JOIN .sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id

SELECT TableName
INTO #TruncateList
FROM _TruncateList

SELECT Scripts = 'ALTER TABLE ' + const.parent_obj + '
    ADD CONSTRAINT ' + const.const_name + ' FOREIGN KEY (
            ' + const.parent_col_csv + '
            ) REFERENCES ' + const.ref_obj + '(' + const.ref_col_csv + ')
'
INTO #CreateFK
FROM (
    SELECT QUOTENAME(fk.NAME) AS [const_name]
        ,QUOTENAME(schParent.NAME) + '.' + QUOTENAME(OBJECT_name(fkc.parent_object_id)) AS [parent_obj]
        ,STUFF((
                SELECT ',' + QUOTENAME(COL_NAME(fcP.parent_object_id, fcp.parent_column_id))
                FROM sys.foreign_key_columns AS fcP
                WHERE fcp.constraint_object_id = fk.object_id
                FOR XML path('')
                ), 1, 1, '') AS [parent_col_csv]
        ,QUOTENAME(schRef.NAME) + '.' + QUOTENAME(OBJECT_NAME(fkc.referenced_object_id)) AS [ref_obj]
        ,STUFF((
                SELECT ',' + QUOTENAME(COL_NAME(fcR.referenced_object_id, fcR.referenced_column_id))
                FROM sys.foreign_key_columns AS fcR
                WHERE fcR.constraint_object_id = fk.object_id
                FOR XML path('')
                ), 1, 1, '') AS [ref_col_csv]
    FROM sys.foreign_key_columns AS fkc
    INNER JOIN sys.foreign_keys AS fk ON fk.object_id = fkc.constraint_object_id
    INNER JOIN sys.objects AS oParent ON oParent.object_id = fkc.parent_object_id
    INNER JOIN sys.schemas AS schParent ON schParent.schema_id = oParent.schema_id
    INNER JOIN sys.objects AS oRef ON oRef.object_id = fkc.referenced_object_id
    INNER JOIN sys.schemas AS schRef ON schRef.schema_id = oRef.schema_id
    GROUP BY fkc.parent_object_id
        ,fkc.referenced_object_id
        ,fk.NAME
        ,fk.object_id
        ,schParent.NAME
        ,schRef.NAME
    ) AS const
ORDER BY const.const_name

INSERT INTO _ScriptLog (Script)
SELECT Scripts
FROM #CreateFK

DECLARE @Cmd NVarChar(4000)
    , @TableName SysName

WHILE 0 < (SELECT Count(1) FROM #DropFK) BEGIN
    SELECT TOP 1 @Cmd = Scripts 
    FROM #DropFK

    EXEC (@Cmd)

    DELETE #DropFK WHERE Scripts = @Cmd
END

WHILE 0 < (SELECT Count(1) FROM #TruncateList) BEGIN
    SELECT TOP 1 @Cmd = N'TRUNCATE TABLE ' +  TableName
        , @TableName = TableName
    FROM #TruncateList

    EXEC (@Cmd)

    DELETE #TruncateList WHERE TableName = @TableName
END

WHILE 0 < (SELECT Count(1) FROM #CreateFK) BEGIN
    SELECT TOP 1 @Cmd = Scripts 
    FROM #CreateFK

    EXEC (@Cmd)

    DELETE #CreateFK WHERE Scripts = @Cmd
END
0 голосов
/ 24 октября 2012

Перед усечением таблиц необходимо удалить все внешние ключи. Используйте этот script для генерации финальных сценариев для удаления и воссоздания всех внешних ключей в базе данных Установите для переменной @action значение CREATE или DROP.

0 голосов
/ 23 ноября 2012

выберите «удалить из» + TABLE_NAME из INFORMATION_SCHEMA.TABLES, где TABLE_TYPE = «BASE TABLE»

, куда приходит результат.

Скопируйте и вставьте в окно запроса и выполните команду

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...