-1

我有数据库 X 和数据库 Y。X 和 Y 有一些表和列是相同的模式。数据库 Y 中没有数据。

为了将所有数据从数据库 X 传输到表和列名相同的数据库 Y,我可以编写什么 SQL/T-SQL?

谢谢

编辑:两个数据库都在同一台服务器上。我们不知道哪些表和列是同名的,所以我不能手动插入每个表(例如可能有100个同名的表和列)

4

3 回答 3

2

如果您的数据库位于不同的服务器上:

  1. 你需要创建一个链接服务器
  2. INSERT INTO database.schema.Table SELECT * FROM server2.database.schema.Table

如果它们在同一台服务器上:

  1. INSERT INTO database.schema.Table SELECT * FROM database2.schema.Table
于 2013-05-14T14:38:19.163 回答
2

在收到来自问题的其他信息后,这变得有点有趣,所以我尝试提出一个查询,该查询应该执行比较两个数据库之间的任务并创建 INSERT/SELECT 脚本sys.tablessys.columns

测试设置:

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逐行运行。

于 2013-05-15T08:19:13.897 回答
0

仍然不确定为什么不能使用 SSIS 导入导出向导将数据从一个数据库简单地传输到另一个相同的表模式?

右键数据库导出,任务,导出数据...

于 2013-05-15T16:29:46.047 回答