示例#1
0
bool BindParameter(Cursor* cur, Py_ssize_t index, ParamInfo& info)
{
    TRACE("BIND: param=%d InputOutputType=%d (%s) ValueType=%d (%s) ParameterType=%d (%s) ColumnSize=%d DecimalDigits=%d BufferLength=%d *pcb=%d\n",
          (index+1), info.InputOutputType, CInputOutputName(info.InputOutputType), info.ValueType, CTypeName(info.ValueType), info.ParameterType, SqlTypeName(info.ParameterType), info.ColumnSize,
          info.DecimalDigits, info.BufferLength, info.StrLen_or_Ind);

    SQLRETURN ret = -1;
    Py_BEGIN_ALLOW_THREADS
    ret = SQLBindParameter(cur->hstmt, (SQLUSMALLINT)(index + 1), info.InputOutputType, info.ValueType, info.ParameterType, info.ColumnSize, info.DecimalDigits, info.ParameterValuePtr, info.BufferLength, &info.StrLen_or_Ind);
    Py_END_ALLOW_THREADS;

    if (GetConnection(cur)->hdbc == SQL_NULL_HANDLE)
    {
        // The connection was closed by another thread in the ALLOW_THREADS block above.
        RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed.");
        return false;
    }

    if (!SQL_SUCCEEDED(ret))
    {
        RaiseErrorFromHandle("SQLBindParameter", GetConnection(cur)->hdbc, cur->hstmt);
        return false;
    }

    return true;
}
示例#2
0
static bool GetParameterInfo(Cursor* cur, Py_ssize_t index, PyObject* param, ParamInfo& info)
{
    // Determines the type of SQL parameter that will be used for this parameter based on the Python data type.
    //
    // Populates `info`.

    // TODO: if the param is a SQLParameter object, then bind to the wrapped value and use the input/output type from that

    // Hold a reference to param until info is freed, because info will often be holding data borrowed from param.
    if (PyObject_TypeCheck(param, (PyTypeObject*)SQLParameter_type))
    {
        info.pParam = ((SQLParameter*)param)->value;
        info.InputOutputType = ((SQLParameter*)param)->type;
    }
    else
    {
        info.pParam = param;
        info.InputOutputType = SQL_PARAM_INPUT;
    }

    if (info.pParam == Py_None)
        return GetNullInfo(cur, index, info);

    if (info.pParam == null_binary)
        return GetNullBinaryInfo(cur, index, info);

    if (PyBytes_Check(info.pParam))
        return GetBytesInfo(cur, index, info.pParam, info);

    if (PyUnicode_Check(info.pParam))
        return GetUnicodeInfo(cur, index, info.pParam, info);

    if (PyBool_Check(info.pParam))
        return GetBooleanInfo(cur, index, info.pParam, info);

    if (PyDateTime_Check(info.pParam))
        return GetDateTimeInfo(cur, index, info.pParam, info);

    if (PyDate_Check(info.pParam))
        return GetDateInfo(cur, index, info.pParam, info);

    if (PyTime_Check(info.pParam))
        return GetTimeInfo(cur, index, info.pParam, info);

    if (PyLong_Check(info.pParam))
        return GetLongInfo(cur, index, info.pParam, info);

    if (PyFloat_Check(info.pParam))
        return GetFloatInfo(cur, index, info.pParam, info);

    if (PyDecimal_Check(info.pParam))
        return GetDecimalInfo(cur, index, info.pParam, info);

#if PY_VERSION_HEX >= 0x02060000
    if (PyByteArray_Check(info.pParam))
        return GetByteArrayInfo(cur, index, info.pParam, info);
#endif

#if PY_MAJOR_VERSION < 3
    if (PyInt_Check(info.pParam))
        return GetIntInfo(cur, index, info.pParam, info);

    if (PyBuffer_Check(info.pParam))
        return GetBufferInfo(cur, index, info.pParam, info);
#endif

    RaiseErrorV("HY105", ProgrammingError, "Invalid parameter type.  param-index=%zd param-type=%s", index, Py_TYPE(info.pParam)->tp_name);
    return false;
}
示例#3
0
文件: params.cpp 项目: ramiro/pyodbc
bool PrepareAndBind(Cursor* cur, PyObject* pSql, PyObject* original_params, bool skip_first)
{
    //
    // Normalize the parameter variables.
    //

    // Since we may replace parameters (we replace objects with Py_True/Py_False when writing to a bit/bool column),
    // allocate an array and use it instead of the original sequence.  Since we don't change ownership we don't bother
    // with incref.  (That is, PySequence_GetItem will INCREF and ~ObjectArrayHolder will DECREF.)

    int        params_offset = skip_first ? 1 : 0;
    Py_ssize_t cParams       = original_params == 0 ? 0 : PySequence_Length(original_params) - params_offset;

    PyObject** params = (PyObject**)malloc(sizeof(PyObject*) * cParams);
    if (!params)
    {
        PyErr_NoMemory();
        return 0;
    }
    
    for (Py_ssize_t i = 0; i < cParams; i++)
        params[i] = PySequence_GetItem(original_params, i + params_offset);

    ObjectArrayHolder holder(cParams, params);

    //
    // Prepare the SQL if necessary.
    //

    if (pSql == cur->pPreparedSQL)
    {
        // We've already prepared this SQL, so we don't need to do so again.  We've also cached the parameter
        // information in cur->paramdescs.

        if (cParams != cur->paramcount)
        {
            RaiseErrorV(0, ProgrammingError, "The SQL contains %d parameter markers, but %d parameters were supplied",
                        cur->paramcount, cParams);
            return false;
        }
    }
    else
    {
        FreeParameterInfo(cur);

        SQLRETURN ret;
        if (PyString_Check(pSql))
        {
            Py_BEGIN_ALLOW_THREADS
            ret = SQLPrepare(cur->hstmt, (SQLCHAR*)PyString_AS_STRING(pSql), SQL_NTS);
            Py_END_ALLOW_THREADS
        }
        else
        {
            Py_BEGIN_ALLOW_THREADS
            ret = SQLPrepareW(cur->hstmt, (SQLWCHAR*)PyUnicode_AsUnicode(pSql), SQL_NTS);
            Py_END_ALLOW_THREADS
        }
  
        if (cur->cnxn->hdbc == SQL_NULL_HANDLE)
        {
            // The connection was closed by another thread in the ALLOW_THREADS block above.
            RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed.");
            return false;
        }

        if (!SQL_SUCCEEDED(ret))
        {
            RaiseErrorFromHandle("SQLPrepare", GetConnection(cur)->hdbc, cur->hstmt);
            return false;
        }
                
        if (!CacheParamDesc(cur))
            return false;

        cur->pPreparedSQL = pSql;
        Py_INCREF(cur->pPreparedSQL);
    }
示例#4
0
PyObject* GetData(Cursor* cur, Py_ssize_t iCol)
{
    // Returns an object representing the value in the row/field.  If 0 is returned, an exception has already been set.
    //
    // The data is assumed to be the default C type for the column's SQL type.

    ColumnInfo* pinfo = &cur->colinfos[iCol];

    // First see if there is a user-defined conversion.

    int conv_index = GetUserConvIndex(cur, pinfo->sql_type);
    if (conv_index != -1)
        return GetDataUser(cur, iCol, conv_index);

    switch (pinfo->sql_type)
    {
    case SQL_WCHAR:
    case SQL_WVARCHAR:
    case SQL_WLONGVARCHAR:
        return GetText(cur, iCol);

    case SQL_CHAR:
    case SQL_VARCHAR:
    case SQL_LONGVARCHAR:
    case SQL_SS_XML:
    case SQL_DB2_XML:
        return GetText(cur, iCol);

    case SQL_GUID:
        if (UseNativeUUID())
            return GetUUID(cur, iCol);
        return GetText(cur, iCol);
        break;

    case SQL_BINARY:
    case SQL_VARBINARY:
    case SQL_LONGVARBINARY:
        return GetBinary(cur, iCol);

    case SQL_DECIMAL:
    case SQL_NUMERIC:
        return GetDataDecimal(cur, iCol);

    case SQL_BIT:
        return GetDataBit(cur, iCol);

    case SQL_TINYINT:
    case SQL_SMALLINT:
    case SQL_INTEGER:
        return GetDataLong(cur, iCol);

    case SQL_BIGINT:
        return GetDataLongLong(cur, iCol);

    case SQL_REAL:
    case SQL_FLOAT:
    case SQL_DOUBLE:
        return GetDataDouble(cur, iCol);


    case SQL_TYPE_DATE:
    case SQL_TYPE_TIME:
    case SQL_TYPE_TIMESTAMP:
        return GetDataTimestamp(cur, iCol);

    case SQL_SS_TIME2:
        return GetSqlServerTime(cur, iCol);
    }

    return RaiseErrorV("HY106", ProgrammingError, "ODBC SQL type %d is not yet supported.  column-index=%zd  type=%d",
                       (int)pinfo->sql_type, iCol, (int)pinfo->sql_type);
}
示例#5
0
文件: getdata.cpp 项目: ramiro/pyodbc
PyObject*
GetData(Cursor* cur, Py_ssize_t iCol)
{
    // Returns an object representing the value in the row/field.  If 0 is returned, an exception has already been set.
    //
    // The data is assumed to be the default C type for the column's SQL type.

    ColumnInfo* pinfo = &cur->colinfos[iCol];

    switch (pinfo->sql_type)
    {
    case SQL_WCHAR:
    case SQL_WVARCHAR:
    case SQL_WLONGVARCHAR:
    case SQL_CHAR:
    case SQL_VARCHAR:
    case SQL_LONGVARCHAR:
    case SQL_GUID:
        return GetDataString(cur, iCol);

    case SQL_BINARY:
    case SQL_VARBINARY:
    case SQL_LONGVARBINARY:
        return GetDataBuffer(cur, iCol);

    case SQL_DECIMAL:
    case SQL_NUMERIC:
    {
        if (decimal_type == 0)
            break;

        return GetDataDecimal(cur, iCol);
    }

    case SQL_BIT:
        return GetDataBit(cur, iCol);

    case SQL_TINYINT:
    case SQL_SMALLINT:
    case SQL_INTEGER:
        return GetDataLong(cur, iCol);

    case SQL_BIGINT:
        return GetDataLongLong(cur, iCol);

    case SQL_REAL:
    case SQL_FLOAT:
    case SQL_DOUBLE:
        return GetDataDouble(cur, iCol);


    case SQL_TYPE_DATE:
    case SQL_TYPE_TIME:
    case SQL_TYPE_TIMESTAMP:
        return GetDataTimestamp(cur, iCol);

    case SQL_SS_TIME2:
        return GetSqlServerTime(cur, iCol);
    }

    return RaiseErrorV("HY106", ProgrammingError, "ODBC SQL type %d is not yet supported.  column-index=%zd  type=%d",
                       (int)pinfo->sql_type, iCol, (int)pinfo->sql_type);
}