unixODBC编程(四)插入数据

news/2024/9/29 14:20:02 标签: 数据库开发

ODBC插入数据也有一定的步骤,我们先来看一下。

1. 分配一个语句句柄,使用SQLAllocHandle()函数,句柄类型为SQL_HANDLE_STMT。

2. 准备语句,使用SQLPrepare()函数。

3. 为绑定的变量赋值。

4. 绑定输入变量,使用SQLBindParameter()函数。

5. 执行语句,使用SQLExecute()函数。

6. 提交执行结果,使用SQLEndTran()函数。

这里只有两个新函数,SQLBindParameter()和SQLEndTran()。看一下他们的原型和参数。

绑定输入变量函数。

SQLRETURN SQLBindParameter(  
      SQLHSTMT           StatementHandle,  
      SQLUSMALLINT    ParameterNumber,  
      SQLSMALLINT      InputOutputType,  
      SQLSMALLINT      ValueType,  
      SQLSMALLINT      ParameterType,  
      SQLULEN             ColumnSize,  
      SQLSMALLINT     DecimalDigits,  
      SQLPOINTER       ParameterValuePtr,  
      SQLLEN                BufferLength,  
      SQLLEN *              StrLen_or_IndPtr);

StatementHandle是一个输入参数,语句句柄。

ParameterNumber是一个输入参数,参数编号,按递增参数顺序按顺序排序,从 1 开始。

InputOutputType是一个输入参数,指示绑定的参数是输入还是输出,这里是SQL_PARAM_INPUT。

ValueType是一个输入参数,指示绑定参数的 C 数据类型。参考下面的表。

ParameterType是一个输入参数,指示绑定参数的 SQL 数据类型。参考下面的表。

ColumnSize是一个输入参数,指示绑定参数列大小,即表的列长度。字符类型的列可以设置长度,其他类型会忽略。

DecimalDigits是一个输入参数,指示绑定参数标记的列的十进制数字位数。其他类型忽略。

ParameterValuePtr是一个输入参数,指向绑定参数数据的缓冲区的指针。

BufferLength是一个输入/输出参数,指示ParameterValuePtr 缓冲区的长度(以字节为单位)。主要限制输出的数据不要超出缓冲区。

StrLen_or_IndPtr是一个输入参数,指向绑定参数长度缓冲区的指针,用作输入的数据长度或指示变量。

ValueType类型对照表

C 类型标识符ODBC C typedefC 类型
SQL_C_CHARSQLCHAR *unsigned char *
SQL_C_WCHARSQLWCHAR *wchar_t *
SQL_C_SSHORTSQLSMALLINTshort int
SQL_C_USHORTSQLUSMALLINTunsigned short int
SQL_C_SLONGSQLINTEGERlong int
SQL_C_ULONGSQLUINTEGERunsigned long int
SQL_C_FLOATSQLREALFLOAT
SQL_C_DOUBLESQLDOUBLE、SQLFLOATDouble
SQL_C_BITSQLCHARunsigned char
SQL_C_STINYINTSQLSCHARsigned char
SQL_C_UTINYINT[j]SQLCHARunsigned char
SQL_C_SBIGINTSQLBIGINT_int64
SQL_C_UBIGINTSQLUBIGINTunsigned _int64
SQL_C_BINARYSQLCHAR *unsigned char *

 

事务提交函数。

SQLRETURN SQLEndTran(
     SQLSMALLINT   HandleType,
     SQLHANDLE      Handle,
     SQLSMALLINT   CompletionType);

HandleType是一个输入参数,句柄类型标识符。 包含SQL_HANDLE_ENV(如果 Handle 是环境句柄 )或SQL_HANDLE_DBC(如果 Handle 是连接句柄)。

Handle是一个输入参数,HandleType 指示的类型句柄,指示事务的范围。

CompletionType是一个输入参数,以下两个值之一:SQL_COMMIT或SQL_ROLLBACK。

看一个实际的例子,在表中插入一条数据,表结构为:

 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER
 F1                                                 VARCHAR2(100)
 F2                                                 VARCHAR2(200)
 F3                                                 VARCHAR2(200)
 F4                                                 VARCHAR2(200)

插入语句为insert into test_tab1 (id, f1, f2, f3, f4) values (?, ?, ?, ?, ?),问号表示输入参数,需要在后面绑定变量。实际的代码如下。

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sql.h"
#include "sqlext.h"
#include "sqltypes.h"


SQLHANDLE       envh;           /* env handle */
SQLHANDLE       dbch;           /* connect handle */
SQLHANDLE       stmth;          /* statement handle */


int main(int argc, char *argv[])
{
    int         conn = 0;
    SQLRETURN   rc;
    SQLLEN      ind1;
    SQLLEN      ind2;
    SQLLEN      ind3;
    SQLLEN      ind4;
    SQLLEN      ind5;
    SQLINTEGER  id;
    char        dsn_str[32];
    char        usrname[32];
    char        passwd[32];
    char        sqltxt[512];
    char        f1[32];
    char        f2[32];
    char        f3[32];
    char        f4[32];


    if (argc < 3) {
        fprintf(stderr, "usage: %s dsn username password\n", argv[0]);
        return (-1);
    }

    strncpy(dsn_str, argv[1], 32);
    dsn_str[31] = '\0';
    strncpy(usrname, argv[2], 32);
    usrname[31] = '\0';
    strncpy(passwd, argv[3], 32);
    passwd[31] = '\0';

    rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &envh);
    if (rc != SQL_SUCCESS) {
        fprintf(stderr, "Allocate environment handle error.\n");
        return (-1);
    }

    rc = SQLSetEnvAttr(envh, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
    if (rc != SQL_SUCCESS) {
        fprintf(stderr, "Set ODBC version error.\n");
        goto free_exit;
    }

    rc = SQLAllocHandle(SQL_HANDLE_DBC, envh, &dbch);
    if (rc != SQL_SUCCESS) {
        fprintf(stderr, "Allocate DB connection handle error.\n");
        goto free_exit;
    }

    rc = SQLSetConnectAttr(dbch, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER)10, 0);
    if (rc != SQL_SUCCESS) {
        fprintf(stderr, "Set connection timeout value error.\n");
        goto free_exit;
    }

    rc = SQLConnect(dbch, (SQLCHAR *)dsn_str, SQL_NTS, (SQLCHAR *)usrname, SQL_NTS, (SQLCHAR *)passwd, SQL_NTS);
    if (rc != SQL_SUCCESS) {
        fprintf(stderr, "Connect to DB error.\n");
        goto free_exit;
    }

    conn = 1;
    fprintf(stdout, "connect DB ok ......\n");

    rc = SQLAllocHandle(SQL_HANDLE_STMT, dbch, &stmth);
    if (rc != SQL_SUCCESS) {
        fprintf(stderr, "Allocate statment handle error.\n");
        goto free_exit;
    }

    sprintf(sqltxt, "insert into test_tab1 (id, f1, f2, f3, f4) values (?, ?, ?, ?, ?)");
    rc = SQLPrepare(stmth, (SQLCHAR *)sqltxt, SQL_NTS);
    if (rc != SQL_SUCCESS) {
        fprintf(stderr, "Prepare statment error.\n");
        goto free_exit;
    }

    id = 10;
    strcpy(f1, "AAAAAAAAAA");
    strcpy(f2, "BBBBBBBBBBBB");
    strcpy(f3, "CCCCCCCCCCCCCC");
    strcpy(f4, "DDDDDDDDDDDDDDDD");

    ind1 = 0;
    ind2 = SQL_NTS;
    ind3 = SQL_NTS;
    ind4 = SQL_NTS;
    ind5 = SQL_NTS;

    rc = SQLBindParameter(stmth, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &id, 0, &ind1);
    if (rc != SQL_SUCCESS) {
        fprintf(stderr, "Bind column 1 error.\n");
        goto free_exit;
    }

    rc = SQLBindParameter(stmth, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 100, 0, &f1, 0, &ind2);
    if (rc != SQL_SUCCESS) {
        fprintf(stderr, "Bind column 2 error.\n");
        goto free_exit;
    }

    rc = SQLBindParameter(stmth, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 200, 0, &f2, 0, &ind3);
    if (rc != SQL_SUCCESS) {
        fprintf(stderr, "Bind column 3 error.\n");
        goto free_exit;
    }

    rc = SQLBindParameter(stmth, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 200, 0, &f3, 0, &ind4);
    if (rc != SQL_SUCCESS) {
        fprintf(stderr, "Bind column 4 error.\n");
        goto free_exit;
    }

    rc = SQLBindParameter(stmth, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 200, 0, &f4, 0, &ind5);
    if (rc != SQL_SUCCESS) {
        fprintf(stderr, "Bind column 5 error.\n");
        goto free_exit;
    }

    rc = SQLExecute(stmth);
    if (rc != SQL_SUCCESS) {
        fprintf(stderr, "Execute statment error.\n");
        goto free_exit;
    }

    rc = SQLEndTran(SQL_HANDLE_DBC, dbch, SQL_COMMIT);
    if (rc != SQL_SUCCESS) {
        fprintf(stderr, "End Transaction error.\n");
        goto free_exit;
    }

    fprintf(stdout, "Insert data successed ......\n");

    SQLFreeHandle(SQL_HANDLE_STMT, stmth);

    SQLDisconnect(dbch);

    SQLFreeHandle(SQL_HANDLE_DBC, dbch);

    SQLFreeHandle(SQL_HANDLE_ENV, envh);

    return (0);

free_exit:
    if (stmth != NULL) {
        SQLFreeHandle(SQL_HANDLE_STMT, stmth);
    }

    if (conn) {
        SQLDisconnect(dbch);
    }

    if (dbch != NULL) {
        SQLFreeHandle(SQL_HANDLE_DBC, dbch);
    }

    if (envh != NULL) {
        SQLFreeHandle(SQL_HANDLE_ENV, envh);
    }

    return (-1);
}

如果对编程有兴趣,请访问www.tomcoding.com网站,里面有高技术含量的代码和文档下载。


http://www.niftyadmin.cn/n/5683168.html

相关文章

数学符号练习-常用导数与四则运算

前言 其实主要的目的是可以在文本中输出各种数学符号&#xff0c;便于以后用到的时候有现成的例子拿过来抄~~ 常用导数公式 序号公式1 ( C ) ′ 0 (C)0 (C)′02 ( x μ ) ′ μ ⋅ x μ − 1 (x^μ)μx^{μ-1} (xμ)′μ⋅xμ−13 ( s i n x ) ′ c o s x (sinx)cosx (sin…

YoloV10改进策略:BackBone改进|PoolFormer赋能YoloV10,视觉检测性能显著提升的创新尝试

摘要 在深度学习的广阔领域中,目标检测作为计算机视觉的基石任务之一,始终吸引着研究者的广泛关注。近期,我们大胆尝试将前沿的PoolFormer主干网络引入经典的目标检测框架YoloV10中,这一创新性融合不仅为YoloV10注入了新的活力,更在检测精度与效率上实现了双重飞跃,成为…

基于STM32的远程工业控制系统架构设计:MQTT通信、React界面与FreeRTOS优化的综合应用

一、项目概述 项目目标和用途 本项目旨在开发一个基于STM32单片机的远程工业控制系统。该系统能够通过互联网监控和控制工业设备&#xff0c;实时采集环境和设备状态数据&#xff0c;并将数据上传至云端以便进行数据分析和可视化。用户可以通过移动应用或网页界面远程操作设备…

Oracle(147)如何进行数据库升级?

数据库升级是一个复杂的过程&#xff0c;涉及到备份现有数据、安装新版本的数据库软件、迁移数据和应用程序的兼容性测试等步骤。这里以从较旧版本的MySQL升级到较新版本为例&#xff0c;提供一个概览性的指导步骤。请注意&#xff0c;具体步骤可能会因数据库的具体版本和操作系…

【源码+文档+调试讲解】基于微信小程序的医院医疗设备管理系统springboot

摘 要 相比于以前的传统手工管理方式&#xff0c;智能化的管理方式可以大幅降低医院的运营人员成本&#xff0c;实现了医院医疗设备的标准化、制度化、程序化的管理&#xff0c;有效地防止了医院医疗设备的随意管理&#xff0c;提高了信息的处理速度和精确度&#xff0c;能够及…

leetcode每日一题day16(24.9.26)——数组元素和与数字和的绝对差

思路&#xff1a;遍历数组在对数组元素进行求和时并使用while循环求数字和&#xff0c;由于对于一个数&#xff0c;其必定大于其个数位数字的和,所以可以直接对sum进行减 代码 int differenceOfSum(vector<int>& nums) {int ans 0;for (int x : nums) {ans x; // …

springboot购物网站源码分享

开头&#xff1a;springboot购物网站源码分享 题目&#xff1a;springboot购物网站源码分享 主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Mysql|大数据|SSM|SpringBoot|Vue|Jsp|MYSQL等)、学习资料、JAVA源码、技术咨询 文末联系获取 感兴趣可以先收藏起来&#xff…

单片机串口AT指令操作SIM800、900拨打电话

文章目录 一、前言1.1 功能简介1.2 拨打电话功能的应用场景1.3 SIM900A与SIM800C模块介绍1.4 原理图 三、模块调试3.1 工具软件下载3.2 准备好模块3.3 串口调试助手的设置3.4 初始化配置3.5 拨打电话的测试流程 四、代码实现4.1 底层的命令发送接口4.2 底层数据接收接口4.3 检测…