Привези ка мне батюшка чудище заморское цветочек аленький.
Как часто бывает в жизни что желания не совпадают с возможностями. Вот и по работе часто пожелания пользователей и чиновников не совпадают со стандартными возможностями MS SQL Server.
Пример: Необходимо отсортировать накладные для реестра по коду(хранится как строка) и дате выписки.
Допустим имеются следующие данные
Код Дата
1/01 01/02/2011
2/01 05/02/2011
11/01 09/02/2011
На первый взгляд можно обойтись банальным ORDER BY, но тут по классике жанра начинают публиковаться пояснения, исключения и замечания.
Сортировать надо не по всему коду, а по части до "/" с приведением к числовому значению, т.к. 2 должно идти перед 11 а не наоборот, т.к. если сортировать как строку то получится порядок 1, 11, 2 вместо требуемого 1, 2, 11.
Ну а дальше начинаются субъективные факторы по типу "погоды на Марсе".
Например если погода на Марсе ясная и накладная выписалась заданному клиенту, когда муха пролетая над кактусом потеряла ориентацию в пространстве и упала в кружку с чаем операциониста, то запись необходимо разместить в самом конце списка, независимо от того когда и с каким номеров эту накладную выписали.
Стандартной сортировкой такие пожелания заказчиков не реализовать, необходимо вводить "синтетическое" поле.
SELECT q.IntCode,
q.Id ,
q.NalDate ,
q.Code
FROM
( SELECT
CASE WHEN CHARINDEX('/', tp.Code) <> 0
AND ISNUMERIC(SUBSTRING(tp.Code, 1, (CHARINDEX('/', tp.Code)-1))) = 1
AND /*погода 4-й планете так себе*/
THEN CONVERT(BIGINT, SUBSTRING(tp.Code, 1, (CHARINDEX('/', tp.Code)-1)))
WHEN CHARINDEX('/', tp.Code) = 0
AND ISNUMERIC(tp.Code) = 1
AND /*погода 4-й планете так себе*/
THEN CONVERT(BIGINT, tp.Code)
WHEN /*погода 4-й планете ясная и муха упала*/
THEN 1000000000
ELSE 0
END AS IntCode,
tp.Id ,
tp.NalDate ,
tp.Code
FROM TaxPaper tp
) AS q
ORDER BY q.IntCode, q.NalDate
Почему без использования CTE? Просто некоторые так и не обновили SQL server(надеясь на авось) и как следствие решение должно работать начиная с SQL 2000.
Другое узкое место возникает в следствии следующей особенности
DECLARE @Code VARCHAR(32)
SET @Code = '1.'
IF ISNUMERIC(@Code)=1
SELECT CONVERT(BIGINT, @Code)
Обязательно вызовет "Error converting data type varchar to bigint.", хотя при
DECLARE @Code VARCHAR
все отработает как швейцарские часы.
Ну тут как говориться "Если жизнь посылает лимоны, сделай из них лимонад". Те тёти которые фантазируют о погоде на ближайших планетах, проявляют не меньшую фантазию и во время проверок. И если кто-то в обход пользовательского интерфейса умудрится впихнуть мусор в поле "Код", то будет очень больно покаран. А значит не будет искать приключений и работать по инструкции.
Комментариев нет:
Отправить комментарий