您能否举例说明使用ODBC API在Oracle数据库中插入blob
的c ++示例?这是我第一次使用BLOB
类型,所以它对我来说是抽象的。我已经对互联网进行了很多研究,现在我的脑子里一片混乱。一个例子真的可以帮助我。
答案 0 :(得分:2)
我在C中有一个简短的(ish)示例。通过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] = '\0';
}
else
{
out_connection_string[out_connection_string_len] ='\0';
}
printf("%s\n", 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, '\0', 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 %s\n", TEST_FILE);
return SQL_ERROR;
}
if (!(fp = fopen(TEST_FILE, "rb")))
{
fprintf(stderr, "Failed to open %s for reading\n", 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 %s\n", TEST_FILE);
return SQL_ERROR;
}
if (readb >= sizeof(p2))
{
fprintf(stderr, "%s is too big a file\n", 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 table\n");
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, '\0', 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 parameters\n");
if (!SQL_SUCCEEDED(SQLFreeStmt(hstmt, SQL_RESET_PARAMS)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLFreeStmt");
}
printf("\tClosing statement\n");
if (!SQL_SUCCEEDED(SQLFreeStmt(hstmt, SQL_CLOSE)))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLFreeStmt");
}
printf("\tDropping Statement\n");
ret = SQLFreeStmt(hstmt, SQL_DROP);
if (!SQL_SUCCEEDED(ret))
{
do_a_error(SQL_HANDLE_STMT, hstmt, "SQLFreeStmt");
}
return ret;
}