/* 包含C头文件 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* 包含SQLCA头文件 */
#include <sqlca.h> /* 定义绑定变量值和 选择列表项值的最大长度
* 绑定变量:即在SQL语句中输入的“&”占位符。
*/
#define MAX_VAR_LEN 30 /* 定义选择列表项名的最大长度 */
#define MAX_NAME_LEN 31 /* 定义宿主变量 */
exec sql begin declare section;
char *usrname = "scott";
char *passwd = "";
char *serverid = "orcl";
char sql_stat[];
char current_date[];
exec sql end declare section; void sql_error(void);
void connet(void);
void process_input(void);
void process_output(void); int main(void)
{
/* 安装错误处理句柄 */
exec sql whenever sqlerror do sql_error(); /* 连接到数据库 */
connet(); /*
* 分配输入描述区和输出描述区
* Ansi定义了该套标准,proc程序开发者按标准实现了它
* 这两条语句在proc编译的时候会开辟对应大小的存储空间
*/
exec sql allocate descriptor 'input_descriptor'; //用来存储输入的宿主变量
exec sql allocate descriptor 'output_descriptor'; //用来缓存数据库端返回的结果集 for( ; ; )
{
printf("\n请输入动态SQL语句(EXIT:退出):\n");
gets(sql_stat); /* EXIT(exit)->退出 */
if( == strncmp(sql_stat , "EXIT" , ) || == strncmp(sql_stat , "exit" , ))
break; /* 准备动态SQL语句 */
exec sql prepare s from :sql_stat; /* 定义游标 */
exec sql declare c cursor for s; /* 处理绑定变量 , 即处理占位符 “&” */
process_input(); /*
* 打开游标成功 意寓着结果已经被保存到输出描述区了。
* select语句:处理查询结果
* 其他SQL语句:执行
*/
exec sql open c using descriptor 'input_descriptor';
if( == strncmp(sql_stat , "SELECT" , ) , == strncmp(sql_stat , "select" , ))
{
process_output();
}
/* 关闭游标 */
exec sql close c;
} /* 释放输入描述区和输出描述区 */
exec sql deallocate descriptor 'input_descriptor';
exec sql deallocate descriptor 'output_descriptor'; /* 提交事务,断开连接 */
exec sql commit work release;
puts("谢谢使用ANSI动态SQL!\n"); return ;
} void sql_error(void)
{
/* 显示SQL错误号、错误描述 */
printf("%.*s\n" , sqlca.sqlerrm.sqlerrml , sqlca.sqlerrm.sqlerrmc);
exit();
} void process_input(void)
{
int i; /* 定义宿主变量 */
exec sql begin declare section;
int input_count;
int input_type ;
int input_len;
char input_buffer[MAX_VAR_LEN];
char name[MAX_NAME_LEN];
int occurs;
exec sql end declare section; /* 绑定变量->输入描述区 */
exec sql describe input s using descriptor 'input_descriptor'; /* 取得绑定变量个数 */
exec sql get descriptor 'input_descriptor' :input_count = count; /* 循环处理绑定变量名 */
for(i = ; i != input_count ; ++i)
{
occurs = i + ; /* 取得绑定变量名 */
exec sql get descriptor 'input_descriptor' value :occurs :name = name;
printf("请输入%s的值:" , name);
gets(input_buffer); /* 以NULL结尾 */
input_len = strlen(input_buffer);
input_buffer[input_len] = '\0'; /* 设置绑定变量类型、长度和值 */
input_type = ;
exec sql set descriptor 'input_descriptor' value :occurs
type = :input_type , length = :input_len , data = :input_buffer;
}
} void process_output(void)
{
int i; // 定义宿主变量
EXEC SQL BEGIN DECLARE SECTION ;
int output_count;
int output_type;
int output_len;
char output_buffer[MAX_VAR_LEN];
short output_indicator;
char name[MAX_NAME_LEN];
int occurs;
EXEC SQL END DECLARE SECTION ; // 选择列表项->输出描述区
exec sql describe output s using descriptor 'output_descriptor'; //取得选择列表项个数
exec sql get descriptor 'output_descriptor' :output_count = count; //循环处理选择列表项(即列名,或者叫表头) output_type = ; //设置类型为变长字符串varchar for(i = ; i != output_count ; ++i)
{
occurs = i + ; output_len = MAX_VAR_LEN; // 设置选择列表项的类型和长度(设置每一列,按照varchar类型进行显示)
exec sql set descriptor 'output_descriptor' value :occurs
type = :output_type , length = :output_len; //取得选择列表项的名称并输出
exec sql get descriptor 'output_descriptor' value :occurs :name = name; //显示选择列表项名称
printf("\t%s" , name);
}
printf("\n"); // 提取数据完毕->退出循环
exec sql whenever not found do break; // 循环处理选择列表项数据
for( ; ; )
{
// 行数据-> fetch into 利用游标从输出描述区读取数据。
exec sql fetch c into descriptor 'output_descriptor'; // 循环处理每列数据
for(i = ; i < output_count ; ++i)
{
occurs = i + ; // 取得列数据和指示变量值
exec sql get descriptor 'output_descriptor' VALUE :occurs
:output_buffer = DATA , :output_indicator = INDICATOR; //输出列数据
if(- == output_indicator)
printf("\t%s", " ");
else
printf("\t%s" , output_buffer);
}
printf("\n");
}
} void connet(void)
{
int ret = ;
//连接数据库
EXEC SQL CONNECT:usrname IDENTIFIED BY:passwd USING:serverid ;
if (sqlca.sqlcode != )
{
ret = sqlca.sqlcode;
printf("sqlca.sqlcode: err:%d \n", sqlca.sqlcode);
return ;
} else {
printf("connect ok...\n");
}
}

1.ASNI 与 ORACLE 实现动态sql的最大区别就在于不用关心描述区的动态扩容,因为ASNI已经封装好了接口,直接调用就成。

2.也是主要分为两部分:输出描述区和输入描述区。两个区的作用同ORACLE 功能一样。

* 分配输入描述区和输出描述区
* Ansi 定义了该套标准,proc 程序开发者按标准实现了它
* 这两条语句在 proc 编译的时候会开辟对应大小的存储空间
*/
exec sql allocate descriptor 'input_descriptor'; //用来存储输入的宿主变量
exec sql allocate descriptor 'output_descriptor'; //用来缓存数据库端返回的结果集

ANSI实现动态 sql的更多相关文章

  1. 值得注意的ibatis动态sql语法格式

    一.Ibatis常用动态sql语法,简单粗暴用一例子 <select id="iBatisSelectList" parameterClass="java.util ...

  2. Mysql - 游标/动态sql/事务

    游标这个在我目前的项目里面用的还不多, 但是其功能还是很强大的. 动态sql以前都没用过, 是跟着富士康(不是张全蛋的富土康哦)过来的同事学的. 还是挺好用的. 我的数据库方面, 跟他学了不少. 在此 ...

  3. MyBatis4:动态SQL

    什么是动态SQL MyBatis的一个强大特性之一通常是它的动态SQL能力.如果你有使用JDBC或其他相似框架的经验,你就明白条件串联SQL字符串在一起是多么地痛苦,确保不能忘了空格或者在列表的最后的 ...

  4. 分享公司DAO层动态SQL的一些封装

    主题 公司在DAO层使用的框架是Spring Data JPA,这个框架很好用,基本不需要自己写SQL或者HQL就能完成大部分事情,但是偶尔有一些复杂的查询还是需要自己手写原生的Native SQL或 ...

  5. MySQL存储过程动态SQL语句的生成

    用Mysql存储过程来完成动态SQL语句,使用存储过程有很好的执行效率: 现在有要求如下:根据输入的年份.国家.节假日类型查询一个节假日,我们可以使用一般的SQL语句嵌入到Java代码中,但是执行效率 ...

  6. 【Java EE 学习 79 下】【动态SQL】【mybatis和spring的整合】

    一.动态SQL 什么是动态SQL,就是在不同的条件下,sql语句不相同的意思,曾经在“酒店会员管理系统”中写过大量的多条件查询,那是在SSH的环境中,所以只能在代码中进行判断,以下是其中一个多条件查询 ...

  7. 自定义函数执行动态sql语句

    --函数中不能调用动态SQL,使用用存储过程吧.如果还要对函数做其他操作,换成存储过程不方便,可以考虑把其他操作一起封装在存储过程里面.如:   create proc [dbo].[FUN_YSCL ...

  8. mybatis入门基础(五)----动态SQL

    一:动态SQL 1.1.定义 mybatis核心对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装. 1.2.案例需求 用户信息综合查询列表这个statement的定义使用动态s ...

  9. mybatis 动态sql表达式相关应用

    一.mybatis 表达式简介 对于mybatis3 ,提供了一种动态sql的方式.通过动态sql我们可以直接在mybatis 的xm映射文件中直接通过条件判断的方式进行查询添加的拼接.mybatis ...

随机推荐

  1. 20162325金立清 实验四 Android程序设计 实验报告

    实验四 Android程序设计 实验报告 代码托管地址 码云链接 实验内容 安装使用Android Stuidio Activity测试 UI测试 布局测试 事件处理测试 Android程序设计-1 ...

  2. 原生js操作HTML DOM

    先上图 1.一些常用的方法 obj.getElementById() 返回带有指定 ID 的元素. obj.getElementsByTagName() 返回包含带有指定标签名称的所有元素的节点列表( ...

  3. Android Studio导入第三方库的三种方法

    叨叨在前 今天在项目中使用一个图片选择器的第三方框架——GalleryFinal,想要导入源码,以便于修改,于是上完查找了一下方法,想到之前用到过其他导入第三方库的方法,现在做个小总结,以防忘记. A ...

  4. 【mybatis】mybatis中放置IN查询拼接sql过长,IN查询进行分批次查询的处理

    需要使用的切割list集合的工具类,链接:https://www.cnblogs.com/sxdcgaq8080/p/9376947.html 处理逻辑,原本的一个LIst,进行切割,循环进行myba ...

  5. JS跳转页面的几种方法

    JS的几种跳转方式: 1. window.open(”url“) 2.用自定义函数 <script> function openWin(tag,obj) { obj.target=&quo ...

  6. linux如何修改登录用户密码

    root登录后,passwd root可以修改root帐号的密码 其他具有sudo权限的用户登录后,sudo passwd root可以修改根帐号的密码 sudo passwd admin可以修改ad ...

  7. 如何判断两个IP是否在同一网段

    下来举例说明,如何去判断A和B两个IP是否在同一网段. A IP:202.194.128.9 B IP:202.194.128.14 子网掩码:255.255.255.0 1.把A和B的地址转换为二进 ...

  8. scrapy爬虫框架实例二

    本实例主要通过抓取慕课网的课程信息来展示scrapy框架抓取数据的过程. 1.抓取网站情况介绍 抓取网站:http://www.imooc.com/course/list 抓取内容:要抓取的内容是全部 ...

  9. http_load压力测试使用

    介绍:http_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载.但是它不同于大多数压力测试工具,它可以以一个单一的进程运行,一般不会把客户机搞死.还可以测试HTTPS类的网站请求. ...

  10. WIN7如何查找网络打印机

    1 在开始菜单中输入"打印机"并点击"添加打印机" 2 点击下面一个,并搜索家庭组的打印机,一般可以搜到(注意这台电脑不能关机或睡眠). 3 查找并添加会需要安 ...