powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / ASA, dblib10.dll, не апдейтится курсор содержащий подзапрос
9 сообщений из 9, страница 1 из 1
ASA, dblib10.dll, не апдейтится курсор содержащий подзапрос
    #34662397
Alexander Mushnikov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hi All.

возможно вопрос делитантский...подскажите:
есть сервер ASA, приложение под win32 с использованием dblib.
есть универсальный класс - UniDataSet, который заточен для работы с разными провайдерами баз данных ( IBMDADB2, ASAProv.90, SAOLEDB.10, dblib9.dll, dblib10.dll ).
только наскочил на очередные грабли с DBLIB.
если запрос используемый для открытия курсора содержит подзапрос, то при апдейте в курсоре получаю ошибку: -190 (Cannot update an expression). тем ни менее тот же самый запрос но через OLE драйвер + TADODataSet выполняет апдейт без проблем.

курсор открываю - For Update, для этого поля в SQlDA->sqlvar[ Index ].sqlindex = -1.
что я делаю не так?
или может это вообще невозможно? но ADO как-то это все-же делает.
...
Рейтинг: 0 / 0
ASA, dblib10.dll, не апдейтится курсор содержащий подзапрос
    #34662506
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Покажи код.
...
Рейтинг: 0 / 0
ASA, dblib10.dll, не апдейтится курсор содержащий подзапрос
    #34663733
Alexander Mushnikov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White OwlПокажи код.

кода очень много, постараюсь только по содержанию .... неважное выкидываю:
//
// собственно тот самый запрос, для курсора
//
CommantText = "select cup_id,start_time,min_players,max_players,bet_amount,price_amount, \
bonus_amount,fee_fraction,admin_name,cup_type,
(SELECT COUNT(USER_ID) FROM BGGGG_CUP_REGISTER WHERE CUP_ID=tB.CUP_ID) as cnt,
towinner,tosecond,to34,to58,to916,bonus_to,
cup_name,numwin,target_cup_id,restart_time,sb_account,restart_days,rems,
cup_ident,expiration_time from BGGGG_CUP tB
where status=0 order by start_time";

enum dbLib_CursorType { dbct_Default=0, dbct_ReadOnly=2, dbct_ForUpdate=4096 };

CursorType = dbct_ForUpdate;
WithoutHold = 0; // 0 - WITH HOLD, 1 - WITHOUT HOLD (default)
//
// метод для открытия курсора
//
bool dbLibDataSet::OpenCursor(void)
{
wchar_t bsrc[ 1024 ];
char bsel[ 1024 ];
int n;
EncDecUTF16 utf16str;
unsigned char *uch;


wcscpy( bsrc, CommandText.operator wchar_t *() );

if( WideCharToMultiByte( CP_ACP, 0, bsrc, -1, bsel, 1024, NULL, NULL ) <= 0 ) return( false );

utf16str = bsel;
uch = utf16str.toUTF8_AsUchar();
if( uch == NULL ) return( false );
//
// Note that database fills in statement number on prepare
//
dbpp_prepare_describe( p_sqlca, SQLNULL, _sql_ptrtypechk_(ProgName,char), &stat, uch, (SQLDA *)0, (SQLDA *)0, 3, 0 );

if( p_sqlca->sqlcode < 0 )
{
CloseCursor();
return( false );
};

dbpp_declare( p_sqlca, CursorName, SQLNULL, _sql_ptrtypechk_(ProgName,char), &stat, CursorType );
if( p_sqlca->sqlcode < 0 )
{
CloseCursor();
return( false );
};

dbpp_open( p_sqlca, CursorName, SQLNULL, SQLNULL, SQLNULL, (SQLDA *)0, 0, 0, WithoutHold );

if( p_sqlca->sqlcode < 0 )
{
CloseCursor();
return( false );
};

n = 3;
SqlDA_New = alloc_sqlda( n ); ///< for update and insert
SqlDA = alloc_sqlda( n );

dbpp_describe( p_sqlca, SQLNULL, _sql_ptrtypechk_(ProgName,char), &stat, SqlDA_New, 1 );
dbpp_describe( p_sqlca, SQLNULL, _sql_ptrtypechk_(ProgName,char), &stat, SqlDA, 1 );

if( p_sqlca->sqlcode < 0 )
{
CloseCursor();
return( false );
};

if( SqlDA->sqld > SqlDA->sqln )
{
n = SqlDA->sqld;

free_sqlda( SqlDA_New );
free_sqlda( SqlDA );


SqlDA_New = alloc_sqlda( n );
SqlDA = alloc_sqlda( n );

dbpp_describe( p_sqlca, SQLNULL, _sql_ptrtypechk_(ProgName,char), &stat, SqlDA_New, 1 );
dbpp_describe( p_sqlca, SQLNULL, _sql_ptrtypechk_(ProgName,char), &stat, SqlDA, 1 );

if( p_sqlca->sqlcode < 0 )
{
CloseCursor();
return( false );
};

}

fill_s_sqlda( SqlDA, StringMaxSize ); /// ЭТО ДЛЯ ЧТЕНИЯ ИЗ ТАБЛИЦЫ
fill_s_sqlda( SqlDA_New, StringMaxSize ); /// ЭТО ДЛЯ ЗАПИСИ В ТАБЛИЦУ

return( true );
}

//
// закрытие курсора
//
bool dbLibDataSet::CloseCursor(void)
{
Post();

dbpp_close( p_sqlca, CursorName );

free_filled_sqlda( SqlDA );
free_filled_sqlda( SqlDA_New );

SqlDA = NULL;
SqlDA_New = NULL;

dbpp_dropstmt( p_sqlca, SQLNULL, _sql_ptrtypechk_(ProgName,char), &stat );

FieldCount = 0;
State = dsInactive;
RowsCount = 0;

return( true );
}

//
// заполнение SQLDA той, которая для записи в таблицу
//
bool dbLibDataSet::SetDataWideString( int Index, int fiSize, WideString data )
{
SQLDA_VARIABLE *svar;
SQLDA_VARIABLE *svar_New;
wchar_t bsrc[ 4096 ];
WideStringList *DataList;
unsigned char *uch;
unsigned short size_field, size_str, fiType;
WideString *pws;


if( !SqlDA ) return( false );
if( !DataWStr ) return( false );

DataList = DataWStr;

if( DataList->Count() != SqlDA->sqld ) return( false );

if( Index >= DataList->Count() || Index >= SqlDA->sqld ) return( false );

svar = &(SqlDA->sqlvar[ Index ]);
svar_New = &(SqlDA_New->sqlvar[ Index ]);
pws = DataList->Item( Index );

if( !pws ) return( false );

*pws = data;

if( data == WideString( "" ) )
{
*( svar_New->sqlind ) = -1;
}
else
{
uch = (unsigned char *)svar_New->sqldata;
fiType = svar_New->sqltype;

memset( bsrc, 0, sizeof( bsrc ) );
wcscpy( bsrc, data.operator wchar_t *() );

*( svar_New->sqlind ) = 0;

switch( fiType )
{
case DT_STRING:
case 461:
if( svar->sqllen < fiSize )
size_field = fiSize;
else
size_field = svar->sqllen;

size_str = WideCharToMultiByte( CP_ACP, 0, bsrc, -1, uch, size_field, NULL, NULL );

if( size_str > 0 )
svar_New->sqllen = size_str;

break;
default:
size_field = svar->sqllen;
size_str = WideCharToMultiByte( CP_ACP, 0, bsrc, -1, uch, size_field, NULL, NULL );
}

if( size_str <= 0 )
return( false );

}

return( true );
}


//
// собственно апдейт записи в текущей позиции курсора
//
bool dbLibDataSet::Update( void )
{
if( !SqlDA_New ) return( false );

dbpp_update( p_sqlca, CursorName, _sql_ptrtypechk_(SqlDA_New,SQLDA) );

if( p_sqlca->sqlcode < 0 ) return( false );

Modified = true;

return( true );
}

//
// добавление новой записи
//
bool dbLibDataSet::Insert( void )
{
if( !SqlDA_New ) return( false );

dbpp_put_into( p_sqlca, CursorName, _sql_ptrtypechk_(SqlDA_New,SQLDA), (SQLDA *)0 );

if( p_sqlca->sqlcode < 0 ) return( false );

Modified = true;

return( true );
}


//
// удаление записи в текущей позиции курсора
//
bool dbLibDataSet::Delete( void )
{
dbpp_delete( p_sqlca, CursorName, SQLNULL, SQLNULL );

if( p_sqlca->sqlcode < 0 ) return( false );

Modified = true;

return( true );
}



//
// собственно - коммит
//
bool dbLibDataSet::Post( void )
{
if( !Modified )
{
State = dsBrowse;
return( true );
}

dbpp_commit( p_sqlca, 0 );

if( p_sqlca->sqlcode < 0 ) return( false );

State = dsBrowse;
Modified = false;

return( true );
}

//
// собственно - роллбэк
//
bool dbLibDataSet::Cancel( void )
{
if( !Modified )
{
State = dsBrowse;

return( true );
}

dbpp_rollback( p_sqlca, 0 );

if( p_sqlca->sqlcode < 0 ) return( false );

State = dsBrowse;
Modified = false;

return( true );
}
...
Рейтинг: 0 / 0
ASA, dblib10.dll, не апдейтится курсор содержащий подзапрос
    #34663770
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexander Mushnikov пишет:

> кода очень много,

Нужен был только код SQL.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
select
  cup_id,start_time,min_players,max_players,bet_amount,price_amount,
  bonus_amount,fee_fraction,admin_name,cup_type,
  (SELECT COUNT(USER_ID) FROM BGGGG_CUP_REGISTER WHERE CUP_ID=tB.CUP_ID) as cnt,
  towinner,tosecond,to34,to58,to916,bonus_to,
  cup_name,numwin,target_cup_id,restart_time,sb_account,restart_days,rems,
  cup_ident,expiration_time
  from BGGGG_CUP tB
  where status= 0  order by start_time

Ну и как ты собираешься UPDATE-ить поле CNT ?
Не-updateable курсор, вот и все дела. Потому что поле cnt - вычисляемое.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
ASA, dblib10.dll, не апдейтится курсор содержащий подзапрос
    #34663778
Фотография Рыжий Кот
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
/topic/230009&hl=

может это как-то связано? попробуйте подзапрос оформнить первым, а потом перечисление остальных полей
...
Рейтинг: 0 / 0
ASA, dblib10.dll, не апдейтится курсор содержащий подзапрос
    #34663848
Alexander Mushnikov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv
Нужен был только код SQL.

Ну и как ты собираешься UPDATE-ить поле CNT ?
Не-updateable курсор, вот и все дела. Потому что поле cnt - вычисляемое.
Posted via ActualForum NNTP Server 1.4

согласен целиком и полностью....и с самого начала.
я так подозреваю, что TADODataSet просто напросто держит в памяти набор данных, а курсор закрывает - затем апдейтит и открывает поновой и устанавливается в прежнюю позицию....
что-то в этом духе. вот почему он так медленно отрабатывает;-(((
из-за этого я и перешел на dblib. но похоже и тут придется сделать немного покривому - для случая вычисляемого поля:
CloseCursor();
dbpp_exuecute_imm( .... );
OpenCursor();
других вариантов больше не вижу;-(
...
Рейтинг: 0 / 0
ASA, dblib10.dll, не апдейтится курсор содержащий подзапрос
    #34664854
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexander Mushnikov пишет:
> из-за этого я и перешел на dblib. но похоже и тут придется сделать
> немного покривому - для случая вычисляемого поля:

Так не надо просто эти мифические UPDATEABLE курсоры использвать.
Сделал SELECT, надо поменять данные - сделай UPDATE.

Это работает на любой СУБД, всегда и везде.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
ASA, dblib10.dll, не апдейтится курсор содержащий подзапрос
    #34665070
Alexander Mushnikov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv
Так не надо просто эти мифические UPDATEABLE курсоры использвать.
Сделал SELECT, надо поменять данные - сделай UPDATE.

Это работает на любой СУБД, всегда и везде.

сервер очень далеко и весьма загружен. процессоры ниже 30% загрузка не опускается. там и база таам и апач с пхп, там и сам игровой сервак.
если я использую какой нибудь там TADOdataSet - некоторые запросы выполняются до 30-40 сек.
пришлось свести до минимума все движения + использовать dblib - задержка упала до 2-х - 3-х секунд. базу конструировал не я;-) и менять ее уже нельзя;-( там кадр не разделил рабочие и архивные таблицы под статистику - вот теперь мучаемся.

спасибо всем, вопрос я думаю закрыт.
...
Рейтинг: 0 / 0
ASA, dblib10.dll, не апдейтится курсор содержащий подзапрос
    #34665327
Фотография Рыжий Кот
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если статистика не нужна до заданной секунды, то можно сделать реплику на другую машину и скормить его апачу..., будет задержка в 1-2 минуты
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / ASA, dblib10.dll, не апдейтится курсор содержащий подзапрос
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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