为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】: 8
【操作系统】:window/linux
【CPU】:
【问题描述】*:在dpi 开发中,dpi_bind_param 如何绑定 DEFAULT 默认值标记?
ctype=DSQL_C_DEFAUL
dtype=DSQL_DEFAULT
数据库报错 -70003 无效的数据库数据类型
示例代码,注释中讲了如何使用DSQL_C_DEFAULT:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "DPI.h"
#include "DPIext.h"
#include "DPItypes.h"
#define DM_SVR "DM8"
#define DM_USER "SYSDBA"
#define DM_PWD "SYSDBA"
dhenv henv; /* 环境句柄 */
dhcon hcon; /* 连接句柄 */
dhstmt hstmt; /* 语句句柄 */
DPIRETURN rt; /* 函数返回值 */
/******************************************************
Notes:
获取错误信息
*******************************************************/
void dpi_err_msg_print(sdint2 hndl_type, dhandle hndl)
{
sdint4 err_code;
sdint2 msg_len;
sdbyte err_msg[SDBYTE_MAX];
/* 获取错误信息集合 */
dpi_get_diag_rec(hndl_type, hndl, 1, &err_code, err_msg, sizeof(err_msg), &msg_len);
printf("err_msg = %s, err_code = %d\n", err_msg, err_code);
}
/*
入口函数
*/
int main(int argc, char *argv[])
{
sdbyte create_table_sql[] = "CREATE TABLE IF NOT EXISTS TEST.MY_TEST (C1 INT, C2 VARCHAR(10 CHAR))";
sdbyte insert_sql[] = "INSERT INTO TEST.MY_TEST (C1, C2) VALUES (?, ?)";
sdint4 in_c1;
sdbyte in_c2[20] = {0};
slength in_c1_ind_ptr, in_c2_ind_ptr;
sdint4 out_c1 = 0;
sdbyte out_c2[20] = {0};
slength out_c1_ind = 0;
slength out_c2_ind = 0;
ulength row_num;
char input[100];
// 连接数据库
rt = dpi_alloc_env(&henv);
rt = dpi_alloc_con(henv, &hcon);
rt = dpi_login(hcon, (sdbyte *)DM_SVR, (sdbyte *)DM_USER, (sdbyte *)DM_PWD);
if (!DSQL_SUCCEEDED(rt))
{
dpi_err_msg_print(DSQL_HANDLE_DBC, hcon);
return rt;
}
rt = dpi_alloc_stmt(hcon, &hstmt);
// 创建表
printf("创建表: TEST.MY_TEST...\n");
rt = dpi_exec_direct(hstmt, create_table_sql);
if (!DSQL_SUCCEEDED(rt))
{
dpi_err_msg_print(DSQL_HANDLE_STMT, hstmt);
}
else
{
printf("表创建成功。\n");
}
// 清空表,初始化测试环境
printf("清空表: TEST.MY_TEST...\n");
dpi_exec_direct(hstmt, (sdbyte *)"DELETE FROM TEST.MY_TEST");
// 用户交互式插入数据
while (1)
{
printf("请输入要插入的C1值(整数)或输入'q'退出:");
fgets(input, sizeof(input), stdin);
if (input[0] == 'q' || input[0] == 'Q')
break;
in_c1 = atoi(input);
printf("请输入要插入的C2值(字符串,最多10字符):");
fgets(input, sizeof(input), stdin);
input[strcspn(input, "\n")] = '\0'; // 去掉换行符
strncpy((char *)in_c2, input, sizeof(in_c2) - 1);
in_c1_ind_ptr = sizeof(in_c1);
in_c2_ind_ptr = strlen((char *)in_c2);
// 插入数据
rt = dpi_prepare(hstmt, insert_sql);
// 使用DSQL_C_DEFAULT来自动确认输入的数据类型。
// dType则需要对应表中该列的数据类型
rt = dpi_bind_param(hstmt, 1, DSQL_PARAM_INPUT, DSQL_C_DEFAULT, DSQL_INT, sizeof(in_c1), 0, &in_c1, sizeof(in_c1), &in_c1_ind_ptr);
rt = dpi_bind_param(hstmt, 2, DSQL_PARAM_INPUT, DSQL_C_DEFAULT, DSQL_VARCHAR, sizeof(in_c2), 0, in_c2, sizeof(in_c2), &in_c2_ind_ptr);
rt = dpi_exec(hstmt);
if (!DSQL_SUCCEEDED(rt))
{
dpi_err_msg_print(DSQL_HANDLE_STMT, hstmt);
return rt;
}
printf("数据插入成功: C1=%d, C2=%s\n", in_c1, in_c2);
}
// 查询数据
dpi_exec_direct(hstmt, (sdbyte *)"SELECT * FROM TEST.MY_TEST");
dpi_bind_col(hstmt, 1, DSQL_C_SLONG, &out_c1, sizeof(out_c1), &out_c1_ind);
dpi_bind_col(hstmt, 2, DSQL_C_NCHAR, &out_c2, sizeof(out_c2), &out_c2_ind);
printf("\n查询表中数据:\n");
while (dpi_fetch(hstmt, &row_num) != DSQL_NO_DATA)
{
printf("C1 = %d, C2 = %s\n", out_c1, out_c2);
}
// 断开数据库连接
rt = dpi_logout(hcon);
if (!DSQL_SUCCEEDED(rt))
{
dpi_err_msg_print(DSQL_HANDLE_DBC, hcon);
return rt;
}
rt = dpi_free_con(hcon);
rt = dpi_free_env(henv);
return rt;
}
编译指令(库文件路径写你本地的):
gcc -g -DDM64 -I/home/dmdba/dmdbms/include -L/home/dmdba/dmdbms/bin -ldmdpi -o dpiBind dpi_bind.c
运行:
./dpiBind
请查阅以下2篇文档,看是否对您有帮助
https://eco.dameng.com/document/dm/zh-cn/app-dev/c_c++_dpi
https://eco.dameng.com/document/dm/zh-cn/pm/dpi-rogramming-guide.html