尽管子查询返回预期值,但使用Select插入会导致“子查询返回的值超过1”

时间:2015-11-11 15:56:33

标签: sql-server tsql select sql-insert

使用MS Sql Server 2008我试图使用花哨的插入/选择语法将多行插入users_roles表。执行此查询时,我收到错误

  

子查询返回的值超过1。这是不允许的   子查询跟随=,!=,<,< =,>,> =或当子查询用作   表达。

两个子查询在自行执行时都会返回预期值。第一个子查询中有多个记录,第二个子查询中有一个记录。

insert into users_roles(userid, roleid)
        select 
            (select distinct users.id as userID from users 
                inner join users_roles on users.id = users_roles.userid 
                inner join roles on users_roles.roleid = roles.id
                where roles.projectid = 1)
            , 
            (select id as roleID from roles where projectid = 1 and name = 'ALL')

我错过了什么?

3 个答案:

答案 0 :(得分:1)

SQL甚至不知道第二个(或第一个)是否会返回0,1或多个

decalare @roleID int;
set @roleID = (select top 1 id from roles where projectid = 1 and name = 'ALL');
insert into users_roles(userid, roleid)
select distinct users.id as userID, @roleID 
from users 
inner join users_roles on users.id = users_roles.userid 
inner join roles on users_roles.roleid = roles.id
where roles.projectid = 1;

答案 1 :(得分:0)

您可以使用此语法插入多个记录或单个记录,但不能同时插入!按照目前的情况,您的查询尝试在第一列中选​​择多个值,在第二列中选择一个值。

您不需要两个子查询。只需将您的第一个子查询放入外部查询(返回多行),然后您的第二个子查询将为每个子查询返回一行:

insert into users_roles(userid, roleid)
    select distinct users.id as userID,
           (select id as roleID from roles where projectid = 1 and name = 'ALL') as roleID
            from users 
            inner join users_roles on users.id = users_roles.userid 
            inner join roles on users_roles.roleid = roles.id
            where roles.projectid = 1) 

请注意,您并不真正需要列别名,它们只是为了清晰起见。

答案 2 :(得分:-1)

第一个子查询中的多行导致了问题。您可以按照构建它的方式将其作为列。如果它返回多行,则sql不知道你想要哪一行。

这样的事情可能就是你想要的。

select distinct users.id as userID from users 
inner join users_roles on users.id = users_roles.userid 
inner join roles on users_roles.roleid = roles.id
cross apply 
(
    select id as roleID from roles where projectid = 1 and name = 'ALL'
)
where roles.projectid = 1