powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / isc_dsql_describe и системные таблицы
12 сообщений из 12, страница 1 из 1
isc_dsql_describe и системные таблицы
    #38833385
Игорь П.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет!

Столкнулся с задачей сделать запрос вида:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
SELECT
MON$ATTACHMENT_ID as a1, MON$SERVER_PID as a2,
MON$REMOTE_ADDRESS as a3, MON$REMOTE_PID as a4,
MON$STAT_ID as a5, MON$TIMESTAMP as a6,
MON$REMOTE_PROCESS as a7
FROM MON$ATTACHMENTS aa 
ORDER BY MON$SERVER_PID;


или все тоже, но без алиасов полей, без разницы.

Запрос делаю при помощи API, с использованием Objective C для Mac и получаю в структуре sel_sqlda->sqlvar пустые значения для всех полей:
Код: plaintext
1.
2.
3.
4.
sel_sqlda->sqlvar[i].sqlname
sel_sqlda->sqlvar[i].sqltype
sel_sqlda->sqlvar[i].sqllen
sel_sqlda->sqlvar[i].aliasname



При этом кол-во полей в структуре указано корректно.

Подобная проблема появилась только для системной таблицы и отсутствовала для запросов в обычные пользовательские. И именно по этой причине я и решил использовать в запросе алиасы, в прочем это не помогло, как я написал выше.

При выполнении запроса в isql на сервере я получаю вот такую структуру SQLDA для запроса без алиасов.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
OUTPUT SQLDA version: 1 sqln: 20 sqld: 8
01: sqltype: 497 LONG	  Nullable sqlscale: 0 sqlsubtype: 0 sqllen: 4
  :  name: (17)MON$ATTACHMENT_ID  alias: (17)MON$ATTACHMENT_ID
  : table: (15)MON$ATTACHMENTS  owner: (6)SYSDBA
02: sqltype: 497 LONG	  Nullable sqlscale: 0 sqlsubtype: 0 sqllen: 4
  :  name: (14)MON$SERVER_PID  alias: (14)MON$SERVER_PID
  : table: (15)MON$ATTACHMENTS  owner: (6)SYSDBA
03: sqltype: 449 VARYING   Nullable sqlscale: 0 sqlsubtype: 2 sqllen: 255
  :  name: (18)MON$REMOTE_ADDRESS  alias: (18)MON$REMOTE_ADDRESS
  : table: (15)MON$ATTACHMENTS  owner: (6)SYSDBA
04: sqltype: 497 LONG	  Nullable sqlscale: 0 sqlsubtype: 0 sqllen: 4
  :  name: (14)MON$REMOTE_PID  alias: (14)MON$REMOTE_PID
  : table: (15)MON$ATTACHMENTS  owner: (6)SYSDBA
05: sqltype: 501 SHORT	 Nullable sqlscale: 0 sqlsubtype: 0 sqllen: 2
  :  name: (20)MON$CHARACTER_SET_ID  alias: (20)MON$CHARACTER_SET_ID
  : table: (15)MON$ATTACHMENTS  owner: (6)SYSDBA
06: sqltype: 497 LONG	  Nullable sqlscale: 0 sqlsubtype: 0 sqllen: 4
  :  name: (11)MON$STAT_ID  alias: (11)MON$STAT_ID
  : table: (15)MON$ATTACHMENTS  owner: (6)SYSDBA
07: sqltype: 511 TIMESTAMP Nullable sqlscale: 0 sqlsubtype: 0 sqllen: 8
  :  name: (13)MON$TIMESTAMP  alias: (13)MON$TIMESTAMP
  : table: (15)MON$ATTACHMENTS  owner: (6)SYSDBA
08: sqltype: 449 VARYING   Nullable sqlscale: 0 sqlsubtype: 3 sqllen: 765
  :  name: (18)MON$REMOTE_PROCESS  alias: (18)MON$REMOTE_PROCESS
  : table: (15)MON$ATTACHMENTS  owner: (6)SYSDBA




В итоге, как мне получить имена полей, типы и алиасы при запросе к системным таблицам? Кто-то может подсказать, есть ли тонкости при работе с системными таблицами при использовании Firebird API?
Спасибо!
...
Рейтинг: 0 / 0
isc_dsql_describe и системные таблицы
    #38833403
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь П.Запрос делаю при помощи API
Код показывай.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
isc_dsql_describe и системные таблицы
    #38833577
Игорь П.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ниже фрагмент кода с isc_dsql_describe на Objective C.
Метод prepare описан ниже.
Замут с типами (sel_sqlda->sqlvar[i].sqltype == 448) я подправлю, это на время дебага сделано.
Под dummyVar*** память выделена.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
        stat = [self prepare:trans selectString:sqlcmd statment:stmt SQLDA:sel_sqlda];
 
        if (isc_dsql_describe(status, &stmt, 1, sel_sqlda)) {
            NSLog(@"Error describing statement");
            isc_print_status(status);
            stat = isc_sqlcode(status);
        }
    
        
        for (int i = 0; i < sel_sqlda->sqld; i++) {
            NSLog(@"sqltype = %hd", sel_sqlda->sqlvar[i].sqltype);
            if((sel_sqlda->sqlvar[i].sqltype == 448) || (sel_sqlda->sqlvar[i].sqltype == 449)) {
                sel_sqlda->sqlvar[i].sqldata = (char *)&dummyVarChar[i];
     
            }
            if(sel_sqlda->sqlvar[i].sqltype == 496) {
                sel_sqlda->sqlvar[i].sqldata = (char *)&dummyLong[i];

            }
            if(sel_sqlda->sqlvar[i].sqltype == 501) {
                sel_sqlda->sqlvar[i].sqldata = (char *)&dummyLong[i];

            }
            if(sel_sqlda->sqlvar[i].sqltype == 511) {
                sel_sqlda->sqlvar[i].sqldata = (char *)&dummyVarChar[i];

            }
            sel_sqlda->sqlvar[i].sqlind = &flag[i];
            
            printf("\nColumn name:    %s\n", sel_sqlda->sqlvar[i].sqlname);
            printf("Column type:    %d\n", sel_sqlda->sqlvar[i].sqltype);
            printf("Column length:  %d\n", sel_sqlda->sqlvar[i].sqllen);
            printf("Column alias name %s\n", sel_sqlda->sqlvar[i].aliasname);
       
        }
        
        if (isc_dsql_execute(status, &trans, &stmt, 1, NULL)) {
            NSLog(@"Error executing sql command");
            isc_print_status(status);
            stat = isc_sqlcode(status);
        }




Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
- (long)prepare:(isc_tr_handle)transaction selectString:(NSString *)selstr statment:(isc_stmt_handle)stmt SQLDA:(XSQLDA *)sel_sqlda {
    const char *sel_str1;
    sel_str1 = [selstr UTF8String];
    
    ISC_STATUS_ARRAY    status;
    long stat = 0;
    
    if (isc_dsql_prepare(status, &transaction, &stmt, 0, sel_str1, 1, sel_sqlda)) {
        NSLog(@"Error preparing sql command");
        isc_print_status(status);
        stat = isc_sqlcode(status);
    }
    
    return stat;
}
...
Рейтинг: 0 / 0
isc_dsql_describe и системные таблицы
    #38833582
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь П.Кто-то может подсказать, есть ли тонкости при работе с системными таблицами
при использовании Firebird API?
Тонкостей никаких нет. И явных багов в твоём коде я тоже не вижу. Ошибок в логе точно нет?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
isc_dsql_describe и системные таблицы
    #38833586
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще-то выходная SQLDA должна заполняться уже при вызове isc_dsql_perepare(). Попробуй
вызов isc_dsql_describe() вообще убрать.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
isc_dsql_describe и системные таблицы
    #38833587
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь П.,

а где выделение памяти под собственно sel_sqlda ?
...
Рейтинг: 0 / 0
isc_dsql_describe и системные таблицы
    #38833599
Игорь П.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovТонкостей никаких нет. И явных багов в твоём коде я тоже не вижу. Ошибок в логе точно нет?
Это оч плохо. Было бы лучше, если б они были явными :)

Dimitry SibiryakovВообще-то выходная SQLDA должна заполняться уже при вызове isc_dsql_perepare(). Попробуй
вызов isc_dsql_describe() вообще убрать.
Сейчас попробую. Спасибо!

hvladИгорь П.,

а где выделение памяти под собственно sel_sqlda ?


Хотел не перегружать кодом. Вот с момента выделения памяти.
Собственно, раньше только коннект.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
sel_sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
        sel_sqlda->sqln = 2;
        sel_sqlda->sqld = 0;
        sel_sqlda->version = 1;
        
        if (isc_dsql_allocate_statement(status, &_dbhandle, &stmt)) {
            NSLog(@"Error allocating statement");
            isc_print_status(status);
            stat = isc_sqlcode(status);
        }
        
        stat = [self prepare:trans selectString:sqlcmd statment:stmt SQLDA:sel_sqlda];
        if (isc_dsql_describe(status, &stmt, 1, sel_sqlda)) {
            NSLog(@"Error describing statement");
            isc_print_status(status);
            stat = isc_sqlcode(status);
        }
    
        long fieldType = 0;
        
        for (int i = 0; i < sel_sqlda->sqld; i++) {
            //именно тут и создаем описания колонок!
            NSLog(@"sqltype = %hd", sel_sqlda->sqlvar[i].sqltype);
            if((sel_sqlda->sqlvar[i].sqltype == 448) || (sel_sqlda->sqlvar[i].sqltype == 449)) {
                sel_sqlda->sqlvar[i].sqldata = (char *)&dummyVarChar[i];
                fieldType = field_char;
            }
            if(sel_sqlda->sqlvar[i].sqltype == 496) {
                sel_sqlda->sqlvar[i].sqldata = (char *)&dummyLong[i];
                fieldType = field_long;
            }
            if(sel_sqlda->sqlvar[i].sqltype == 501) {
                sel_sqlda->sqlvar[i].sqldata = (char *)&dummyLong[i];
                fieldType = field_short;
            }
            if(sel_sqlda->sqlvar[i].sqltype == 511) {
                sel_sqlda->sqlvar[i].sqldata = (char *)&dummyVarChar[i];
                fieldType = field_timestamp;
            }
            sel_sqlda->sqlvar[i].sqlind = &flag[i];
            
            [ds addField:[[NSString alloc] initWithCString:sel_sqlda->sqlvar[i].sqlname
                                                  encoding:NSWindowsCP1251StringEncoding]
              fieldAlias:[[NSString alloc] initWithCString:sel_sqlda->sqlvar[i].aliasname
                                                  encoding:NSWindowsCP1251StringEncoding]
              fieldType:fieldType];
            
            printf("\nColumn name:    %s\n", sel_sqlda->sqlvar[i].sqlname);
            printf("Column type:    %d\n", sel_sqlda->sqlvar[i].sqltype);
            printf("Column length:  %d\n", sel_sqlda->sqlvar[i].sqllen);
            printf("Column alias name %s\n", sel_sqlda->sqlvar[i].aliasname);
       
        }
...
Рейтинг: 0 / 0
isc_dsql_describe и системные таблицы
    #38833601
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь П.sel_sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
sel_sqlda->sqln = 2;
Выделяешь места под одну переменную, а говоришь, что под две. Нехорошо обманывать.
Особенно когда пытаешься засунуть туда сразу восемь.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
isc_dsql_describe и системные таблицы
    #38833656
Игорь П.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovИгорь П.sel_sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
sel_sqlda->sqln = 2;
Выделяешь места под одну переменную, а говоришь, что под две. Нехорошо обманывать.
Особенно когда пытаешься засунуть туда сразу восемь.


"Семен Семеныч!!.." и правда, я слопушил!

в итоге делаю так:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
if(self.connected) {
        sel_sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
        sel_sqlda->sqln = 2;
        sel_sqlda->sqld = 0;
        sel_sqlda->version = 1;
        
        if (isc_dsql_allocate_statement(status, &_dbhandle, &stmt)) {
            NSLog(@"Error allocating statement");
            isc_print_status(status);
            stat = isc_sqlcode(status);
        }
        
        stat = [self prepare:trans selectString:sqlcmd statment:stmt SQLDA:sel_sqlda];

        long cnt = sel_sqlda->sqld;
        if(cnt > 1) {
                free(sel_sqlda);
            
                sel_sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(cnt));
                sel_sqlda->sqln = 2;
                sel_sqlda->sqld = cnt;
                sel_sqlda->version = 1;
        }
            
        if (isc_dsql_describe(status, &stmt, 1, sel_sqlda)) {
            NSLog(@"Error describing statement");
            isc_print_status(status);
            stat = isc_sqlcode(status);
        }



То есть добавил проверку, что колонок в запросе более 1. И если это так, то освобождаю память и выделяю ее заново.

Но надо сказать, что изменений это не дало в плане изначальной проблемы.
Часть полей стали в логах выглядеть так:
Column name: \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377
Column type: 0
Column length: 0
Column alias name

Часть вот так:
Column name: 23:20:39.913
Column type: 28492
Column length: 24931
Column alias name

а половина все равно пуста.
...
Рейтинг: 0 / 0
isc_dsql_describe и системные таблицы
    #38833657
Игорь П.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь П.[src PLSQL]
if(self.connected) {
sel_sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
sel_sqlda->sqln = 1;
sel_sqlda->sqld = 0;
sel_sqlda->version = 1;
...
Рейтинг: 0 / 0
isc_dsql_describe и системные таблицы
    #38833659
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь П.в итоге делаю так:
Число в sqln должно точно совпадать с числом в предыдущем XSQLDA_LENGTH().
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
isc_dsql_describe и системные таблицы
    #38838825
Игорь П.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все, проблема решена.
Нужно более внимательно к параметрам относиться. В моем случае sqln и sqld

sqln - Указывает число элементов в массиве sqlvar; приложение должно устанавливать это поле каждый раз, когда оно выделяет память для дескриптора
sqld - Указывает число параметров XSQLDA для ввода, или число элементов списка выбора XSQLDA для вывода;
устанавливается c помощью isc_dsql_describe (), isc_dsql_describe_bind () или isc_dsql_prepare ()

Для дескриптора ввода, sqld= 0 указывает, что инструкция SQL не имеет никаких параметров;
Для дескриптора вывода, sqld= 0 указывает, что инструкция SQL - не инструкция SELECT
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / isc_dsql_describe и системные таблицы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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