2013-05-14 6 views
-1

У меня есть база данных X и база данных Y. X и Y имеют некоторые таблицы и столбцы, которые имеют одну и ту же схему. В базе данных нет данных.Вставьте общие данные из одной базы данных в другую?

Какой SQL/T-SQL я могу написать для переноса всех данных из базы данных X в базу данных Y, где имена таблиц и столбцов одинаковы?

Спасибо

Edit: Обе базы данных на одном сервере. Мы не знаем, какие таблицы и столбцы имеют одно и то же имя, поэтому я не могу вставлять их в каждую таблицу вручную (например, может быть 100 столов и столбцов с тем же именем)

+0

Вы пробовали bcp? – aingram

+1

Являются ли обе базы данных на одном сервере или нет? – Pondlife

+0

Вы, кажется, изменили (или расширили) свой вопрос в комментариях ниже; теперь вы спрашиваете, как это сделать, когда «мы не знаем, какие таблицы и столбцы одинаковы». Вам нужно объяснить, как вы хотите сопоставить исходные и целевые таблицы и столбцы в этом случае, но общее решение состоит в том, чтобы генерировать инструкцию 'INSERT ... SELECT ...' динамически, используя метаданные из 'sys.tables' и' sys .columns'. См. [Этот вопрос] (http://stackoverflow.com/questions/6844137/sql-insert-into-statement-but-suppose-you-do-not-know-origin-and-target-header), который по существу тоже самое. – Pondlife

ответ

2

После получения дополнительной информации от вопроса это оказалось немного интересно, поэтому я попытался прийти с задачей, которая должна выполнить задачу сравнения sys.tables и sys.columns между двумя базами данных и создать сценарий INSERT/SELECT.

Test Setup:

USE X 
CREATE TABLE t1 (co1 INT, col2 VARCHAR(10)) 
CREATE TABLE t2 (co1 INT, col2 VARCHAR(10)) 
CREATE TABLE t3 (co1 INT, col2 VARCHAR(10)) 
CREATE TABLE t4 (co1 INT, col2 VARCHAR(10)) 
CREATE TABLE t5 (co1 INT, col2 VARCHAR(10)) 
CREATE TABLE t6 (co1 INT, col2 VARCHAR(10)) 
CREATE TABLE t7 (co1 INT, col2 VARCHAR(10)) 
CREATE TABLE t8 (co1 INT IDENTITY(1,1), col2 VARCHAR(10)) 

USE Y 
CREATE TABLE t1 (co1 INT, col2 VARCHAR(10)) 
CREATE TABLE t2 (co1 INT, col2 VARCHAR(10)) 
CREATE TABLE t3 (co1 VARCHAR(10), col2 VARCHAR(10)) 
CREATE TABLE t4 (co11 INT, col22 VARCHAR(10)) 
CREATE TABLE t5 (co11 INT, col2 VARCHAR(10)) 
CREATE TABLE t6 (co1 INT, col2 VARCHAR(10), col3 int) 
CREATE TABLE t7 (co1 INT) 
CREATE TABLE t8 (co1 INT IDENTITY(1,1), col2 VARCHAR(10)) 

Я попытался создать несколько различных сценариев, которые должны быть крышки. Таблица в Y, имеющая дополнительные или менее столбцы, разные типы данных, идентификаторы. Может быть, есть еще больше вариантов, о которых я не думал, но идея должна быть в порядке.

Также я предположил, что если две таблицы с одинаковым именем имеют одинаковые столбцы, но не все, передача не должна выполняться вообще для этих таблиц. Если вы хотите также перенести эти таблицы для сопоставления столбцов, некоторые JOINS должны быть изменены, но есть также проблема того, что без переданных столбцов в Y разрешает NULL или нет.

В этом случае таблицы T1, T2 и T8 будут скопированы.

Запрос:

WITH CTE_X AS 
(
    SELECT xt.object_id, xs.NAME + '.' + xt.NAME AS tblName, COUNT(*) AS colsNo FROM x.sys.tables xt 
    INNER JOIN x.sys.columns xc ON xc.object_id = xt.object_id 
    INNER JOIN x.sys.schemas xs ON xt.schema_id = xs.schema_id 
    GROUP BY xt.object_id, xt.NAME, xs.NAME 
) 
,CTE_Y AS 
(
    SELECT yt.object_id, ys.NAME + '.' + yt.NAME AS tblName, COUNT(*) AS colsNo FROM y.sys.tables yt 
    INNER JOIN y.sys.columns yc ON yc.object_id = yt.object_id 
    INNER JOIN y.sys.schemas ys ON yt.schema_id = ys.schema_id 
    GROUP BY yt.object_id, yt.NAME, ys.NAME 
) 
,CTE_XY AS 
(
    SELECT xt.object_id, xt.tblName, COUNT(*) colsNO FROM CTE_X xt 
    INNER JOIN x.sys.columns xc ON xc.object_id = xt.object_id 
    INNER JOIN CTE_Y yt ON xt.tblName = yt.tblName AND xt.colsNo = yt.colsNo 
    INNER JOIN y.sys.columns yc ON yc.object_id = yt.object_id AND xc.name = yc.name AND xc.user_type_id = yc.user_type_id AND xc.precision = yc.precision AND xc.scale = yc.scale 
    GROUP BY xt.object_id, xt.tblName 
) 
,CTE_Tables AS 
(
    SELECT xy.object_id, xy.tblName 
    FROM CTE_XY xy 
    INNER JOIN CTE_X x ON xy.colsNO = x.colsNo AND xy.tblName = x.tblName 
) 
,CTE_Columns AS 
(
    SELECT c.object_id, c.name, c.is_identity FROM CTE_Tables t 
    INNER JOIN y.sys.columns c ON t.object_id = c.object_id 
) 
,CTE_ColConc AS 
(
    SELECT OBJECT_ID, 
      STUFF((SELECT ', ' + name 
        FROM CTE_Columns c2 
        WHERE c2.OBJECT_ID = c1.OBJECT_ID 
        FOR XML PATH('')), 1, 2, '') Cols, 
      MAX(CAST(c1.is_identity AS INT)) AS hasIdentity 
    FROM CTE_Columns c1 
    GROUP BY c1.object_id 
) 
SELECT 
     CASE WHEN hasIdentity = 1 THEN 'SET IDENTITY_INSERT Y.' + tblName + ' ON; ' ELSE '' END 
    + 'INSERT INTO Y.' + tblName + ' (' + Cols + ') SELECT '+ Cols + ' FROM X.' + tblName + ';' 
    + CASE WHEN hasIdentity = 1 THEN 'SET IDENTITY_INSERT Y.' + tblName + ' OFF;' ELSE '' END 
FROM CTE_Tables t 
INNER JOIN CTE_ColConc c ON c.OBJECT_ID = t.object_id 

Результат запроса будет сценарий с INSERT/SELECT заявления. Затем вы можете скопировать его в новое окно запроса и дважды проверить его перед запуском. Если вам нужен автоматический процесс - просто введите результаты в таблицу #temp в конце и запустите строку sp_executesql.

+0

Я могу сформировать ваш ответ в соответствии с моими требованиями, спасибо! – Kurren

2

Если ваши базы данных находятся на разных серверах:

  1. необходимо создать linked server.
  2. INSERT INTO database.schema.Table SELECT * FROM server2.database.schema.Table

Если они находятся на том же сервере:

  1. INSERT INTO database.schema.Table SELECT * FROM database2.schema.Table
+1

Почему вы предполагаете, что обе базы данных находятся на разных серверах ?. Кроме того, правильным способом запроса таблицы с другого сервера является «LinkedServer.Database.schema.table' – Lamak

+1

Это просто неправильно. – JNK

+0

Да, ошибся, опуская базу данных. Предполагалось, что они находятся на разных серверах, потому что иначе это было бы слишком просто ... :) –

0

Еще не знаете, почему нельзя было использовать мастер импорта импорта SSIS для простой передачи данных из одной базы данных в другую, такой же схемы таблиц?

Щелкните правой кнопкой мыши базу данных, чтобы экспортировать, задачи, экспортировать данные ...

+0

Я подумал об этом. Но моя ситуация требует немного более тонкой настройки. Например, я хочу передать все данные из DB X в DB Y, где имена таблиц и столбцов совпадают, а таблица назначения имеет 0 строк. Итак, я подумал, может быть, SQL-запрос позволит мне указать такие условия? – Kurren