Конкатенация TSQL

Мне часто нужно объединять поля в TSQL ...

TSQL заставляет вас иметь дело с двумя проблемами при использовании оператора '+': Приоритет типов данных и значения NULL.

При приоритете типов данных проблема заключается в ошибках преобразования.

1) SELECT 1 + 'B' = Conversion ERROR
2) SELECT 1 + '1' = 2
3) SELECT '1' + '1' = '11'

В 2) varchar '1' неявно преобразуется в int, и математика работает. Однако в 1) int 1 неявно преобразовывается в varchar. Вот где DTP (ИМО) мешает. По сути, он предпочитает математические функции строковым функциям. Я желаю :-), чтобы DTP даже не рассматривался в этом случае - почему бы не настроить оператор '+' так, чтобы операция могла способствовать успеху определенному типы данных? Я бы не возражал, если бы он по-прежнему отдавал предпочтение функциям MATH, а не строковым функциям, когда это возможно, но почему он не предпочитает строковые функции ошибкам? (Единственный способ добиться успеха в 1) - рассматривать ее как строковую функцию - так что здесь нет никакой двусмысленности.) Кто-то в Microsoft подумал, что выброс ошибки в 1) будет более ценным для программиста, чем лечение '+' как строковая функция. Зачем? И почему они не предоставили способ преодолеть это? (Или они ... это действительно суть моего вопроса.) SET STRING_PREFERENCE ON было бы неплохо! :-P

Чтобы справиться с этим, вам нужно проделать больше работы - вы должны явно преобразовать 1 в varchar, используя любое количество различных строковых функций - обычно CAST / CONVERT, но также и многие другие (как LTRIM ()) будет работать.

Преобразования становятся трудоемкими, когда вы имеете дело с полями таблицы, когда вы не знаете тип данных. Это может сработать:

SELECT 'Fall '  + ' (' + [Term] + ')' -- Output: Fall (2011)

Но опять же, может и нет. Это просто зависит от типа данных [Term]. И что еще больше усложняет ситуацию, dba может изменить тип данных в какой-то момент, никому не сообщая (потому что это было частью большого пакета обновления, когда поставщик наконец понял, что в поле [Term] хранятся только числа, или по любой другой причине ).

Итак, если вы хотите быть мальчишкой, сделайте следующее:

SELECT 'Fall '  + ' (' + LTRIM([Term]) + ')'

Итак, теперь я запускаю эту функцию LTRIM каждый раз, хотя она может не понадобиться, потому что я не не знаю тип данных [Term] (хорошо - я могу это посмотреть, но это почти похоже на работу, и я не люблю прерывания, пока я кодирую :-P * grump ), а также я не знаю, что тип данных никогда не изменится.

Вторая проблема, с которой вы должны столкнуться при объединении TSQL, - это как работать со значениями NULL. Например, это не сработает:

SELECT NULL + 'B'

Итак, вам нужно сделать это:

SELECT 'Fall '  + ' (' + LTRIM(ISNULL([Term],'')) + ')'

Какая боль - я бы хотел просто сделать это:

SELECT 'Fall '  + ' (' + [Term] + ')'

Поэтому мне интересно, есть ли какие-либо (TSQL) способы избегать явных преобразований типов данных и проверок на null для каждого поля, где я должен убедиться, что оператор '+' ведет себя так, как мне нужно.

Спасибо!

EDIT
@ a1ex07 придумал отличный ответ для решения проблемы NULL ( SET CONCAT_NULL_YEILDS_NULL OFF ), но, когда я изучил его, он оказался проблематичным в плане принудительной повторной компиляции хранимых процедур при каждом их выполнении.

5
задан Chains 25 August 2011 в 04:38
поделиться