2017-02-20 19 views
2

Я пытаюсь использовать переменные связывания SQL Developer, чтобы ускорить выполнение запроса, но я не получаю желаемый результат: похоже, что значения, которые я вставлял, преобразуются в число ,SQL bind bind variables prompt: force string values ​​

Описание таблицы:

Nome    Null  Type   
------------------ -------- ------------ 
NUM    NOT NULL VARCHAR2(13) 
IS_OK      NUMBER(1) 

исходная ситуация:

enter image description here

select NUM, IS_OK from numbers_table where NUM = cast(:dn as varchar2(13)); 

NUM   |IS_OK | 
------------|------| 
08331930078 |1  | 

рабочих обновления:

1.

update numbers_table set IS_OK = 0 where NUM = 08331930078; 

2.

update numbers_table set IS_OK = 0 where NUM = '08331930078'; 

Ouput:

'1 row updated' 

нерабочим обновление:

update numbers_table set IS_OK = 0 where NUM = cast(:dn as varchar2(13)); 

Ouput:

'0 rows updated' 

Не знаю, что еще я могу сделать, чтобы заставить значение анализироваться как строку.

SQL Developer версии 4.1.3.20

+2

Нет необходимости бросать что-либо, ваш запрос должен быть: update numbers_table set IS_OK = 0 где NUM =: dn; –

+0

Оказывается, это не работает (это было то, что я изначально предполагал) – Dariopnc

ответ

0

Это интересно, и выглядит как ошибка. Вы на самом деле не нужно отбрасывать, значение из окна «ввода привязывает» является строкой в ​​любом случае, так это работает:

update numbers_table set IS_OK = 0 where NUM = :dn; 

когда нулями строка 08331930078 вводится в диалоговом окне.

Приведение не требуется, но должно по-прежнему работать. Если вы работаете в качестве сценария вместо того, чтобы, с определенной переменной связывания, то обе формы работают:

var dn varchar2(13); 
exec :dn := '08331930078'; 
update numbers_table set IS_OK = 0 where NUM = :dn; 
rollback; 
update numbers_table set IS_OK = 0 where NUM = cast(:dn as varchar2(13)); 
rollback; 

Вы 1 row updated для обоих заявлений. Возврат к запуску, поскольку оператор все еще запрашивает и по-прежнему имеет такое же (нечетное) поведение, даже когда переменная связывания была определена в скрипте в том же сеансе.

Кстати, когда вы делаете:

update numbers_table set IS_OK = 0 where NUM = 08331930078; 

, что вы на самом деле делаете, как вы можете видеть, сформировать предикат раздел плана выполнения, является:

update numbers_table set IS_OK = 0 where to_number(NUM) = 8331930078; 

который остановит любой индекс по используется столбец num и может привести к неожиданным результатам - в этом случае, если это, например, Телефонные номера Великобритании, которые, вероятно, не будут иметь одинаковое значение с нулевым ном и без него, но это должно быть остерегаемо в целом.

+0

На самом деле первое обновленное вами сообщение (одно со связующей переменной, но без явного приведения) не работает на моей стороне, либо – Dariopnc

+0

Может ли это быть что разработчик SQL пытается быть умным? Возможно, он видит все цифры и предполагает, что переменная bind является числом. Таким образом, он отбрасывает начало 0. Когда запрос выполняется, мы получаем либо неявное преобразование типа данных, либо вы выполняете явное CAST(); в любом случае, строка теперь потеряла лидерство 0. Просто теория ... – BobC

+0

Забудьте эту теорию ... – BobC