Showing posts with label Firebird C API. Show all posts
Showing posts with label Firebird C API. Show all posts
2010/12/30
Firebird C API - 질의문 수행 후 반영된 레코드 수 구하는 함수
struct AFFECTED_ROW
<
{
int Insert;
int Select;
int Update;
int Delete;
AFFECTED_ROW()
{
Init();
}
void Init()
{
Insert = 0;
Select = 0;
Update = 0;
Delete = 0;
}
};
void CTestEFBDlg::GetAffectedRow( isc_stmt_handle stmt, AFFECTED_ROW& affected )
{
static char const info_count[] = { isc_info_sql_records };
char result[64] = { 0, };
int ret = 0;
ISC_STATUS_ARRAY status;
ISC_LONG sqlcode;
affected.Init();
isc_dsql_sql_info( status, &stmt, sizeof(info_count), info_count, sizeof(result), result );
if ( status[ 0 ] == 1 && status[ 1 ] > 0 )
{
// Error occurred
sqlcode = isc_sqlcode( status );
char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );
CString strMsg;
strMsg.Format( _T("Fail to isc_dsql_sql_info : %d - %s"), sqlcode, CString( szMsg ) );
AppendResult( strMsg );
}
else
{
char* pCur = result;
int length;
if ( *pCur == isc_info_sql_records )
{
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
while(*pCur != 1)
{
switch(*pCur)
{
case isc_info_req_select_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
affected.Select = isc_vax_integer(pCur, length);
pCur += length;
break;
case isc_info_req_insert_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
affected.Insert = isc_vax_integer(pCur, length);
pCur += length;
break;
case isc_info_req_update_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
affected.Update = isc_vax_integer(pCur, length);
pCur += length;
break;
case isc_info_req_delete_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
affected.Delete = isc_vax_integer(pCur, length);
pCur += length;
break;
default:
pCur++;
break;
}
}
}
}
}
GetAffectedRow( stmt, affected );
CString strMsg;
strMsg.Format( _T("%d Row(s) Updated"), affected.Update );
AfxMessageBox( strMsg );
Original Post : http://neodreamer-dev.tistory.com/481
2010/12/26
Firebird C API 질의문 수행 후 반영된 레코드 수 구하기
아래 코드는 isc_dsql_sql_info() 함수를 이용하여 질의문를 후행 한 후 반영된 레코드 수를 가져오는 코드 이다.
isc_info_sql_records 파라메터를 이용하여 isc_dsql_sql_info() 함수를 수행 한 후의 Request Buffer 내용
자료 출처
int del_count = 0, ins_count = 0, upd_count = 0, sel_count = 0;
static char const info_count[] = { isc_info_sql_records };
char result[64];
int ret = 0;
isc_dsql_sql_info( status, &stmt, sizeof(info_count), info_count, sizeof(result), result );
if ( status[ 0 ] == 1 && status[ 1 ] > 0 )
{
// Error occurred
sqlcode = isc_sqlcode( status );
char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );
CString strMsg;
strMsg.Format( _T("Fail to isc_dsql_sql_info : %d - %s"), sqlcode, CString( szMsg ) );
AfxMessageBox( strMsg );
}
else
{
char* pCur = result;
int length;
if ( *pCur == isc_info_sql_records )
{
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
while(*pCur != 1)
{
switch(*pCur)
{
case isc_info_req_select_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
sel_count = isc_vax_integer(pCur, length);
pCur += length;
break;
case isc_info_req_insert_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
ins_count = isc_vax_integer(pCur, length);
pCur += length;
break;
case isc_info_req_update_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
upd_count = isc_vax_integer(pCur, length);
pCur += length;
break;
case isc_info_req_delete_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
del_count = isc_vax_integer(pCur, length);
pCur += length;
break;
default:
pCur++;
break;
}
}
CString strMsg;
strMsg.Format( _T("%d Row(s) Updated"), upd_count );
AfxMessageBox( strMsg );
}
}
isc_info_sql_records 파라메터를 이용하여 isc_dsql_sql_info() 함수를 수행 한 후의 Request Buffer 내용
Result buffer for DELETE statement contains:
23, 29,0, (isc_info_sql_records, length=29)
15, 4,0, 0,0,0,0, (isc_info_req_update_count, 0 rows updated)
16, 4,0, 4,0,0,0, (isc_info_req_delete_count, 4 rows deleted)
13, 4,0, 4,0,0,0, (isc_info_req_select_count, 4 rows selected)
14, 4,0, 0,0,0,0, (isc_info_req_insert_count)
1, (isc_info_end)
Result buffer for UPDATE statement contains:
23, 29,0,
15, 4,0, 4,0,0,0,
16, 4,0, 0,0,0,0,
13, 4,0, 4,0,0,0,
14, 4,0, 0,0,0,0,
1,
Result buffer for INSERT statement contains:
23, 29,0,
15, 4,0, 0,0,0,0,
16, 4,0, 0,0,0,0,
13, 4,0, 0,0,0,0,
14, 4,0, 1,0,0,0,
1,
isc_dsql_sql_info() 함수에 isc_info_sql_records 파라메터를 이용하여 데이터베이스에서 반영 된 레코드 수를 가져올 수 있는데 반영된 수가 누적되고 있다. 이에 대한 내용은 좀 더 분석을 해 보아야겠다. Firebird C API 의 경우 관련 자료가 많지 않아서 분석이 쉽지가 않다.
자료 출처
Labels:
Affected Row Count
,
firebird
,
Firebird C API
,
isc_dsql_sql_info
,
isc_info_sql_records
,
TistoryOldPost
Firebird C API 간단 사용기
C API를 이용한 Firebird embedded 를 간단하게 사용하는 예이다. 질의문의 결과난 파라메터를 이용한 방법은 XSQLDA(eXtended SQL Descriptor Area)를 이해한 후에 정리를 해야 할 것 같다.
ClearResult();
<
AppendResult( _T("Try to attach database!!") );
isc_db_handle db = 0L; /* database handle */
isc_tr_handle trans = NULL; /* transaction handle */
isc_stmt_handle stmt = NULL; /* statement handle */
char szDBName[ MAX_PATH ] = "E:\TEST.FDB";
ISC_STATUS_ARRAY status;
ISC_LONG sqlcode;
// Database Parameter Block (DPB) 준비
std::string strDPB;
strDPB.append( 1, isc_dpb_version1 ); // DPB 버전
strDPB.append( 1, isc_dpb_user_name ); // User Account
strDPB.append( 1, (char)strlen("sysdba") );
strDPB.append( "sysdba" );
strDPB.append( 1, isc_dpb_password ); // Password
strDPB.append( 1, (char)strlen("masterkey") );
strDPB.append( "masterkey" );
// Database connect
if ( isc_attach_database( status, 0, szDBName, &db, (short)strDPB.length(), strDPB.c_str() ) )
{
AppendResult( _T("Fail to attach database!!") );
return;
}
// Start Transaction
isc_start_transaction( status, &trans, 1, &db, 0, NULL );
// Execute query
char szQuery[1024];
// Create Table
sprintf_s( szQuery, 1024,
"CREATE TABLE employee ("
" name VARCHAR(20) "
", birth INTEGER"
", enter TIMESTAMP"
")");
isc_dsql_execute_immediate( status, &db, &trans, strlen(szQuery), szQuery, 1, NULL );
isc_commit_transaction( status, &trans );
if ( status[0] == 1 && status[ 1 ] > 0 )
{
// Error occurred
sqlcode = isc_sqlcode( status );
char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );
CString strMsg;
strMsg.Format( _T("Fail to Create Table : %d - %s"), sqlcode, CString( szMsg ) );
AppendResult( strMsg );
}
else
{
AppendResult( _T("Table Creaded.") );
}
// Insert Data
isc_start_transaction( status, &trans, 1, &db, 0, NULL );
AppendResult( _T("Insertion!!") );
for ( int i = 0; i < 5; ++i )
{
sprintf_s( szQuery, 1024,
"INSERT INTO employee ( name, birth, enter ) VALUES ( 'name%d', %d, CURRENT_TIMESTAMP )"
, i, 20 + i
);
isc_dsql_execute_immediate( status, &db, &trans, strlen(szQuery), szQuery, 1, NULL );
if ( status[0] == 1 && status[ 1 ] > 0 )
{
// Error occurred
sqlcode = isc_sqlcode( status );
char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );
CString strMsg;
strMsg.Format( _T("Fail to Insert : %d - %s"), sqlcode, CString( szMsg ) );
AppendResult( strMsg );
}
else
{
AppendResult( _T("1 Row Inserted.") );
}
}
// Update Data
// Statement allocation
isc_dsql_allocate_statement( status, &db, &stmt );
AppendResult( _T("Update!!") );
sprintf_s( szQuery, 1024, "UPDATE employee SET birth = birth + 2 WHERE birth > 22");
isc_dsql_prepare( status, &trans, &stmt, 0, szQuery, 0, NULL );
isc_dsql_execute( status, &trans, &stmt, 0, NULL );
isc_commit_transaction( status, &trans );
if ( status[ 0 ] == 1 && status[ 1 ] > 0 )
{
// Error occurred
sqlcode = isc_sqlcode( status );
char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );
CString strMsg;
strMsg.Format( _T("Fail to Update : %d - %s"), sqlcode, CString( szMsg ) );
AppendResult( strMsg );
}
else
{
AppendResult( _T("Table Updated") );
}
isc_dsql_free_statement( status, &stmt, DSQL_close );
// Delete Table
AppendResult( _T("Drop Table!!") );
sprintf_s( szQuery, 1024, "DROP TABLE employee");
isc_dsql_execute_immediate( status, &db, &trans, strlen(szQuery), szQuery, 1, NULL );
// Commit Transaction
isc_commit_transaction( status, &trans );
// Database disconnect
isc_detach_database( status, &db );
AppendResult( _T("Database detached!!") );
AppendResult( _T("Finished!!") );
Original Post : http://neodreamer-dev.tistory.com/479
2010/11/01
Firebird C API 로 Firebird Embedded 사용하기
Firebird Embedded 패키기에서 아래 파일을 프로젝트 폴더에 복사를 한다.
fbembed.dll 을 fbclient.dll 로 이름을 바꾸고 일반적인 Firebird 를 사용하듯 하면 된다.
아래 코드는 테스트를 위한 코드이다.
- fbembed.dll
- firebird.conf
- firebird.msg
- ib_util.dll
- icudt30.dll
- icuin30.dll
- icuuc30.dll
fbembed.dll 을 fbclient.dll 로 이름을 바꾸고 일반적인 Firebird 를 사용하듯 하면 된다.
아래 코드는 테스트를 위한 코드이다.
isc_db_handle db = NULL; /* database handle */
<
isc_tr_handle trans = NULL; /* transaction handle */
ISC_STATUS_ARRAY status; /* status vector */
long sqlcode; /* SQLCODE */
char *szDBName = "e:\ est.fdb";
// 데이터베이스 생성 DDL
std::string strQuery = "CREATE DATABASE 'e:\ est.fdb' USER 'sysdba' PASSWORD 'masterkey';";
// 데이터베이스 생성 시도
isc_dsql_execute_immediate(status, &db, &trans, 0, strQuery.c_str(), 1, NULL);
if ( status[0] == 1 && status[1] > 0 )
{
sqlcode = isc_sqlcode(status);
char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );
char szMsg2[512];
ISC_STATUS* pStatus = status;
isc_interprete( szMsg2, &pStatus );
TRACE( "Fail to create database : %d - %s (%s)\n", sqlcode, szMsg, szMsg2 );
if ( sqlcode == -902 )
{
TRACE( "Database exists!!\n" );
}
else
{
return;
}
}
else
{
TRACE( "Database created!!!\n" );
}
isc_detach_database( status, &db );
char *dpb_buffer = 0; // Database Parameter Buffer
short dpb_length = 0;
// Set parameter User Name and Password
/*
isc_expand_dpb( &dpb_buffer, &dpb_length
, isc_dpb_num_buffers, 80
, isc_dpb_user_name, "sysdba"
, isc_dpb_password, "masterkey"
, isc_dpb_connect_timeout, 180
);
//*/
// Database Parameter Block (DPB) 준비
std::string strDPB;
strDPB.append( 1, isc_dpb_version1 ); // DPB 버전
strDPB.append( 1, isc_dpb_user_name ); // User Account
strDPB.append( 1, (char)strlen("sysdba") );
strDPB.append( "sysdba" );
strDPB.append( 1, isc_dpb_password ); // Password
strDPB.append( 1, (char)strlen("masterkey") );
strDPB.append( "masterkey" );
strDPB.append( 1, isc_dpb_num_buffers );
strDPB.append( 1, (char)1 );
strDPB.append( 1, (char)90 );
strDPB.append( 1, isc_dpb_connect_timeout );
strDPB.append( 1, (char)4 );
strDPB.append( 1, (char)180 );
strDPB.append( 1, (char)(180 >> 8) );
strDPB.append( 1, (char)(180 >> 16) );
strDPB.append( 1, (char)(180 >> 24) );
int nParam = (int)strDPB.length();
// 데이터베이스 연결
//isc_attach_database( status, (int)strlen( szDBName ), szDBName, &db, dpb_length, dpb_buffer );
isc_attach_database( status, (int)strlen( szDBName ), szDBName, &db,
(short)strDPB.length(), strDPB.c_str() );
if ( status[0] == 1 && status[1] > 0 )
{
// Error occurred
sqlcode = isc_sqlcode( status );
char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );
TRACE( "Fail to connect Database : %d - %s\n", sqlcode, szMsg );
return;
}
else
{
TRACE( "Database connected!!\n" );
}
isc_start_transaction( status, &trans, 1, &db, 0, NULL );
// 테이블 생성
isc_dsql_execute_immediate( status, &db, &trans, 0,
"CREATE TABLE member ( name VARCHAR(20), age INTEGER )", 1, NULL );
if ( status[0] == 1 && status[1] > 0 )
{
// Error occurred
sqlcode = isc_sqlcode(status);
char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );
TRACE( "Fail to Create table : %d - %s\n", sqlcode, szMsg );
isc_rollback_transaction( status, &trans );
// Release parameter buffer
isc_free( dpb_buffer );
isc_detach_database( status, &db );
return;
}
else
{
TRACE( "Table created!!\n" );
}
isc_commit_transaction( status, &trans );
// Release parameter buffer
isc_free( dpb_buffer );
isc_detach_database( status, &db );
Original Post : http://neodreamer-dev.tistory.com/474
Labels:
firebird
,
Firebird API
,
Firebird C API
,
Firebird Embedded
,
TistoryOldPost
2009/12/02
Firebird C API 데이터베이스 연결하기
char *szDBName = "e:\test.fdb";
char szSQL[2048] = {0,};
isc_db_handle db = NULL; // database handle
isc_tr_handle trans = NULL; // transaction handle
ISC_STATUS_ARRAY status; // status vector
long sqlcode; // SQLCODE
char *dpb_buffer = 0; // Database Parameter Buffer
short dpb_length = 0;
// Prepare parameter buffer
dpb_buffer = (char *)malloc(1);
*dpb_buffer = isc_dpb_version1;
dpb_length = 1;
// Set parameter User Name and Password
isc_expand_dpb( &dpb_buffer, &dpb_length
, isc_dpb_user_name, "SYSDBA"
, isc_dpb_password, "masterkey"
);
// Connect database
isc_attach_database( status, (int)strlen( szDBName ), szDBName, &db, dpb_length, dpb_buffer );
sqlcode = isc_sqlcode( status );
if ( status[0] == 1 && status[1] )
{
// Error occured
TRACE( "Fail to connect Database : %d\n", sqlcode );
return;
}
// Disconnect database
isc_detach_database( status, &db );
// Release parameter buffer
isc_free( dpb_buffer );
+ 2009/12/06
위의 코드는 메모리 1byte 의 메모리 누수가 생긴다. 누수가 발생하는 부분은 12번째 줄의 parameter buffer 에 버퍼 버전을 할당하는 부분으로 이부분을 주석처리하면 메모리 누수가 발생하지 않고 동작을 하게 된다. 버전을 명시하지 않아도 문제가 되는지 그리고 버전을 명시하고서도 메모리 누수가 발생하지 않도록 하는 방법이 있는지는 확인을 해 보아야 겠다
Original Post : http://neodreamer-dev.tistory.com/342
Labels:
C++
,
Database
,
firebird
,
Firebird C API
,
TistoryOldPost
,
데이터베이스
2009/12/01
Firebird C API를 이용하여 데이터베이스 생성하기
isc_db_handle db = NULL; /* database handle */
isc_tr_handle trans = NULL; /* transaction handle */
ISC_STATUS_ARRAY status; /* status vector */
long sqlcode; /* SQLCODE */
char *szSQL = "CREATE DATABASE 'e:\\ew.fdb' USER 'sysdba' PASSWORD 'masterkey';";
if ( isc_dsql_execute_immediate(status, &db, &trans, 0, szSQL, 1, NULL) )
{
sqlcode = isc_sqlcode(status);
TRACE( "Fail to create database : %d\n", sqlcode );
}
else
{
TRACE( "Database created!!!\n" );
}
Original Post : http://neodreamer-dev.tistory.com/341
Labels:
firebird
,
Firebird C API
,
Free RDBMS
,
TistoryOldPost
Subscribe to:
Posts
(
Atom
)