ODBC 写入 blob 示例 Oracle C++
ODBC write blob example Oracle C++
你能用 c++ 给我一个使用 ODBC API 在 Oracle 数据库中插入blob
的例子吗?这是我第一次使用BLOB
类型,所以它对我来说很抽象。我研究了很多互联网,现在我的脑子里都是乱七八糟的。一个例子真的会对我有帮助。
我在 C 中有一个简短的例子。通过 ODBC 插入 blob 的基本原则如下:
SQLPrepare("insert into mytable (mycolumne) values(?)");
SQLBindParameter(1, other_args, indicator SQL_LEN_DATA_AT_EXEC(size));
SQLExecute will return SQL_NEED_DATA
call SQLParamData to find which parameter data is required for
call SQLPutData as much as you like in chunks to insert data
call SQLParamData again to find the next parameter requiring data
在这里的示例代码中,您必须编写自己的 do_a_error() 函数,但它只调用 SQLGetDiagRec。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined (WIN32)
# include <windows.h>
# include <io.h>
#else
# include <unistd.h>
#endif
#include <stdio.h>
#include <sql.h>
#include <sqlext.h>
#include "helper.h" /* contained do_a_error() defn etc - you won't have this header */
#ifdef WIN32
# define F_OK 0
# define W_OK 2
# define R_OK 4
# define access _access /* file check */
#endif
static SQLUINTEGER array_row_counts;
static SQLUINTEGER array_selects;
static SQLUINTEGER static_ca1;
static SQLUINTEGER static_ca2;
unsigned int debug=0;
const char fixed_data_source[] = "example";
#define TEST_FILE "easycd.jpg"
#define DISPLAY_GIF "/usr/X11/bin/xv"
static short insert_into_table(
SQLHDBC *hdbc,
typeinfo_t typeinfo);
/************************************************************************/
/* */
/* main */
/* ==== */
/* */
/************************************************************************/
int main(int argc, char *argv[], char *envp[])
{
SQLHENV henv; /* environment handle */
SQLHDBC hdbc; /* database handle */
char *data_source_name; /* chosen datasource */
SQLRETURN ret; /* function return status */
char in_connection_string[512]; /* SQLDriverConnect string */
char out_connection_string[512]; /* returned connection string */
SQLSMALLINT out_connection_string_len; /* ... and length */
unsigned int i; /* loop variable */
typeinfo_t typeinfo[100]; /* data type information */
int type_element = -1;
SQLINTEGER max_column_size = 0; /* largest column */
/*
* Get the datasource name.
*/
if (argc > 1)
{
for (i = 1; i < argc; i++)
{
if (!strcmp (argv[i], "-d")) debug = 1;
}
if (((argc > 2) && debug) ||
((argc > 1) && !debug))
data_source_name = argv[argc - 1];
}
else
{
data_source_name = fixed_data_source;
}
sprintf(in_connection_string, "DSN=%s;", data_source_name);
/*
* Allocate and set up the environment and connection.
*/
if (SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv) != SQL_SUCCESS)
{
fprintf(stderr, "** Failed to allocate environment **n");
exit(1);
}
if (SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
(SQLPOINTER)SQL_OV_ODBC3, 0) != SQL_SUCCESS)
{
do_a_error(SQL_HANDLE_ENV, henv, "SQLSetEnvAttr");
SQLFreeHandle(SQL_HANDLE_ENV, henv);
exit(2);
}
if (SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc) != SQL_SUCCESS)
{
do_a_error(SQL_HANDLE_ENV, henv, "SQLAllocHandle");
SQLFreeHandle(SQL_HANDLE_ENV, henv);
exit(3);
}
ret = SQLDriverConnect(hdbc, NULL,
(SQLCHAR *)in_connection_string, SQL_NTS,
(SQLCHAR *)out_connection_string,
sizeof(out_connection_string),
&out_connection_string_len, SQL_DRIVER_COMPLETE);
if (!SQL_SUCCEEDED(ret))
{
do_a_error(SQL_HANDLE_DBC, hdbc, "SQLDriverConnect");
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
exit(4);
}
if (out_connection_string_len > sizeof(out_connection_string))
{
out_connection_string[sizeof(out_connection_string) - 1] = ' ';
}
else
{
out_connection_string[out_connection_string_len] =' ';
}
printf("%sn", out_connection_string);
if (ret == SQL_SUCCESS_WITH_INFO)
{
do_a_error(SQL_HANDLE_DBC, hdbc, "SQLDriverConnect");
}
/*
* Get a list of the types supported.
*/
memset(typeinfo, ' ', sizeof(typeinfo));
do_get_info(hdbc, &array_row_counts, &array_selects,
&static_ca1, &static_ca2);
if (!SQL_SUCCEEDED(do_type_info(hdbc, typeinfo)))
{
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
exit(5);
}
/*
* Find a type big enough for our gif image.
*/
for (i = 0; strlen(typeinfo[i].type_name); i++)
{
if ((typeinfo[i].column_size > max_column_size) &&
(max_column_size != SQL_NO_TOTAL))
{
max_column_size = typeinfo[i].column_size;
type_element = i;
}
else
{
if (typeinfo[i].column_size == SQL_NO_TOTAL)
{
if (max_column_size != SQL_NO_TOTAL)
{
max_column_size = SQL_NO_TOTAL;
type_element = i;
}
}
}
}
if (type_element < 0) abort();
if (debug)
printf("t Biggest type is %s at %ld in size, requiring "%s"n",
typeinfo[type_element].type_name,
typeinfo[type_element].column_size,
typeinfo[type_element].create_params);
/*
* Delete existing table and create a new one.
*/
ret = do_create_table(hdbc, ""blob"", CREATE_TABLE_BIGCOL,
typeinfo[type_element].column_size,
typeinfo[type_element].type_name,
typeinfo[type_element].create_params);
if (!SQL_SUCCEEDED(ret))
{
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
exit(4);
}
insert_into_table(hdbc, typeinfo[type_element]);
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 0;
}
/************************************************************************/
/* */
/* insert_into_table */
/* ================= */
/* */
/************************************************************************/
static short insert_into_table(
SQLHDBC *hdbc,
typeinfo_t typeinfo)
{
SQLINTEGER len_ind[2]; /* parameter lengths */
SQLINTEGER p1; /* first parameter array */
SQLCHAR p2[50000]; /* second parameter array */
SQLINTEGER row_counts; /* rows affected */
SQLRETURN ret; /* function status return */
unsigned int row; /* current row */
SQLHSTMT hstmt; /* statement handle */
char qbuf[1024]; /* query buffer */
FILE *fp; /* test file file ptr */
size_t readb; /* bytes read from test file */
size_t writeb; /* bytes written to test file */
SQLINTEGER retrieved; /* data retrieved from GetData */
unsigned int pos; /* position in GetData buffer */
printf("---------- insert_into_table ----------n");
printf("-- Creating rows with BIG column data --n");
if (access(TEST_FILE, R_OK))
{
fprintf(stderr, "Can't find test binary %sn", TEST_FILE);
return SQL_ERROR;
}
if (!(fp = fopen(TEST_FILE, "rb")))
{
fprintf(stderr, "Failed to open %s for readingn", TEST_FILE);
return SQL_ERROR;
}
clearerr(fp);
readb = fread(p2, 1, sizeof(p2), fp);
if ((readb == 0) || ferror(fp))
{
fprintf(stderr, "Failed to read data from %sn", TEST_FILE);
return SQL_ERROR;
}
if (readb >= sizeof(p2))
{
fprintf(stderr, "%s is too big a filen", TEST_FILE);
return SQL_ERROR;
}
fclose(fp);
if (SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt) != SQL_SUCCESS)
{
do_a_error(SQL_HANDLE_DBC, hdbc, "SQLAllocHandle");
return SQL_ERROR;
}
/*
* Delete all the rows.
*/
sprintf(qbuf, "delete from "blob"");
printf(""%s"n", qbuf);
ret = SQLExecDirect(hstmt, (SQLCHAR *)qbuf, SQL_NTS);
if (ret != SQL_SUCCESS)
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLExecDirect");
/*
* Create the rows.
*/
sprintf(qbuf, "insert into "blob" (a,b) values(?,?)");
printf(""%s"n", qbuf);
if (SQLPrepare(hstmt, (SQLCHAR *)qbuf, SQL_NTS) != SQL_SUCCESS)
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLPrepare");
return SQL_ERROR;
}
/*
* Bind Parameters
*/
ret = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER,
5, 0, &p1, 0, &len_ind[0]);
if (!SQL_SUCCEEDED(ret))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLBindParameter");
return ret;
}
ret = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY,
typeinfo.sql_data_type,
sizeof(p2), 0, (SQLPOINTER)2, 0,
&len_ind[1]);
if (!SQL_SUCCEEDED(ret))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLBindParameter");
return ret;
}
printf("tInserting rows into tablen");
for (row = 0; row < 1; row++)
{
/* a */
p1 = row;
len_ind[0] = sizeof(p1);
/* b */
len_ind[1] = SQL_LEN_DATA_AT_EXEC(readb);
ret = SQLExecute(hstmt);
if (ret == SQL_NEED_DATA)
{
SQLPOINTER val;
ret = SQLParamData(hstmt, &val);
if (ret != SQL_NEED_DATA)
{
fprintf(stderr,
"** SQLParamData returned %d, "
"expected SQL_NEED_DATA **n", ret);
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLParamData");
return SQL_ERROR;
}
if (val != (SQLPOINTER)2)
{
fprintf(stderr,
"** SQLParamData said it required data for parameter "
"marker %p, and we expected 2 **n", val);
return SQL_ERROR;
}
ret = SQLPutData(hstmt, p2, readb);
if (!SQL_SUCCEEDED(ret))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLPutData");
return SQL_ERROR;
}
ret = SQLParamData(hstmt, &val);
if (!SQL_SUCCEEDED(ret))
{
fprintf(stderr,
"** Second SQLParamData returned %d, "
"We though all data was sent **n", ret);
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLParamData");
return SQL_ERROR;
}
}
else if (!SQL_SUCCEEDED(ret))
{
fprintf(stderr,
"** Driver returned a successful state for SQLExecute "
"buf there were data-at-exec parameters **n");
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLExecute");
return SQL_ERROR;
}
else
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLExecute");
}
if (!SQL_SUCCEEDED(SQLRowCount(hstmt, &row_counts)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLRowCount");
}
if (row_counts != 1)
{
fprintf(stderr, "** RowCount=%ld, expected 1 **n", row_counts);
}
printf(".");
fflush(stdout);
}
printf("n");
/*
* Now get it back to check we sent it OK.
*/
memset(p2, ' ', sizeof(p2));
sprintf(qbuf, "select * from "blob"");
if (!SQL_SUCCEEDED(ret = SQLPrepare(hstmt, (SQLCHAR *)qbuf, SQL_NTS)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLPrepare");
return SQL_ERROR;
}
if (!SQL_SUCCEEDED(ret = SQLExecute(hstmt)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLExecute");
}
if (!SQL_SUCCEEDED(ret = SQLFetch(hstmt)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLFetch");
}
pos = 0;
while(SQL_SUCCEEDED(ret = SQLGetData(hstmt, 2, SQL_C_BINARY,
&p2[pos], sizeof(p2), &retrieved)))
{
if (retrieved == SQL_NO_TOTAL) abort();
if (retrieved == SQL_NULL_DATA) abort();
pos += retrieved;
}
if (ret != SQL_NO_DATA)
{
fprintf(stderr,
"** SQLGetData finished with a status other than SQL_NO_DATA **n");
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLGetData");
return SQL_ERROR;
}
if (!SQL_SUCCEEDED(SQLCloseCursor(hstmt)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLCloseCursor");
}
if (!(fp = fopen("out.jpg", "w")))
{
fprintf(stderr, "** Failed to open out.jpg for writing **n");
return SQL_ERROR;
}
writeb = fwrite(p2, 1, pos, fp);
if (writeb != pos)
{
fprintf(stderr, "** Failed to write out.jpg **n");
return SQL_ERROR;
}
fclose(fp);
system(DISPLAY_GIF" out.jpg");
printf("tResetting parametersn");
if (!SQL_SUCCEEDED(SQLFreeStmt(hstmt, SQL_RESET_PARAMS)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLFreeStmt");
}
printf("tClosing statementn");
if (!SQL_SUCCEEDED(SQLFreeStmt(hstmt, SQL_CLOSE)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLFreeStmt");
}
printf("tDropping Statementn");
ret = SQLFreeStmt(hstmt, SQL_DROP);
if (!SQL_SUCCEEDED(ret))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLFreeStmt");
}
return ret;
}
相关文章:
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- 如何从 oracle 数据库 c++ 读取 unicode
- Oracle OCCI 和 g++ 7.1 的兼容性问题
- 如何从 Oracle 数据库中获取 qt 中 SQL 查询的传输字节大小?
- Proc*C 应用程序在 Oracle 12.2 中崩溃
- 如何在 Oracle Linux 上的 Eclipse 中编译和链接 boost 库
- 在C++中连接 Oracle 数据库
- 在运行Visual Studio中用C 编写的Oracle DB客户端时,我会收到错误32104
- 从Ubuntu连接到Oracle数据库
- 如何在Oracle DB中编写C 中的UDF
- 使用 occi 库将 c++ 程序与 Oracle 连接起来
- 在CodeBlocks上编译C 中的Oracle数据库环境时的错误
- SourcePro DB可以使用PKI连接到Oracle吗?
- 当在Select子句中使用情况时,Oracle编号的精度和缩放为零
- Soci Clob数据类型中的Oracle C
- Oracle ODBC 插入失败,没有任何错误诊断
- 将特定结果集从Oracle数据库复制到C 中的SQLite数据库的最佳方法
- 如何在ORACLE数据库的结果集中返回空字符串(使用sys_refcursor)
- 通过 occi 连接 oracle db 的 MFC 应用程序.但它在 64 位机器中运行时0xC000007b错误
- 是 Oracle 正式支持的动态记录集