首页 文章

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

提问于
浏览
1

使用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 回答

  • -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;
    
  • 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)
    

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

  • 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
    

相关问题