다른 SQL2008 데이터베이스로 테이블 이동 (인덱스, 트리거 등 포함) 일반 INT로 변환되었지만 마법사.) 이것을하는

하나의 SQL2008 데이터베이스에서 다른 테이블로 전체 (100 +) 큰 (수백만 행) 테이블을 이동해야합니다.

원래는 가져 오기 / 내보내기 마법사를 사용했지만 모든 대상 테이블에 기본 및 외래 키, 인덱스, 제약 조건, 트리거 등이 누락되었습니다. (ID 열도 일반 INT로 변환되었지만 마법사.)

이것을하는 올바른 방법은 무엇입니까?

이것이 두 개의 테이블 인 경우 소스로 돌아가서 테이블 정의 (모든 인덱스 등)를 스크립팅 한 다음 대상에서 스크립트의 인덱스 작성 부분을 실행합니다. 그러나 테이블이 너무 많으면 실용적이지 않은 것 같습니다.

데이터가 너무 많지 않으면 “스크립트 생성 …”마법사를 사용하여 데이터를 포함하여 소스를 스크립팅 할 수 있지만 72m 행 스크립트는 좋은 생각처럼 보이지 않습니다!



답변

테이블을 스크립팅 한 다음 SSIS를 사용하여 데이터를 전송하는 것이 데이터를 새 데이터베이스로 이동하는 가장 안정적이고 효과적인 방법입니다.


답변

실제로 가져 오기 마법사와 함께 많은 수동 스크립팅을 사용했지만 Tibor Karaszi의 블로그 기사 에서 더 나은 답변을 찾았습니다 .

여기서 좌절의 한 부분은 SQL 2000 “DTS 가져 오기 / 내보내기 마법사”가 “객체 및 데이터 복사”를 선택하여 실제로이 작업을 쉽게 수행 할 수 있다는 것입니다.

이 세 번째 옵션은 인덱스 / 트리거 등을 포함하는 기능이 포함 된 옵션입니다.

이 옵션은 SQL 2005/2008 가져 오기 마법사 에서 제거 되었습니다 . 왜? 몰라요:

2005/2008 년에는 BIDS에서 SSIS 패키지 를 수동으로 작성 하고 2000 마법사에서와 동일한 옵션이 모두 포함 된 Transfer SQL Server Objects Task를 사용해야합니다 .


답변

테이블을 스크립팅하거나 비교 도구 (예 : Red Gate)를 사용하여 대상 데이터베이스에 테이블을 생성하는 것을 고려합니다. 아직 인덱스 나 제약이 없습니다.

그런 다음 동일한 서버에서 다른 이름으로 데이터베이스를 복원하고

 INSERT newdb.dbo.newtable SELECT * FROM olddb.dbo.oldtable

.. 필요한 경우 SET IDENTITY INSERT ON을 사용하여 각 테이블에 대해

그런 다음 데이터를로드 한 후 색인과 제약 조건을 추가합니다.

SSIS (mrdenny ‘s answer)의 편안함 수준 또는 원시 SQL을 선호하는지 여부에 따라 다릅니다.


답변

Mr Denny의 답변에 추가하겠습니다. 테이블 스키마를 스크립팅 한 다음 BCP를 사용하여 데이터를 이동하십시오. SSIS에 익숙하지 않다면 BCP와 배치를 사용하는 것이 쉬워야합니다. 수백만 행에 대해서는 BCP (bulk insert)보다 우수하지 않습니다.


답변

나는 SSIS에 완전히 불편한 사람입니다.

소스 테이블에 ID 열이없는 경우

  1. 대상 서버에서 빈 데이터베이스를 작성하십시오.
  2. 대상 서버에서 원본 서버에 연결된 서버를 만듭니다.
  3. select * into … 문을 생성하기 위해 소스 데이터베이스에서 아래 스크립트를 실행하십시오.
  4. 대상 데이터베이스에서 생성 된 스크립트를 실행하십시오.
  5. 소스 데이터베이스의 스크립트 기본 키, 인덱스, 트리거, 기능 및 프로 시저
  6. 생성 된 스크립트로 이러한 객체를 생성

이제 Select * into … 문을 생성하는 T-SQL

SET NOCOUNT ON

declare @name sysname
declare @sql varchar(255)

declare db_cursor cursor for
select name from sys.tables order by 1
open db_cursor

fetch next from db_cursor into @name
while @@FETCH_STATUS = 0
begin
    Set @sql = 'select * into [' + @name + '] from [linked_server].[source_db].[dbo].[' + @name + '];'
    print @sql

    fetch next from db_cursor into @name
end

close db_cursor
deallocate db_cursor

이렇게하면 각 테이블마다 복사 할 줄이 생성됩니다.

select * into [Table1] from [linked_server].[source_db].[dbo].[Table1];

테이블에 ID 열이 포함 된 경우 ID 속성 및 기본 키를 포함하여 테이블을 스크립팅합니다.

이것은 대량 기술이 아니기 때문에 연결된 서버를 사용하여 insert into … select …를 사용하지 않습니다. [이 SO 질문 1 과 유사한 일부 PowerShell 스크립트에서 작업하고 있지만 여전히 오류 처리 작업을하고 있습니다. SQLBulkCopy를 통해 데이터베이스로 보내기 전에 전체 테이블이 메모리에로드되므로 실제로 큰 테이블은 메모리 부족 오류를 유발할 수 있습니다.

지수 등의 재생산은 위의 경우와 유사합니다. 이번에는 기본 키의 재생을 건너 뛸 수 있습니다.


답변

데이터베이스 스키마와 데이터를 비교하고 먼저 데이터베이스 스키마를 원래 db와 동기화하는 비교 도구를 사용 하여 모든 테이블을 작성할 수 있습니다.

그런 다음 원래 데이터베이스의 데이터를 새 데이터베이스 (모든 테이블이 있지만 모두 비어 있음)와 동기화하여 레코드를 테이블에 삽입하십시오.

내가 사용 ApexSQL DIFFApexSQL 데이터 DIFF을 이 들어 있지만, 다른 유사한 도구가 있습니다.

이 프로세스의 좋은 점은 도구를 사용하여 데이터베이스를 실제로 동기화 할 필요가 없다는 것입니다. 수백만 행에 대해 상당히 고통 스러울 수 있기 때문입니다.

당신은 할 수 는 INSERT INTO SQL 스크립트를 작성 합니다 (몇 기가 있다면 놀라지 않는 것)을 실행합니다.

SQL Server Management Studio에서 큰 스크립트를 열 수 없으므로 sqlcmd를 사용합니다. 또는 osql을 사용합니다.


답변

@mrdenny가 언급했듯이-

  1. 먼저 모든 인덱스, FK 등으로 테이블을 스크립팅하고 대상 데이터베이스에 빈 테이블을 만듭니다.

SSIS를 사용하는 대신 BCP를 사용하여 데이터 삽입

  1. 아래 스크립트를 사용하여 데이터를 bcp로 출력하십시오. 텍스트 모드에서 SSMS를 설정하고 아래 스크립트에서 생성 된 출력을 bat 파일로 복사하십시오.

    -- save below output in a bat file by executing below in SSMS in TEXT mode
    
    -- clean up: create a bat file with this command --> del D:\BCP\*.dat 
    
    select '"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\bcp.exe" ' /* path to BCP.exe */
        +  QUOTENAME(DB_NAME())+ '.' /* Current Database */
        +  QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+'.'
        +  QUOTENAME(name)
        +  ' out D:\BCP\'  /* Path where BCP out files will be stored */
        +  REPLACE(SCHEMA_NAME(schema_id),' ','') + '_'
        +  REPLACE(name,' ','')
        + '.dat -T -E -SServerName\Instance -n' /* ServerName, -E will take care of Identity, -n is for Native Format */
    from sys.tables
    where is_ms_shipped = 0 and name <> 'sysdiagrams'                       /* sysdiagrams is classified my MS as UserTable and we dont want it */
    /*and schema_name(schema_id) <> 'unwantedschema'    */                             /* Optional to exclude any schema  */
    order by schema_name(schema_id)
  2. 지정한 폴더에 .dat 파일을 생성 할 bat 파일을 실행하십시오.

  3. 에 아래 스크립트를 실행

    --- Execute this on the destination server.database from SSMS.
    
    --- Make sure the change the @Destdbname and the bcp out path as per your environment.
    
    declare @Destdbname sysname
    set @Destdbname = 'destinationDB' /* Destination Database Name where you want to Bulk Insert in */
    select 'BULK INSERT '
    /*Remember Tables must be present on destination database */
    + QUOTENAME(@Destdbname) + '.'
    + QUOTENAME(SCHEMA_NAME(SCHEMA_ID))
    + '.' + QUOTENAME(name)
    + ' from ''D:\BCP\' /* Change here for bcp out path */
    + REPLACE(SCHEMA_NAME(schema_id), ' ', '') + '_' + REPLACE(name, ' ', '')
    + '.dat'' with ( KEEPIDENTITY, DATAFILETYPE = ''native'', TABLOCK )'
    + char(10)
    + 'print ''Bulk insert for ' + REPLACE(SCHEMA_NAME(schema_id), ' ', '') + '_' + REPLACE(name, ' ', '') + ' is done... '''
    + char(10) + 'go'
       from sys.tables
       where is_ms_shipped = 0
    and name <> 'sysdiagrams' /* sysdiagrams is classified my MS as UserTable and we dont want it */
    and schema_name(schema_id) <> 'unwantedschema' /* Optional to exclude any schema */
        order by schema_name(schema_id) 
  4. SSMS를 사용하여 출력을 실행하여 테이블에 데이터를 다시 삽입하십시오.

기본 모드를 사용하므로 매우 빠른 bcp 방법입니다.