我有数据库 X 和数据库 Y。X 和 Y 有一些表和列是相同的模式。数据库 Y 中没有数据。
为了将所有数据从数据库 X 传输到表和列名相同的数据库 Y,我可以编写什么 SQL/T-SQL?
谢谢
编辑:两个数据库都在同一台服务器上。我们不知道哪些表和列是同名的,所以我不能手动插入每个表(例如可能有100个同名的表和列)
我有数据库 X 和数据库 Y。X 和 Y 有一些表和列是相同的模式。数据库 Y 中没有数据。
为了将所有数据从数据库 X 传输到表和列名相同的数据库 Y,我可以编写什么 SQL/T-SQL?
谢谢
编辑:两个数据库都在同一台服务器上。我们不知道哪些表和列是同名的,所以我不能手动插入每个表(例如可能有100个同名的表和列)
如果您的数据库位于不同的服务器上:
INSERT INTO database.schema.Table SELECT * FROM server2.database.schema.Table
如果它们在同一台服务器上:
INSERT INTO database.schema.Table SELECT * FROM database2.schema.Table
在收到来自问题的其他信息后,这变得有点有趣,所以我尝试提出一个查询,该查询应该执行比较两个数据库之间的任务并创建 INSERT/SELECT 脚本sys.tables
。sys.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
逐行运行。
仍然不确定为什么不能使用 SSIS 导入导出向导将数据从一个数据库简单地传输到另一个相同的表模式?
右键数据库导出,任务,导出数据...