代码拉取完成,页面将自动刷新
同步操作将从 openGauss/openGauss-connector-odbc 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/*--------
* Module: options.c
*
* Description: This module contains routines for getting/setting
* connection and statement options.
*
* Classes: n/a
*
* API functions: SQLSetConnectOption, SQLSetStmtOption, SQLGetConnectOption,
* SQLGetStmtOption
*
* Comments: See "readme.txt" for copyright and license information.
*--------
*/
#include "psqlodbc.h"
#include "unicode_support.h"
#include <string.h>
#include "misc.h"
#include "environ.h"
#include "connection.h"
#include "statement.h"
#include "qresult.h"
#include "pgapifunc.h"
static RETCODE
set_statement_option(ConnectionClass *conn,
StatementClass *stmt,
SQLUSMALLINT fOption,
SQLULEN vParam)
{
CSTR func = "set_statement_option";
char changed = FALSE;
ConnInfo *ci = NULL;
SQLULEN setval;
if (conn)
ci = &(conn->connInfo);
else
ci = &(SC_get_conn(stmt)->connInfo);
switch (fOption)
{
case SQL_ASYNC_ENABLE: /* ignored */
break;
case SQL_BIND_TYPE:
/* now support multi-column and multi-row binding */
if (conn)
conn->ardOptions.bind_size = (SQLUINTEGER) vParam;
if (stmt)
SC_get_ARDF(stmt)->bind_size = (SQLUINTEGER) vParam;
break;
case SQL_CONCURRENCY:
/*
* positioned update isn't supported so cursor concurrency is
* read-only
*/
MYLOG(0, "SQL_CONCURRENCY = " FORMAT_LEN " ", vParam);
setval = SQL_CONCUR_READ_ONLY;
if (SQL_CONCUR_READ_ONLY == vParam)
;
else if (ci->drivers.lie)
setval = vParam;
else if (0 != ci->updatable_cursors)
setval = SQL_CONCUR_ROWVER;
if (conn)
conn->stmtOptions.scroll_concurrency = (SQLUINTEGER) setval;
else if (stmt)
{
if (SC_get_Result(stmt))
{
SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "The attr can't be changed because the cursor is open.", func);
return SQL_ERROR;
}
stmt->options.scroll_concurrency =
stmt->options_orig.scroll_concurrency = (SQLUINTEGER) setval;
}
if (setval != vParam)
changed = TRUE;
MYPRINTF(0, "-> " FORMAT_LEN "\n", setval);
break;
case SQL_CURSOR_TYPE:
/*
* if declare/fetch, then type can only be forward. otherwise,
* it can only be forward or static.
*/
MYLOG(0, "SQL_CURSOR_TYPE = " FORMAT_LEN " ", vParam);
setval = SQL_CURSOR_FORWARD_ONLY;
if (ci->drivers.lie)
setval = vParam;
else if (SQL_CURSOR_STATIC == vParam)
setval = vParam;
else if (SQL_CURSOR_KEYSET_DRIVEN == vParam)
{
if (0 != (ci->updatable_cursors & ALLOW_KEYSET_DRIVEN_CURSORS))
setval = vParam;
else
setval = SQL_CURSOR_STATIC; /* at least scrollable */
}
else if (SQL_CURSOR_DYNAMIC == vParam)
{
if (0 != (ci->updatable_cursors & ALLOW_DYNAMIC_CURSORS))
setval = vParam;
else if (0 != (ci->updatable_cursors & ALLOW_KEYSET_DRIVEN_CURSORS))
setval = SQL_CURSOR_KEYSET_DRIVEN;
else
setval = SQL_CURSOR_STATIC; /* at least scrollable */
}
if (conn)
conn->stmtOptions.cursor_type = (SQLUINTEGER) setval;
else if (stmt)
{
if (SC_get_Result(stmt))
{
SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "The attr can't be changed because the cursor is open.", func);
return SQL_ERROR;
}
stmt->options_orig.cursor_type =
stmt->options.cursor_type = (SQLUINTEGER) setval;
}
if (setval != vParam)
changed = TRUE;
MYPRINTF(0, "-> " FORMAT_LEN "\n", setval);
break;
case SQL_KEYSET_SIZE: /* ignored, but saved and returned */
MYLOG(0, "SQL_KEYSET_SIZE, vParam = " FORMAT_LEN "\n", vParam);
if (conn)
conn->stmtOptions.keyset_size = vParam;
if (stmt)
{
stmt->options_orig.keyset_size = vParam;
if (!SC_get_Result(stmt))
stmt->options.keyset_size = vParam;
if (stmt->options.keyset_size != (SQLLEN) vParam)
changed = TRUE;
}
break;
case SQL_MAX_LENGTH: /* ignored, but saved */
MYLOG(0, "SQL_MAX_LENGTH, vParam = " FORMAT_LEN "\n", vParam);
if (conn)
conn->stmtOptions.maxLength = vParam;
if (stmt)
{
stmt->options_orig.maxLength = vParam;
if (!SC_get_Result(stmt))
stmt->options.maxLength = vParam;
if (stmt->options.maxLength != (SQLLEN) vParam)
changed = TRUE;
}
break;
case SQL_MAX_ROWS: /* ignored, but saved */
MYLOG(0, "SQL_MAX_ROWS, vParam = " FORMAT_LEN "\n", vParam);
if (conn)
conn->stmtOptions.maxRows = vParam;
if (stmt)
{
stmt->options_orig.maxRows = vParam;
if (!SC_get_Result(stmt))
stmt->options.maxRows = vParam;
if (stmt->options.maxRows != (SQLLEN)vParam)
changed = TRUE;
}
break;
case SQL_NOSCAN: /* ignored */
MYLOG(0, "SQL_NOSCAN, vParam = " FORMAT_LEN "\n", vParam);
break;
case SQL_QUERY_TIMEOUT: /* ignored */
MYLOG(0, "SQL_QUERY_TIMEOUT, vParam = " FORMAT_LEN "\n", vParam);
if (conn)
conn->stmtOptions.stmt_timeout = (SQLULEN) vParam;
if (stmt)
{
stmt->options.stmt_timeout = (SQLULEN) vParam;
stmt->options.timeout = (SQLUINTEGER)vParam;
}
break;
case SQL_RETRIEVE_DATA:
MYLOG(0, "SQL_RETRIEVE_DATA, vParam = " FORMAT_LEN "\n", vParam);
if (conn)
conn->stmtOptions.retrieve_data = (SQLUINTEGER) vParam;
if (stmt)
stmt->options.retrieve_data = (SQLUINTEGER) vParam;
break;
case SQL_ROWSET_SIZE:
MYLOG(0, "SQL_ROWSET_SIZE, vParam = " FORMAT_LEN "\n", vParam);
if (vParam < 1)
{
vParam = 1;
changed = TRUE;
}
if (conn)
conn->ardOptions.size_of_rowset_odbc2 = vParam;
if (stmt)
SC_get_ARDF(stmt)->size_of_rowset_odbc2 = vParam;
break;
case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
if (stmt)
{
SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Simulated positioned update/delete not supported. Use the cursor library.", func);
}
if (conn)
{
CC_set_error(conn, CONN_NOT_IMPLEMENTED_ERROR, "Simulated positioned update/delete not supported. Use the cursor library.", func);
}
return SQL_ERROR;
case SQL_USE_BOOKMARKS:
if (stmt)
{
MYLOG(0, "USE_BOOKMARKS %s\n", (vParam == SQL_UB_OFF) ? "off" : ((vParam == SQL_UB_VARIABLE) ? "variable" : "fixed"));
setval = vParam;
stmt->options.use_bookmarks = (SQLUINTEGER) setval;
}
if (conn)
conn->stmtOptions.use_bookmarks = (SQLUINTEGER) vParam;
break;
case 1204: /* SQL_COPT_SS_PRESERVE_CURSORS ? */
if (stmt)
{
SC_set_error(stmt, STMT_OPTION_NOT_FOR_THE_DRIVER, "The option may be for MS SQL Server(Set)", func);
}
else if (conn)
{
CC_set_error(conn, CONN_OPTION_NOT_FOR_THE_DRIVER, "The option may be for MS SQL Server(Set)", func);
}
return SQL_ERROR;
case 1227: /* SQL_SOPT_SS_HIDDEN_COLUMNS ? */
case 1228: /* SQL_SOPT_SS_NOBROWSETABLE ? */
if (stmt)
{
#ifndef NOT_USED
if (0 != vParam)
changed = TRUE;
break;
#else
SC_set_error(stmt, STMT_OPTION_NOT_FOR_THE_DRIVER, "The option may be for MS SQL Server(Set)", func);
#endif /* NOT_USED */
}
else if (conn)
{
CC_set_error(conn, CONN_OPTION_NOT_FOR_THE_DRIVER, "The option may be for MS SQL Server(Set)", func);
}
return SQL_ERROR;
default:
{
char option[64];
if (stmt)
{
SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Unknown statement option (Set)", func);
SPRINTF_FIXED(option, "fOption=%d, vParam=" FORMAT_ULEN, fOption, vParam);
SC_log_error(func, option, stmt);
}
if (conn)
{
CC_set_error(conn, CONN_NOT_IMPLEMENTED_ERROR, "Unknown statement option (Set)", func);
SPRINTF_FIXED(option, "fOption=%d, vParam=" FORMAT_ULEN, fOption, vParam);
CC_log_error(func, option, conn);
}
return SQL_ERROR;
}
}
if (changed)
{
if (stmt)
{
SC_set_error(stmt, STMT_OPTION_VALUE_CHANGED, "Requested value changed.", func);
}
if (conn)
{
CC_set_error(conn, CONN_OPTION_VALUE_CHANGED, "Requested value changed.", func);
}
return SQL_SUCCESS_WITH_INFO;
}
else
return SQL_SUCCESS;
}
/* Implements only SQL_AUTOCOMMIT */
RETCODE SQL_API
PGAPI_SetConnectOption(HDBC hdbc,
SQLUSMALLINT fOption,
SQLULEN vParam)
{
CSTR func = "PGAPI_SetConnectOption";
ConnectionClass *conn = (ConnectionClass *) hdbc;
char changed = FALSE;
RETCODE retval;
BOOL autocomm_on;
MYLOG(0, "entering fOption = %d vParam = " FORMAT_LEN "\n", fOption, vParam);
if (!conn)
{
CC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE;
}
switch (fOption)
{
/*
* Statement Options (apply to all stmts on the connection and
* become defaults for new stmts)
*/
case SQL_ASYNC_ENABLE:
case SQL_BIND_TYPE:
case SQL_CONCURRENCY:
case SQL_CURSOR_TYPE:
case SQL_KEYSET_SIZE:
case SQL_MAX_LENGTH:
case SQL_MAX_ROWS:
case SQL_NOSCAN:
case SQL_QUERY_TIMEOUT:
case SQL_RETRIEVE_DATA:
case SQL_ROWSET_SIZE:
case SQL_SIMULATE_CURSOR:
case SQL_USE_BOOKMARKS:
/*
* Become the default for all future statements on this
* connection
*/
retval = set_statement_option(conn, NULL, fOption, vParam);
if (retval == SQL_SUCCESS_WITH_INFO)
changed = TRUE;
else if (retval == SQL_ERROR)
return SQL_ERROR;
break;
/*
* Connection Options
*/
case SQL_ACCESS_MODE: /* ignored */
break;
case SQL_AUTOCOMMIT:
switch (vParam)
{
case SQL_AUTOCOMMIT_ON:
autocomm_on = TRUE;
break;
case SQL_AUTOCOMMIT_OFF:
autocomm_on = FALSE;
break;
default:
CC_set_error(conn, CONN_INVALID_ARGUMENT_NO, "Illegal parameter value for SQL_AUTOCOMMIT", func);
return SQL_ERROR;
}
if (autocomm_on && SQL_AUTOCOMMIT_OFF != conn->autocommit_public)
break;
else if (!autocomm_on && SQL_AUTOCOMMIT_OFF == conn->autocommit_public)
break;
conn->autocommit_public = (autocomm_on ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);
MYLOG(0, "AUTOCOMMIT: transact_status=%d, vparam=" FORMAT_LEN "\n", conn->transact_status, vParam);
#ifdef _HANDLE_ENLIST_IN_DTC_
if (CC_is_in_global_trans(conn))
{
CC_set_error(conn, CONN_ILLEGAL_TRANSACT_STATE, "Don't change AUTOCOMMIT mode in a distributed transaction", func);
return SQL_ERROR;
}
#endif /* _HANDLE_ENLIST_IN_DTC_ */
CC_set_autocommit(conn, autocomm_on);
break;
case SQL_CURRENT_QUALIFIER: /* ignored */
break;
case SQL_LOGIN_TIMEOUT:
conn->login_timeout = (SQLUINTEGER) vParam;
break;
case SQL_PACKET_SIZE: /* ignored */
break;
case SQL_QUIET_MODE: /* ignored */
break;
case SQL_TXN_ISOLATION:
if (conn->isolation == vParam)
break;
/*
* If the connection is not established, just record the setting to
* reflect it upon connection.
*/
if (CC_not_connected(conn))
{
conn->isolation = (UInt4) vParam;
break;
}
/* The ODBC spec prohibits changing the isolation level while in manual transaction. */
if (CC_is_in_trans(conn))
{
if (CC_does_autocommit(conn) && !CC_is_in_error_trans(conn))
CC_commit(conn);
else
{
CC_set_error(conn, CONN_TRANSACT_IN_PROGRES, "Cannot switch isolation level while a transaction is in progress", func);
return SQL_ERROR;
}
}
if (!CC_set_transact(conn, (UInt4) vParam))
return SQL_ERROR;
conn->isolation = (UInt4) vParam;
break;
/* These options should be handled by driver manager */
case SQL_ODBC_CURSORS:
case SQL_OPT_TRACE:
case SQL_OPT_TRACEFILE:
case SQL_TRANSLATE_DLL:
case SQL_TRANSLATE_OPTION:
CC_log_error(func, "This connect option (Set) is only used by the Driver Manager", conn);
break;
default:
{
char option[64];
CC_set_error(conn, CONN_UNSUPPORTED_OPTION, "Unknown connect option (Set)", func);
SPRINTF_FIXED(option, "fOption=%d, vParam=" FORMAT_LEN, fOption, vParam);
#ifdef WIN32
if (fOption == 30002 && vParam)
{
int cmp;
#ifdef UNICODE_SUPPORT
if (CC_is_in_unicode_driver(conn))
{
char *asPara = ucs2_to_utf8((SQLWCHAR *) vParam, SQL_NTS, NULL, FALSE);
cmp = strcmp(asPara, "Microsoft Jet");
free(asPara);
}
else
#endif /* UNICODE_SUPPORT */
cmp = strncmp((char *) vParam, "Microsoft Jet", 13);
if (0 == cmp)
{
MYLOG(0, "Microsoft Jet !!!!\n");
CC_set_errornumber(conn, 0);
conn->ms_jet = 1;
return SQL_SUCCESS;
}
}
#endif /* WIN32 */
CC_log_error(func, option, conn);
return SQL_ERROR;
}
}
if (changed)
{
CC_set_error(conn, CONN_OPTION_VALUE_CHANGED, "Requested value changed.", func);
return SQL_SUCCESS_WITH_INFO;
}
else
return SQL_SUCCESS;
}
/* This function just can tell you whether you are in Autcommit mode or not */
RETCODE SQL_API
PGAPI_GetConnectOption(HDBC hdbc,
SQLUSMALLINT fOption,
PTR pvParam,
SQLINTEGER *StringLength,
SQLINTEGER BufferLength)
{
CSTR func = "PGAPI_GetConnectOption";
ConnectionClass *conn = (ConnectionClass *) hdbc;
const char *p = NULL;
SQLLEN len = sizeof(SQLINTEGER);
SQLRETURN result = SQL_SUCCESS;
MYLOG(0, "entering...\n");
if (!conn)
{
CC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE;
}
switch (fOption)
{
case SQL_ACCESS_MODE: /* NOT SUPPORTED */
*((SQLUINTEGER *) pvParam) = SQL_MODE_READ_WRITE;
break;
case SQL_AUTOCOMMIT:
*((SQLUINTEGER *) pvParam) = conn->autocommit_public;
break;
case SQL_CURRENT_QUALIFIER: /* don't use qualifiers */
len = 0;
p = CurrCatString(conn);
break;
case SQL_LOGIN_TIMEOUT:
*((SQLUINTEGER *) pvParam) = conn->login_timeout;
break;
case SQL_PACKET_SIZE: /* NOT SUPPORTED */
*((SQLUINTEGER *) pvParam) = 4096;
break;
case SQL_QUERY_TIMEOUT:
*((SQLULEN *) pvParam) = conn->stmtOptions.stmt_timeout;
break;
case SQL_QUIET_MODE: /* NOT SUPPORTED */
*((SQLULEN *) pvParam) = 0;
break;
case SQL_TXN_ISOLATION:
if (conn->isolation == 0)
{
if (CC_not_connected(conn))
return SQL_NO_DATA;
conn->isolation = CC_get_isolation(conn);
}
*((SQLUINTEGER *) pvParam) = conn->isolation;
break;
#ifdef SQL_ATTR_CONNECTION_DEAD
case SQL_ATTR_CONNECTION_DEAD:
#else
case 1209:
#endif /* SQL_ATTR_CONNECTION_DEAD */
MYLOG(0, "CONNECTION_DEAD status=%d", conn->status);
*((SQLUINTEGER *) pvParam) = CC_not_connected(conn);
MYPRINTF(0, " val=%d\n", *((SQLUINTEGER *) pvParam));
break;
case SQL_ATTR_ANSI_APP:
*((SQLUINTEGER *) pvParam) = CC_is_in_ansi_app(conn);
MYLOG(0, "ANSI_APP val=%d\n", *((SQLUINTEGER *) pvParam));
break;
/* These options should be handled by driver manager */
case SQL_ODBC_CURSORS:
case SQL_OPT_TRACE:
case SQL_OPT_TRACEFILE:
case SQL_TRANSLATE_DLL:
case SQL_TRANSLATE_OPTION:
CC_log_error(func, "This connect option (Get) is only used by the Driver Manager", conn);
break;
default:
{
char option[64];
CC_set_error(conn, CONN_UNSUPPORTED_OPTION, "Unknown connect option (Get)", func);
SPRINTF_FIXED(option, "fOption=%d", fOption);
CC_log_error(func, option, conn);
return SQL_ERROR;
break;
}
}
if (NULL != p && 0 == len)
{
/* char/binary data */
len = strlen(p);
if (pvParam)
{
#ifdef UNICODE_SUPPORT
if (CC_is_in_unicode_driver(conn))
{
len = utf8_to_ucs2(p, len, (SQLWCHAR *) pvParam , BufferLength / WCLEN);
len *= WCLEN;
}
else
#endif /* UNICODE_SUPPORT */
strncpy_null((char *) pvParam, p, (size_t) BufferLength);
if (len >= BufferLength)
{
result = SQL_SUCCESS_WITH_INFO;
CC_set_error(conn, CONN_TRUNCATED, "The buffer was too small for the pvParam.", func);
}
}
}
if (StringLength)
*StringLength = (SQLINTEGER) len;
return result;
}
RETCODE SQL_API
PGAPI_SetStmtOption(HSTMT hstmt,
SQLUSMALLINT fOption,
SQLULEN vParam)
{
CSTR func = "PGAPI_SetStmtOption";
StatementClass *stmt = (StatementClass *) hstmt;
RETCODE retval;
MYLOG(0, " entering...\n");
/*
* Though we could fake Access out by just returning SQL_SUCCESS all
* the time, but it tries to set a huge value for SQL_MAX_LENGTH and
* expects the driver to reduce it to the real value.
*/
if (!stmt)
{
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE;
}
retval = set_statement_option(NULL, stmt, fOption, vParam);
return retval;
}
RETCODE SQL_API
PGAPI_GetStmtOption(HSTMT hstmt,
SQLUSMALLINT fOption,
PTR pvParam,
SQLINTEGER *StringLength,
SQLINTEGER BufferLength)
{
CSTR func = "PGAPI_GetStmtOption";
StatementClass *stmt = (StatementClass *) hstmt;
QResultClass *res;
SQLLEN ridx;
SQLINTEGER len = sizeof(SQLINTEGER);
Int4 bookmark;
MYLOG(0, "entering...\n");
/*
* thought we could fake Access out by just returning SQL_SUCCESS all
* the time, but it tries to set a huge value for SQL_MAX_LENGTH and
* expects the driver to reduce it to the real value
*/
if (!stmt)
{
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE;
}
switch (fOption)
{
case SQL_GET_BOOKMARK:
case SQL_ROW_NUMBER:
res = SC_get_Curres(stmt);
if (!res)
{
SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "The cursor has no result.", func);
return SQL_ERROR;
}
ridx = GIdx2CacheIdx(stmt->currTuple, stmt, res);
if (!SC_is_fetchcursor(stmt))
{
/* make sure we're positioned on a valid row */
if ((ridx < 0) ||
(((SQLULEN) ridx) >= QR_get_num_cached_tuples(res)))
{
SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row.", func);
return SQL_ERROR;
}
}
else
{
if (stmt->currTuple < 0 || !res->tupleField)
{
SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row.", func);
return SQL_ERROR;
}
}
if (fOption == SQL_GET_BOOKMARK && stmt->options.use_bookmarks == SQL_UB_OFF)
{
SC_set_error(stmt, STMT_OPERATION_INVALID, "Operation invalid because use bookmarks not enabled.", func);
return SQL_ERROR;
}
bookmark = SC_make_int4_bookmark(stmt->currTuple);
memcpy(pvParam, &bookmark, sizeof(UInt4));
break;
case SQL_ASYNC_ENABLE: /* NOT SUPPORTED */
*((SQLINTEGER *) pvParam) = SQL_ASYNC_ENABLE_OFF;
break;
case SQL_BIND_TYPE:
*((SQLINTEGER *) pvParam) = SC_get_ARDF(stmt)->bind_size;
break;
case SQL_CONCURRENCY: /* NOT REALLY SUPPORTED */
MYLOG(0, "SQL_CONCURRENCY %d\n", stmt->options.scroll_concurrency);
*((SQLINTEGER *) pvParam) = stmt->options.scroll_concurrency;
break;
case SQL_CURSOR_TYPE: /* PARTIAL SUPPORT */
MYLOG(0, "SQL_CURSOR_TYPE %d\n", stmt->options.cursor_type);
*((SQLINTEGER *) pvParam) = stmt->options.cursor_type;
break;
case SQL_KEYSET_SIZE: /* NOT SUPPORTED, but saved */
MYLOG(0, "SQL_KEYSET_SIZE\n");
*((SQLLEN *) pvParam) = stmt->options.keyset_size;
break;
case SQL_MAX_LENGTH: /* NOT SUPPORTED, but saved */
*((SQLLEN *) pvParam) = stmt->options.maxLength;
break;
case SQL_MAX_ROWS: /* NOT SUPPORTED, but saved */
*((SQLLEN *) pvParam) = stmt->options.maxRows;
MYLOG(0, "MAX_ROWS, returning " FORMAT_LEN "\n", stmt->options.maxRows);
break;
case SQL_NOSCAN: /* NOT SUPPORTED */
*((SQLINTEGER *) pvParam) = SQL_NOSCAN_ON;
break;
case SQL_QUERY_TIMEOUT: /* NOT SUPPORTED */
*((SQLULEN *) pvParam) = stmt->options.stmt_timeout;
break;
case SQL_RETRIEVE_DATA:
*((SQLINTEGER *) pvParam) = stmt->options.retrieve_data;
break;
case SQL_ROWSET_SIZE:
*((SQLLEN *) pvParam) = SC_get_ARDF(stmt)->size_of_rowset_odbc2;
break;
case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
*((SQLINTEGER *) pvParam) = SQL_SC_NON_UNIQUE;
break;
case SQL_USE_BOOKMARKS:
*((SQLINTEGER *) pvParam) = stmt->options.use_bookmarks;
break;
case 1227: /* SQL_SOPT_SS_HIDDEN_COLUMNS ? */
case 1228: /* SQL_SOPT_SS_NOBROWSETABLE ? */
*((SQLINTEGER *) pvParam) = 0;
break;
default:
{
char option[64];
SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Unknown statement option (Get)", func);
SPRINTF_FIXED(option, "fOption=%d", fOption);
SC_log_error(func, option, stmt);
return SQL_ERROR;
}
}
if (StringLength)
*StringLength = len;
return SQL_SUCCESS;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。