sqlind = -1. Всегда ли NULL в поле?

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

Ответить
sunduk4
Сообщения: 18
Зарегистрирован: 02 май 2006, 13:45

sqlind = -1. Всегда ли NULL в поле?

Сообщение sunduk4 » 09 июн 2006, 07:52

Код выборки данных -

Код: Выделить всё

    main_sqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(3)); 
    main_sqlda->sqln = 3; 
    main_sqlda->sqld = 3; 
    main_sqlda->version = 1; 

    if (isc_dsql_prepare(status, &trans, &main_stmt, 0, main_select, 1,  NULL)) 
    { 
        ERREXIT(status, 1) 
    } 

    isc_dsql_describe(status, &main_stmt, 1, main_sqlda); 


    for (i=0, main_var = main_sqlda->sqlvar; i < main_sqlda->sqld; i++, main_var++) 
      { 
         main_dtype = (main_var->sqltype & ~1); 
         switch(main_dtype) 
         { 
            case SQL_VARYING: 
              main_var->sqldata = (char *)malloc(sizeof(char)*main_var->sqllen + 2); 
              break; 
            case SQL_TEXT: 
              main_var->sqldata = (char *)malloc(sizeof(char)*main_var->sqllen); 
              break;           
            case SQL_LONG: 
               main_var->sqldata = (char *)malloc(sizeof(long)); 
               break; 
            case SQL_SHORT: 
               main_var->sqldata = (char *)malloc(sizeof(short)); 
                break; 
         } 

         main_var->sqlind = (short *)malloc(sizeof(short)); 
      } 

    if (isc_dsql_execute(status, &trans, &main_stmt, 1, NULL)) 
    { 
        ERREXIT(status, 1) 
    } 

    isc_dsql_set_cursor_name(status, &main_stmt, "main_cursor", NULL); 

    while ((main_fetch_stat = isc_dsql_fetch(status, &main_stmt, 1, main_sqlda)) == 0) 
    { 
       for(i = 0; i <= col_count - 1; i++)
          {
             main_dtype = (main_sqlda->sqlvar[i].sqltype & ~1);
             switch(main_dtype)
              {
                 case SQL_LONG:
                 strcpy(long_s, "");
                 if (*(short *) (chn_sqlda->sqlvar[chn_i].sqlind) == -1)
                        sprintf(long_s, "%s", "NULL");
                   else
                        sprintf(long_s, "%d", *(long *) (main_sqlda->sqlvar[i].sqldata));
               }
          }
     } 

    if (main_fetch_stat != 100L) 
    { 
        ERREXIT(status, 1) 
    } 

    if (isc_dsql_free_statement(status, &main_stmt, DSQL_close)) 
    { 
        ERREXIT(status, 1) 
    } 
Почему-то условие if (*(short *) (chn_sqlda->sqlvar[chn_i].sqlind) == -1) выполняется на некоторых записях поля, которое not null. Подскажите, пожалуйста, что не так.

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 09 июн 2006, 11:05

Во-первых, я что-то не вижу чему равен chn_i...
Во-вторых, для non-nullable полей sqlind просто игнорируется и, соответственно, там может остаться мусор. Я не помню, у нас malloc() выделенную память обнуляет? Если нет - лучше сделать это принудительно.
И, кстати, sqlind и так short*. Лишний раз кастить...

sunduk4
Сообщения: 18
Зарегистрирован: 02 май 2006, 13:45

Сообщение sunduk4 » 09 июн 2006, 11:36

Во-первых, я что-то не вижу чему равен chn_i...
извиняюсь, там i естественно.. код большой, копировал только основные моменты..
Во-вторых, для non-nullable полей sqlind просто игнорируется и, соответственно, там может остаться мусор. Я не помню, у нас malloc() выделенную память обнуляет? Если нет - лучше сделать это принудительно.
память не обнуляется.. можно в таком случае calloc тогда использовать..
каким образом тогда лучше проверять значения полей на null?
И, кстати, sqlind и так short*. Лишний раз кастить...
гм.. понял, исправлюсь..

v6y
Сообщения: 78
Зарегистрирован: 12 мар 2005, 17:45

Сообщение v6y » 09 июн 2006, 13:19

sunduk4 писал(а):

каким образом тогда лучше проверять значения полей на null?
По науке (apifull из examples) примерно так:

Код: Выделить всё

#define IS_NULL(x) (x->sqltype & 1) && (*x->sqlind < 0)
x - переменная типа XSQLVAR

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 09 июн 2006, 13:29

sunduk4 писал(а):
Я не помню, у нас malloc() выделенную память обнуляет? Если нет - лучше сделать это принудительно.
память не обнуляется.. можно в таком случае calloc тогда использовать..
каким образом тогда лучше проверять значения полей на null?
Твой способ нормальный, только как я и сказал после
main_var->sqlind = (short *)malloc(sizeof(short));
добавь
*(main_var->sqlind) = 0;

sunduk4
Сообщения: 18
Зарегистрирован: 02 май 2006, 13:45

Сообщение sunduk4 » 09 июн 2006, 14:17

Спасибо всем! Получилось.

Ответить