⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 statement.c

📁 oci的源码,可以在任何平台上编译,相当方便实用
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
   +----------------------------------------------------------------------+
   |                                                                      |
   |                     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 + -