Переменная предложения SQL Where IN

#sql #sql-server #vba #ssms

#sql #sql-сервер #vba #ssms

Вопрос:

У меня есть процесс, в котором мне в основном приходится просматривать электронную таблицу и искать имена пользователей по имени во внутренней системе по имени / фамилии и DOB, а затем извлекать настройки в том, что они посещают.

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

Я хочу знать, могу ли я в любом случае сделать это более простым способом, в конечном итоге я подключусь к БД через VBA и получу данные таким образом. Я не знаю, могу ли я вставить переменную в предложение IN и создать пользовательскую функцию, которая создаст переменную, которая вернет что-то вроде ‘Bob’, ‘Keith’ и т. Д., Чтобы ее можно было передать в SQL (надеюсь, это имеет смысл). Кроме того, можете ли вы передавать сокращенные имена таблиц, если вы передаете SQL через VBA?

Также я не уверен, возможно ли, чтобы параметр возвращался в правильные строки или лучше использовать какую-либо функцию поиска по нескольким критериям?

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

 SELECT  p.Forename
      ,p.Surname
      ,p.Birth_Date
      ,p.xxx
      ,p.xxx
      ,csc.name
      ,cs.name2 
FROM dbo.Person AS P
INNER JOIN dbo.banana AS csc ON csc.xxx = p.xxx
INNER JOIN dbo.apple AS cs ON cs.xxx = p.xxx
WHERE p.forename IN('xxx', 'xxx', 'xxx', 'xxx')
  AND p.surname IN('xx','xx','xx', 'xx')
  AND p.Birth_Date IN(N'xx', N'xxx', N'xxx', N'xxx')

 

Комментарии:

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

2. Храните ли вы даты в столбце nvarchar?

3. Канонический способ сделать это — использовать TVP, но старомодный драйвер ADO, используемый в VBA, его не поддерживает. Может быть, CSV, а затем разделить его на STRING_SPLIT ?

4. Привет @ jarlh даты указаны как даты, я думаю, это не обязательно должно быть в апострофах?

5.Нет, для этого не нужен символ обозначения ( N ) @paulr23 . N'xx' подразумевает, что ваш столбец Birth_Date является an nvarchar , поскольку вы передаете nvarchar ему литералы; что вы сделали бы только с an nvarchar . Даты при использовании строк лучше всего использовать как varchar значения в формате yyyyMMdd или yyyy-MM-ddThh:mm:ss.nnnnnnn , но на самом деле вы должны передавать их как тип данных даты и времени (хотя это невозможно, если вам нужно перейти к STRING_SPLIT методу).

Ответ №1:

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

Вот пример того, что я имею в виду:

 DECLARE
    @forenames xml = '<names><name>Bill</name><name>Steven</name><name>Steve</name></names>',
    @surnames xml = '<names><name>Gates</name><name>Spielberg</name><name>Jobs</name></names>',
    @birthdates xml = '<dates><date>10/28/1955</date><date>12/18/1946</date><date>02/24/1955</date></dates>';

SELECT 
    p.Forename
    , p.Surname
    , p.Birth_Date
    , p.xxx
    , p.xxx
    , csc.name
    , cs.name2 
FROM dbo.Person AS P
INNER JOIN dbo.banana AS csc ON csc.xxx = p.xxx
INNER JOIN dbo.apple AS cs ON cs.xxx = p.xxx
WHERE 
    p.forename IN(
        SELECT x.f.value( '.', 'varchar(50)' ) FROM @forenames.nodes( '//names/name' ) x( f )
    )
    AND p.surname IN(
        SELECT x.f.value( '.', 'varchar(50)' ) FROM @surnames.nodes( '//names/name' ) x( f )
    )
    AND p.Birth_Date IN(
        SELECT x.f.value( '.', 'varchar(50)' ) FROM @birthdates.nodes( '//dates/date' ) x( f )
    );
 

Комментарии:

1. спасибо за предложение, не могли бы вы вообще объяснить, что это такое на самом деле, поскольку я не слишком хорошо это понимаю. И как я передаю значения в xml, это будет вручную?

2. Это позволяет передавать список значений через строку в XML, с которой можно использовать IN .