Мне часто нужно объединять поля в 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 (IMO) мешает. По сути, он предпочитает математические функции над строковыми функциями. Желаю :-), чтобы DTP даже не рассматривался в данном случае - почему бы не настроить оператор '+' так, чтобы операция могла благоприятствовать success по сравнению с конкретными типы данных? Я не возражаю, если он по-прежнему предпочитает MATH, а не функции String, когда это возможно, но почему он не поддерживает функции String по сравнению с ошибками? (Единственный способ добиться успеха в 1) - это трактовать ее как строковую функцию, поэтому нет никакой двусмысленности.) Кто-то в Microsoft считал, что выдача ошибки в 1) будет более ценной для программиста, чем лечение «+» как строковая функция. Зачем? И почему они не предоставили способ переопределить это? (Или они ... это действительно суть моего вопроса.) SET STRING_PREFERENCE ON
было бы неплохо! : -Р
Чтобы справиться с этим, вам нужно проделать больше работы - вам нужно явно преобразовать 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) способы, позволяющие избежать явных преобразований типов данных и нулевых проверок в каждом поле, где я должен убедиться, что оператор «+» ведет себя так, как мне нужно.
Спасибо!
EDIT
@ a1ex07 придумал отличный ответ для работы с проблемой NULL (SET CONCAT_NULL_YEILDS_NULL OFF
), но, как я уже рассмотрел, кажется, что проблема заключается в том, чтобы заставить хранимые процедуры перекомпилироваться каждый раз, когда они выполняются.