IT story

TSQL을 사용하여 데이터베이스의 모든 테이블을 어떻게 자르나요?

hot-time 2020. 5. 10. 10:25
반응형

TSQL을 사용하여 데이터베이스의 모든 테이블을 어떻게 자르나요?


테스트주기가 시작될 때 새 데이터로 다시로드하려는 데이터베이스에 대한 테스트 환경이 있습니다. 전체 데이터베이스를 재 구축하는 데 관심이 없으며 단순히 데이터를 "재설정"합니다.

TSQL을 사용하여 모든 테이블에서 모든 데이터를 제거하는 가장 좋은 방법은 무엇입니까? 사용할 수있는 시스템 저장 프로 시저, 뷰 등이 있습니까? 각 테이블에 대해 잘리는 테이블 문을 수동으로 생성하고 유지 관리하고 싶지 않습니다. 동적 테이블을 선호합니다.


SQL 2005의 경우

EXEC sp_MSForEachTable 'TRUNCATE TABLE ?'

2000 년2005 / 2008 년에 대한 더 많은 링크 ..


외래 키 관계가있는 테이블에서 데이터를 삭제하는 경우 기본적으로 올바르게 설계된 데이터베이스의 경우와 같이 모든 제약 조건을 비활성화하고 모든 데이터를 삭제 한 다음 제약 조건을 다시 활성화 할 수 있습니다

-- disable all constraints
EXEC sp_MSForEachTable "ALTER TABLE ? NOCHECK CONSTRAINT all"

-- delete data in all tables
EXEC sp_MSForEachTable "DELETE FROM ?"

-- enable all constraints
exec sp_MSForEachTable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"

제약 조건 및 트리거 비활성화에 대한 자세한 내용은 여기를 참조하십시오.

일부 테이블에 ID 열이있는 경우 다시 열어야 할 수도 있습니다.

EXEC sp_MSForEachTable "DBCC CHECKIDENT ( '?', RESEED, 0)"

RESEED의 동작은 새 테이블과 이전에 BOL 에서 일부 데이터를 삽입 한 테이블간에 다릅니다 .

DBCC CHECKIDENT ( 'table_name', RESEED, newReseedValue)

현재 ID 값은 newReseedValue로 설정됩니다. 작성된 이후 테이블에 행이 삽입되지 않은 경우 DBCC CHECKIDENT를 실행 한 후 삽입 된 첫 번째 행은 newReseedValue를 ID로 사용합니다. 그렇지 않으면 삽입 된 다음 행은 newReseedValue + 1을 사용합니다. newReseedValue의 값이 ID 열의 최대 값보다 작은 경우, 테이블에 대한 후속 참조에서 오류 메시지 2627이 생성됩니다.

제약 조건을 비활성화하면 자르기를 사용할 수 없다는 사실을 지적한 Robert 에게 감사의 말을 전하고 제약 조건을 삭제 한 다음 다시 만들어야합니다.


다음은 데이터베이스 삭제 스크립트의 왕자입니다. 모든 테이블을 지우고 올바르게 다시 시드합니다.

SET QUOTED_IDENTIFIER ON;
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? NOCHECK CONSTRAINT ALL'  
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? DISABLE TRIGGER ALL'  
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'  
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? CHECK CONSTRAINT ALL'  
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? ENABLE TRIGGER ALL' 
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON';

IF NOT EXISTS (
    SELECT
        *
    FROM
        SYS.IDENTITY_COLUMNS
        JOIN SYS.TABLES ON SYS.IDENTITY_COLUMNS.Object_ID = SYS.TABLES.Object_ID
    WHERE
        SYS.TABLES.Object_ID = OBJECT_ID('?') AND SYS.IDENTITY_COLUMNS.Last_Value IS NULL
)
AND OBJECTPROPERTY( OBJECT_ID('?'), 'TableHasIdentity' ) = 1

    DBCC CHECKIDENT ('?', RESEED, 0) WITH NO_INFOMSGS;

즐기 되 조심하십시오!


가장 간단한 방법은

  1. SQL Management Studio를 엽니 다
  2. 데이터베이스로 이동
  3. 마우스 오른쪽 단추를 클릭하고 태스크-> 스크립트 생성을 선택하십시오 (그림 1).
  4. "객체 선택"화면에서 "특정 객체 선택"옵션을 선택하고 "테이블"을 확인하십시오 (그림 2).
  5. 다음 화면에서 "고급"을 선택한 다음 "스크립트 DROP 및 작성"옵션을 "스크립트 DROP 및 작성"으로 변경하십시오 (그림 3).
  6. 스크립트를 새 편집기 창 또는 파일에 저장하고 필요에 따라 실행하도록 선택하십시오.

이렇게하면 디버깅이나 모든 것을 포함했는지에 대해 걱정할 필요없이 모든 테이블을 삭제하고 다시 만드는 스크립트가 제공됩니다. 이것은 잘림 이상의 기능을 수행하지만 결과는 동일합니다. 할당 된 마지막 값을 기억하는 잘린 테이블과 달리 자동 증가 기본 키는 0에서 시작합니다. PreProd 또는 프로덕션 환경에서 Management Studio에 액세스 할 수없는 경우 코드에서이를 실행할 수도 있습니다.

1.

여기에 이미지 설명을 입력하십시오

2.

여기에 이미지 설명을 입력하십시오

삼.

여기에 이미지 설명을 입력하십시오


SQL Server에서는 외래 키를 사용하여 테이블을자를 수 없으므로 테이블간에 외래 키 관계가없는 경우에만 모든 테이블을 잘릴 수 있습니다.

이에 대한 대안은 외래 키가있는 테이블을 결정하고 먼저 외래 키를 삭제하는 것입니다. 그런 다음 외래 키없이 테이블을자를 수 있습니다.

자세한 내용은 http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=65341http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=72957참조 하십시오 .


MSSQL Server Deveploper 또는 Enterprise와 함께 사용하는 다른 옵션은 빈 스키마를 만든 직후 데이터베이스의 스냅 샷을 만드는 것입니다. 이 시점에서 데이터베이스를 계속 스냅 샷으로 복원 할 수 있습니다.


이러지 마! 실제로는 좋은 생각이 아닙니다.

잘라내려는 테이블을 알고있는 경우 잘리는 저장 프로 시저를 만듭니다. 외래 키 문제를 피하기 위해 순서를 수정할 수 있습니다.

실제로 모두 잘라내려면 (예를 들어 BCP를로드 할 수 있음) 데이터베이스를 신속하게 삭제하고 처음부터 새 데이터베이스를 작성하면 위치를 정확히 알 수있는 추가 이점이 있습니다.


동일한 db 내에서 다른 테이블의 데이터를 삭제 / 잘라내는 동안 특정 테이블 (예 : 정적 조회 테이블)에 데이터를 유지하려면 예외가있는 루프가 필요합니다. 이것이 내가이 질문을 우연히 발견했을 때 찾고 있던 것입니다.

sp_MSForEachTable은 버그가있는 것 같습니다 (즉, IF 문과 일치하지 않는 동작). 아마도 MS가 문서화하지 않은 이유 일 것입니다.

declare @LastObjectID int = 0
declare @TableName nvarchar(100) = ''
set @LastObjectID = (select top 1 [object_id] from sys.tables where [object_id] > @LastObjectID order by [object_id])
while(@LastObjectID is not null)
begin
    set @TableName = (select top 1 [name] from sys.tables where [object_id] = @LastObjectID)

    if(@TableName not in ('Profiles', 'ClientDetails', 'Addresses', 'AgentDetails', 'ChainCodes', 'VendorDetails'))
    begin
        exec('truncate table [' + @TableName + ']')
    end 

    set @LastObjectID = (select top 1 [object_id] from sys.tables where [object_id] > @LastObjectID order by [object_id])
end

빈 "템플릿"데이터베이스를 만들고 전체 백업을 수행하십시오. 새로 고침해야 할 때는 WITH REPLACE를 사용하여 복원하십시오. 빠르고 간단하며 방탄. 그리고 여기에 몇 개의 테이블이 있거나 기본 데이터 (예 : 구성 정보 또는 앱을 실행시키는 기본 정보)가 필요한 경우도 처리합니다.


모든 테이블을 잘라내는 가장 어려운 부분은 외래 키 제약 조건을 제거하고 다시 추가하는 것입니다.

다음 쿼리는 @myTempTable의 각 테이블 이름과 관련된 각 제약 조건에 대해 drop & create 문을 만듭니다. 모든 테이블에 대해 이들을 생성하려면 정보 스키마를 사용하여 이러한 테이블 이름을 대신 수집 할 수 있습니다.

DECLARE @myTempTable TABLE (tableName varchar(200))
INSERT INTO @myTempTable(tableName) VALUES
('TABLE_ONE'),
('TABLE_TWO'),
('TABLE_THREE')


-- DROP FK Contraints
SELECT 'alter table '+quotename(schema_name(ob.schema_id))+
  '.'+quotename(object_name(ob.object_id))+ ' drop constraint ' + quotename(fk.name) 
  FROM sys.objects ob INNER JOIN sys.foreign_keys fk ON fk.parent_object_id = ob.object_id
  WHERE fk.referenced_object_id IN 
      (
         SELECT so.object_id 
         FROM sys.objects so JOIN sys.schemas sc
         ON so.schema_id = sc.schema_id
         WHERE so.name IN (SELECT * FROM @myTempTable)  AND sc.name=N'dbo'  AND type in (N'U'))


 -- CREATE FK Contraints
 SELECT 'ALTER TABLE [PIMSUser].[dbo].[' +cast(c.name as varchar(255)) + '] WITH NOCHECK ADD CONSTRAINT ['+ cast(f.name as varchar(255)) +'] FOREIGN KEY (['+ cast(fc.name as varchar(255)) +'])
      REFERENCES [PIMSUser].[dbo].['+ cast(p.name as varchar(255)) +'] (['+cast(rc.name as varchar(255))+'])'
FROM  sysobjects f
      INNER JOIN sys.sysobjects c ON f.parent_obj = c.id
      INNER JOIN sys.sysreferences r ON f.id = r.constid
      INNER JOIN sys.sysobjects p ON r.rkeyid = p.id
      INNER JOIN sys.syscolumns rc ON r.rkeyid = rc.id and r.rkey1 = rc.colid
      INNER JOIN sys.syscolumns fc ON r.fkeyid = fc.id and r.fkey1 = fc.colid
WHERE 
      f.type = 'F'
      AND
      cast(p.name as varchar(255)) IN (SELECT * FROM @myTempTable)

그런 다음 실행할 명령문을 복사하지만 약간의 노력으로 커서를 사용하여 동적으로 실행할 수 있습니다.


It is much easier (and possibly even faster) to script out your database, then just drop and create it from the script.


This is one way to do it... there are likely 10 others that are better/more efficient, but it sounds like this is done very infrequently, so here goes...

get a list of the tables from sysobjects, then loop over those with a cursor, calling sp_execsql('truncate table ' + @table_name) for each iteration.


I do not see why clearing data would be better than a script to drop and re-create each table.

That or keep a back up of your empty DB and restore it over old one


Before truncating the tables you have to remove all foreign keys. Use this script to generate final scripts to drop and recreate all foreign keys in database. Please set the @action variable to 'CREATE' or 'DROP'.


select 'delete from ' +TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_TYPE='BASE TABLE'

where result come.

Copy and paste on query window and run the command


Run the commented out section once, populate the _TruncateList table with the tables you want truncated, then run the rest of the script. The _ScriptLog table will need to be cleaned up over time if you do this a lot.

You can modify this if you want to do all tables, just put in SELECT name INTO #TruncateList FROM sys.tables. However, you usually don't want to do them all.

또한 이것은 데이터베이스의 모든 외래 키에 영향을 미치며 응용 프로그램에 너무 무딘 경우에도 수정할 수 있습니다. 내 목적이 아닙니다.

/*
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

조금 늦었지만 누군가를 도울 수 있습니다. 때때로 T-SQL을 사용하여 다음을 수행하는 프로 시저를 작성했습니다.

  1. 모든 제약 조건을 임시 테이블에 저장
  2. 모든 제약 조건 제거
  3. 잘릴 필요가없는 일부 테이블을 제외하고 모든 테이블을 자릅니다.
  4. 모든 제약 조건을 재현하십시오.

내 블로그에 여기 에 나열했습니다

참고 URL : https://stackoverflow.com/questions/155246/how-do-you-truncate-all-tables-in-a-database-using-tsql

반응형