Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / RDB$SET_CONTEXT и RDB$GET_CONTEXT / 7 сообщений из 7, страница 1 из 1
26.09.2018, 02:21
    #39708084
CyberMax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RDB$SET_CONTEXT и RDB$GET_CONTEXT
Два вопроса, связанных с методами работы с контекстными переменными в FB 3.0.

1. Длина имени переменной.
По доке она ограничена длиной 80 символов. По факту можно присвоить и 100 символов.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
EXECUTE BLOCK
RETURNS (VAL INTEGER)
AS
DECLARE VARIABLE VAL_PARAM VARCHAR(30000);
DECLARE VARIABLE LEN INTEGER;
BEGIN
    RDB$SET_CONTEXT('USER_SESSION', LPAD('', 100, '0'), LPAD('', 100, '1'));
    VAL_PARAM = RDB$GET_CONTEXT('USER_SESSION', LPAD('', 100, '0'));
    VAL = CHAR_LENGTH(:VAL_PARAM);
    SUSPEND;
END



Возвращается число 100.

Но попытка открыть таблицу мониторинга приводит к исключению:
Код: sql
1.
SELECT * FROM MON$CONTEXT_VARIABLES


Код: plaintext
1.
2.
3.
4.
Arithmetic overflow or division by zero has occurred.
arithmetic exception, numeric overflow, or string truncation.
string right truncation.
expected length 80, actual 100.

2. Длина значения переменной.
В руководстве написано:
Код: plaintext
1.
Таблица 7.3. Параметры функции RDB$GET_CONTEXT
Тип возвращаемого результата: VARCHAR(255)

А таблица MON$CONTEXT_VARIABLES говорит о том, что это не так:
Код: sql
1.
2.
3.
4.
5.
6.
CREATE TABLE MON$CONTEXT_VARIABLES (
    MON$ATTACHMENT_ID   BIGINT,
    MON$TRANSACTION_ID  BIGINT,
    MON$VARIABLE_NAME   VARCHAR(80) CHARACTER SET NONE,
    MON$VARIABLE_VALUE  VARCHAR(32765) CHARACTER SET NONE
);


Проверяем:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
EXECUTE BLOCK
RETURNS (VAL INTEGER)
AS
DECLARE VARIABLE PARAM VARCHAR(30000);
DECLARE VARIABLE VAL_PARAM VARCHAR(30000);
DECLARE VARIABLE LEN INTEGER;
BEGIN
    PARAM = LPAD('', 10000, '0');
    LEN = CHAR_LENGTH(:PARAM);
    RDB$SET_CONTEXT('USER_SESSION', 'CONT_PARAM', :PARAM);
    VAL_PARAM = RDB$GET_CONTEXT('USER_SESSION', 'CONT_PARAM');

    VAL = CHAR_LENGTH(:VAL_PARAM);
    SUSPEND;
END


Выборка из таблицы мониторинга работает:
Код: sql
1.
SELECT * FROM MON$CONTEXT_VARIABLES



Но использование в запросе приводит к ошибке:
Код: sql
1.
SELECT RDB$GET_CONTEXT('USER_SESSION', 'CONT_PARAM') FROM RDB$DATABASE


Код: plaintext
1.
2.
3.
4.
Arithmetic overflow or division by zero has occurred.
arithmetic exception, numeric overflow, or string truncation.
string right truncation.
expected length 255, actual 10000.

Вопрос Владу - написать об этих проблемах в трекер?
...
Рейтинг: 0 / 0
26.09.2018, 09:00
    #39708160
dimitr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RDB$SET_CONTEXT и RDB$GET_CONTEXT
Изначально RDB$GET/SET были встроенными в сервер UDF и их метаданные описывались в RDB$FUNCTIONS/RDB$FUNCTION_ARGUMENTS. И там была прописана длина 80 символов. Оттуда оно перекочевало в таблицы мониторинга. После чего RDB$GET/SET были переделаны на нативные серверные функции и ограничение испарилось (ибо в коде оно никогда и не проверялось, оно было чисто декларативное). А в мониторинге все осталось как есть.

В трекер, наверное, есть смысл занести. Но надо решить - объявлять его в мониторинге длиной 32К или ввести какой-то явный лимит на имя и придерживаться его и в RDB$SET_CONTEXT тоже.
...
Рейтинг: 0 / 0
26.09.2018, 09:34
    #39708174
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RDB$SET_CONTEXT и RDB$GET_CONTEXT
dimitr,

кстати в 3.0 и 4.0 есть вот такое

README.context_variables2...
Declared as:
DECLARE EXTERNAL FUNCTION RDB$GET_CONTEXT
VARCHAR(80),
VARCHAR(80)
RETURNS VARCHAR(255) FREE_IT;

DECLARE EXTERNAL FUNCTION RDB$SET_CONTEXT
VARCHAR(80),
VARCHAR(80),
VARCHAR(255)
RETURNS INTEGER BY VALUE;
...

мне кажется оно сейчас лишнее и просто перекочевало из 2.5
...
Рейтинг: 0 / 0
26.09.2018, 22:15
    #39708839
dimitr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RDB$SET_CONTEXT и RDB$GET_CONTEXT
Симонов Денис,

README редко кто переписывает от версии к версии :-)
...
Рейтинг: 0 / 0
02.10.2018, 19:15
    #39711976
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RDB$SET_CONTEXT и RDB$GET_CONTEXT
dimitrили ввести какой-то явный лимит на имя и придерживаться его и в RDB$SET_CONTEXT тоже

Домен завести, явно именованный системный домен, в нём и лимит будет. Сегдоня один, а завтра, если понадобится ушиpить, другой.
...
Рейтинг: 0 / 0
02.10.2018, 19:45
    #39712001
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RDB$SET_CONTEXT и RDB$GET_CONTEXT
Arioch,

не нужен он теперь. Функция встроенная
...
Рейтинг: 0 / 0
02.10.2018, 19:48
    #39712009
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RDB$SET_CONTEXT и RDB$GET_CONTEXT
Симонов Денис,

ну да, ну вот вообще не нужен!

CyberMax
Код: plaintext
Arithmetic overflow or division by zero has occurred.
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / RDB$SET_CONTEXT и RDB$GET_CONTEXT / 7 сообщений из 7, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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