SQL: вернуть «true», если список записей существует? - PullRequest
29 голосов
/ 19 мая 2010

Альтернативное название может быть: Проверить наличие нескольких строк?

Используя комбинацию SQL и C #, я хочу, чтобы метод возвращал значение true, если все продукты в списке существуют в таблице. Если это можно сделать все на SQL, это было бы предпочтительнее. Я написал метод, который возвращает, существует ли один productID, используя следующий SQL:

SELECT productID FROM Products WHERE ProductID = @productID

Если это возвращает строку, то метод c # возвращает true, иначе false.

Теперь мне интересно, есть ли у меня список идентификаторов продуктов (не большой список, как правило, младше 20). Как я могу написать запрос, который будет возвращать строку, если все идентификаторы продукта существуют, и нет строки, если один или несколько идентификаторов продукта не существует?

(Maybe something involving "IN" like:
SELECT * FROM Products WHERE ProductID IN ('1', '10', '100', 'ABC'))

EDIT:

Как выражается результат, для меня не важно. Возвращает ли запрос 1 или 0, пустой набор результатов или непустой, true или false, не имеет значения. Я бы предпочел ответ: 1) легко читаемый и понятный и 2) исполнитель

Я предполагал объединить список идентификаторов продуктов с SQL. Очевидно, что это открывает код до внедрения SQL (идентификаторы продукта на самом деле varchar. В этом случае вероятность невелика, но все же мы хотим избежать этой возможности). Так что, если есть способ обойти это, было бы лучше. Использование SQL Server 2005.

Идентификатор продукта: varchar

Ответы [ 13 ]

0 голосов
/ 19 мая 2010
// not familiar with C#, but C#'s equivalent of PHP's:
$count = count($productIds); // where $productIds is the array you also use in IN (...)

SELECT IF ((SELECT COUNT(*) FROM Products WHERE ProductID IN (1, 10, 100)) = $count, 1, 0)
0 голосов
/ 19 мая 2010

Предполагается, что вы используете SQL Server, логический тип не существует, но есть битовый тип, который может содержать только 0 или 1, где 0 представляет False, а 1 представляет True.

Я бы пошел по этому пути:

select 1
    from Products
    where ProductId IN (1, 10, 100)

Здесь будет возвращена нулевая или нулевая строка (если строки не существует).

Или даже:

select case when EXISTS (
    select 1
        from Products
        where ProductId IN (1, 10, 100)
    ) then 1 else 0 end as [ProductExists]

Здесь любое из скалярных значений 1 или 0 будет всегда возвращаться (если строки не существует).

0 голосов
/ 19 мая 2010

Вашему c # придется немного поработать (считая количество переданных идентификаторов), но попробуйте это:

select (select count(*) from players where productid in (1, 10, 100, 1000)) = 4

Edit:

4 определенно может быть параметризован, как и список целых чисел.

Если вы не генерируете SQL из строки, введенной пользователем, вам не нужно беспокоиться о атаках. Если это так, вам просто нужно убедиться, что вы получаете только целые числа. Например, если вы взяли строку «1, 2, 3, 4», вы бы сделали что-то вроде

String.Join(",", input.Split(",").Select(s => Int32.Parse(s).ToString()))

Это выбросит, если вы ошиблись. Затем просто установите это как параметр.

Кроме того, обязательно убедитесь, что в особом случае, если items.Count == 0, так как ваша БД захлебнется, если вы отправите ее where ParameterID in ().

...