📄 statement.c
字号:
/*
+----------------------------------------------------------------------+
| |
| OCILIB - C Driver for Oracle |
| |
| (C Wrapper for Oracle OCI) |
| |
+----------------------------------------------------------------------+
| Website : http://ocilib.net |
+----------------------------------------------------------------------+
| Copyright (c) 2007-2009 Vincent ROGIER |
+----------------------------------------------------------------------+
| This library is free software; you can redistribute it and/or |
| modify it under the terms of the GNU Library General Public |
| License as published by the Free Software Foundation; either |
| version 2 of the License, or (at your option) any later version. |
| |
| This library is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| Library General Public License for more details. |
| |
| You should have received a copy of the GNU Library General Public |
| License along with this library; if not, write to the Free |
| Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
+----------------------------------------------------------------------+
| Author: Vincent ROGIER <vince.rogier@gmail.com> |
+----------------------------------------------------------------------+
*/
/* ------------------------------------------------------------------------ *
* $Id: statement.c, v 3.2.0 2009/04/20 00:00 Vince $
* ------------------------------------------------------------------------ */
#include "ocilib_internal.h"
/* ************************************************************************ *
* PRIVATE FUNCTIONS
* ************************************************************************ */
/* ------------------------------------------------------------------------ *
* OCI_BindFreeAll
* ------------------------------------------------------------------------ */
boolean OCI_BindFreeAll(OCI_Statement *stmt)
{
int i;
OCI_CHECK(stmt == NULL, FALSE);
/* free user binds */
if (stmt->ubinds != NULL)
{
for(i = 0; i < stmt->nb_ubinds; i++)
{
OCI_BindFree(stmt->ubinds[i]);
}
OCI_FREE(stmt->ubinds);
}
/* free register binds */
if (stmt->rbinds != NULL)
{
for(i = 0; i < stmt->nb_rbinds; i++)
{
OCI_BindFree(stmt->rbinds[i]);
}
OCI_FREE(stmt->rbinds);
}
stmt->nb_ubinds = 0;
stmt->nb_rbinds = 0;
return TRUE;
}
/* ------------------------------------------------------------------------ *
* OCI_BindCheck
* ------------------------------------------------------------------------ */
boolean OCI_BindCheck(OCI_Statement *stmt)
{
boolean res = TRUE;
OCI_Bind *bnd = NULL;
sb2 *ind = NULL;
ub4 i, j;
OCI_CHECK(stmt == NULL, FALSE)
OCI_CHECK(stmt->ubinds == NULL, TRUE);
for(i = 0; i < stmt->nb_ubinds; i++)
{
bnd = stmt->ubinds[i];
ind = (sb2 *) bnd->buf.inds;
if (bnd->alloc == TRUE)
{
if (bnd->stmt->bind_array == FALSE)
{
/* - For big integer (64 bits), we use an OCINumber.
- Oracle date/time type is the only non scalar type
implemented by oracle through a public structure instead
of using a handle. So we need to copy the value
*/
if (bnd->type == OCI_CDT_NUMERIC)
{
res = OCI_NumberSet(stmt->con,
(OCINumber *) bnd->buf.data,
(void *) bnd->input,
(uword) sizeof(big_int),
bnd->subtype);
}
else if (bnd->type == OCI_CDT_DATETIME)
{
memcpy((void *) bnd->buf.data,
((OCI_Date *) bnd->input)->handle,
sizeof(OCIDate));
}
#ifdef OCI_CHECK_DATASTRINGS
else if (bnd->type == OCI_CDT_TEXT)
{
/* need conversion if bind buffer was allocated */
int osize = -1;
OCI_GetOutputString(bnd->input, bnd->buf.data, &osize,
sizeof(dtext), sizeof(odtext));
}
#endif
else
{
bnd->buf.data[0] = ((OCI_Datatype *) bnd->input)->handle;
/* for handles, check anyway the value for null data */
if (ind != NULL && *ind != -1)
*ind = OCI_IND(bnd->buf.data);
}
if (res == FALSE)
break;
}
else
{
for (j = 0; j < bnd->buf.count; j++, ind++)
{
/* - For big integer (64 bits), we use an OCINumber.
- Oracle date/time type is the only non scalar type
implemented by oracle through a public structure instead
of using a handle. So we need to copy the value
*/
if (bnd->type == OCI_CDT_NUMERIC)
{
res = OCI_NumberSet(stmt->con,
(OCINumber *) ((ub1 *) bnd->buf.data + (j*bnd->size)),
(void *) (((ub1 *) bnd->input) + (j*sizeof(big_int))),
(uword) sizeof(big_int), bnd->subtype);
}
else if (bnd->type == OCI_CDT_DATETIME)
{
memcpy(((ub1 *) bnd->buf.data) + (j*bnd->size),
((OCI_Date *) bnd->input[j])->handle,
sizeof(OCIDate));
}
#ifdef OCI_CHECK_DATASTRINGS
else if (bnd->type == OCI_CDT_TEXT)
{
/* need conversion if bind buffer was allocated */
int osize = -1;
int offset1 = (bnd->size/sizeof(odtext))*sizeof(dtext);
int offset2 = bnd->size;
OCI_GetOutputString(((ub1 *) bnd->input) + (j*offset1),
((ub1 *) bnd->buf.data) + (j*offset2),
&osize, sizeof(dtext), sizeof(odtext));
}
#endif
else
{
bnd->buf.data[j] = ((OCI_Datatype *) bnd->input[j])->handle;
/* for handles, check anyway the value for null data */
if (ind != NULL && *ind != -1)
*ind = OCI_IND(bnd->buf.data[j]);
}
if (res == FALSE)
break;
}
}
}
}
return res;
}
/* ------------------------------------------------------------------------ *
* OCI_BindReset
* ------------------------------------------------------------------------ */
boolean OCI_BindReset(OCI_Statement *stmt)
{
ub4 i, j;
OCI_CHECK(stmt == NULL, FALSE)
OCI_CHECK(stmt->ubinds == NULL, FALSE);
/* avoid unused param warning from compiler */
i = j = 0;
for(i = 0; i < stmt->nb_ubinds; i++)
{
OCI_Bind *bnd = stmt->ubinds[i];
memset(bnd->buf.inds, 0, bnd->buf.count * sizeof(sb2));
#ifdef OCI_CHECK_DATASTRINGS
if (stmt->ubinds[i]->type == OCI_CDT_TEXT)
{
for (j = 0; j < bnd->buf.count; j++)
{
/* need conversion if bind buffer was allocated */
int osize = -1;
int offset1 = (bnd->size/sizeof(odtext))*sizeof(dtext);
int offset2 = bnd->size;
OCI_GetOutputString(((ub1 *) bnd->buf.data) + (j*offset2),
((ub1 *) bnd->input) + (j*offset1),
&osize, sizeof(odtext), sizeof(dtext));
}
}
#endif
}
return TRUE;
}
/* ------------------------------------------------------------------------ *
* OCI_BindData
* ------------------------------------------------------------------------ */
boolean OCI_BindData(OCI_Statement *stmt, void *data, ub4 size,
const mtext *name, ub1 type, unsigned int code,
unsigned int mode, unsigned int subtype,
OCI_TypeInfo *typinf, unsigned int nbelem)
{
boolean res = TRUE;
OCI_Bind *bnd = NULL;
ub4 exec_mode = OCI_DEFAULT;
boolean is_pltbl = FALSE;
boolean reused = FALSE;
ub4 *pnbelem = NULL;
int index = 0;
ub4 i;
/* check index if necessary */
if (res == TRUE)
{
if (stmt->bind_mode == OCI_BIND_BY_POS)
{
index = (int) mtstol(&name[1], NULL, 10);
if (index <= 0 || index > OCI_BIND_MAX)
{
OCI_ExceptionOutOfBounds(stmt->con, index);
res = FALSE;
}
}
}
/* check if the bind name has already been used */
if (res == TRUE)
{
if (mode == OCI_BIND_INPUT)
{
int test_index = OCI_BindGetIndex(stmt, name);
if (test_index > 0)
{
if (stmt->bind_reuse == FALSE)
{
OCI_ExceptionBindAlreadyUsed(stmt, name);
res = FALSE;
}
else
{
bnd = stmt->ubinds[test_index-1];
reused = TRUE;
}
index = test_index;
}
}
}
/* check if we can handle another bind */
if (res == TRUE)
{
if (mode == OCI_BIND_INPUT)
{
if (stmt->nb_ubinds >= OCI_BIND_MAX)
{
OCI_ExceptionMaxBind(stmt);
res = FALSE;
}
/* allocate user bind array if necessary */
if (stmt->ubinds == NULL)
{
stmt->ubinds = (OCI_Bind **) OCI_MemAlloc(OCI_IPC_BIND_ARRAY,
sizeof(*stmt->ubinds),
OCI_BIND_MAX, TRUE);
}
res = (stmt->ubinds != NULL);
}
else
{
if (stmt->nb_rbinds >= OCI_BIND_MAX)
{
OCI_ExceptionMaxBind(stmt);
res = FALSE;
}
/* allocate register bind array if necessary */
if (stmt->rbinds == NULL)
{
stmt->rbinds = (OCI_Bind **) OCI_MemAlloc(OCI_IPC_BIND_ARRAY,
sizeof(*stmt->rbinds),
OCI_BIND_MAX, TRUE);
}
res = (stmt->rbinds != NULL);
}
}
/* checks done */
if (res == TRUE)
{
/* check out the number of elements that the bind variable will hold */
if (nbelem > 0)
{
/* is it a pl/sql table bind ? */
if (stmt->type == OCI_CST_BEGIN || stmt->type == OCI_CST_DECLARE)
is_pltbl = TRUE;
}
else
nbelem = stmt->nb_iters;
}
/* create hash table for mapping bind names / index */
if (res == TRUE)
{
if (stmt->map == NULL)
{
stmt->map = OCI_HashCreate(OCI_HASH_DEFAULT_SIZE, OCI_HASH_INTEGER);
res = (stmt->map != NULL);
}
}
/* allocate bind object */
if (res == TRUE)
{
if (bnd == NULL)
{
bnd = (OCI_Bind *) OCI_MemAlloc(OCI_IPC_BIND, sizeof(*bnd), 1, TRUE);
}
res = (bnd != NULL);
}
/* allocate indicators array */
if (res == TRUE)
{
if (bnd->buf.inds == NULL)
{
bnd->buf.inds = (void *) OCI_MemAlloc(OCI_IPC_INDICATOR_ARRAY,
sizeof(sb2), nbelem, TRUE);
}
res = (bnd->buf.inds != NULL);
}
/* check need for PL/SQL table extra info */
if ((res == TRUE) && (is_pltbl == TRUE))
{
bnd->nbelem = nbelem;
pnbelem = &bnd->nbelem;
/* allocate array of returned codes */
if (res == TRUE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -