Ленивый, эффективный способ сделать это в T-SQL:
В моем случае, некоторые таблицы имеют большой размер, поэтому составление сценариев данных нецелесообразно.
Кроме того, нам нужно было перенести только часть очень большой базы данных, поэтому я не хотел выполнять резервное копирование / восстановление.
Поэтому я пошел с INSERT INTO / SELECT FROM идля создания кода использовали information_schema и т. д.
Шаг 1: создайте таблицы в новой БД
Для каждой таблицы, которую вы хотите перенести в новую базу данных, создайте эту таблицу в новой базе данных.
Либо составьте сценарий из таблиц, либо используйте SQL Compare, динамический sql из information_schema - множество способов сделать это.Ответ Даллина показывает один из способов использования SSMS (но обязательно выбирайте только схему).
Шаг 2: создать UDF на целевой БД для создания списка столбцов
Это просто вспомогательная функция, используемая при генерации кода.
USE [staging_edw]
GO
CREATE FUNCTION dbo.udf_get_column_list
(
@table_name varchar(8000)
)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE @var VARCHAR(8000)
SELECT
@var = COALESCE(@var + ',', '', '') + c.COLUMN_NAME
FROM INFORMATION_SCHEMA.columns c
WHERE c.TABLE_SCHEMA + '.' + c.TABLE_NAME = @table_name
AND c.COLUMN_NAME NOT LIKE '%hash%'
RETURN @var
END
Шаг 3: создать журналтаблица
Сгенерированный код будет регистрировать прогресс в этой таблице, чтобы вы могли отслеживать.Но сначала нужно создать эту таблицу журнала.
USE staging_edw
GO
IF OBJECT_ID('dbo.tmp_sedw_migration_log') IS NULL
CREATE TABLE dbo.tmp_sedw_migration_log
(
step_number INT IDENTITY,
step VARCHAR(100),
start_time DATETIME
)
Шаг 4: сгенерировать сценарий миграции
Здесь вы создадите T-SQL, который будет переносить данные для вас.Он просто генерирует операторы INSERT INTO / SELECT FROM для каждой таблицы и записывает ход выполнения.
Этот сценарий фактически ничего не меняет.Он просто выводит некоторый код, который вы можете проверить перед выполнением.
USE staging_edw
GO
-- newline characters for formatting of generated code
DECLARE @n VARCHAR(100) = CHAR(13)+CHAR(10)
DECLARE @t VARCHAR(100) = CHAR(9)
DECLARE @2n VARCHAR(100) = @n + @n
DECLARE @2nt VARCHAR(100) = @n + @n + @t
DECLARE @nt VARCHAR(100) = @n + @t
DECLARE @n2t VARCHAR(100) = @n + @t + @t
DECLARE @2n2t VARCHAR(100) = @n + @n + @t + @t
DECLARE @3n VARCHAR(100) = @n + @n + @n
-- identify tables with identity columns
IF OBJECT_ID('tempdb..#identities') IS NOT NULL
DROP TABLE #identities;
SELECT
table_schema = s.name,
table_name = o.name
INTO #identities
FROM sys.objects o
JOIN sys.columns c on o.object_id = c.object_id
JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE 1=1
AND c.is_identity = 1
-- generate the code
SELECT
@3n + '-- ' + t.TABLE_SCHEMA + '.' + t.TABLE_NAME,
@n + 'BEGIN TRY',
@2nt + IIF(i.table_schema IS NOT NULL, 'SET IDENTITY_INSERT staging_edw.' + t.TABLE_SCHEMA + '.' + t.TABLE_NAME + ' ON ', ''),
@2nt + 'TRUNCATE TABLE staging_edw.' + t.TABLE_SCHEMA + '.' + t.TABLE_NAME,
@2nt + 'INSERT INTO staging_edw.' + t.TABLE_SCHEMA + '.' + t.TABLE_NAME + ' WITH (TABLOCKX) ( ' + f.f + ' ) ',
@2nt + 'SELECT ' + f.f + + @nt + 'FROM staging.' + t.TABLE_SCHEMA + '.' + t.TABLE_NAME,
@2nt + IIF(i.table_schema IS NOT NULL, 'SET IDENTITY_INSERT staging_edw.' + t.TABLE_SCHEMA + '.' + t.TABLE_NAME + ' OFF ', ''),
@2nt + 'INSERT INTO dbo.tmp_sedw_migration_log ( step, start_time ) VALUES ( ''' + t.TABLE_SCHEMA + '.' + t.TABLE_NAME + ' inserted successfully'', GETDATE() );' ,
@2n + 'END TRY',
@2n + 'BEGIN CATCH',
@2nt + 'INSERT INTO dbo.tmp_sedw_migration_log ( step, start_time ) VALUES ( ''' + t.TABLE_SCHEMA + '.' + t.TABLE_NAME + ' FAILED'', GETDATE() );' ,
@2n + 'END CATCH'
FROM INFORMATION_SCHEMA.tables t
OUTER APPLY (SELECT f = staging_edw.dbo.udf_get_column_list(t.TABLE_SCHEMA + '.' + t.TABLE_NAME)) f
LEFT JOIN #identities i ON i.table_name = t.TABLE_NAME
AND i.table_schema = t.TABLE_SCHEMA
WHERE t.TABLE_TYPE = 'base table'
Шаг 5: запустите код
Теперь вы просто копируете вывод из шага 4, вставляете в новое окно запроса,и беги.
Примечания
- На шаге 1 я исключаю хеш-столбцы из списка столбцов (в UDF), поскольку в моей ситуации это вычисляемые столбцы