该查询的正确解决方案是什么

时间:2015-01-07 06:08:01

标签: sql

insert into Orders values ('1111',
    (Select CustomerID from Customers where CustomerID = (Select CustomerID from customers where CompanyName= 'erp')),
    (Select EmployeeID from Employees where EmployeeID = (Select EmployeeID from Employees where FirstName  = 'Hello')),
    (Select ShipperID  from Shippers  Where ShipperID  = (Select ShipperID  from Shippers  where CompanyName= 'Ntat')),
    '2014-12-01','2013-12-01','22','22','aa','aa','dd','gs','ga','ga','qq');

我无法运行此查询,因为我收到错误:

  

错误代码:1242。子查询返回的行数超过1行

请帮助

3 个答案:

答案 0 :(得分:2)

INSERT命令有两种形式:

(1)您可以使用所有值,如文字或SQL Server变量 - 在这种情况下,您可以使用INSERT .. VALUES()方法:

INSERT INTO dbo.YourTable(Col1, Col2, ...., ColN)
VALUES(Value1, Value2, @Variable3, @Variable4, ...., ValueN)

注意:我建议始终明确指定要插入数据的列列表 - 这样,如果您的表突然有一个额外的列,或者如果突然您的表有额外的列,您将不会有任何令人讨厌的意外您的表具有IDENTITY或计算列。是的 - 这是一个更多的工作 - 一次 - 但是你的INSERT陈述尽可能坚实,如果你的桌子你不必经常摆弄它变化。

(2)如果您将所有值都作为文字和/或变量,而是您想要依赖另一个表,多个表或视图,提供值,然后您可以使用INSERT ... SELECT ...方法:

INSERT INTO dbo.YourTable(Col1, Col2, ...., ColN)
   SELECT
       SourceColumn1, SourceColumn2, @Variable3, @Variable4, ...., SourceColumnN
   FROM
       dbo.YourProvidingTableOrView

在这里,您必须在SELECT中定义与INSERT所期望的完全相同的项目 - 这些项目可以是表格(或视图)中的列,或者那些可以是文字或变量。再次:明确提供要插入的列的列表 - 参见上文。

您可以使用其中一个 - 但无法混合两者 - 您无法使用VALUES(...)然后进行SELECT查询在你的价值列表中间 - 选择其中一个 - 坚持下去。

有关详细信息和进一步深入报道,see the official MSDN SQL Server Books Online documentation on INSERT - 与SQL Server相关的所有问题的绝佳资源!

答案 1 :(得分:1)

<强> TL; DR

您的应用程序存在设计完整性问题,您将无法在Sql查询级别进行恢复。

详情

在插入过程中使用非键值查找外键不是一个好主意,正如您现在发现的那样 - 错误消息表明一个或多个子查询已匹配多行,现在您是面对幂等问题。

e.g。让我们说,在这种情况下,您有多个名为&#39; Hello&#39;的员工。您的选项似乎是:

  • 将订单归于FIRST员工,其名称为“Hello&#39; - 显然这对进行销售的真正员工可能不公平
  • 插入多个订单,每个员工一个 - 但现在我们面临双重送货和结算问题的风险。

因此,真正的解决方案是确保您始终通过您的应用程序为每个FK角色列携带所有关键字段(主键或唯一键,无论是自然键还是唯一键)。

这意味着您可以放心地插入数据

insert into Orders values ('1111',
@CustomerId, 
@EmployeeId, 
@ShipperId, 
'2014-12-01','2013-12-01','22','22','aa','aa','dd','gs','ga','ga','qq');

答案 2 :(得分:0)

你必须在程序的帮助下做这件事,因为你在select语句中得到了多个值....

您必须在insert语句

中逐个传递值
 create procedure test
 as
  declare @customerid int    
  declare @empid int    
  declare @shipperid int    
begin    
  set @customerid= (Select CustomerID from customers where CompanyName='erp')   
  set @empid=(Select EmployeeID from Employees where FirstName = 'Hello')    
  set @shipperid =(Select ShipperID from Shippers where CompanyName='Ntat')   
  -- but note down that it will assign last value to variable     
   -- but if it returns more than one value you will have to create a temporary table       and    --then assign value to it and will have to apply loop    
  -- like this create #temp1 (customerid id) 
  insert into orders values(@customerid,@smpid,@shipperid,'val1','val2'...ans so one)
 end