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

时间:2018-01-27 11:08:04

标签: sql database join names

我之前在搜索,无法找到任何答案。

让我们来看一个我们有两张桌子的场景:
- 客户
- 订单

和2个数据库:
- DB1
- DB2

客户:

  • ID int
  • 名称varchar

订单:

  • ID int
  • CustomerID int

DB1和DB2具有相同的表结构并包含不同的数据。
现在让我们说我想运行这个查询:

 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

此查询按预期工作。现在让我们设置一个场景,你在桌子上有超过20列,你不想通过并指定所有这些列,我想做类似的事情:
< / p>

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

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

这是否有解决方法?我很高兴听到有人有任何想法。 感谢您抽出宝贵的时间阅读本文!

2 个答案:

答案 0 :(得分:0)

感谢@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版本中&lt; 2012年,formatmessage func不支持直接使用字符串。希望能帮助别人!

答案 1 :(得分:-1)

首先编写插入时,列出所有列。如果查询中有多个列,请使用表格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查询中的表和列需要显式选择。如果要将查询视为字符串,只需替换部分字符串,就可以执行此操作。它被称为动态SQL,在SQL Server中,您将使用sp_executesql执行它。

相反,只需在数据库中查询列并自行将它们放入查询中。在学习动态SQL之前,请确保您已经很好地掌握了SQL。