Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Вопрос по execute statement / 18 сообщений из 18, страница 1 из 1
28.02.2017, 14:24
    #39411644
Polesov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
Привет всем.

FB 2.5.6

Создадим простую табличку:
Код: sql
1.
2.
3.
create table T (
    S  char( 4 )
);



Следующий запрос вернет 0:
Код: sql
1.
2.
3.
select count(*)
  from T
 where S = '12345';



Обернем запрос в execute block:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
execute block
returns (
   N integer )
as
begin
  execute statement ( '
select count(*)
  from T
 where S = :S
' ) ( S := '12345' )
  into :N;

  suspend;
end

При выполнении получаем ошибку:
Код: powershell
1.
2.
3.
4.
Arithmetic overflow or division by zero has occurred.
arithmetic exception, numeric overflow, or string truncation.
string right truncation.
At block line: 6, col: 3.


Но достаточно преобразовать тип через cast, так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
execute block
returns (
   N integer )
as
begin
  execute statement ( '
select count(*)
  from T
 where cast( S as varchar(16) ) = :S
' ) ( S := '12345' )
  into :N;

  suspend;
end

Или так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
execute block
returns (
   N integer )
as
begin
  execute statement ( '
select count(*)
  from T
 where S = cast( :S as varchar(16) )
' ) ( S := '12345' )
  into :N;

  suspend;
end

запрос выполняется без ошибок

Это так и должно быть?

С уважением, Polesov.
...
Рейтинг: 0 / 0
28.02.2017, 14:37
    #39411659
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
Polesov, конечно!
В изначальном варианте, подготовленный запрос имеет параметр типа CHAR(4), а передается строка из пяти символов.
...
Рейтинг: 0 / 0
28.02.2017, 15:13
    #39411696
Polesov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
rdb_dev,

Изменим запрос:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
execute block (
    S varchar( 16 ) = :S )
returns (
    N integer )
as
begin
  execute statement ( '
select count(*)
  from T
 where S = :S
' ) ( S := :S )
  into :N;

  suspend;
end

В качестве параметра передадим строку 12345 - получаем ошибку:
Код: plaintext
1.
2.
3.
4.
Arithmetic overflow or division by zero has occurred.
arithmetic exception, numeric overflow, or string truncation.
string right truncation.
At block line: 7, col: 3.
...
Рейтинг: 0 / 0
28.02.2017, 15:17
    #39411707
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
PolesovЭто так и должно быть?Встречный вопрос - при чём тут EXEC BLOCK ?
...
Рейтинг: 0 / 0
28.02.2017, 15:21
    #39411715
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
Polesov,

это давно известный факт. Firebird определяет типы и размеры параметров запроса на этапе prepare. Для типов CHAR и VARCHAR это может нести некоторые проблемы, например как описана у тебя.
...
Рейтинг: 0 / 0
28.02.2017, 15:24
    #39411724
Polesov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
hvlad,

Надо проверить, есть ли в таблице записи, в которых значение поля содержит определенное значение. Имя таблицы и имя поля передаются в качестве параметров.
...
Рейтинг: 0 / 0
28.02.2017, 15:25
    #39411727
Polesov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
Симонов ДенисPolesov,

это давно известный факт. Firebird определяет типы и размеры параметров запроса на этапе prepare. Для типов CHAR и VARCHAR это может нести некоторые проблемы, например как описана у тебя.

Но та же ошибка возникает, если описать тип входного параметра:
Код: sql
1.
2.
3.
execute block (
    S varchar( 16 ) = :S )
:
...
Рейтинг: 0 / 0
28.02.2017, 15:30
    #39411736
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
Polesov,

считай что когда ты выполняешь запрос в EXECUTE STATEMENT, ты выполняешь его через клиента. Грубо говоря EXECUTE STAEMENT сам контролирует типы параметров внутреннего запроса. Внешний блок на его типы повлиять не может.
...
Рейтинг: 0 / 0
28.02.2017, 15:33
    #39411741
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
Polesov,

при чём тут то, что тебе надо ? :)

Напиши свой запрос с параметром в IBE, попробуй засунуть в пар-р больше символов, чем в поле.
И снова ответь мне - при чём тут EXEC BLOCK ?

PS Тип параметра запроса выводится движком из текста запроса. Тип параметра, передаваемый
вызывающим кодом (приложением, EXEC BLOCK'ом, чёртом лысым) - не обязан совпадать, но должен
быть совместим.
...
Рейтинг: 0 / 0
28.02.2017, 15:35
    #39411745
Polesov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
Симонов Денис, понятно. Спасибо.
...
Рейтинг: 0 / 0
28.02.2017, 15:40
    #39411753
Polesov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
hvladТип параметра, передаваемый вызывающим кодом (приложением, EXEC BLOCK'ом, чёртом лысым) - не обязан совпадать, но должен быть совместим.
Понятно, получается execute block не при чем.

Тогда как сервер разруливает превышение длины поля значением параметра, переданного литерально?
Код: sql
1.
2.
3.
select count(*)
  from T
 where S = '12345';
...
Рейтинг: 0 / 0
28.02.2017, 15:45
    #39411762
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
Polesov,

ну чего тут не понятного? Когда ты в запросе используешь литерал строки никаких параметров нет.

возьмём запрос

Код: sql
1.
2.
3.
select count(*)
  from T
 where S = :S



сколько сервер должен выделить места под параметр S? Заметь ты никакого значения в параметр ещё не передал только prepare сделал.
...
Рейтинг: 0 / 0
28.02.2017, 15:56
    #39411773
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
PolesovТогда как сервер разруливает превышение длины поля значением параметра, переданного литерально?
Код: sql
1.
2.
3.
select count(*)
  from T
 where S = '12345';

Здесь нет параметра и "разруливать" нечего
...
Рейтинг: 0 / 0
28.02.2017, 15:58
    #39411776
Polesov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
Симонов Денис, hvlad, спасибо за разъяснения.
Тему можно считать закрытой.
...
Рейтинг: 0 / 0
28.02.2017, 16:53
    #39411816
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
Polesovrdb_dev,

Изменим запрос:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
execute block (
    S varchar( 16 ) = :S )
returns (
    N integer )
as
begin
  execute statement ( '
select count(*)
  from T
 where S = :S
' ) ( S := :S )
  into :N;

  suspend;
end

В качестве параметра передадим строку 12345 - получаем ошибку:
Код: plaintext
1.
2.
3.
4.
Arithmetic overflow or division by zero has occurred.
arithmetic exception, numeric overflow, or string truncation.
string right truncation.
At block line: 7, col: 3.

Дык ничёж не изменилось!...
Запрос в EXECUTE STATEMENT как хотел CHAR(4), так по прежнему и хочет, а ты толкаешь ему какой-то VARCHAR(16), тогда как в мануале чёрным по белому написано, что EXECUTE STATEMENT не проверяет тип передающихся параметров, а ошибкой в тебя плюётся именно SELECT внутри EXECUTE STATEMENT.
...
Рейтинг: 0 / 0
01.03.2017, 06:28
    #39412106
Exteris
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
hvladPolesovТогда как сервер разруливает превышение длины поля значением параметра, переданного литерально?
Код: sql
1.
2.
3.
select count(*)
  from T
 where S = '12345';

Здесь нет параметра и "разруливать" нечего
Попутно у меня вопрос. Почему сервер проглатывает без ошибки такие, не влезающие в длину поля, значения?
...
Рейтинг: 0 / 0
01.03.2017, 06:58
    #39412108
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
Exteris,

ребята вы чего издеваетесь?
...
Рейтинг: 0 / 0
01.03.2017, 08:49
    #39412128
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по execute statement
Симонов Денис, шок, это по-нашему!
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Вопрос по execute statement / 18 сообщений из 18, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]