LINUX.ORG.RU

Вопрос по SQL/OCI 7.3


0

0

почему в следующем коде апдейт не находит строчку вставленную первым инсертом. 
код выполняется без ошибок

...........

{                                                                                                                      
    char *insert;                                                                                                                                 
                                                                                                                                                  
    if(g->cmd==CMD_PRIHOD||g->cmd==CMD_RASHOD||g->cmd==CMD_REPRICE)                                                                               
         insert =  "INSERT INTO roz_control VALUES (:id_apparat, :command,  0, sysdate, 0, :doc_id,  0,0,0, 'FAILURE', -1 )";                     
    else insert =  "INSERT INTO roz_control VALUES (:id_apparat, :command,  0, sysdate, 0, 0,        0,0,0, 'FAILURE', -1 )";                     
                                                                                                                                                  
    syslog(LOG_INFO,"%s:try to execute '%s'",__func__,insert);                                                                                    
                                                                                                                                                  
    if(  oparse(&g->cda, insert, (sb4) -1, FALSE, (ub4) VERSION_7)  )           do_exit_with_err_report(g,EXIT_FAILURE);                          
                                                                                                                                                  
    obndrv( &g->cda, (text*)":id_apparat",-1, (ub1*)&g->id_kassa, (sword)sizeof(g->id_kassa), SQLT_INT,-1, (sb2*)0,     (text*)0,-1,-1);          
    obndrv( &g->cda, (text*)":command",   -1, (ub1*)commands[g->cmd],                     -1, SQLT_STR,-1, (sb2*)0,     (text*)0,-1,-1);          
    if(g->cmd==CMD_PRIHOD||g->cmd==CMD_RASHOD||g->cmd==CMD_REPRICE)                                                                               
        obndrv( &g->cda, (text*)":doc_id",-1, (ub1*)g->doc_num_str,                       -1, SQLT_STR,-1, (sb2*)0,     (text*)0,-1,-1);          
                                                                                                                                                  
    if ( oexec( &g->cda ) )             do_exit_with_err_report(g,EXIT_FAILURE);                                                                  
    if(ocom(&g->lda)){                                                                                                                            
        text msg[512];                                                                                                                            
                                                                                                                                                  
        oerhms(&g->lda, g->lda.rc, msg, (sword) sizeof msg);                                                                                      
        syslog(LOG_ERR, "%s:%s:ORACLE ERROR:%s",   __func__,  (g->lda.fc > 0)?(oci_func_tab[g->lda.fc]):(text*)"UNCKNOWN",   msg);                
    }                                                                                                                                             
}                                                                                                                                                 
//----------------------------------------------------                                                                                            
{                                                                                                                       
    char update[] =  "update roz_control set error_ekka = 1, status = 'SUCCESS'"                                                                  
    " where cmd = :command and error_ekka = -1 and apparat_id = :id_apparat and                                                                   
    data = (select max(data) from roz_control where apparat_id = :id_apparat)";                                                                   
    syslog(LOG_INFO,"%s:try to execute '%s'",__func__,update);                                                                                    
                                                                                                                                                  
    if(  oparse(&g->cda, update, (sb4) -1, FALSE, (ub4) VERSION_7)  )           do_exit_with_err_report(g,EXIT_FAILURE);                          
                                                                                                                                                  
    obndrv( &g->cda, (text*)":id_apparat",-1, (ub1*)&g->id_kassa, (sword)sizeof(g->id_kassa), SQLT_INT,-1, (sb2*)0,     (text*)0,-1,-1);          
    obndrv( &g->cda, (text*)":command",   -1, (ub1*)commands[g->cmd],                     -1, SQLT_STR,-1, (sb2*)0,     (text*)0,-1,-1);          
                                                                                                                                                  
    if ( oexec( &g->cda ) )             do_exit_with_err_report(g,EXIT_FAILURE);                                                                  
    if (ocom(&g->lda)){                                                                                                                           
        text msg[512];                                                                                                                            
                                                                                                                                                  
        oerhms(&g->lda, g->lda.rc, msg, (sword) sizeof msg);                                                                                      
        syslog(LOG_ERR, "%s:%s:ORACLE ERROR:%s",   __func__,  (g->lda.fc > 0)?(oci_func_tab[g->lda.fc]):(text*)"UNCKNOWN",   msg);                
    }                                                                                                                                             
}

.........................

????
★★★★★

Тебе проще анализировать ситуацию, чем кому-либо еще, хотя бы из-за возможности отладки. Почему бы не посмотреть, что появляется в базе после INSERT и почему бы не воспроизвести UPDATE руками? Вообще, все довольно разумно (хотя и _крайне_ коряво), и самые большие подозрения вызывает внутренний select max(data) from roz_control where apparat_id = :id_apparat. Если не рассматривать поведение этого механизма при параллельной работе нескольких сессий(поннятно, что это не будет работать), то достаточно положить запись с датой в далеком будущем, чтобы находили именно ее.

anonymous
()
Ответ на: комментарий от anonymous

>Тебе проще анализировать ситуацию, чем кому-либо еще, хотя бы из-за возможности отладки.

уже пытался. результаты привели к полному недоумению.

>Почему бы не посмотреть, что появляется в базе после INSERT

что запихиваем то и получаем. insert отрабатывает абсолютно коррекно.

>почему бы не воспроизвести UPDATE руками?

воспроизводили из sqlplus и tora. нормально работает.

>самые большие подозрения вызывает внутренний select max(data) from roz_control where apparat_id = :id_apparat.

у меня тоже. В конкретном случае именно он по непонятной мне причине именно/только в моей программе возвращает NULL

>хотя и _крайне_ коряво

а поподробней можно?????

cvv ★★★★★
() автор топика
Ответ на: комментарий от cvv

>В конкретном случае именно он по непонятной мне причине именно/только в моей программе возвращает NULL

Попробуй вызвать UPDATE сразу после INSERT и/или поизучать происходящее между UPDATE и INSERT. Самое простое - этот NULL туда кладут. Попробуй сделать ALTER TABLE, сделав DATA NOT NULL.

>а поподробней можно?????

Если доживу до вечера, то попробую что-нибудь написать. Понятно, что мне будет проще высказывать свои соображения (и, главное, от них будет больше пользы), если я буду чуть-чуть представлять бизнес логику.

anonymous
()
Ответ на: комментарий от anonymous

>Попробуй вызвать UPDATE сразу после INSERT

update и так вызывается сразу после insert

>и/или поизучать происходящее между UPDATE и INSERT.

там ничего не происходит.

>Самое простое - этот NULL туда кладут.

никто его туда не кладёт. Кроме моей программы запущенной в *одном* экземпляре туда больше никто не лезет. это поле не имеет NULL ни в одной строчке. стрвнным является то что это явление наблюдается только в сишной программе на OCI. в остальных случаях всё ОК.

кстати а может OCI имеет траблы с биндингом переменных к вложенным sql-выражениям????

cvv ★★★★★
() автор топика
Ответ на: комментарий от cvv

>кстати а может OCI имеет траблы с биндингом переменных к вложенным sql-выражениям????

OCI не знает, что это вложенное sql-выражение.

Вообще-то, в былые времена я старался избегать двух одинаковых place holder'ов в выражении. Я не знаю, есть ли под этим опасением какая-то почва, но я бы попробовал заменить второй :id_apparat на что-нибудь другое и, соответственно, добавить еще один obndrv.

anonymous
()
Ответ на: комментарий от anonymous

не помогло.

кстати обнаружил что эти sql-выражения работают если первое и второе выражения были выполнены в разных процессах но неработает если в одном независимо от приложения выполняющего sql-код

cvv ★★★★★
() автор топика
Ответ на: комментарий от cvv

не совсем так. если точнее то эксперимент повторился в торе но не повторился в sqlplus хотя тот его обработал непонятным мне образом

cvv ★★★★★
() автор топика
Ответ на: комментарий от cvv

разобрался. трабла была в том что поле roz_control.cmd имеет тип CHAR вместо ожидаемого varchar2 вследствие кривизны рук проэктировщика базы со всеми вытекающими отсюдова последствиями

cvv ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.