c - 如何在一个变量中使用 OCIBindDynamic 来输入/输出?
问题描述
我的程序有一些关于 OCI/C 传输的代码。但是在将struct与OCIBindDynamics一起使用后我没有任何结果,我认为错误需要删除cbf_no_data,并在动态绑定后为输出变量添加BindByName。我不使用堆栈作为内存,所以在函数后删除数据时不会出现问题
int conn_dynamic(uint16_t id,int pos,char *name,uint16_t type,uint32_t size,int16_t ind,void *data,uint16_t typein,uint32_t sizein,int16_t indin,void *datain,uint16_t mass_arr){
CHECK_CURSOR_ID(id)
int state = 1;
cb_context_t* cbct = (cb_context_t*)malloc(sizeof(cb_context_t));
cbct->cht.ptr = (void*)malloc(sizeof(void*));
cbct->err = connection.errhp;
temp_arr_num = mass_arr;
CHECK_IN_ID(id, pos)
uint8_t bindbyname = 1;
char bindname[65536];
uint32_t bindpos;
if (name[0] >= '0' && name[0] <= '9') {
bindbyname = 0;
bindpos = atoi(name);
} else {
bindname[0] = ':';
strcpy(bindname + 1, name);
}
connection.statements[id].inbinds[pos].type = typein;
connection.statements[id].inbinds[pos].ind = indin;
memcpy(connection.statements[id].inbinds[pos].ptr, datain, sizein);
if (typein == SQLT_CLOB || typein == SQLT_BLOB) {
assert(connection.statements[id].inbinds[pos].lob == NULL);
OCI_CALL(OCIDescriptorAlloc(connection.envhp, (void **)&connection.statements[id].inbinds[pos].lob, OCI_DTYPE_LOB, 0, 0));
OCI_CALL(OCILobCreateTemporary(connection.svchp, connection.errhp, connection.statements[id].inbinds[pos].lob, (ub2)OCI_DEFAULT, OCI_DEFAULT,
(typein == SQLT_CLOB)?OCI_TEMP_CLOB:OCI_TEMP_BLOB, OCI_ATTR_NOCACHE, OCI_DURATION_SESSION));
OCI_CALL(OCILobOpen(connection.svchp, connection.errhp, connection.statements[id].inbinds[pos].lob, OCI_LOB_READWRITE));
uint32_t amtp = sizein;
OCI_CALL(OCILobWrite(connection.svchp, connection.errhp, connection.statements[id].inbinds[pos].lob, &amtp, 1, datain, sizein, OCI_ONE_PIECE, 0, 0, 0, SQLCS_IMPLICIT));
if (bindbyname) {
OCI_CALL(OCIBindByName(connection.statements[id].handle, &(connection.statements[id].inbinds[pos].handle), connection.errhp, (OraText *) name, strlen(name),
&(connection.statements[id].inbinds[pos].lob), 0, typein, 0, 0, 0, 0, 0, OCI_DATA_AT_EXEC));
} else {
OCI_CALL(OCIBindByPos(connection.statements[id].handle, &(connection.statements[id].inbinds[pos].handle), connection.errhp, bindpos,
&(connection.statements[id].inbinds[pos].lob), 0, typein, 0, 0, 0, 0, 0, OCI_DATA_AT_EXEC));
}
} else {
if (!(connection.statements[id].inbinds[pos].ptr = malloc(sizein))) { //create temporary storage for value
connection.error.code = 301;
strcpy(connection.error.msg, "Out of memory");
return -1;
}
// if (bindbyname) {
// OCI_CALL(OCIBindByName(connection.statements[id].handle, &(connection.statements[id].inbinds[pos].handle), connection.errhp, (OraText *) name, strlen(name),
// &(connection.statements[id].inbinds[pos].ptr), sizein, typein, &connection.statements[id].inbinds[pos].ind, 0, 0, 0, 0, OCI_DATA_AT_EXEC));
// } else {
// OCI_CALL(OCIBindByPos(connection.statements[id].handle, &(connection.statements[id].inbinds[pos].handle), connection.errhp, bindpos,
// &(connection.statements[id].inbinds[pos].ptr), sizein, typein, &connection.statements[id].inbinds[pos].ind, 0, 0, 0, 0, OCI_DATA_AT_EXEC));
// }
}
uint16_t oratype=0;
WRITELOG(params,LDEBUG1,"TYPE IN BIND %d \n", type);
switch (type) {
case 2:{
oratype = SQLT_INT;
OCIBindDynamic(connection.statements[id].outbinds[pos].handle,connection.errhp,(dvoid*)cbct,cbf_no_data,(dvoid*)cbct,cbf_get_numeric_data);
break;
}
case 3:{
oratype = SQLT_FLT;
OCIBindDynamic(connection.statements[id].outbinds[pos].handle,connection.errhp,(dvoid*)cbct,cbf_no_data,(dvoid*)cbct,cbf_get_numeric_data);
break;
}
case 1:
case 4:
case 5:
{
if (type == 1){
oratype = SQLT_STR;
WRITELOG(params,LDEBUG1,"call str\n");
OCI_CALL(OCIBindDynamic(connection.statements[id].outbinds[pos].handle,connection.errhp,(dvoid*)cbct,cbf_no_data,(dvoid*)cbct,cbf_get_string));
}
if (type == 5){ oratype = SQLT_CLOB;
OCIBindDynamic(connection.statements[id].outbinds[pos].handle,connection.errhp,(dvoid*)cbct,cbf_no_data,(dvoid*)cbct,cbf_get_clob_data);
}
if (type == 4){
oratype = SQLT_BLOB;
OCIBindDynamic(connection.statements[id].outbinds[pos].handle,connection.errhp,(dvoid*)cbct,cbf_no_data,(dvoid*)cbct,cbf_get_blob_data);
break;}
case 6:{
oratype = SQLT_RSET;
OCIBindDynamic(connection.statements[id].outbinds[pos].handle,connection.errhp,(dvoid*)cbct,cbf_no_data,(dvoid*)cbct,cbf_ref_cursor);
break;}
}
default:
return -1;
}
printf("error here??");
out_array[temp_arr_num]->type = oratype;
out_array[temp_arr_num]->pos = pos;
printf("No");
//it's not a magic numbers. See outputbind in commands.c
cursorid = id;
//WRITE LOG HERE
return 1;
}
所以我没有输出绑定,程序尝试获取变量。例如 cbf_get_string
sb4 cbf_get_string(dvoid *ctxp, OCIBind *bindp, ub4 iter, ub4 index,
dvoid **bufpp, ub4 **alenp, ub1 *piecep,
dvoid **indpp, ub2 **rcodepp) {
cb_context_t* cbct = (cb_context_t*)ctxp;
ub4 pos = *((ub4 *)ctxp);
/* find out how many rows we are expecting */
if (index == 0) {
int rows = 0;
OCIAttrGet((dvoid*)bindp, OCI_HTYPE_BIND, (dvoid*)&rows, (ub4*)sizeof(int), OCI_ATTR_ROWS_RETURNED, cbct->err);
int sz = rows * sizeof(out_string_t);
void* rs = (void*)malloc(sz);
memcpy(cbct->cht.ptr, &rs, sizeof(void*)); /* ptr is now a pointer to a pointer */
#ifdef DEBUG
char dbuf[256]; snprintf(dbuf, 255, "cbf_get_string: rows=%d rs=%p cbct->cht.ptr=%p bytes=%d", rows, rs, *(void**)cbct->cht.ptr, sz); debug(dbuf);
#endif
}
out_string_t* offset = (out_string_t*) ((*(void**)cbct->cht.ptr) + (index * sizeof(out_string_t)));
*indpp = (dvoid*)&offset->indicator;
*rcodepp = (dvoid*)&offset->rc;
*bufpp = (dvoid*)&offset->bufpp;
int size = sizeof(bufpp);
offset->alenp = size;
*alenp = (dvoid*)&offset->alenp;
*piecep = OCI_ONE_PIECE;
out_array[temp_arr_num]->ptr = cbct->cht.ptr;
out_array[temp_arr_num]->index = index;
WRITELOG(params,LDEBUG1,"string in bind %s \n", *(offset->bufpp));
return OCI_CONTINUE;
}
你能告诉我,我哪里错了吗?因为我不能显示一些错误。我尝试只将“a”绑定到输入,将“a”绑定到输出。例如“Begin :a := :b End; 我需要查看 a
解决方案
推荐阅读
- acumatica - Acumatica - 引发多个错误/异常
- typescript - Sinon 存根函数不能与函数内部的函数一起使用
- flutter - Cubit State 不会在 BottomSheet 内刷新
- postgresql - PostgreSQL 中的外键过滤
- c# - 无法让 Identity Server 4 API 授权其自己的端点,而是发送登录页面
- python - 用于 KMeans 聚类每次迭代中的标签的 Scikit-learn api
- javascript - 用于 ECDH 输出的 Web 密码学实现 HKDF
- android - 如何在 kotlin 的帮助下从 Cloud Firestore 中删除 recyclerview 项目?
- powershell - powershell在计算前计算属性插入变量
- r - 使用 fct_infreq() 按频率排列带有字符的多列