Существует ли такое поведение во всех основных базах данных? - PullRequest
1 голос
/ 21 апреля 2010
mysql> select 0.121='0.121';
+---------------+
| 0.121='0.121' |
+---------------+
|             1 |
+---------------+

Имеется ли в другой базе данных значение number='number' true?

Ответы [ 5 ]

6 голосов
/ 21 апреля 2010

Прежде всего: большинство баз данных используют локализованные числовые форматы . Таким образом, превращение числа в строку, скорее всего, не всегда будет таким же, как ваша жестко закодированная строка.

Тогда: у вас возникнут проблемы с используемым вами синтаксисом sql. Смотрите мои эксперименты с оракулом ниже.


В Oracle вам всегда нужно предложение FROM (за исключением того, что они изменили это в версии 10).

select 0.121='0.121' from sys.dual

В Oracle вы не можете иметь подобное выражение в предложении select.

Вам нужен регистр:

select case when 0.121 = '0.121' then 1 else 0 end as xy 
from sys.dual

Тогда вы получите ошибку, что это не номер. Чтобы это исправить, конвертируйте это:

select case when To_Char(0.121) = '0.121' then 1 else 0 end as xy 
from sys.dual

это вернет 0! Потому что на моей машине 0.121 преобразуется в строку ".121". Это швейцарские настройки. Если бы у меня были немецкие настройки, это было бы ",121" (обратите внимание на запятую).

Итак, чтобы окончательно ответить на вопрос: Нет .

3 голосов
/ 21 апреля 2010

Даже если это так. Что это поможет вам? В любом случае, я бы никогда не сделал это предположение. Вам всегда нужно преобразовывать оба операнда в один и тот же тип, чтобы, по крайней мере, вы знали, с чем сравниваете.

0 голосов
/ 21 апреля 2010

Postgresql немного более строг, чем mysql о преобразовании типов , и не позволяет вам неявно приводить / преобразовывать числа и строки. Это нормальное поведение, и оно становится более строгим с новыми версиями. Некоторые примеры из Postgres 8.4:

db=# select 0.112::float = '0.112'::text;
ERROR:  operator does not exist: double precision = text
LINE 1: select 0.112::float = '0.112'::text;
                            ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.

db=# select 0.112 = ('0.1' || '12');
ERROR:  operator does not exist: numeric = text
LINE 1: select 0.112 = ('0.1' || '12');
                     ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.

db=# select 0.112 = ('0.1' || '12')::float; -- explicit cast
 t

Однако этот пример (оригинальный вопрос) работает:

db=# select 0.122 = '0.122';
 t

Это немного удивительно (или вводит в заблуждение), учитывая вышесказанное. Но это связано с тем, как анализируется запрос: когда он видит (неквалифицированный) литерал «0.122», синтаксический анализатор не обязательно предполагает, что он имеет тип TEXT, но вместо этого назначает предварительный «неизвестный» тип; его окончательный тип выводится позже некоторыми эвристиками .

В любом случае, полагаться на это - плохая практика, как уже упоминали другие.

0 голосов
/ 21 апреля 2010

Нет.

Я не знаю, почему Stackoverflow требует от меня ввода более 3 символов в ответ на этот вопрос.

0 голосов
/ 21 апреля 2010

Большинство авторитетных баз данных будут выполнять неявное преобразование для этого типа запроса. Могут быть опубликованы правила для неявных преобразований в конкретной системе - вам нужно взглянуть на рекомендации поставщиков, чтобы выяснить, какие неявные преобразования выполняются в вашей системе.

Например, здесь - официальное указание от Microsoft для SQL Server 2000, и здесь запись в блоге о неявных преобразованиях SQL Server.

...