Можете ли вы подтвердить, что тип данных flag
является CHAR, а не VARCHAR2?
Это будет соответствовать поведению, показанному ниже ...
create table t1(
flag char(2)
,flag2 varchar2(2)
);
insert into t1 values('F', 'F');
insert into t1 values('T', 'T');
insert into t1 values('X', 'X');
insert into t1 values(null, null);
commit;
select decode(flag, 'F', 0, 'T', 1, null) as with_char
,decode(flag2, 'F', 0, 'T', 1, null) as with_varchar
from t1;
WITH_CHAR WITH_VARCHAR
---------- ------------
null 0
null 1
null null
null null
Чтобы это исправить, вам нужно:
- Переписать свою логику ( предпочтительнее )
- Использование
DECODE(TRIM(flag), ...)
- Изменить тип данных на VARCHAR2
Редактировать: Почему флаг = 'F' верно?
Это потому, что выражение 'F'
имеет неявный тип данных CHAR(1)
. В особом случае сравнения двух выражений char(x)
Oracle будет перетаскивать короткое из них на длину более длинного столбца. По-видимому, это требование стандарта ANSI / ISO SQL.
Столбец флага уже будет пусто заполнен до 'F '
в соответствии с семантикой char (2), и когда оракул увидит ваше выражение 'F'
, он поймет, что сравнивает char (2) с char (1) и подставляет пустые блоки 'F'
выражение 'F '
.
И вот почему 'F' = 'F '
:)
Не так с DECODE
, хотя, потому что здесь 'F' <> 'F '
. Это не единственный случай, когда DECODE несовместим с SQL, и вам следует избегать его.
Вы можете прочитать больше в главе CHAR против VARCHAR2 в документации Oracle.