2013-04-16 2 views
2

У меня есть скалярная функция, которая возвращает VARCHAR имени столбца.Элегантный способ выбора столбца на основе результата переменной/запроса?

Я хотел бы использовать этот результат в основе запроса на выборку на, так:

SELECT dbo.udf_GetColName('Val1', ColumnFromThisTable, etc) AS myCol 
FROM tbl_ThisTable WHERE ... 

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

То, что я хотел бы для выбора заявления, чтобы вернуть значение столбца возвращаемого функцией , так:

SET @sql = 'SELECT ' + dbo.udf_GetColName('Val1', ColumnFromThisTable, etc) + ' AS myCol 
FROM tbl_ThisTable WHERE ... ' 

И запустить EXEC sp_executesql

Есть ли лучший способ, чем динамический SQL-маршрут? Каким-то образом SQL может запросить этот столбец как вывод из UDF?


EDIT ДОБАВИТЬ

Это где бизнес нужно управлять правилами, по которым выход выбран, следовательно, они должны быть в обновляемой таблице. Если они жестко закодированы в SELECT функций Table-Valued, это уже не тот бизнес, который их контролирует.

Так что да, запрос очень настраиваемый, но в этом случае «хорошая вещь».

Кроме того, существует конечное число параметров в udf_GetColName. Он получает имя исходного столбца, значение исходного столбца, которое выполняет поиск в таблице правил. Если правило находит совпадение этого столбца с этим значением, выбирается и возвращается output column, в противном случае используется значение по умолчанию output column. Это столбец, который нужно выбрать, следовательно, потенциально может сильно отличаться от входного или входного значения.

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


FINAL РЕДАКТИРОВАТЬ НА ДЕНЬ ДО Я иду домой

Я ищу способ, чтобы выбрать, какие колонки использовать из tbl_ThisTable, основываясь на других значений столбцов в tbl_ThisTable.

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

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

+5

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

+1

Что @Neils сказал. Это приближается к http://en.wikipedia.org/wiki/Inner-platform_effect. – gbn

+0

@Niels. Попробуйте установить некоторые правила в отношении того, какие данные должны выводиться на основе критериев - однако управление этими правилами необходимо разместить с бизнесом, следовательно, в обновляемой таблице, а не жестко закодированной в функции views/Table-Valued. Это не идеально, но, к сожалению, необходимо. – RemarkLima

ответ

1

Rewind,

вместо

SET @sql = 
    'SELECT ' + dbo.udf_GetColName('Val1', ColumnFromThisTable, etc) + 
     ' AS myCol FROM tbl_ThisTable WHERE ... ' 

почему бы не просто сделать

SELECT Val1 [myCol] FROM tbl_ThisTable WHERE ... 

в первую очередь?

Сделать вызывающего устройства разветвлением.


Что я имею в виду, создайте свой SQL-код на клиенте, используя ORM по вашему выбору.

EDIT


использование sp_executesql и читать Sommarskog

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

+0

К сожалению, ограничение установки, где я Работа. Интерфейс может вызывать только прямые функции/sp, поэтому вся эта работа должна выполняться внутри SQL. В противном случае я бы с радостью вернул все потенциальные данные из SQL и принял решение на передний план на основе таблицы правил. – RemarkLima

+0

@RemarkLima, какие данные находятся в 'tbl_ThisTable', являются атрибутами столбцов объекта или, является ли' tbl_ThisTable' таблицей обратного поиска? – Jodrell

+0

'tbl_ThisTable' - это таблица данных, поэтому столбцы представляют собой столбцы данных -' udf_GetColName' вернет одно из имен столбцов из 'tbl_ThisTable' на основе определенных значений' tbl_ThisTable'. – RemarkLima

3

Единственный способ, которым я могу думать о том, чтобы использовать случай заявление:

select (case when udf_GetColName('Val1', . . .) = 'Col1' then Col1 
      when udf_GetColName('Val1', . . .) = 'Col2' then Col2 
      . . . 
     ) as MyCol 
from tbl_ThisTable . . . 

Динамический SQL кажется проще. Однако в обоих случаях будьте осторожны с типами. С case это вернет тип первого then. С динамическим SQL тип возвращаемого значения зависит от типа базового столбца.

+0

Спасибо за мысли - случай будет довольно грязным, и, как вы говорите, может также пойти динамичным в этот момент;) – RemarkLima

Смежные вопросы