2013-12-12 5 views
3

Допустим, у меня есть такой код:СУБД Firebird выполнить оператор с параметром BIGINT имени входного

execute block 
as 
declare var_mask bigint; 
declare var_dummy int; 
begin 
    var_mask = bin_shl(1, (64 - 1)); 

    execute statement (' 
select first 1 null 
from rdb$database 
where bin_and(cast(0 as bigint), :var_mask) <> cast(0 as bigint) 
    ') 
    (var_mask := var_mask) 
    into :var_dummy 
    ; 
end 

Это один дает хороший arithmetic exception, numeric overflow, or string truncation. numeric value is out of range..

Чтобы сделать его работу я должен сделать явное приведение переменной:

execute block 
as 
declare var_mask bigint; 
declare var_dummy int; 
begin 
    var_mask = bin_shl(1, (64 - 1)); 

    execute statement (' 
select first 1 null 
from rdb$database 
where bin_and(cast(0 as bigint), cast(:var_mask as bigint)) <> cast(0 as bigint) 
    ') 
    (var_mask := var_mask) 
    into :var_dummy 
    ; 
end 

Кто-нибудь знает, почему? Информация о типе должна нести, не так ли?

+0

Firebird вводит тип параметра из [структуры самого запроса] (http://www.firebirdsql.org/refdocs/langrefupd25-sqlnull.html#langrefupd25-sqlnull-rationale), а не от типа переменной ни то, что было бы равносильно тому, что окружающий язык понимает переменные. Некоторые считают это [ограничение движка] (http://stackoverflow.com/a/11451797/132382). – pilcrow

+1

Проклятье. На самом деле я ответил на этот вопрос. :) –

+0

Ha. Несколько раз я заработал значок «амнезия». – pilcrow

ответ

1

Чтобы добавить ответ Адриано, информация о типе фактически не несет - более here, от меня на самом деле :).

3

Поскольку BIN_AND описывает второй параметр как INTEGER, даже когда вы передаете BIGINT на первый. Будет ли это хорошо или плохо, может быть обсуждено.

+0

Как работает вторая версия? –

+0

"cast (: var_mask as bigint)" делает описанный параметр как BIGINT. Это похоже на старый трюк «CAST (? AS SOMETHING)» в клиенте, который, если он не задан, выкинет «Ошибка типа данных». –

Смежные вопросы