Я понимаю, что вы уже исправили свою проблему и приняли ответ, но я подумал, что я также укажу несколько других потенциальных улучшений (как для вас, так и для будущих читателей вопроса).
ALTER PROCEDURE dbo.get_persons_by_search_criteria
@month_from VARCHAR(2) = NULL,
@year_from VARCHAR(4) = NULL,
@month_to VARCHAR(2) = NULL,
@year_to VARCHAR(4) = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT
PersonID, DOBYear, DOBMonth
FROM
dbo.Person
WHERE
DOBYear + RIGHT('0' + DOBMonth, 2) + '01'
BETWEEN @year_from + RIGHT('0' + @month_from, 2) + '01'
AND @year_to + RIGHT('0' + @month_to, 2) + '01'
ORDER BY
PersonID, DOBYear, DOBMonth;
END
GO
Разве это не легче для глаз, легче следить и легче поддерживать?
Описание:
всегда используйте префикс схемы при создании, изменении или ссылке на объекты.
не используйте Unicode (NCHAR
/ NVARCHAR
), когда вам не нужно поддерживать данные Unicode (например, числа никогда не должны содержать умлауты). Выбор правильного типа данных может быть не так важен в данном конкретном случае, но может иметь решающее значение в других.
оберните тело процедуры в BEGIN
/ END
- это предотвратит неосознанный выбор другого нежелательного кода из окна запроса. И всегда используйте SET NOCOUNT ON
в начале вашей процедуры. Я обращаюсь к этим и другим вопросам в моем « контрольном списке передовых практик хранимых процедур ».
, чтобы избежать изменений в поведении, вы всегда должны включать предложение ORDER BY
. Если сегодня он заказывает по имени, а завтра начинает заказывать по фамилии, кто-то собирается пожаловаться. См. Второй раздел этого поста .
научиться писать SQL без динамического SQL, когда это возможно. Если вы собираетесь продолжать использовать динамический SQL, по крайней мере, пожалуйста, попробуйте использовать sp_executesql
вместо EXEC () . Я объяснил причины в другом недавнем вопросе: SQL Server использует EXEC / sp_executesql или просто SQL в хранимой процедуре?
Еще лучше было бы просто сохранить дату своего рождения в качестве ДАТЫ. Зачем хранить год и месяц как отдельные строки? Должна быть какая-то причина, по которой вы делаете это, но я не могу представить, что это такое. Все, что он делает, - делает этот вид сопоставления строк менее эффективным, чем если бы вы на самом деле использовали даты, уменьшает вашу способность выполнять любые операции с датами над значениями и очень затрудняет проверку переданных значений. Прямо сейчас ваши вещи будет задыхаться позже, чем должно быть, если кто-то позвонит по следующему номеру:
EXEC get_persons_by_search_criteria
@month_from = '97',
@year_from = 'Audi',
@month_to = 'TT',
@year_to = 'Oy!!';
Что они могли бы сделать, потому что вы вообще не выполняете проверку. С переменными DATE, по крайней мере, возвращаемое сообщение об ошибке имело бы смысл. Прямо сейчас с любой из наших версий они просто получат пустой набор результатов.