Это можно было бы сделать без динамического c SQL, но его нужно было бы жестко закодировать.
Каждый раз, когда вы сохраняете где-нибудь имена столбцов и хотите делать логические операции c на основе этого, скорее всего, это рано или поздно приведет вас к Dynami c SQL.
Более того, он не должен быть неэффективным, так как запрос таблицы с необходимыми полями не займет много времени, так как ( Полагаю, что он не будет большим, и после того, как вы не будете проверять полученные динамические значения c SQL, вы можете создать надлежащие индексы, чтобы уменьшить количество запросов к другой таблице (например, ContactTypeId
- хороший кандидат для индекса).
Сказав это, в данном подходе используется функция Dynami c SQL (примечание string_agg
, которая доступна в новых SQL серверах), для старых вам необходимо применить другой подход, который можно легко найти на этом сайте я использовал string_agg
для краткости):
create table TestTable (ContactID int, ContactTypeID int, FirstName varchar(30), LastName varchar(30), HomePhone varchar(30), Address varchar(30), Email varchar(30));
insert into TestTable values
(1 , 1 ,'Mary' ,'Smith', Null ,Null , Null),
(2 , 1 ,'Jim' ,'Smith', '999-999-9999' ,Null , Null),
(3 , 2 ,'Steve' ,'Jones', Null ,Null , Null);
create table RequiredInfo (ContactTypeID int, FieldID int, ColumnName varchar(30), FieldName varchar(30));
insert into RequiredInfo values
(1, 1, 'FirstName', 'First Name'),
(1, 2, 'LastName', 'Last Name'),
(1, 3, 'HomePhone', 'Home Phone'),
(2, 1, 'FirstName', 'First Name'),
(2, 2, 'LastName', 'Last Name'),
(2, 3, 'HomePhone', 'Home Phone'),
(2, 4, 'Address', 'Home Address'),
(2, 5, 'Email', 'Email Address');
declare @sql as varchar(1000) = 'select * from TestTable where ';
select @sql = @sql + string_agg(clauses, ' or ') from (
select '( ContactTypeId = ' + cast(ContactTypeId as varchar(10)) + ' and (' +
string_agg( ColumnName + ' is null', ' or ' ) + ') )' clauses
from RequiredInfo
group by contacttypeid
) a
exec (@sql)