#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
является annvarchar
, поскольку вы передаетеnvarchar
ему литералы; что вы сделали бы только с annvarchar
. Даты при использовании строк лучше всего использовать как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
.