Подсчет динамических параметров для SQL с C#

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

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

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

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

Где @List_of_names может содержать т.е.

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

(меня зовут Йохан, поэтому он там))

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

Я хочу использовать либо 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

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

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

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

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

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

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

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

Количество «поисковых имен» может быть бесконечным, если у меня есть имя: Йохан Андерс Карл Филип Экберг (это всего лишь 1 человек с множеством имен), и я просто пропускаю «Карл Филип», я хочу найти этого пользователя.

Это все проясняет?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
1 505
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

А пока вы можете использовать классику:

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

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

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

Итак, вы бы сказали, что использование параметров таблицы и создание настраиваемой таблицы данных с количеством имен от 1 до N и использование этого в хранимой процедуре было бы хорошо? Я попробую это!

Filip Ekberg 04.12.2008 17:09

Я еще не тестировал это, но я читал, что это будет новая функция SQL Server 2008!

Sergiu Damian 04.12.2008 17:31

Думаю, мне было непонятно, как устроены таблицы! Я немного перефразирую вопрос.

Filip Ekberg 04.12.2008 17:43

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

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

Если вы хотите, чтобы указанное выше помогло найти Андерса Экберга, вам нужен лайк '% Ekberg'

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

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

Это SQL Server, и IN выберет Андерса Экберга. Потому что Select выберет все идентификаторы, у которых Экберг и Андерс и Филип используют этот NameID.

Filip Ekberg 04.12.2008 18:12

Извините, что? Если вы используете select UserId из NameTable, где Name IN (@List_of_names), который является вашим запросом, а ваш список имен ('Anders', 'Ekberg'), например, вы никогда не найдете 'Anders Ekberg' Только точные совпадения

Robert 04.12.2008 18:17

Первый пример был немного плохим, поэтому я добавил еще один. Если вы выберете из таблицы Name и присоединитесь к Name Connections, где Name IN ('Ekberg'), вы получите строки как для Андерса, так и для Филипа. я это проверил. Но проблема в том, что я не могу сделать динамическое количество параметров.

Filip Ekberg 04.12.2008 18:20

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

Robert 04.12.2008 18:22

Точно. Вот тут и начинается проблема :)

Filip Ekberg 04.12.2008 18:25

Что вы действительно хотите, так это передать массив в процесс SQL Server и использовать этот массив в списке IN по вашему выбору, вам может понравиться этот support.microsoft.com/kb/555266, он показывает, как передавать массивы в процесс. Я знаю, что для этого есть nn встроенная поддержка. Обычно мы передаем XML процессу и зацикливаем его.

Robert 04.12.2008 18:27

GL с ним, метод работает, мы его использовали, извиняюсь за первоначальную путаницу :)

Robert 04.12.2008 18:31

Здорово! Я собираюсь взглянуть на это!

Filip Ekberg 04.12.2008 18:33
Ответ принят как подходящий

Похоже, что 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, а не точные совпадения, вы можете это сделать.

Из аналогичного вопроса только для 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();

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

Другие вопросы по теме