Классический ASP - разделяется и содержится в простом запросе SQL - PullRequest
0 голосов
/ 07 октября 2009

У меня следующий SQL-запрос:

SQL = "ВЫБРАТЬ * ИЗ ПРОДУКТА, ГДЕ ProductCategoryId =" & Request.QueryString ("CategoryId")

Этот запрос указывает, чтобы получить все продукты из ОДНОЙ категории. Мне нужна возможность, чтобы товары могли быть из некоторых категорий, а не только из одной категории.

Итак, я изменил поле [Product] .ProductCategoryId на varchar (50) и написал несколько идентификаторов категорий, разделенных запятыми, например:

1,5,7,4

Теперь, как мне заставить это работать в запросе SQL? В ASP есть функции Split and Contains (http://www.devx.com/vb2themax/Tip/18364)), но как я могу это сделать в SQL?

Спасибо и простите за английский ...

Ответы [ 4 ]

3 голосов
/ 07 октября 2009

Обязательное примечание: НИКОГДА не объединять предоставленные пользователем данные в SQL-запрос; вы открываете себя для атак с использованием SQL-инъекций.

Мой предыдущий ответ (с использованием «IN») был основан на ошибочной идее, что вы собирали у пользователя несколько идентификаторов и выполняли поиск по столбцу с одним значением. Но вы делаете противоположное - столбец имеет несколько значений, и вы пытаетесь сопоставить одно значение, полученное от пользователя.

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

SQL = "SELECT Product.* FROM Product, ProductCategory WHERE ProductCategory.ProductId=Product.ID AND ProductCategory.CategoryId = " & Request.QueryString("CategoryId")

Если вы действительно хотите сделать запятую, вы можете выполнить поиск, используя LIKE и% групповые символы, но это будет хрупким (например, вы должны убедиться, что идентификатор "2" t соответствует "12").

2 голосов
/ 07 октября 2009

Не даром, но WHERE ProductCategoryId = " & Request.QueryString("CategoryId") - БОГОВОЙ УЖАСНЫЙ способ выполнения вашего запроса.

Вы только что открылись для безумных SQL-инъекций атак.

1 голос
/ 08 октября 2009

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

В результате вы получите функцию разбиения TSQL и можете использовать ее следующим образом:

SELECT
    y.*
    FROM YourTable y
        INNER JOIN dbo.FN_ListToTable(',','1,2,3,444,5,,,6') s ON y.ID=s.ListValue

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

Чтобы этот метод работал, вам нужно выполнить настройку единовременного расписания:

SELECT TOP 10000 IDENTITY(int,1,1) AS Number
    INTO Numbers
    FROM sys.objects s1
    CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)

После настройки таблицы чисел создайте эту функцию:

CREATE FUNCTION [dbo].[FN_ListToTable]
(
     @SplitOn  char(1)      --REQUIRED, the character to split the @List string on
    ,@List     varchar(8000)--REQUIRED, the list to split apart
)
RETURNS TABLE
AS
RETURN 
(   ----------------
    --SINGLE QUERY-- --this will not return empty rows
    ----------------
    SELECT
        ListValue
        FROM (SELECT
                  LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
                  FROM (
                           SELECT @SplitOn + @List + @SplitOn AS List2
                       ) AS dt
                      INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
                  WHERE SUBSTRING(List2, number, 1) = @SplitOn
             ) dt2
        WHERE ListValue IS NOT NULL AND ListValue!=''
);
GO 

Теперь вы можете легко разбить строку CSV на таблицу и присоединиться к ней:

select * from dbo.FN_ListToTable(',','1,2,3,,,4,5,6777,,,')

ВЫВОД:

ListValue
-----------------------
1
2
3
4
5
6777

(6 row(s) affected)

Вы можете передать строку CSV в процедуру и обработать только строки для заданных идентификаторов или просто использовать ее в запросе, например:

SELECT
    y.*
    FROM YourTable y
        INNER JOIN dbo.FN_ListToTable(',',@GivenCSV) s ON y.ID=s.ListValue
1 голос
/ 07 октября 2009
...