Proc *C/C++入门之动态SQL

基本概念
在有些情况下, 在编码时 SQL 语句还不能完整地写出来, 而是在程序执行时才能
构造出来,这种在程序执行临时生成的 SQL 语句叫动态 SQL 语句. 利用动态 SQL 来
编写 Pro*C 程序的方法叫动态 SQL 技术!

目的:加强应用程序的功能和灵活
静态SQL —- 在编写应用程序时,使用EXEC SQL关键字直接嵌入的SQL语句;在proc编译应用程序生成c语言的时,都已经确定
动态SQL —- 在运行应用程序时,由用户动态输入的SQL语句。
在下列情况之一不知道时, 使用动态 SQL 技术:

SQL 语句的文本.
宿主变量的个数。
宿主变量的数据类型
引用的数据库对象, 如列, 索引, 序列, 表, 用户名和视图.
Oracle 中动态 SQL 可用以下两种方法实现:一个是 Oracle 自己的方法, 一个是 ANSI 的方法. 一般建议使用 Oracle 的方法,
但对于较复杂的应用, 可以使用 ANSI 的方法, 因为这样可以使自己的程序简化。

动态SQL1
语法:
EXEC SQL EXECUTE IMMEDIATE :host_string
host_string 字符串

限制
不能执行select语言,仅适用于非select语句
在sqlplus上运行的命令,都可以拿过来来执行
语句中不包含输入宿主变量–一个宿主指针变量指向一块内存空间(存有用户输入的SQL语句)
常用于仅执行一次的动态语句
对重复执行多次的动态SQL语句,降低执行效率

nt main01()
{
    int     ret = 0;    
    int     i = 0;
    char    choosechar;

    memset(mySql, 0, sizeof(mySql));
    pSql = NULL;

    EXEC SQL WHENEVER SQLERROR DO sqlerr02();
    connet();
    pSql = mySql;
    //循环处理sql语言
    for(;;)
    {
        printf("\nplease enter sql(not select ): ");
        gets(mySql);
        //scanf("%s", mySql); --空格截断
        printf("mysql:%s\n", mySql);
        printf("任意键继续....\n");
        getchar();
        EXEC SQL EXECUTE IMMEDIATE :pSql;

        EXEC SQL COMMIT;
        printf("继续执行吗?\n");
        scanf("%c", &choosechar);
        fflush(stdin);

        if (choosechar=='n' || choosechar=='N')
        {
            break;
        }
    }

    EXEC SQL COMMIT WORK RELEASE;
    printf("return ok...\n");

    return ret ;
}

动态SQL2
使用PREPARE命令准备SQL语句
EXEC SQL PREPARE statement_name FROM :host_string;

statement_name: 标识符,
host_string:含SQL语句的字符串

使用EXECUTE命令执行SQL语句
EXEC SQL EXECUTE statement_name [USING :host_variable]

如果SQL语句要通过宿主变量赋值,输入SQL语句时要用占位符仅适用于非select语句
可包含虚拟输入宿主变量和指示器变量,其个数和类型在预编译时已知

int main02()
{
    int     ret = 0;    
    int     i = 0;
    char    choosechar;

    memset(mySql, 0, sizeof(mySql));
    pSql = NULL;

    EXEC SQL WHENEVER SQLERROR DO sqlerr02();
    connet();

    pSql = mySql;
    //循环处理sql语言
    for(;;)
    {
        printf("\n请输入要更新部门编号 ");
        scanf("%d", &deptno);

        printf("\n请输入要新loc值 ");
        scanf("%s", loc);

        //准备动态sql
        EXEC SQL PREPARE my_pre_sql FROM 'update dept set loc = :a where deptno = :b';
        //执行动态sql
        EXEC SQL EXECUTE my_pre_sql USING :loc, :deptno;

        EXEC SQL COMMIT;

        printf("\n 按任意键继续? ");
        getchar();
        printf("\n退出键入n, 其他继续? ");
        scanf("%c", &choosechar);
        fflush(stdin);

        if (choosechar=='n' || choosechar=='N')
        {
            break;
        }
    }

    EXEC SQL COMMIT WORK RELEASE;
    printf("return ok...\n");

    return ret ;
}


动态SQL3
使用PREPARE命令准备SQL语句
EXEC SQL PREPARE statement_name FROM :host_string;

statement_name: 标识符,
host_string:含SQL语句的字符串

使用DECLARE命令定义游标,可以结合游标一块使用
 EXEC SQL DECLARE cursor_name CURSOR FOR statement_name; 
 EXEC SQL OPEN cursor_name [using host_variable_list]
 EXEC SQL FETCH cursor_name INTO host_variable_list
 EXEC SQL CLOSE cursor_name 

查询部门号大于10的所有部门信息
动态sql3 处理选择列表项(select查询出来的结果列数固定) 和 输入宿主变量个数一定
本质:
输入宿主变量个数固定 查询条件固定
输出宿主变量个数固定 返回结果固定

//可以结合游标一块使用

int main()
{
    int     ret = 0;    
    int     i = 0;
    char    choosechar;

    memset(mySql, 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值