【问题标题】:Error: SubQuery Returned More than One Value错误:子查询返回多个值
【发布时间】:2010-07-23 15:03:20
【问题描述】:

下面的 SQL 代码给了我一个名义上的错误。

WHERE

        (SELECT Tokens FROM StringSplitter(@DocumentValue, '|', 1)) IN
        (SELECT Tokens FROM StringSplitter(@sortValue, '|', 1))

其中@DocumentValue 和@sortValue 都是由分隔符(在本例中为“|”)分隔的串联字符串。

StringSplitter 函数返回一个包含每个单独字符串的表。例如Fox|Brown|SQL 将返回一个包含三个记录的表:Fox、Brown 和 SQL。

想要发生的是比较两组字符串,如果 @DocumentValue 中的任何单个字符串与来自的任何单个字符串匹配,则将它们插入另一个表(因此是 WHERE) @sortValue。

此实现存在缺陷。如果 @DocumentValue 和 @sortValue 包含多个匹配字符串,则查询将失败,并出现给定错误。

也就是说,考虑到我不关心 哪个 值匹配,我该如何解决这个错误,只要我知道 至少 是否匹配?

Sql Server 2008

【问题讨论】:

  • 好点。 T-SQL,SQL Server 2008。我会去编辑它。

标签: sql tsql sql-server-2008 subquery expression


【解决方案1】:

尝试用 INTERSECT 代替 IN。可能是这样的:

declare @tokenTable table (token nvarchar(50) primary key)
insert into @tokenTable (select ...) INTERSECT (select ...)

编辑: 不能立即确定我搞砸了什么。不过,以下工作有效(请注意,我使用了 @documentValue 和 @sortValue 表,因为我没有您的拆分器功能):

declare @documentValue table(token nvarchar(50) primary key)
declare @sortValue table(token nvarchar(50) primary key)
declare @result table(token nvarchar(50) primary key)

insert into @documentValue (token) values ('A')
insert into @documentValue (token) values ('B')
insert into @documentValue (token) values ('C')
insert into @sortValue select * from @documentValue
delete from @sortValue where token = 'C'


insert into @result 
    select 
        A.* 
    from 
        @documentValue A
    inner join 
        @sortValue B 
    on 
        A.token = B.token
select * from @result

【讨论】:

  • 找出问题所在——在 SQL Server 2000 实例上进行测试!您可以替换此插入查询:insert into @result select token from @documentValue intersect select token from @sortValue
  • intersect 应该可以正常工作,+1。我将语法放入我的答案中。
【解决方案2】:
<your action here>
WHERE EXISTS (SELECT 1 FROM dbo.StringSplitter(@DocumentValue, '|', 1)  AS a
                       JOIN dbo.StringSplitter(@sortValue, '|', 1)  AS b
                       ON a.Tokens = b.Tokens)

【讨论】:

    【解决方案3】:

    我认为你只是错过了一个WHERE(或者放错地方了)

    INSERT INTO YourTable
    SELECT Tokens FROM StringSplitter(@DocumentValue, '|', 1)
    WHERE Tokens IN (SELECT Tokens FROM StringSplitter(@sortValue, '|', 1))
    

    虽然@expedient 对INTERSECT 的回答也应该可以正常工作

    INSERT INTO YourTable
    SELECT Tokens FROM StringSplitter(@DocumentValue, '|', 1)
    INTERSECT
    SELECT Tokens FROM StringSplitter(@sortValue, '|', 1)
    

    【讨论】:

      【解决方案4】:

      加入?

       (SELECT count(*)
        FROM StringSplitter(@DocumentValue, '|', 1) AS one JOIN
             StringSplitter(@sortValue, '|', 1) AS two ON one.Tokens = two.Tokens
       ) > 0
      

      【讨论】:

        【解决方案5】:
        insert into yourNewTableGoesHere(Token)
        select a.Tokens 
        from StringSplitter(@DocumentValue, '|', 1) a
        where exists (select Tokens 
                        from StringSplitter(@sortValue, '|', 1) 
                        where Tokens = a.Tokens)
        

        【讨论】:

          【解决方案6】:

          为什么不把你的令牌放在 2 个临时表中

          (SELECT Tokens INTO #DocTokens FROM StringSplitter(@DocumentValue, '|', 1)) IN 
          (SELECT Tokens INTO #SortTokens FROM StringSplitter(@sortValue, '|', 1)) 
          
          SELECT d.Tokens INTO #Tokens FROM #DocTokens d JOIN #SortTokens s ON s.Tokens = d.Tokens
          

          这只会给你匹配。然后,您可以将查询加入到#Tokens 以过滤您的主要选择。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-02-15
            • 1970-01-01
            相关资源
            最近更新 更多