SQL 在另一个 table 上使用 JOIN 从 DB1 插入到 DB2 并避免指定列名

SQL Insert from DB1 to DB2 using JOIN on another table and avoid specifying column names

我之前一直在搜索,但找不到任何答案。

假设我们有 2 个 tables:
- 客户
- 订单

和 2 个数据库:
- DB1
- DB2

客户:

订单:

DB1 和 DB2 具有相同的 table 结构,但包含不同的数据。
现在假设我想 运行 这个查询:

 INSERT INTO
    DB1.dbo.Order
 SELECT
    ID, CustomerID
 FROM 
    DB2.dbo.Order AS db2Order
    LEFT JOIN
    DB2.dbo.Customer AS db2Cust
 ON 
    db2Order.CustomerID = db2Cust.ID

此查询按预期工作。现在让我们提出一个场景,您在 table 上有超过 20 列并且您不想遍历并指定所有列,我想做这样的事情:

INSERT INTO
    DB1.dbo.Order
 SELECT
 (
    SELECT COLUMN_NAME
    FROM DB1.INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME = N'Order'
 )
 FROM 
    DB2.dbo.Order AS db2Order
    LEFT JOIN
    DB2.dbo.Customer AS db2Cust
 ON 
    db2Order.CustomerID = db2Cust.ID

因为我们 JOIN tables 我们必须指定列,因为它们不匹配 Order table 结构,因为我们试图插入,我们必须满足这个例外:
Column name or number of supplied values does not match table definition.

有解决办法吗?如果有人有任何想法,我会很高兴听到。 感谢您花时间阅读本文!

首先在写插入时,列出所有列。当查询中有多个列时,请使用 table alises:

INSERT INTO DB1.dbo.Order(Id, CustomerId)
    SELECT c.ID, c.CustomerID
    FROM DB2.dbo.Order o LEFT JOIN
         DB2.dbo.Customer c
         ON o.CustomerID = c.ID;

那么,在这种情况下,您想要 INSERT 似乎不太可能(我的意思是,JOIN 可能甚至不是必需的),但这是另一回事。

SQL 查询中的 table 和列需要明确选择。如果你想将查询视为一个字符串,你可以只替换字符串的一部分,你可以这样做。它被称为动态 SQL 并且在 SQL 服务器中,您将使用 sp_executesql.

执行它

相反,只需查询数据库中的列,然后自己将它们放入查询中。在学习动态 SQL.

之前,请确保您对 SQL 有很好的掌握

感谢@GordonLinoff 为我指出动态 SQL,这是我的解决方案:

DECLARE @CustomerID SMALLINT = 201,
        @ID         SMALLINT = 14007

DECLARE @columns AS NVARCHAR(1500) = '',
        @params  AS NVARCHAR(1000),
        @query   AS NVARCHAR(2000)

SELECT @columns += COLUMN_NAME + ',' FROM DB1.dbo.Order.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = N'Order'
SELECT @columns = SUBSTRING(@columns, 0, LEN(@columns))

SET @params = '@CustomerID smallint, @ID smallint'
SET @query = 'INSERT INTO 
    DB1.dbo.Order
SELECT
    %s
FROM 
    DB2.dbo.Order AS db2Order
    LEFT JOIN
    DB2.dbo.Customer AS db2Cust
ON 
    db2Order.CustomerID = db2Cust.ID
WHERE 
    db2Order.CustomerID = @CustomerID AND db2Cust.ID = @ID'
EXEC sp_addmessage 50001, 16, @query, NULL, NULL, 'replace'
SET @query = FORMATMESSAGE(50001, @columns)
EXEC sp_executesql @query, @params, @CustomerID=@CustomerID, @ID=@ID

我在这里使用了 sp_addmessage,所以我可以使用 FORMATMESSAGE 函数,因为在 SQL 版本 < 2012 中,formatmessage func 不支持直接使用字符串。希望对某人有所帮助!