DCL 3.7.4
Loading...
Searching...
No Matches
OciQuery Class Reference

#include <OciQuery.h>

Inheritance diagram for OciQuery:
SQL::Query Object

Public Member Functions

 OciQuery (OciConnection *_connHandle)
virtual ~OciQuery ()
virtual void __destroy ()
virtual bool __prepare (const char *_sql, size_t _sqllen, size_t _paramCount)
virtual bool __execute ()
virtual bool __fetch ()
virtual bool __getField (size_t _index, SQL::Field **_fieldHandleOut)
virtual bool __getParam (size_t _index, SQL::Param **_paramHandleOut)
Public Member Functions inherited from Object
virtual String toString () const
virtual void destroy ()
String className () const
bool isInstanceOf (const std::type_info &typeinfo) const
virtual const std::type_info & typeInfo () const

Protected Member Functions

bool reset ()
bool initFields ()
bool initParams (size_t _paramCount)
Protected Member Functions inherited from SQL::Query
 Query (Connection *_connHandle)
virtual ~Query ()
virtual bool __moreResults (bool *_moreResults)
Protected Member Functions inherited from Object
virtual ~Object ()
 Object ()

Protected Attributes

OCIStmt * __stmt
ub2 __stmtType
void * __fieldsBuffer
OciParam__params
OciField__fields
Protected Attributes inherited from SQL::Query
Connection__connHandle
bool __eof
int64_t __affectedRows
size_t __fieldCount
size_t __paramCount
wchar_t __placeholder
unsigned int __states

Additional Inherited Members

Public Types inherited from SQL::Query
enum  State { stStandBy = (unsigned int) 0x0001 , stPrepared = 0x0002 , stExecuted = 0x0004 , stFetched = 0x0008 }

Detailed Description

Definition at line 11 of file OciQuery.h.

Constructor & Destructor Documentation

◆ OciQuery()

OciQuery::OciQuery ( OciConnection * _connHandle)

◆ ~OciQuery()

OciQuery::~OciQuery ( )
virtual

Definition at line 74 of file OciQuery.cpp.

75{
76#ifdef __DCL_DEBUG
77 if (!reset()) {
78 char buf[256];
79 size_t buflen = sizeof(buf) - 1;
80 bool b = conn()->__getErrorMessage(buf, &buflen);
81 buf[b ? buflen : 0] = '\0';
82 __DCL_TRACE1(L"Warning! Query reset error! %hs\n", buf);
83 }
84#else
85 (void)reset();
86#endif
87}
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
bool reset()
Definition OciQuery.cpp:94

Member Function Documentation

◆ __destroy()

void OciQuery::__destroy ( )
virtual

Implements SQL::Query.

Definition at line 89 of file OciQuery.cpp.

90{
91 delete this;
92}

◆ __execute()

bool OciQuery::__execute ( )
virtual

Implements SQL::Query.

Definition at line 353 of file OciQuery.cpp.

354{
355 for(size_t i = 0; i < Query::__paramCount; i++) {
356 if (!__params[i].doBind())
357 return false;
358 }
359
360 sword status = OCIStmtExecute(
361 conn()->svcHandle(), // OCISvcCtx *svchp
362 __stmt, // OCIStmt *stmtp
363 conn()->errorHandle(), // OCIError *errhp
364 (__stmtType == OCI_STMT_SELECT) ? 0 : 1, // ub4 iters
365 0, // ub4 rowoff
366 NULL, // const OCISnapshot *snap_in
367 NULL, // OCISnapshot *snap_out
368 OCI_DEFAULT // ub4 mode
369 );
370 if (status != OCI_SUCCESS) {
371 __SET_ERROR_NORESET(SQL::eServerError, status, conn()->errorHandle());
372 return false;
373 }
374
375 // OCI의 경우 stmt execute 후 fields를 결정할 수 있다.
376 if (__stmtType == OCI_STMT_SELECT) {
377 if (!initFields()) {
378 return false;
379 }
380
381 Query::__eof = false;
382 }
383
384 for(size_t i = 0; i < Query::__paramCount; i++) {
385 if (!__params[i].onAfterExecute()) {
386 return false;
387 }
388 }
389
390 if (__stmtType == OCI_STMT_UPDATE
391 || __stmtType == OCI_STMT_INSERT
392 || __stmtType == OCI_STMT_DELETE) {
393
394 ub8 rowCount = 0;
395 ub4 size = sizeof(rowCount);
396 status = OCIAttrGet(
397 __stmt, // const void *trgthndlp
398 OCI_HTYPE_STMT, // ub4 trghndltyp
399 &rowCount, // void *attributep
400 &size, // ub4 *sizep
401 OCI_ATTR_UB8_ROW_COUNT, // ub4 attrtype
402 conn()->errorHandle() // OCIError *errhp
403 );
404 __DCL_ASSERT(size == sizeof(rowCount));
405 if (status != OCI_SUCCESS) {
406 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
407 return false;
408 }
409 Query::__affectedRows = rowCount;
410 }
411 return true;
412}
#define NULL
Definition Config.h:312
#define __SET_ERROR_HANDLE(_SQLCODE)
#define __DCL_ASSERT(expr)
Definition Object.h:394
#define __SET_ERROR_NORESET(_error, _status, _OCIError)
Definition OciQuery.cpp:52
bool initFields()
Definition OciQuery.cpp:184
ub2 __stmtType
Definition OciQuery.h:21
OCIStmt * __stmt
Definition OciQuery.h:20
OciParam * __params
Definition OciQuery.h:25
@ eServerError
Definition SQLCore.h:21

◆ __fetch()

bool OciQuery::__fetch ( )
virtual

Implements SQL::Query.

Definition at line 414 of file OciQuery.cpp.

415{
416 __DCL_ASSERT(!Query::__eof);
417 sword status = OCIStmtFetch2(
418 __stmt, // OCIStmt *stmthp
419 conn()->errorHandle(), // OCIError *errhp
420 1, // ub4 nrows
421 OCI_FETCH_NEXT, // ub2 orientation
422 0, // sb4 fetchOffset
423 OCI_DEFAULT // ub4 mode
424 );
425 switch (status) {
426 case OCI_NO_DATA: {
427 Query::__eof = true;
428 return true;
429 }
430 case OCI_SUCCESS_WITH_INFO: {
431 // 2026-02-28
432 // 19.30.0.0.0 버전 AIX에서 처음 발견되었다.
433 // 구체적인 내용을 확인해야 한다.
434 // 아마도 ODBC의 경우와 유사할 것으로 추정된다.
435 }
436 case OCI_SUCCESS: {
437 for (size_t i = 0; i < Query::__fieldCount; i++) {
438 if (!__fields[i].onAfterFetch())
439 return false;
440 }
441 return true;
442 }
443 default: {
444 ;
445 }
446 }
447
448 __SET_ERROR_NORESET(SQL::eServerError, status, conn()->errorHandle());
449 return false;
450}
OciField * __fields
Definition OciQuery.h:26

◆ __getField()

bool OciQuery::__getField ( size_t _index,
SQL::Field ** _fieldHandleOut )
virtual

Implements SQL::Query.

Definition at line 452 of file OciQuery.cpp.

453{
454 __DCL_ASSERT(Query::__fieldCount > 0);
455 __DCL_ASSERT((0 <= _index) && (_index < Query::__fieldCount));
456 *_fieldHandleOut = &__fields[_index];
457 return true;
458}

◆ __getParam()

bool OciQuery::__getParam ( size_t _index,
SQL::Param ** _paramHandleOut )
virtual

Implements SQL::Query.

Definition at line 460 of file OciQuery.cpp.

461{
462 __DCL_ASSERT(Query::__paramCount > 0);
463 __DCL_ASSERT((0 <= _index) && (_index < Query::__paramCount));
464 *_paramHandleOut = &__params[_index];
465 return true;
466}

◆ __prepare()

bool OciQuery::__prepare ( const char * _sql,
size_t _sqllen,
size_t _paramCount )
virtual

Implements SQL::Query.

Definition at line 305 of file OciQuery.cpp.

309{
310 if (!reset()) {
311 return false;
312 }
313
314 sword status = OCIStmtPrepare2(
315 conn()->svcHandle(), // OCISvcCtx *svchp
316 &__stmt, // OCIStmt **stmthp
317 conn()->errorHandle(), // OCIError *errhp
318 (const text* )_sql, // const OraText *stmttext
319 (ub4)_sqllen, // ub4 stmt_len
320 NULL, // const OraText *key
321 0, // ub4 keylen
322 OCI_NTV_SYNTAX, // ub4 language
323 OCI_DEFAULT // ub4 mode
324 );
325 if (status != OCI_SUCCESS) {
326 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
327 return false;
328 }
329
330 ub4 size = sizeof(__stmtType);
331 status = OCIAttrGet(
332 __stmt, // const void *trgthndlp
333 OCI_HTYPE_STMT, // ub4 trghndltyp
334 &__stmtType, // void *attributep
335 &size, // ub4 *sizep
336 OCI_ATTR_STMT_TYPE, // ub4 attrtype
337 conn()->errorHandle() // OCIError *errhp
338 );
339 __DCL_ASSERT(size == sizeof(__stmtType));
340 if (status != OCI_SUCCESS) {
341 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
342 return false;
343 }
344
345 if (_paramCount > 0) {
346 if (!initParams(_paramCount))
347 return false;
348 }
349
350 return true;
351}
bool initParams(size_t _paramCount)
Definition OciQuery.cpp:137

◆ initFields()

bool OciQuery::initFields ( )
protected

Definition at line 184 of file OciQuery.cpp.

185{
187 && (Query::__fieldCount == 0)
188 && (__fields == NULL)
189 && (__fieldsBuffer == NULL)
190 );
191
192 ub4 fieldCount = 0;
193 ub4 size = sizeof(fieldCount);
194 sword status = OCIAttrGet(
195 __stmt, // const void *trgthndlp
196 OCI_HTYPE_STMT, // ub4 trghndltyp
197 &fieldCount, // void *attributep
198 &size, // ub4 *sizep
199 OCI_ATTR_PARAM_COUNT, // ub4 attrtype
200 conn()->errorHandle() // OCIError *errhp
201 );
202 __DCL_ASSERT(size == sizeof(fieldCount));
203 if (status != OCI_SUCCESS) {
204 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
205 return false;
206 }
207
208 TYPESIZE* ts = (TYPESIZE*)alloca(sizeof(TYPESIZE) * fieldCount);
209 for (ub4 i = 0; i < fieldCount; i++) {
210 OCIParam* param = NULL;
211 status = OCIParamGet(
212 __stmt, // const void *hndlp
213 OCI_HTYPE_STMT, // ub4 htype
214 conn()->errorHandle(), // OCIError *errhp
215 (dvoid**)&param, // void **parmdpp
216 i + 1 // ub4 pos
217 );
218 if (status != OCI_SUCCESS) {
219 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
220 return false;
221 }
222
223 ub2 sqlt = 0;
224 size = sizeof(sqlt);
225 status = OCIAttrGet(
226 param, // const void *trgthndlp
227 OCI_DTYPE_PARAM, // ub4 trghndltyp
228 &sqlt, // void *attributep
229 &size, // ub4 *sizep
230 OCI_ATTR_DATA_TYPE, // ub4 attrtype
231 conn()->errorHandle() // OCIError *errhp
232 );
233 __DCL_ASSERT(size == sizeof(sqlt));
234 if (status != OCI_SUCCESS) {
235 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
236 return false;
237 }
238
239 // ub2 dataSize 이었었는데, Assert failed 되었다.
240 // 반환값의 범위는 0 ~ 4000이다.
241 ub4 dataSize = 0;
242 size = sizeof(dataSize);
243 status = OCIAttrGet(
244 param, // const void *trgthndlp
245 OCI_DTYPE_PARAM, // ub4 trghndltyp
246 &dataSize, // void *attributep
247 &size, // ub4 *sizep
248 OCI_ATTR_DATA_SIZE, // ub4 attrtype
249 conn()->errorHandle() // OCIError *errhp
250 );
251 __DCL_ASSERT(size == sizeof(dataSize));
252 if (status != OCI_SUCCESS) {
253 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
254 return false;
255 }
256
257 ts[i].sqlt = sqlt;
258 ts[i].buflen = OciData::__TYPE_SIZE(ts[i].sqlt, dataSize);
259 __DCL_TRACE5_N(L"Field [%2d] size [%6d %6d] type [%3d %ls]\n",
260 i + 1, dataSize, ts[i].buflen,
261 ts[i].sqlt, OciData::__TYPE_NAME(ts[i].sqlt)
262 );
263 }
264
265 // __fieldsBuffer에 적용할, 레코드 버퍼 크기를 계산한다.
266 size_t offset = 0;
267 for (ub4 i = 0; i < fieldCount; i++) {
268 offset = OciData::__TYPE_ALIGN(offset, ts[i].sqlt);
269 __DCL_TRACE5_N(L"Field [%2d] offset [%6zd %6d] type [%3d %ls]\n",
270 i + 1, offset, ts[i].buflen, ts[i].sqlt, OciData::__TYPE_NAME(ts[i].sqlt));
271 offset += ts[i].buflen;
272 }
273
274 __DCL_TRACE1_N(L"outBuffer [%zd]\n", offset);
275 // Oracle에서 __TYPE_SIZE(field) == 0인 경우는 없다.
276 __fieldsBuffer = malloc(offset);
277 if (__fieldsBuffer == NULL) {
279 return false;
280 }
281
282 Query::__fieldCount = fieldCount;
283 __fields = new OciField[Query::__fieldCount];
284 if (__fields == NULL) {
286 return false;
287 }
288
289 offset = 0;
290 for (ub4 i = 0; i < Query::__fieldCount; i++) {
291 offset = OciData::__TYPE_ALIGN(offset, ts[i].sqlt);
292 char* buf = (char*)__fieldsBuffer + offset;
293 //__DCL_TRACE3_N(L"offset [%4zd %4d] [%p]\n", offset, ts[i].buflen, buf);
294 if (!(__fields[i].init(this, i + 1, ts[i].sqlt,
295 buf, ts[i].buflen))
296 ) {
297 return false;
298 }
299 offset += ts[i].buflen;
300 }
301
302 return true;
303}
#define __DCL_TRACE1_N(fmt, arg)
#define __DCL_TRACE5_N(fmt, arg1, arg2, arg3, arg4, arg5)
Definition ODBCQuery.cpp:44
struct __TYPESIZE TYPESIZE
static const wchar_t * __TYPE_NAME(ub2 _sqlt)
Definition OciData.cpp:924
static size_t __TYPE_ALIGN(size_t _offset, ub2 _sqlt)
Definition OciData.cpp:997
static ub4 __TYPE_SIZE(ub2 _sqlt, ub4 _size)
Definition OciData.cpp:952
void * __fieldsBuffer
Definition OciQuery.h:23
@ eOutOfMemory
Definition SQLCore.h:24

◆ initParams()

bool OciQuery::initParams ( size_t _paramCount)
protected

Definition at line 137 of file OciQuery.cpp.

138{
140 && (_paramCount > 0)
141 && (Query::__paramCount == 0)
142 && (__params == NULL)
143 );
144
145#if defined(__DCL_DEBUG) && 1
146 ub4 bindCount = 0;
147 ub4 size = sizeof(bindCount);
148 sword status = OCIAttrGet(
149 __stmt, // const void *trgthndlp
150 OCI_HTYPE_STMT, // ub4 trghndltyp
151 &bindCount, // void *attributep
152 &size, // ub4 *sizep
153 OCI_ATTR_BIND_COUNT, // ub4 attrtype
154 conn()->errorHandle() // OCIError *errhp
155 );
156 __DCL_ASSERT(size == sizeof(bindCount));
157 if (status != OCI_SUCCESS) {
158 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
159 return false;
160 }
161 __DCL_ASSERT(bindCount == _paramCount);
162#endif
163
164 Query::__paramCount = _paramCount;
165 __params = new OciParam[Query::__paramCount];
166 if (__params == NULL) {
168 return false;
169 }
170
171 for(ub4 i = 0; i < Query::__paramCount; i++) {
172 if (!__params[i].init(this, i + 1))
173 return false;
174 }
175
176 return true;
177}

◆ reset()

bool OciQuery::reset ( )
protected

Definition at line 94 of file OciQuery.cpp.

95{
96 Query::__eof = true;
97 Query::__affectedRows = -1;
99
100 if (__fields) {
101 __DCL_ASSERT(Query::__fieldCount > 0);
102 delete[] __fields;
103 __fields = NULL;
104 Query::__fieldCount = 0;
105 }
106
107 if (__params) {
108 __DCL_ASSERT(Query::__paramCount > 0);
109 delete[] __params;
110 __params = NULL;
111 Query::__paramCount = 0;
112 }
113
114 if (__fieldsBuffer) {
115 free(__fieldsBuffer);
117 }
118
119 if (__stmt) {
120 sword status = OCIStmtRelease(
121 __stmt, // OCIStmt *stmthp
122 conn()->errorHandle(), // OCIError *errhp
123 NULL, // const OraText *key
124 0, // ub4 keylen
125 OCI_DEFAULT // ub4 mode
126 );
127 if (status != OCI_SUCCESS) {
129 return false;
130 }
131 __stmt = NULL;
132 }
133
134 return true;
135}
#define __OCI_STMT_TYPE_UNKNOWN
Definition OciQuery.h:6

Member Data Documentation

◆ __fields

OciField* OciQuery::__fields
protected

Definition at line 26 of file OciQuery.h.

◆ __fieldsBuffer

void* OciQuery::__fieldsBuffer
protected

Definition at line 23 of file OciQuery.h.

◆ __params

OciParam* OciQuery::__params
protected

Definition at line 25 of file OciQuery.h.

◆ __stmt

OCIStmt* OciQuery::__stmt
protected

Definition at line 20 of file OciQuery.h.

◆ __stmtType

ub2 OciQuery::__stmtType
protected

Definition at line 21 of file OciQuery.h.


The documentation for this class was generated from the following files: