Exec sql/c

利用高级语言的过程性结构来弥补SQL语言实现复杂应用方面的不足。

嵌入SQL的高级语言称为主语言或宿主语言。

在混合编程中,SQL语句负责操作数据库,高级语言语句负责控制程序流程。

预编译方法:由DBMS的预处理程序对源程序扫描,识别出SQL语句,把它们转换成主语言调用语句,以使主语言编译器能识别它,最后由主语言编译器将整个源程序编译成目标码。

☆嵌入式SQL的一般形式

所有的嵌入式SQL语句都必须加前缀EXEC SQL

在C语言中:  EXEC SQL <SQL语句>

例如:EXEC SQL DROP TABLE Student;

☆嵌入式SQL与主语言的通信

向主语言传递SQL语句执行状态信息,使语言能够据此信息控制程序流程,用SQL通信区(SQLCA【SQL Communication Area】)实现。

主语言向SQL语句提供参数,主要用主变量(Host Variable)实现;

将SQL语句查询数据库的结果交主语言进一步处理,主要用主变量和游标(Cursor)实现。

☆SQL通信区

SQLCA中有一个存放每次执行SQL语句后返回代码的变量SQLCODE。

每次执行完SQL语句后都应该测试一下SQLCODE的值,以了解该SQL语句执行情况并做相应处理,如果SQLCODE等于预定的常量SUCCESS,则表示SQL语句成功,否则在SQLCODE中存放错误代码。

SQLCA(SQL Communication Access) 系由系统提供之系统记录架构,作为back end与 front end 之间沟通之用,当发生 I/O 状态时,系统会记录该状态于SQLCA 中,front end 即可依据其其内容得知 I/O 运作是否成功,再决定往后执行的步骤。SQLCA 为系统定义之 GLOBAL变量,以下为其架构并介绍其内容与用途:

DEFINE SQLCA RECORD

SQLCODE     INTEGER,

SQLERRM     CHAR(71),

SQLERRP     CHAR(8),

SQLERRD     ARRAY[6] OF INTEGER,

SQLAWARN    CHAR(8)

END RECORD

.SQLCODE :表示 I/O 的结果

0    表示 I/O 成功

100 表示 NOTFOUND

< 0 表示 I/O 失败

.SQLERRM :保留未用

.SQLERRP :保留未用

.SQLERRD :为一个含有6个INTEGER数组

SQLERRD[1]:保留未用

SQLERRD[2]:新增时 SERIAL 字段所传回之值

SQLERRD[3]:处理资料的笔数

SQLERRD[4]:查询时预估的 CPU COST

SQLERRD[5]:SQL指令之错误位移

SQLERRD[6]:最后一个 ROWID 值

.SQLAWARN :为一个含有8个字符的字符串,以记录I/O时产生的警告讯息。若正确无误,则相对应之字符设定为空白,否则会被设定为"W"。

SQLAWARN[1]:若第2至第8字符中任意一个被设成"W",则此字符亦为"W",否则为空白。

SQLAWARN[2]:若资料太长而被截掉时,会被设成 "W"。

SQLAWARN[3]:若 aggregate function(如 SUM,AVG,MAX,MIN) 处理时遇到 NULL 值,则会被设成"W"。

SQLAWARN[4]:若查询时,若欲查询的字段数目和 INTO 之变量数目不合时,会被设成 "W"。

SQLAWARN[5]:如转换 float 成 integer 时,则会被设成 "W"。

SQLAWARN[6]:保留未用

SQLAWARN[7]:保留未用

SQLAWARN[8]:保留未用

☆主变量

一个主变量既可是输入主变量也可是输出主变量。

主变量必须在SQL语句EXEC SQL BEGIN DECLARE SECTION与EXEC SQL END DECLARE SECTION之间进行说明。

例如:

EXEC SQL BEGIN DECLARE SECTION;

int     i=0;

EXEC SQL END DECLARE SECTION;

SQL语句的主变量名前要加冒号作为标志。

在SQL语句之外,主变量直接引用,不须加冒号。

☆使用游标查询

EXEC SQL DECLARE cur CURSOR FOR select name,sex from student where no like :no;//定义游标

EXEC SQL OPEN cur;//打开游标

for(;;){

EXEC SQL fetch cur into :name,:sex;//推进游标

if(sqlca.sqlcode==100)//没有满足条件的数据

break;

//操作数据

}

EXEC SQL close cur;//关闭游标

EXEC SQL free   cur;//释放游标

☆使用事务

事务的三个常用操作:开始事务(BEGIN WORK),提交事务(COMMIT WORK),回滚(ROLLBACK WORK),

例如:

EXEC   SQL  BEGIN WORK;

……//数据库操作

if(sqlca.sqlcode<0)

EXEC   SQL ROLLBACK  WORK;

else

EXEC   SQL COMMIT  WORK;

☆CURRENT形式的UPDATE语句和DELETE语句

UPDATE和DELETE语句都是集合操作,如果只想修改或删除其中的某个记录,则需要用带游标的SELECT语句查出所有满足条件记录,从中进一步找出要修改或删除的记录,然后用CURRENT形式的UPDATE和DELETE语句处理。

用DELCARE语句说明游标。如果是为CURRENT形式的UPDATE语句作准备,则SELECT语句中要用 FOR UPDATE OF<列名>用来指明查询出的数据在指定列是可修改的。如果是为CURRENT形式的DELETE语句作准备,则不必使用上述子句。

检查该记录是否为该修改或删除的记录。如果是,则修改或删除之。这时UPDATE和DELETE语句中要用子句   WHERE CURRENT OF<游标名>,表示修改或删除的是最近一次取出的记录,即游标指针指向的记录。

例如:

char yn;

EXEC SQL BEGIN DELCARE SECTION;

char Sno[20],Sname[20],NEWSname[20];

EXEC SQL END DECLARE SECTION;

EXEC SQL DECLARE cur CURSOR FOR SELECT Sno, Sname FROM Student WHERE Sno like '01%' FOR UPDATE OF Sname;

EXEC SQL OPEN cur

while(1) { /*用循环结构逐条处理结果集中的记录*/

EXEC SQL FETCH cur INTO :Sno,:Sname;

if(sqlca.sqlcode==100)

break;                /*若查询结果处理完或出现错误,则退出循环*/

printf("no=%s,name=%s",Sno,Sname);

printf("UPDATE Name(y/n)?");         /*问用户是否需要修改*/

scanf("%c", &yn);

if(yn='y' or yn='Y')                      /*需要修改*/

{

printf("INPUT NEW Name:");

scanf("%d",&NEWSname);

EXEC SQL UPDATE Student SET Sname = :NEWSname WHERE CURRENT OF cur;

};

};

EXEC SQL CLOSE cur;

☆数据类型

1、SQL与C数据类型的对应简单类型

SQL         C

CHAR(n)        char(n+1)

CHARCTER(n)    char *

SMALLINT    short

INTERGER    int

SMALLFLOAT    float

FLOAT/DOUBLE    double

SERIAL        long int

DATE         long int

VARCHAR        string

2、数据类型转换

转换类型      转换后

FLOAT         DECIMAL(16)

SMALLFLOAT     DECIMAL(8)

INTERGER     DECIMAL(10,0)

SAMLLINT     DECIMAL(5,0)

☆有关CHAR类型的函数

1、以空值结尾的串的操作函数

rdownshift(char *s)         把一个字符串中的所有字母转换成小写形式。

rupshift(char *s)         把一个字符串中的所有字母转换成大写形式。

stcat(char *s, char *dest)     把一个字符串同另一个字符串相连接。

stcmpr(char *s1, char *s2)     比较两个字符串。

stcopy(char *from, char *to)     把一个字符串拷贝到另一个字符串。

stleng(char *string)     统计字符串的长度。

2、定长串的操作函数

bycmpr(char byte1, byte2, rpt len)     比较两组连续的字节内存块。

bycopy(char *from, char *to, int len)     把一块内存的内容拷贝到另一块内存。

byfill(char *to, int len, char ch)     用字符填充指定的内存块。

byleng(char from, int count)     统计有效字符的数目。有效字符是指字符串去除了末尾空格所剩的字符。

3、字符串操作函数

ldchar(char *from, int num, char *to)     拷贝定长串到空值结尾的串。

stchar(char *from, char *to, int num)     拷贝空值结尾的串到定长串。

4、字符串函数简单数值转换

rstod(char *str, double *dblval)     把以空值结束的字符串转换成C的double型

rstoi(char *str, int *intval)     把以空值结束的字符串转换成C的int类型。

rstol(char *str, long *lngval)     把以空值结束的字符串转换成C的long类型。

-----------------------------------------------------------------------------------------------------

1 :普通SQL语句可以用exec执行

Select * from tableName

exec('select * from tableName')

exec sp_executesql N'select * from tableName' -- 请注意字符串前一定要加N

2:字段名,表名,数据库名之类作为变量时,必须用动态SQL

declare @fname varchar(20)

set @fname = 'FiledName'

--Select @fname from tableName -- 错误,不会提示错误,但结果为固定值FiledName,并非所要。

exec('select ' + @fname + ' from tableName') -- 请注意 加号前后的 单引号的边上加空格

--当然将字符串改成变量的形式也可

declare @fname varchar(20)

set @fname = 'FiledName' --设置字段名

declare @s varchar(1000)

set @s = 'select ' + @fname + ' from tableName'

exec(@s) -- 成功

--exec sp_executesql @s -- 此句会报错

declare @s Nvarchar(1000) -- 注意此处改为nvarchar(1000) (必须为ntext或nchar哐nvarchar类型,不能是varchar类型)

set @s = 'select ' + @fname + ' from tableName'

exec(@s) -- 成功

exec sp_executesql @s -- 此句正确

3. 输入或输出参数

--(1)输入参数:

declare @QueryString nvarchar(1000) --动态查询语句变量(注:必须为ntext或nchar哐nvarchar类型,不能是varchar类型)

declare @paramstring nvarchar(200) --设置动态语句中的参数的字符串(注:必须为ntext或nchar哐nvarchar类型,不能是varchar类型)

declare @input_id int--定义需传入动态语句的参数的值

set @QueryString='select * from tablename  where id=@id'  --id为字段名,@id为要传入的参数

set @paramstring='@id int' --设置动态语句中参数的定义的字符串

set @input_id =1  --设置需传入动态语句的参数的值为1

exec sp_executesql @querystring,@paramstring,@id=@input_id  

--若有多个参数:

declare @QueryString nvarchar(1000) --动态查询语句变量(注:必须为ntext或nchar哐nvarchar类型,不能是varchar类型)

declare @paramstring nvarchar(200) --设置动态语句中的参数的字符串(注:必须为ntext或nchar哐nvarchar类型,不能是varchar类型)

declare @input_id int--定义需传入动态语句的参数的值,参数1

declare @input_name varchar(20)--定义需传入动态语句的参数的值,参数2

set @QueryString='select * from tablename  where id=@id and name=@name'   --id与name为字段名,@id与@name为要传入的参数

set @paramstring='@id int,@name varchar(20)' --设置动态语句中参数的定义的字符串,多个参数用","隔开

set @input_id =1  --设置需传入动态语句的参数的值为1

set @input_name='张三'   --设置需传入动态语句的参数的值为"张三"

exec sp_executesql @querystring,@paramstring,@id=@input_id,@name=@input_name --请注意参数的顺序

--(2)输出参数

declare @num int, @sqls nvarchar(4000)

set @sqls='select count(*) from tableName'

exec(@sqls)

--如何将exec执行结果放入变量中?

declare @QueryString nvarchar(1000) --动态查询语名变量(注:必须为ntext或nchar哐nvarchar类型,不能是varchar类型)

declare @paramstring nvarchar(200) --设置动态语句中的参数的字符串(注:必须为ntext或nchar哐nvarchar类型,不能是varchar类型)

declare @output_result int--查询结果赋给@output_result

set @QueryString='select @totalcount=count(*) from tablename' --@totalcount 为输出结果参数

set @paramstring='@totalcount int output' --设置动态语句中参数的定义的字符串,多个参数用","隔开

exec sp_executesql @querystring,@paramstring,@totalcount=@output_result output

select @output_result

--当然,输入与输出参数可以一起使用,大家可以自己去试一试。

--另外,动态语句查询的结果集要输出的话,我只想到以下用临时表的方法,不知各位有没有更好的方法.

IF object_id('[tempdb].[dbo].#tmp') IS NOT NULL --判断临时表#tmp是否存在,存在则删除

drop table #tmp

select * into #tmp from tablename where 1=2 --创建临时表#tmp,其结构与tablename相同

declare @QueryString nvarchar(1000) --动态查询语名变量(注:必须为ntext或nchar哐nvarchar类型,不能是varchar类型)

set @QueryString='select * from tablename '

insert into #tmp(field1,field2,) exec(@querystirng)

Exec sql/c的更多相关文章

  1. Oracle的 EXEC SQL CONTEXT学习

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL杂记页     回到顶级页面:PostgreSQL索引页 [作者 高健@博客园  luckyjackgao@gmail. ...

  2. SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别

    SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别 MSSQL为我们提供了两种动态执行SQL语句的命令,分别是 EXEC 和 SP_EXECUTESQL ,我们先来看一下两种方 ...

  3. 动态sql语句基本语法--Exec与Exec sp_executesql 的区别

    http://www.cnblogs.com/goody9807/archive/2010/10/19/1855697.html 动态sql语句基本语法 1   :普通SQL语句可以用Exec执行   ...

  4. 普通SQL语句可以用Exec执行

    例如存储过名为:myprocedure use AdventureWorks create procedure myprocedure @city varchar(20) as begin selec ...

  5. sql存储过程exec执行字符串select 的区别

    USE [GuangHong]GO/****** Object: StoredProcedure [dbo].[st_MES_SelInspctDetail] Script Date: 11/23/2 ...

  6. 动态SQL的执行,注:exec sp_executesql 其实可以实现参数查询和输出参数的

    本文转自:http://www.cnblogs.com/hnsdwhl/archive/2011/07/23/2114730.html 当需要根据外部输入的参数来决定要执行的SQL语句时,常常需要动态 ...

  7. SQL Server-聚焦sp_executesql执行动态SQL查询性能真的比exec好?

    前言 之前我们已经讨论过动态SQL查询呢?这里为何再来探讨一番呢?因为其中还是存在一定问题,如标题所言,很多面试题也好或者有些博客也好都在说在执行动态SQL查询时sp_executesql的性能比ex ...

  8. 使用exec和sp_executesql动态执行SQL语句(转载)

    当需要根据外部输入的参数来决定要执行的SQL语句时,常常需要动态来构造SQL查询语句,个人觉得用得比较多的地方就是分页存储过程和执行搜索查询的SQL语句.一个比较通用的分页存储过程,可能需要传入表名, ...

  9. Sql语句拼接(EXEC和sp_executesql的区别)

    1.前言 MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最 ...

随机推荐

  1. jQuery实现逐字输入效果

    之前做了个测试小游戏(姑且叫游戏吧)为了增加神秘性,就想给她加个逐字输入效果:刚好在网上找到一个挺好用的,于是就发扬拿来主义:按照自己的喜好做了一丢丢的修改(勉强算是吧\( ̄︶ ̄)> ). 代码 ...

  2. IPTV小窗口播放视频 页面焦点无法移动的解决方法

    在IPTV高清页面中,小窗口播放视频时,在某些机顶盒上(如高清中兴.高清大亚4904)会出现焦点无法移动现象,即按键无响应.被这个bug困扰了很久,虽然我知道解决方法,但只知其然,不知其所以然.今天做 ...

  3. asp.net mvc4中model与Model的区别

    @model模型定义 使用@model关键字可以定义一个Action里所对应的一个模型(经常可以叫他实体类), 其实是对动态变量进行实例化,这样就可以直接在cshtml文件中调用“Model”变量. ...

  4. 数据结构-B树

      1.前言: 动态查找树主要有:二叉查找树(Binary Search Tree),平衡二叉查找树(Balanced Binary Search Tree),红黑树(Red-Black Tree ) ...

  5. sshd服务---暴力破解应对策略

    sshd服务暴力破解步骤 sshd暴力破解方法 防止暴力破解调优 1. 变更默认端口 2. 变更root用户 3. 日志监控-->防止暴力破解(fail2ban应用) fail2ban详解 在初 ...

  6. POJ——放苹果

    4:放苹果 查看 提交 统计 提问 总时间限制:  1000ms  内存限制:  65536kB 描述 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示) ...

  7. LOL是什么意思? - 已解决 - 搜狗问问

    LOL是什么意思? - 已解决 - 搜狗问问 N A T S U . |分类:QQ工具栏 2009-05-04 LOL是什么意思? 满意答案 Shim Nyong 19级 2009-05-04 LOL ...

  8. [置顶] hdu4747 Mex 线段树

    题意:给你一个序列,让你求出对于所有区间<i, j>的mex和,mex表示该区间没有出现过的最小的整数. 思路:从时限和点数就可以看出是线段树,并且我们可以枚举左端点i, 然后求出所有左端 ...

  9. php 多维数组 arrayList array()

    <pre name="code" class="php">$params=array( "tid"=>"3&qu ...

  10. magento中的各种form标签

    1. Text Field    $fieldset->addField('title', 'text', array(          'label'     => Mage::hel ...