Число динамических параметров для SQL с C # - PullRequest
2 голосов
/ 04 декабря 2008

Итак, я подумал о создании динамического SQL-вопроса, то есть я хочу, чтобы количество параметров было динамическим.

Посмотрев на это: Параметризация предложения SQL IN Я думал, что использование слов "% x%" - МЕДЛЕННО и не хорошо.

Что я на самом деле хотел бы сделать, так это использовать ключевое слово IN и сделать его примерно таким:

выберите UserId из NameTable, где Name IN (@List_of_names)

Где @List_of_names может содержать, например,

  • Филип Экберг
  • Filip
  • Экберг Филип
  • Экберг
  • Йохан Экберг
  • Юхан

(мое второе имя - Йохан, вот почему он там))

Так что все это должно совпадать с Йоханом Филипом Экбергом.

Я хочу использовать LINQ to SQL или LINQ to SQL (хранимая процедура) с использованием C #.

Предложения и мысли, пожалуйста!

----------------- Очистка сценария и таблиц -------------------------

Представьте, что у меня есть следующее: таблица с пользователями, таблица с именами и таблица, которая связывает имена с определенным пользователем.

Итак, имея

[User Table]
User ID   Full Name
1         Johan Filip Ekberg
2         Anders Ekberg

[Names]
Name ID   Name
1         Filip
2         Ekberg
3         Johan
4         Anders

[Connect Names]
Name ID   User ID
1         1
2         1
3         1
2         4
2         2

Так что, если я хочу искать: Экберг

Возвращение должно быть:

  • Йохан Филип Экберг
  • Андерс Экберг

Если я хочу найти Йохана Экберга

  • Йохан Филип Экберг

Если я хочу найти Андерса

  • Андерс Экберг

Количество «поисковых имен» может быть бесконечным, если у меня есть имя: Johan Anders Carl Filip Ekberg (это всего лишь 1 человек со многими именами), и я просто передаю «Carl Filip», я хочу найти это Пользователь.

Делает ли это все яснее?

Ответы [ 4 ]

2 голосов
/ 04 декабря 2008

Похоже, что SQL 2008 - это вариант, поэтому лучше всего передавать параметр таблицы. Другим возможным решением для тех, кто еще не может перейти на 2008 год, является написание табличного UDF, который генерирует таблицу из строки с разделителями. Тогда вы можете сделать что-то вроде этого:

SELECT DISTINCT
     CN.user_id
FROM
     dbo.Names N
INNER JOIN dbo.Connect_Names CN ON CN.name_id = N.name_id
INNER JOIN dbo.GetTableFromNameList(@names) T ON T.name = N.name

Это даст вам идентификаторы пользователей, где ЛЮБОЕ из переданных имен совпадает с ЛЮБЫМ из имен пользователя. Если вы хотите изменить его так, чтобы оно совпадало только тогда, когда ВСЕ переданные имена совпадают с одним из имен пользователя, вы можете сделать что-то вроде этого:

SELECT
     CN.user_id
FROM
     dbo.Names N
INNER JOIN dbo.Connect_Names CN ON CN.name_id = N.name_id
INNER JOIN dbo.GetTableFromNameList(@names) T ON T.name = N.name
GROUP BY CN.user_id
HAVING COUNT(*) = (SELECT COUNT(*) FROM dbo.GetTableFromNameList(@names))

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

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

1 голос
/ 04 декабря 2008

Из аналогичного вопроса только для SQL здесь: Запрос SQL: имитация «И» для нескольких строк вместо подзапроса

Попробуйте это.

List<string> targets = new List<string>() {"Johan", "Ekberg"};
int targetCount = targets.Count;
//
List<Users> result = 
  dc.Names
    .Where(n => targets.Contains(n.Name))
    .SelectMany(n =>
      dc.ConnectNames.Where(cn => cn.NameId == n.NameId)
    )
    .GroupBy(cn => cn.UserId)
    .Where(g => g.Count() == targetCount)
    .SelectMany(g =>
      dc.Users.Where(u => u.UserId == g.Key)
    )
    .ToList();

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

1 голос
/ 04 декабря 2008

Вы говорите, что хотите использовать IN? IN ищет точные совпадения, поэтому, если вы используете IN ('Ekberg')

Вы найдете только Экберга, а не Андерса Экберга.

Если вы хотите, чтобы вышеупомянутый нашел Anders Ekberg, вам нужен Like '% Ekberg'

Фактически, во втором примере, где у вас есть имя A B C и вы передаете A C, вы хотите, чтобы оно нашло A B C.

На самом деле вы хотите, чтобы Мне нравилось каждое слово, которое вы произносите. Есть и другие способы добиться того, что звучит так, как вам нужно. Не возражаете, если я спрошу базу данных, с которой вы работаете в первую очередь? :) Спасибо

1 голос
/ 04 декабря 2008

Я слышал, что в SQL Server 2008 есть функция, называемая параметрами таблицы, поэтому вы можете передать таблицу в качестве параметра функции или хранимой процедуре.

До этого вы могли бы использовать классический:

SELECT UserId FROM NameTable WHERE CHARINDEX( '|' + Name + '|', '|Filip Ekberg|Filip|Ekberg Filip|') > 0

Это означает, что имя столбца может быть любым из значений, которые есть в списке.

Вы также можете передать параметр XML в хранимую процедуру и затем использовать его в качестве таблицы в своем коде с помощью команды OPENXML.

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