我之前在搜索,无法找到任何答案。
让我们来看一个我们有两张桌子的场景:
- 客户
- 订单
和2个数据库:
- DB1
- DB2
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.
这是否有解决方法?我很高兴听到有人有任何想法。 感谢您抽出宝贵的时间阅读本文!
答案 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。