📄 esqlc方面的资料.txt
字号:
CS_CHAR publisher[5];
exec sql end declare section;
...
exec sql delete from titles where title_id = :id;
exec sql update titles set pub_id = :publisher
where title_id = :id;
另外,也可以通过宿主变量获得存储过程的执行状态信息。如:
exec sql begin declare section;
CS_SMALLINT retcode;
exec sql end declare section;
exec sql begin transaction;
exec sql exec :retcode = update_proc;
if (retcode != 0)
{
exec sql rollback transaction;
也可以通过宿主变量获得存储过程的返回值。如:
exec sql exec a_proc :par1 out, :par2 out;
2)、主变量的数据类型
SYBASE SQL SERVER支持的数据类型与程序设计语言支持的数据类型之间有很大差别。这些差别对主变量影响很大。一方面,主变量是一个用程序设计语言的数据类型说明并用程序设计语言处理的程序变量;另一方面,在嵌入SQL语句中用主变量保存数据库数据。所以,在嵌入SQL语句中,必须映射C数据类型为合适的SQL Server数据类型。必须慎重选择主变量的数据类型。在SQL SERVER中,预编译器能够自动转换兼容的数据类型。请看下面这个例子:
EXEC SQL BEGIN DECLARE SECTION;
int hostvar1 = 39;
char *hostvar2 = "telescope";
float hostvar3 = 355.95;
EXEC SQL END DECLARE SECTION;
EXEC SQL UPDATE inventory
SET department = :hostvar1
WHERE part_num = "4572-3";
EXEC SQL UPDATE inventory
SET prod_descrip = :hostvar2
WHERE part_num = "4572-3";
EXEC SQL UPDATE inventory
SET price = :hostvar3
WHERE part_num = "4572-3";
在第一个update语句中,department列为smallint数据类型(integer ),所以应该把hostvar1定义为int数据类型(integer)。这样的话,从C到SQL Server的hostvar1可以直接映射。在第二个update语句中,prod_descip列为varchar数据类型,所以应该把hostvar2定义为字符数组。这样的话,从C到SQL Server的hostvar2可以从字符数组映射为varchar数据类型。在第三个update语句中,price列为money数据类型。在C语言中,没有相应的数据类型,所以用户可以把hostvar3定义为C的浮点变量或字符数据类型。SQL Server可以自动将浮点变量转换为money数据类型(输入数据),或将money数据类型转换为浮点变量(输出数据)。
注意的是,如果数据类型为字符数组,那么SQL Server会在数据后面填充空格,直到填满该变量的声明长度(CS_CHAR数据类型除外)。
下表列出了C的数据类型和SQL SERVER数据类型的一些兼容关系:
可兼容的C数据类型分配的SQL Server数据类型SYBASE提供的数据类型描述
shortSmallintCS_SMALLINT2字节整数
IntSmallintCS_SMALLINT2字节整数
LongIntCS_INT4字节整数
FloatRealCS_REAL4字节浮点数
DoubleFloatCS_FLOAT8字节浮点数
CharCarchar[X]VARCHARCS_CHAR字符数据类型
Unsigned charBinaryVarbinaryCS_BINARYBinary数据类型
Unsigned char tinyintCS_TINYINT1字节整数
无DatetimeCS_DATETIME8字节datetime类型
无SmalldatetimeCS_DATETIME44字节datetime类型
无DecimalCS_DECIMALDecimal数据类型
无numericCS_NUMERICNumeric数据类型
无MoneyCS_MONEY8字节money类型
无smallmoneyCS_MONEY44字节money类型
Unsigned char TextCS_TEXT文本数据类型
Unsigned char imageCS_IMAGE图象数据类型
无booleanCS_BITBit数据类型
因为C没有date或time数据类型,所以SQL Server的date或time列将被转换为字符。缺省情况下,使用以下转换格式:mm dd yyyy hh:mm:ss[am | pm]。你也可以使用字符数据格式将C的字符数据存放到SQL Server的date列上。你也可以使用Transact-SQL中的convert语句来转换数据类型。如:SELECT CONVERT(char, date, 8) FROM sales。
下表是从SQL SERVER数据类型到C的数据类型的转换关系:
SQL SERVER 数据类型C数据类型
CS_TINYINTCS_SMALLINTCS_INTCS_REALCS_CHARCS_MONEYCS_DATETIME
char可以可以可以可以可以可以可以
varchar可以可以可以可以可以可以可以
bit可以可以可以可以可以可以
binary可以可以可以可以可以可以
tinyint可以可以可以可以可以可以
smallint可以可以可以可以可以可以
int可以可以可以可以可以可以
float可以可以可以可以可以可以
money可以可以可以可以可以可以
datetime可以可以
decimal可以可以可以可以可以可以
numeric可以可以可以可以可以可以
下表是从C的数据类型到SQL SERVER数据类型的转换关系:
C数据类型SQL SERVER数据类型
tinyintbitsmallintintfloatcharmoneydatetimedecimalnumeric
Unsigned char可以可以可以可以可以需要自己转换可以可以可以
Short int可以可以可以可以可以需要自己转换可以可以可以
Long int可以可以可以可以可以需要自己转换可以可以可以
Double float可以可以可以可以可以需要自己转换可以可以可以
Char需要自己转换需要自己转换需要自己转换需要自己转换需要自己转换可以需要自己转换可以需要自己转换需要自己转换
money可以可以可以可以可以可以可以可以可以
datetime需要自己转换可以
3)、主变量和NULL
大多数程序设计语言(如C)都不支持NULL。所以对NULL的处理,一定要在SQL中完成。我们可以使用主机指示符变量(host indicator variable)来解决这个问题。在嵌入式SQL语句中,主变量和指示符变量共同规定一个单独的SQL类型值。如:
EXEC SQL SELECT price INTO :price :price_nullflag FROM titles
WHERE au_id = "mc3026"
其中,price是主变量,price_nullflag是指示符变量。
使用指示符变量的语法为:: host_variable [[indicator] : indicator_variable]。其中,indicator可以不写。针对宿主变量是输出宿主变量,还是输入宿主变量。指示符变量共分两种情况。
情况1:同输出宿主变量一起使用,则indicator_varibale为:
l-1。表示相应列值为NULL。表示主变量应该假设为NULL。(注意:宿主变量的实际值是一个无关值,不予考虑)。
l0。表示非NULL值。该变量存放了非NULL的列值。
l>0。表示宿主变量包含了列值的截断值。该指示变量存放了该列值的实际长度。
下面是一个同输出宿主变量一起使用的指示变量的例子:
exec sql begin declare section;
CS_CHAR id[6];
CS_SMALLINT indic;
CS_CHAR pub_name[41];
exec sql end declare section;
exec sql select pub_id into :id indicator :indic
from titles where title
like "%Stress%";
if (indic == -1)
{
printf("\npub_id is null");
}
else
{
exec sql select pub_name into :pub_name
from publishers where pub_id = :id;
printf("\nPublisher: %s", pub_name);
情况2:同输入宿主变量一起使用,则indicator_varibale为:
l-1。表示主变量应该假设为NULL。(注意:宿主变量的实际值是一个无关值,不予考虑)。应该将NULL赋值给相应列。
l0。表示非NULL值。该变量存放了非NULL值。应该将宿主变量的值赋值给相应列。
对于以下语句:
EXEC SQL SELECT price INTO :price :price_nullflag FROM titles
WHERE au_id = "mc3026"
如果不存在mc3026写的书,那么price_nullflag为-1,表示price为NULL;如果存在,则price为实际的价格。下面我们再看一个update的例子:
EXEC SQL UPDATE closeoutsale
SET temp_price = :saleprice :saleprice_null, listprice = :oldprice;
如果saleprice_null是-1,则上述语句等价为:
EXEC SQL UPDATE closeoutsale
SET temp_price = null, listprice = :oldprice;
我们也可以在指示符变量前面加上“INDICATOR”关键字,表示后面的变量为指示符变量。如:
EXEC SQL UPDATE closeoutsale
SET temp_price = :saleprice INDICATOR :saleprice_null;
指示符变量也是宿主变量,定义指示符变量同定义宿主变量一样。它应该是一个2个字节的整数(short或CS_SMALLINT)。
2.3.2 连接数据库
在程序中,使用CONNECT语句来连接数据库。该语句的完整语法为:
exec sql connect : user [identified by : password]
[at : connection_name] [using : server]
[labelname labelname labelvalue labelvalue...] 其中,
lserver为服务器名。如省略,则为本地服务器名。
lconnection_name为连接名。可省略。如果你仅仅使用一个连接,那么无需指定连接名。可以使用SET CONNECTION来使用不同的连接。
luser为登录名。
lpassword为密码。
如:使用my_id用户和passes密码连接到SYBASE服务器。
exec sql begin declare section;
CS_CHAR user[16];
CS_CHAR passwd[16];
CS_CHAR server[BUFSIZ];
exec sql end declare section;
strcpy(server,"SYBASE");
strcpy(passwd,"passes");
strcpy(user, "my_id");
exec sql connect :user identified by :passwd using
:server;
请看下面这些例子来理解连接名的使用方法。
...
exec sql begin declare section;
CS_CHAR user[16];
CS_CHAR passwd[16];
CS_CHAR name;
CS_INT value, test;
CS_CHAR server_1[BUFSIZ];
CS_CHAR server_2[BUFSIZ];
exec sql end declare section;
...
strcpy (server_1, "sybase1");
strcpy (server_2, "sybase2");
strcpy(user, "my_id");
strcpy(passwd, "mypass");
exec sql connect :user identified by :passwd
at connection_2 using :server_2;
exec sql connect :user identified by :passwd using
:server_1;
/* 下面这个语句使用了"server_1"的连接*/
exec sql select royalty into :value from authors
where author = :name;
if (value == test)
{
/* 下面这个语句使用了"connection_2"连接 */
exec sql at connection_2 update authors
set column = :value*2
where author = :name;
在嵌入SQL语句中,使用DISCONNECT语句断开数据库的连接。其语法为:
DISCONNECT [connection_name | ALL | CURRENT]
其中,connection_name为连接名。ALL表示断开所有的连接。CURRENT表示断开当前连接。断开连接会回滚当前事务、删除临时表、关闭游标和释放锁等。
2.3.3 数据的查询和修改
可以使用SELECT INTO语句查询数据,并将数据存放在主变量中。如:查询lastname为stringer的firstname信息。
EXEC SQL SELECT au_fname INTO :first_name
from authors where au_lname = "stringer";
使用DELETE语句删除数据。其语法类似于Transact-SQL中的DELETE语法。如:
EXEC SQL DELETE FROM authors WHERE au_lname = 'White'
使用UPDATE语句可以更新数据。其语法类似Transact-SQL中的UPDATE语法。如:
` EXEC SQL UPDATE authors SET au_fname = 'Fred' WHERE au_lname = 'White'
使用INSERT语句可以插入新数据。其语法就是Transact-SQL中的INSERT语法。如:
EXEC SQL INSERT INTO homesales (seller_name, sale_price)
real_estate('Jane Doe', 180000.00);
多行数据的查询和修改请参见下一节——游标。
2.3.4 游标的使用
用嵌入式SQL语句查询数据分成两类情况。一类是单行结果,一类是多行结果。对于单行结果,可以使用SELECT INTO语句;对于多行结果,你必须使用cursor(游标)来完成。游标(Cursor)是一个与SELECT语句相关联的符号名,它使用户可逐行访问由SQL Server返回的结果集。先请看下面这个例子,这个例子的作用是逐行打印staff表的id、name、dept、 job、years、salary和comm的值。
………..
EXEC SQL DECLARE C1 CURSOR FOR
SELECT id, name, dept, job, years, salary, comm FROM staff;
EXEC SQL OPEN c1;
while (SQLCODE == 0)
{
/* SQLCODE will be zero if data is successfully fetched */
EXEC SQL FETCH c1 INTO :id, :name, :dept, :job, :years, :salary, :comm;
if (SQLCODE == 0)
printf("%4d %12s %10d %10s %2d %8d %8d",
id, name, dept, job, years, salary, comm);
}
EXEC SQL CLOSE c1;
………
从上例看出,你首先应该定义游标结果集,即定义该游标的SELECT语句返回的行的集合。然后,使用FETCH语句逐行处理。
值得注意的是,嵌入SQL语句中的游标定义选项同Transact-SQL 中的游标定义选项有些不同。必须遵循嵌入SQL语句中的游标定义选项。
1)、声明游标:
如:EXEC SQL DECLARE C1 CURSOR FOR
SELECT id, name, dept, job, years, salary, comm FROM staff;
其中,C1是游标的名称。
2)、打开游标
如:EXEC SQL OPEN c1;
完整语法为:EXEC SQL OPEN 游标名 [USING 主变量名 | DESCRIPTOR 描述名]。关于动态OPEN游标的描述见第四节。
3)、取一行值
如:EXEC SQL FETCH c1 INTO :id, :name, :dept, :job, :years, :salary, :comm;
关于动态FETCH语句见第四小节。
4)、关闭游标
如:EXEC SQL CLOSE c1;
关闭游标的同时,会释放由游标添加的锁和放弃未处理的数据。在关闭游标前,该游标必须已经声明和打开。另外,程序终止时,系统会自动关闭所有打开的游标。
也可以使用UPDATE语句和DELETE语句来更新或删除由游标选择的当前行。使用DELETE语句删除当前游标所在的行数据的具体语法如下:
DELETE [FROM] {table_name | view_name} WHERE CURRENT OF cursor_name
其中,
ltable_name是表名,该表必须是DECLARE CURSOR中SELECT语句中的表。
lview_name是视图名,该视图必须是DECLARE CURSOR中SELECT语句中的视图。
lcursor_name是游标名。
请看下面这个例子,逐行显示firstname和lastname,询问用户是否删除该信息,如果回答“是”,那么删除当前行的数据。
EXEC SQL DECLARE c1 CURSOR FOR
SELECT au_fname, au_lname FROM authors ;
EXEC SQL OPEN c1;
while (SQLCODE == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -