Оператор SET считает 0 как ноль - PullRequest
1 голос
/ 12 октября 2019

Я не знаю, как объяснить мою проблему, но я постараюсь сделать все возможное, чтобы прояснить ситуацию.

Я пытаюсь создать хранимую процедуру, которая будет использоваться для обработки запросов на праздники. У меня есть две таблицы:

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

TABLE A
------------------------
| HOLIDAY NAME| QUOTA  |
------------------------
| Yearly      | 40     |
------------------------

Таблица B отслеживает все запросы на праздники и автоматически обновляет оставшееся количество дней для определенного праздника. После нескольких запросов столбец «Баланс» определяет, сколько дней еще доступно. В приведенном ниже случае баланс равен 0 после последнего запроса.

TABLE B
----------------------------------------------------
| HOLIDAY NAME | FROM       | TO         | BALANCE |
----------------------------------------------------
| Yearly       | 2019-10-12 | 2019-10-22 | 0       |
----------------------------------------------------

Я хочу, чтобы всякий раз, когда баланс был равен 0, запрос на новый выходной не проходил. Чтобы добиться этого, я применил следующую логику (фрагмент моей процедуры):

DECLARE @quota_requested int, @quota int, @balance int, @balance_new int, @period_from date, @period_to date
SET     @period_from = '2019-12-27'
SET     @period_to = '2019-12-31'
SET @quota_requested = (datediff(dd, @period_from, @period_to) + 1) - (datediff(wk, @period_from, @period_to)*2) - (CASE WHEN datename(dw,@period_from) = 'Sunday' THEN 1 ELSE 0 END) - (CASE WHEN datename(dw, @period_to) = 'Sunday' THEN 1 ELSE 0 END)
SET @balance = (SELECT balance FROM dbo.TABLE_B WHERE holiday = 'Yearly')
SET @quota = (SELECT quota FROM dbo.TABLE_A WHERE holiday = 'Yearly')

IF @balance is null
    SET @balance_new = @quota 
ELSE 
    SET @balance_new = @balance

В этом коде я делаю следующее:

  • Я вычисляю количество днейчто человек запрашивает (@quota_requested)
  • Я сравниваю его с квотой, разрешенной для этого праздника (@quota)

    * If @quota_requested > @quota: Don't proceed
    * If @quota_requested <= @quota: Proceed to next check
    
  • Я сравниваюколичество дней, запрошенных с балансом для этого праздника (@balance)

    * If @quota_requested > @balance: Don't proceed
    * If @quota_requested <= @balance: Insert the request into the table
    

Эта логика работает очень хорошо, когда баланс> 0, но когда баланс достигает 0, следующеечасть кода:

SET @balance = (SELECT balance FROM dbo.TABLE_B WHERE holiday = 'Yearly')

передает NULL в переменную @balance, даже если баланс = 0. В результате я никогда не могу остановить вставку, когда баланс достигает нуля икод запускает баланс к значению квоты из-за этой части кода:

IF @balance = null or @balance = '' or @balance is null
    SET @balance_new = @quota 
ELSE 
    SET @balance_new = @balance

Мне бы очень хотелось узнать, что здесь происходит и почему 0 трактуется как NULL. Может ли это быть из-за функции SET? Я изменился на SELECT, но это ничего не изменило.

Спасибо

1 Ответ

0 голосов
/ 13 октября 2019

Ответ хрустального шара

Проблема в том, что вы думаете, что 0 и '' - это разные значения;с числовыми типами данных вы были бы не правы. Попробуйте это:

SELECT CASE WHEN 0 WHEN '' THEN 0 END;

Вы получите результат 0 правильно? Это потому, что '' было преобразовано в int и как int значение равно 0.

Вот почему ваш IF приводит к значению true. Я не совсем уверен, почему вы сравниваете int с varchar.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...