2010-07-23 3 views
0

У меня есть следующий фрагмент кода SQL, который дает мне титульную ошибку.Ошибка: SubQuery возвратил больше одного значения

WHERE 

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

Где @DocumentValue и @sortValue оба сцепленные строки, разделенные разделителем (в данном случае, «|»).

Функция StringSplitter возвращает таблицу каждой отдельной строки. например Fox | Brown | SQL вернет таблицу с тремя записями: Fox, Brown и SQL.

То, что я хочу произойти, чтобы сравнить два набора строк, вставляя их в другую таблицу (отсюда WHERE), если какой-либо из отдельных строк из @DocumentValue соответствует ни одному из отдельных строк из @sortValue.

Эта реализация является ошибочной. Если @DocumentValue и @sortValue когда-либо содержат более одной строки соответствия, запрос терпит неудачу с данной ошибкой.

Это говорит, как я мог исправить эту ошибку, полагая, что я не забочусь , которые значения совпадает, до тех пор, как я знаю, является ли или не по крайней мере, один сделал?

Sql Server 2008

+1

Какая база данных? – pascal

+0

хорошо пункт. T-SQL, SQL Server 2008. Я буду редактировать это. –

ответ

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

Попробуйте заменить INTERSECT для IN. Может быть что-то вроде:

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

Edit: Не сразу уверен, что я goofed с этим. Следующие работы, хотя (обратите внимание, что я использовал таблицы для @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 
+0

Изменение IN to INTERSECT дало мне синтаксическую ошибку. –

+0

Выяснил, в чем проблема: тестирование на экземпляре SQL Server 2000!Вы можете заменить эту вставку запрос: \t вставку в @result \t выберите маркер из @documentValue \t пересекается \t выберите маркер из @sortValue – expedient

+0

'intersect' должны работать нормально для этого, +1. Я ввел синтаксис в свой ответ. –

0

JOIN?

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

Вы просто отсутствует WHERE я думаю (или получил его в неправильном месте)

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

Хотя @ целесообразных по INTERSECT должен работать нормально, а

INSERT INTO YourTable 
SELECT Tokens FROM StringSplitter(@DocumentValue, '|', 1) 
INTERSECT 
SELECT Tokens FROM StringSplitter(@sortValue, '|', 1) 
0
insert into yourNewTableGoesHere(Token) 
select a.Tokens 
from StringSplitter(@DocumentValue, '|', 1) a 
where exists (select Tokens 
       from StringSplitter(@sortValue, '|', 1) 
       where Tokens = a.Tokens) 
0

Почему нет t положить ваши жетоны в 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, чтобы отфильтровать ваш основной выбор.

Смежные вопросы