Charindex в SQL не дает желаемого результата - PullRequest
1 голос
/ 18 мая 2009

У меня есть строка, которая является выводом из функции, например: "1,3,16, .., ..".

Я использовал следующий запрос SQL и запустил его в построителе запросов в Visual Studio, и он не дал мне никаких синтаксических ошибок.

SELECT ItemID, Name, RelDate, Price, Status FROM item_k WHERE (ItemID = cast(charindex(',', @itemIDs) as int))

Я дал 3,16 в качестве значений параметра @itemID, но он не дал желаемых результатов.

Затем я использовал следующий SQL-запрос (без charindex):

SELECT ItemID, Name, RelDate, Price, Status FROM item_k WHERE (ItemID = @itemIDs)

Я дал 3 в качестве значения параметра @itemID и получил для него результат. Я также дал 16 (в отдельном случае) в качестве значения параметра @itemID и получил для него результат. Я пришел к выводу, что есть значения для ItemID 3 и 16.

Почему запрос SQL с charindex не дает мне никакого результата?

Я не могу понять проблему здесь, пожалуйста, помогите.

Ответы [ 4 ]

3 голосов
/ 18 мая 2009

Вот еще одно решение. По моему опыту, когда у вас есть список ItemIds в виде строки значений, разделенных запятыми, вам нужна функция split. Это очень полезно иметь.

Используя функцию разделения, вы можете просто выполнить ВНУТРЕННЕЕ СОЕДИНЕНИЕ с результатами вызова функции разделения и передачи списка ItemIds и связанного с ним разделителя следующим образом:

DECLARE @ItemIDs varchar(100)
SET @ItemIDs = '1,3,16,22,34,35'

SELECT 
     ItemID, Name, RelDate, Price, Status 
FROM item_k
     INNER JOIN dbo.UTILfn_Split(@ItemIDs,',') itemIds 
       ON itemIds.Value = item_k.ItemID

Поначалу это может показаться сложным, но это более элегантное и удобное решение. Вот код для создания функции dbo.UTILfn_Split . Вам нужно сначала запустить это:

IF EXISTS (SELECT * FROM sysobjects WHERE id = 
object_id(N'[dbo].[UTILfn_Split]') AND xtype IN (N'FN', N'IF', N'TF'))
DROP FUNCTION [dbo].[UTILfn_Split]
GO

CREATE FUNCTION dbo.UTILfn_Split
(
    @String nvarchar (4000),
    @Delimiter nvarchar (10)
)
RETURNS @ValueTable TABLE ([Value] nvarchar(4000))
BEGIN
 DECLARE @NextString nvarchar(4000)
 DECLARE @Pos int
 DECLARE @NextPos int
 DECLARE @CommaCheck nvarchar(1)

 --Initialize
 SET @NextString = ''
 SET @CommaCheck = RIGHT(@String,1)  
 --Check for trailing Comma, if not exists, INSERT
 --if (@CommaCheck <> @Delimiter )
 SET @String = @String + @Delimiter

 --Get position of first Comma
 SET @Pos = CHARINDEX(@Delimiter,@String)
 SET @NextPos = 1

 --Loop while there is still a comma in the String of levels
 WHILE (@pos <>  0)  
 BEGIN
  SET @NextString = SUBSTRING(@String,1,@Pos - 1)

  INSERT INTO @ValueTable ( [Value]) Values (@NextString)

  SET @String = SUBSTRING(@String,@pos +1,LEN(@String))

  SET @NextPos = @Pos
  SET @pos  = CHARINDEX(@Delimiter,@String)
 END 
 RETURN
END
1 голос
/ 18 мая 2009

Вы можете создать запрос динамически, используя оператор in:

declare @Sql varchar(1000)
set @Sql = 'select ItemID, Name, RelDate, Price, Status from item_k where ItemID in (' + @itemIDs + ')'
exec(@Sql)

Будьте осторожны с тем, что вы отправляете в процедуру. Как и в случае любого динамического SQL, если данные поступают из пользовательского ввода без проверки, процедура широко открыта для внедрения SQL.

Edit:
Вот что происходит в запросе:

Сначала мы объявляем переменную для хранения динамического запроса. Это просто varchar достаточно большая переменная.

В переменной мы помещаем переменную @itemIDs между двумя строками, чтобы сформировать запрос. Значения, разделенные запятыми, помещаются в скобки оператора in, чтобы сформировать выражение, подобное: where ItemID in (1,3,16)

Наконец, команда exec выполняет запрос в переменной.

1 голос
/ 18 мая 2009

CHARINDEX просто возвращает позицию, в которой символ находится в строке.

Таким образом, когда @ItemIDs установлен на '3,16', тогда ваше WHERE предложение ...

WHERE (ItemID = CAST(CHARINDEX(',', @ItemIDs) AS INT))

... эквивалентно ...

WHERE ItemID = 2

... потому что CHARINDEX возвращает 2, поскольку запятая находится в позиции 2 строки '3,16'.

Я предполагаю, что (a) в вашей таблице нет строки, где ItemID равно 2, а (b) нет очень хочу, чтобы позиция запятой определяла, какие строки будут возвращены.

0 голосов
/ 18 мая 2009

Try ВЫБЕРИТЕ ItemID, Имя, RelDate, Цена, Статус ОТ item_k ГДЕ ItemID in (@itemIDs)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...