欢迎来到千学网!
您现在的位置:首页 > 实用文 > 其他范文

告诉你使用SQL Server 的3个理由数据库教程

时间:2022-05-24 00:24:16 其他范文 收藏本文 下载本文

【导语】下面是小编整理的告诉你使用SQL Server 的3个理由数据库教程(共9篇),欢迎大家阅读分享借鉴,希望对大家有所帮助。

告诉你使用SQL Server 的3个理由数据库教程

篇1:告诉你使用SQL Server 的3个理由数据库教程

1:使用分区表来提高数据库性能

以前的处理大数据量时很多人会采取使用多个结构相同的表按时间段来分,不同时间的数据存在不同的数据表里,这样如果只查询一个表的数据就很快,如果需要跨表查询则再通过连接视图将这些表连起来伪装成一个表的样子,这样可以提高查询效率,但牺牲了程序设计的优雅性和数据库设计的简单性,特别是在处理关系、约束、数据完整性时会非常的繁琐复杂,

升级到sql2005可以采用分区表(partition table)来处理这种需求,我们可以将我们的分区规则写成分区函数,然后我们的分区表就可以按照这个分区函数来将我们的表存储在不同的存储介质上,当我们查询时SQL Server最优化程序会自动选择分区做Join这样当然要比大数量过滤起来有效的多。

2:通过Row_Number来给查询结果集加个序号

查询结果集没有序号郁闷的问题相信折腾了不少人,每每有客户指着我的Grid OR Report对我说“小莫,你能不能给这个地方加个序号?”对于这样的合理要求只能说是,然后就将查询来的结果手动的加个序号,对牺牲的性能也只好烧把高香祝福它能升上天堂,然后就是保佑着客户查询数据量不要太大,

升级到SQL2005 我可以将序号这个功能默认给用户不要他再给我提这样的合理要求了。

3:交叉表恶梦的结束

如果你做过考勤管理,选择建31个列还是添加31行?选择31列直观,但你查询的时候你也许更喜欢你头撞墙而不是来查询,添加31行当你决定用列显示日期的时候你发现你还是愿意撞墙。还有当你做类似学生成绩管理系统的时候你要将课程表中的课程数据做列学生表中的学生作行的时候这个时候你突然醒悟还是撞墙好些。

升级到SQL Server2005你可以用Pivot这个单词的意思就是“枢轴”有了轴你可以将行扭成列还可将列扭成行

篇2:使用oralce Cursor数据库教程

使用Cursor:

declare

RoomID      Room.RoomID%Type;

RoomName    Room.RoomName%Type;

cursor crRoom is

select RoomID,RoomName

from Room;

begin

open crRoom;

loop;

fetch crRoom into RoomID,RoomName;

exit when crRoom%notFound;

end loop;

close crRoom;

end;

3.1在游标使用入口参数

在SQL语句的Where 子句中恰当使用 相关语句简化逻辑,本来需要使用两个游标,把相关入口参数放入到SQL语句的Where 子句中,一个就搞定了:

cursor   crRoom   is

select

distinct 楼层,房屋用途

from     TT_没有处理的房屋 t

where    数据级别>= 0

and  房屋处理类别= 3

and  产权编号=p_产权编号

and  拆迁房屋类别=p_拆迁房屋类别

and  面积>0

and  (not p_房屋用途 is null

and 房屋用途=p_房屋用途

or p_房屋用途 is null);

另外一个例子:

CREATE OR REPLACE PROCEDURE PrintStudents(

p_Major IN students.major%TYPE) AS

CURSOR c_Students IS

SELECT first_name, last_name

FROM students

WHERE major = p_Major;

BEGIN

FOR v_StudentRec IN c_Students LOOP

DBMS_OUTPUT.PUT_LINE(v_StudentRec.first_name || ' ' ||

v_StudentRec.last_name);

END LOOP;

END;

Oracle带的例子examp6.sql

DECLARE

CURSOR bin_cur(part_number NUMBER) IS SELECT amt_in_bin

FROM bins

WHERE part_num = part_number AND

amt_in_bin > 0

ORDER BY bin_num

FOR UPDATE OF amt_in_bin;

bin_amt        bins.amt_in_bin%TYPE;

total_so_far   NUMBER(5) := 0;

amount_needed  CONSTANT NUMBER(5) := 1000;

bins_looked_at NUMBER(3) := 0;

BEGIN

OPEN bin_cur(5469);

WHILE total_so_far < amount_needed LOOP

FETCH bin_cur INTO bin_amt;

EXIT WHEN bin_cur%NOTFOUND;

/* If we exit, there's not enough to *

* satisfy the order.               */

bins_looked_at := bins_looked_at + 1;

IF total_so_far + bin_amt < amount_needed THEN

UPDATE bins SET amt_in_bin = 0

WHERE CURRENT OF bin_cur;

-- take everything in the bin

total_so_far := total_so_far + bin_amt;

ELSE       -- we finally have enough

UPDATE bins SET amt_in_bin = amt_in_bin

- (amount_needed - total_so_far)

WHERE CURRENT OF bin_cur;

total_so_far := amount_needed;

END IF;

END LOOP;

CLOSE bin_cur;

INSERT INTO temp VALUES (NULL, bins_looked_at, '<- bins looked at');

COMMIT;

END;

-- Created on -8-9 by ADMINISTRATOR

declare

--带有变量的Cursor

cursor crBooks(c_bookTitle varchar2) is

select *

from books a

where a.title like c_bookTitle||'%';

begin

for v_Books in crBooks('Oracle8') loop

dbms_output.put_line(v_Books.author1);

end loop;

end;

篇3:创建和使用图表数据库教程

图表是SQL Server 特有的一种数据库对象,它提供给用户直观的管理数据库表的方式,

创建和使用图表数据库教程

。通过图表,用户可以直观地创建、编辑数据库表之间的关系,也可以编辑表及其列的属性。

在Enterprise Manager 中创建图表的步骤如下:

(1) 在Enterprise Manager 中选择“Diagrams”, 单击右键,从快捷菜单中选择“New Database Diagram” 选项,就会运行创建数据库图表向导,如图8-23所示。,

(2) 单击“下一步”按钮,即会出现如图8-24 所示的选择包含在图表中的数据库表对话框,其中选中“Add related tables automatically” 选项后,当添加一个表到图表中时,系统自动将与其有关联的表添加到图表中。

(3) 单击“下一步”按钮,即会出现如图8-25 所示的结束图表创建对话,框其中列出了即将用于创建图表的数据库表,

(4) 单击“完成”按钮,即会出现如图8-26 所示的编辑图表对话框。

在编辑图表对话框中,创建表之间的关系特别简捷,只需从主表中选择关键字段,再按住鼠标右键不放直接移动鼠标到从表的相应字段上,松开鼠标即可。例如,创建表orders和表order_firm 之间的关系,作此操作后即会出现如图8-27 所示的创建关系对话框。在其中可对关系作设置。

(5) 在工具栏中单击按钮,保存图表。在Enterprise Manager 中即会出现如图8-28 所示的图表对象。

在图表对象上单击右键,从快捷菜单中选择“Design Diagram” 选项,即会出现同图表创建对话框相似的图表编辑对话框,可在其中编辑图表对象,也可以编辑相应的表及其字段、索引、约束和其它属性等。

本章小结:

索引就是可以加快数据检索的一种结构。理解和掌握索引的创建与管理,对于学习和进行数据查询很有帮助。

篇4:SQL查询语句使用简要数据库教程

精华|语句

一、 简单查询

简单的Transact-SQL查询只包括选择列表、FROM子句和WHERE子句,它们分别说明所查询列、查询的

表或视图、以及搜索条件等。

例如,下面的语句查询testtable表中姓名为“张三”的nickname字段和email字段。

SELECT nickname,email

FROM testtable

WHERE name='张三'

(一) 选择列表

选择列表(select_list)指出所查询列,它可以是一组列名列表、星号、表达式、变量(包括局部变

量和全局变量)等构成。

1、选择所有列

例如,下面语句显示testtable表中所有列的数据:

SELECT *

FROM testtable

2、选择部分列并指定它们的显示次序

查询结果集合中数据的排列顺序与选择列表中所指定的列名排列顺序相同。

例如:

SELECT nickname,email

FROM testtable

3、更改列标题

在选择列表中,可重新指定列标题。定义格式为:

列标题=列名

列名 列标题

如果指定的列标题不是标准的标识符格式时,应使用引号定界符,例如,下列语句使用汉字显示列

标题:

SELECT 昵称=nickname,电子邮件=email

FROM testtable

4、删除重复行

SELECT语句中使用ALL或DISTINCT选项来显示表中符合条件的所有行或删除其中重复的数据行,默认

为ALL。使用DISTINCT选项时,对于所有重复的数据行在SELECT返回的结果集合中只保留一行。

5、限制返回的行数

使用TOP n [PERCENT]选项限制返回的数据行数,TOP n说明返回n行,而TOP n PERCENT时,说明n是

表示一百分数,指定返回的行数等于总行数的百分之几。

例如:

SELECT TOP 2 *

FROM testtable

SELECT TOP 20 PERCENT *

FROM testtable

(二)FROM子句

FROM子句指定SELECT语句查询及与查询相关的表或视图。在FROM子句中最多可指定256个表或视图,

它们之间用逗号分隔。

在FROM子句同时指定多个表或视图时,如果选择列表中存在同名列,这时应使用对象名限定这些列

所属的表或视图。例如在usertable和citytable表中同时存在cityid列,在查询两个表中的cityid时应

使用下面语句格式加以限定:

SELECT username,citytable.cityid

FROM usertable,citytable

WHERE usertable.cityid=citytable.cityid

在FROM子句中可用以下两种格式为表或视图指定别名:

表名 as 别名

表名 别名

(二) FROM子句

FROM子句指定SELECT语句查询及与查询相关的表或视图。在FROM子句中最多可指定256个表或视图,

它们之间用逗号分隔。

在FROM子句同时指定多个表或视图时,如果选择列表中存在同名列,这时应使用对象名限定这些列

所属的表或视图。例如在usertable和citytable表中同时存在cityid列,在查询两个表中的cityid时应

使用下面语句格式加以限定:

SELECT username,citytable.cityid

FROM usertable,citytable

WHERE usertable.cityid=citytable.cityid

在FROM子句中可用以下两种格式为表或视图指定别名:

表名 as 别名

表名 别名

例如上面语句可用表的别名格式表示为:

SELECT username,b.cityid

FROM usertable a,citytable b

WHERE a.cityid=b.cityid

SELECT不仅能从表或视图中检索数据,它还能够从其它查询语句所返回的结果集合中查询数据。

例如:

SELECT a.au_fname+a.au_lname

FROM authors a,titleauthor ta

(SELECT title_id,title

FROM titles

WHERE ytd_sales>10000

) AS t

WHERE a.au_id=ta.au_id

AND ta.title_id=t.title_id

此例中,将SELECT返回的结果集合给予一别名t,然后再从中检索数据。

(三) 使用WHERE子句设置查询条件

WHERE子句设置查询条件,过滤掉不需要的数据行。例如下面语句查询年龄大于20的数据:

SELECT *

FROM usertable

WHERE age>20

WHERE子句可包括各种条件运算符:

比较运算符(大小比较):>、>=、=、<、<=、、!>、!<

范围运算符(表达式值是否在指定的范围):BETWEEN…AND…

NOT BETWEEN…AND…

列表运算符(判断表达式是否为列表中的指定项):IN (项1,项2……)

NOT IN (项1,项2……)

模式匹配符(判断值是否与指定的字符通配格式相符):LIKE、NOT LIKE

空值判断符(判断表达式是否为空):IS NULL、NOT IS NULL

逻辑运算符(用于多条件的逻辑连接):NOT、AND、OR

1、范围运算符例:age BETWEEN 10 AND 30相当于age>=10 AND age<=30

2、列表运算符例:country IN ('Germany','China')

3、模式匹配符例:常用于模糊查找,它判断列值是否与指定的字符串格式相匹配。可用于char、

varchar、text、ntext、datetime和smalldatetime等类型查询。

可使用以下通配字符:

百分号%:可匹配任意类型和长度的字符,如果是中文,请使用两个百分号即%%。

下划线_:匹配单个任意字符,它常用来限制表达式的字符长度。

方括号[]:指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。

[^]:其取值也[] 相同,但它要求所匹配对象为指定字符以外的任一个字符。

例如:

限制以Publishing结尾,使用LIKE '%Publishing'

限制以A开头:LIKE '[A]%'

限制以A开头外:LIKE '[^A]%'

4、空值判断符例WHERE age IS NULL

5、逻辑运算符:优先级为NOT、AND、OR

(四)查询结果排序

使用ORDER BY子句对查询返回的结果按一列或多列排序,

ORDER BY子句的语法格式为:

ORDER BY {column_name [ASC|DESC]} [,…n]

其中ASC表示升序,为默认值,DESC为降序。ORDER BY不能按ntext、text和image数据类型进行排

序。

例如:

SELECT *

FROM usertable

ORDER BY age desc,userid ASC

另外,可以根据表达式进行排序。

二、 联合查询

UNION运算符可以将两个或两个以上上SELECT语句的查询结果集合合并成一个结果集合显示,即执行联

合查询。UNION的语法格式为:

select_statement

UNION [ALL] selectstatement

[UNION [ALL] selectstatement][…n]

其中selectstatement为待联合的SELECT查询语句。

ALL选项表示将所有行合并到结果集合中。不指定该项时,被联合查询结果集合中的重复行将只保留一

行。

联合查询时,查询结果的列标题为第一个查询语句的列标题。因此,要定义列标题必须在第一个查询语

句中定义。要对联合查询结果排序时,也必须使用第一查询语句中的列名、列标题或者列序号。

在使用UNION 运算符时,应保证每个联合查询语句的选择列表中有相同数量的表达式,并且每个查询选

择表达式应具有相同的数据类型,或是可以自动将它们转换为相同的数据类型。在自动转换时,对于数值类

型,系统将低精度的数据类型转换为高精度的数据类型。

在包括多个查询的UNION语句中,其执行顺序是自左至右,使用括号可以改变这一执行顺序。例如:

查询1 UNION (查询2 UNION 查询3)

三、连接查询

通过连接运算符可以实现多个表查询。连接是关系数据库模型的主要特点,也是它区别于其它类型

数据库管理系统的一个标志。

在关系数据库管理系统中,表建立时各数据之间的关系不必确定,常把一个实体的所有信息存放在

一个表中。当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息。连接操作给用户带

来很大的灵活性,他们可以在任何时候增加新的数据类型。为不同实体创建新的表,尔后通过连接进行

查询。

连接可以在SELECT 语句的FROM子句或WHERE子句中建立,似是而非在FROM子句中指出连接时有助于

将连接操作与WHERE子句中的搜索条件区分开来。所以,在Transact-SQL中推荐使用这种方法。

SQL-92标准所定义的FROM子句的连接语法格式为:

FROM join_table join_type join_table

[ON (join_condition)]

其中join_table指出参与连接操作的表名,连接可以对同一个表操作,也可以对多表操作,对同一

个表操作的连接又称做自连接。

join_type 指出连接类型,可分为三种:内连接、外连接和交叉连接。内连接(INNER JOIN)使用比

较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行。根据所使用

的比较方式不同,内连接又分为等值连接、自然连接和不等连接三种。

外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN)

和全外连接(FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不只列出与连接条件相匹

配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的

数据行。

交叉连接(CROSS JOIN)没有WHERE 子句,它返回连接表中所有数据行的笛卡尔积,其结果集合中的

数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

连接操作中的ON (join_condition) 子句指出连接条件,它由被连接表中的列和比较运算符、逻辑

运算符等构成。

无论哪种连接都不能对text、ntext和image数据类型列进行直接连接,但可以对这三种列进行间接

连接。例如:

SELECT p1.pub_id,p2.pub_id,p1.pr_info

FROM pub_info AS p1 INNER JOIN pub_info AS p2

ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info)

(一)内连接

内连接查询操作列出与连接条件匹配的数据行,它使用比较运算符比较被连接列的列值。内连接分

三种:

1、等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接

表中的所有列,包括其中的重复列。

2、不等连接: 在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些

运算符包括>、>=、<=、<、!>、!<和>。

3、自然连接:在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询

结果集合中所包括的列,并删除连接表中的重复列。

例,下面使用等值连接列出authors和publishers表中位于同一城市的作者和出版社:

SELECT *

FROM authors AS a INNER JOIN publishers AS p

ON a.city=p.city

又如使用自然连接,在选择列表中删除authors 和publishers 表中重复列(city和state):

SELECT a.*,p.pub_id,p.pub_name,p.country

FROM authors AS a INNER JOIN publishers AS p

ON a.city=p.city

(二)外连接

内连接时,返回查询结果集合中的仅是符合查询条件( WHERE 搜索条件或 HAVING 条件)和连接条件

的行。而采用外连接时,它返回到查询结果集合中的不仅包含符合连接条件的行,而且还包括左表(左外

连接时)、右表(右外连接时)或两个边接表(全外连接)中的所有数据行。

如下面使用左外连接将论坛内容和作者信息连接起来:

SELECT a.*,b.* FROM luntan LEFT JOIN usertable as b

ON a.username=b.username

下面使用全外连接将city表中的所有作者以及user表中的所有作者,以及他们所在的城市:

SELECT a.*,b.*

FROM city as a FULL OUTER JOIN user as b

ON a.username=b.username

(三)交叉连接

交叉连接不带WHERE 子句,它返回被连接的两个表所有数据行的笛卡尔积,返回到结果集合中的数

据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

例,titles表中有6类图书,而publishers表中有8家出版社,则下列交叉连接检索到的记录数将等

于6*8=48行。

SELECT type,pub_name

FROM titles CROSS JOIN publishers

ORDER BY type

篇5:SQL查询语句使用数据库教程

语句

作者:任我行一、简单查询

简单的Transact-SQL查询只包括选择列表、FROM子句和WHERE子句,它们分别说明所查询列、查询的

表或视图、以及搜索条件等。

例如,下面的语句查询testtable表中姓名为“张三”的nickname字段和email字段。

SELECT nickname,email

FROM testtable

WHERE name='张三'

(一)选择列表

选择列表(select_list)指出所查询列,它可以是一组列名列表、星号、表达式、变量(包括局部变

量和全局变量)等构成。

1、选择所有列

例如,下面语句显示testtable表中所有列的数据:

SELECT *

FROM testtable

2、选择部分列并指定它们的显示次序

查询结果集合中数据的排列顺序与选择列表中所指定的列名排列顺序相同。

例如:

SELECT nickname,email

FROM testtable

3、更改列标题

在选择列表中,可重新指定列标题。定义格式为:

列标题=列名

列名 列标题

如果指定的列标题不是标准的标识符格式时,应使用引号定界符,例如,下列语句使用汉字显示列

标题:

SELECT 昵称=nickname,电子邮件=email

FROM testtable

4、删除重复行

SELECT语句中使用ALL或DISTINCT选项来显示表中符合条件的所有行或删除其中重复的数据行,默认

为ALL。使用DISTINCT选项时,对于所有重复的数据行在SELECT返回的结果集合中只保留一行。

5、限制返回的行数

使用TOP n [PERCENT]选项限制返回的数据行数,TOP n说明返回n行,而TOP n PERCENT时,说明n是

表示一百分数,指定返回的行数等于总行数的百分之几。

例如:

SELECT TOP 2 *

FROM testtable

SELECT TOP 20 PERCENT *

FROM testtable

(二)FROM子句

FROM子句指定SELECT语句查询及与查询相关的表或视图。在FROM子句中最多可指定256个表或视图,

它们之间用逗号分隔。

在FROM子句同时指定多个表或视图时,如果选择列表中存在同名列,这时应使用对象名限定这些列

所属的表或视图。例如在usertable和citytable表中同时存在cityid列,在查询两个表中的cityid时应

使用下面语句格式加以限定:

SELECT username,citytable.cityid

FROM usertable,citytable

WHERE usertable.cityid=citytable.cityid

在FROM子句中可用以下两种格式为表或视图指定别名:

表名 as 别名

表名 别名

例如上面语句可用表的别名格式表示为:

SELECT username,b.cityid

FROM usertable a,citytable b

WHERE a.cityid=b.cityid

SELECT不仅能从表或视图中检索数据,它还能够从其它查询语句所返回的结果集合中查询数据。

例如:

SELECT a.au_fname+a.au_lname

FROM authors a,titleauthor ta

(SELECT title_id,title

FROM titles

WHERE ytd_sales>10000

) AS t

WHERE a.au_id=ta.au_id

AND ta.title_id=t.title_id

此例中,将SELECT返回的结果集合给予一别名t,然后再从中检索数据。

(三)使用WHERE子句设置查询条件

WHERE子句设置查询条件,过滤掉不需要的数据行。例如下面语句查询年龄大于20的数据:

SELECT *

FROM usertable

WHERE age>20

WHERE子句可包括各种条件运算符:

比较运算符(大小比较):>、>=、=、<、<=、、!>、!<

范围运算符(表达式值是否在指定的范围):BETWEEN…AND…

NOT BETWEEN…AND…

列表运算符(判断表达式是否为列表中的指定项):IN (项1,项2……)

NOT IN (项1,项2……)

模式匹配符(判断值是否与指定的字符通配格式相符):LIKE、NOT LIKE

空值判断符(判断表达式是否为空):IS NULL、NOT IS NULL

逻辑运算符(用于多条件的逻辑连接):NOT、AND、OR

1、范围运算符例:age BETWEEN 10 AND 30相当于age>=10 AND age<=30

2、列表运算符例:country IN ('Germany','China')

3、模式匹配符例:常用于模糊查找,它判断列值是否与指定的字符串格式相匹配。可用于char、

varchar、text、ntext、datetime和smalldatetime等类型查询。

可使用以下通配字符:

百分号%:可匹配任意类型和长度的字符,如果是中文,请使用两个百分号即%%。

下划线_:匹配单个任意字符,它常用来限制表达式的字符长度。

方括号[]:指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。

[^]:其取值也[] 相同,但它要求所匹配对象为指定字符以外的任一个字符。

例如:

限制以Publishing结尾,使用LIKE '%Publishing'

限制以A开头:LIKE '[A]%'

限制以A开头外:LIKE '[^A]%'

4、空值判断符例WHERE age IS NULL

5、逻辑运算符:优先级为NOT、AND、OR

(四)查询结果排序

使用ORDER BY子句对查询返回的结果按一列或多列排序。ORDER BY子句的语法格式为:

ORDER BY {column_name [ASC|DESC]} [,…n]

其中ASC表示升序,为默认值,DESC为降序。ORDER BY不能按ntext、text和image数据类型进行排

序。

例如:

SELECT *

FROM usertable

ORDER BY age desc,userid ASC

另外,可以根据表达式进行排序,

二、联合查询

UNION运算符可以将两个或两个以上上SELECT语句的查询结果集合合并成一个结果集合显示,即执行联

合查询。UNION的语法格式为:

select_statement

UNION [ALL] selectstatement

[UNION [ALL] selectstatement][…n]

其中selectstatement为待联合的SELECT查询语句。

ALL选项表示将所有行合并到结果集合中。不指定该项时,被联合查询结果集合中的重复行将只保留一

行。

联合查询时,查询结果的列标题为第一个查询语句的列标题。因此,要定义列标题必须在第一个查询语

句中定义。要对联合查询结果排序时,也必须使用第一查询语句中的列名、列标题或者列序号。

在使用UNION 运算符时,应保证每个联合查询语句的选择列表中有相同数量的表达式,并且每个查询选

择表达式应具有相同的数据类型,或是可以自动将它们转换为相同的数据类型。在自动转换时,对于数值类

型,系统将低精度的数据类型转换为高精度的数据类型。

在包括多个查询的UNION语句中,其执行顺序是自左至右,使用括号可以改变这一执行顺序。例如:

查询1 UNION (查询2 UNION 查询3)

三、连接查询

通过连接运算符可以实现多个表查询。连接是关系数据库模型的主要特点,也是它区别于其它类型

数据库管理系统的一个标志。

在关系数据库管理系统中,表建立时各数据之间的关系不必确定,常把一个实体的所有信息存放在

一个表中。当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息。连接操作给用户带

来很大的灵活性,他们可以在任何时候增加新的数据类型。为不同实体创建新的表,尔后通过连接进行

查询。

连接可以在SELECT 语句的FROM子句或WHERE子句中建立,似是而非在FROM子句中指出连接时有助于

将连接操作与WHERE子句中的搜索条件区分开来。所以,在Transact-SQL中推荐使用这种方法。

SQL-92标准所定义的FROM子句的连接语法格式为:

FROM join_table join_type join_table

[ON (join_condition)]

其中join_table指出参与连接操作的表名,连接可以对同一个表操作,也可以对多表操作,对同一

个表操作的连接又称做自连接。

join_type 指出连接类型,可分为三种:内连接、外连接和交叉连接。内连接(INNER JOIN)使用比

较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行。根据所使用

的比较方式不同,内连接又分为等值连接、自然连接和不等连接三种。

外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN)

和全外连接(FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不只列出与连接条件相匹

配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的

数据行。

交叉连接(CROSS JOIN)没有WHERE 子句,它返回连接表中所有数据行的笛卡尔积,其结果集合中的

数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

连接操作中的ON (join_condition) 子句指出连接条件,它由被连接表中的列和比较运算符、逻辑

运算符等构成。

无论哪种连接都不能对text、ntext和image数据类型列进行直接连接,但可以对这三种列进行间接

连接。例如:

SELECT p1.pub_id,p2.pub_id,p1.pr_info

FROM pub_info AS p1 INNER JOIN pub_info AS p2

ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info)

(一)内连接

内连接查询操作列出与连接条件匹配的数据行,它使用比较运算符比较被连接列的列值。内连接分

三种:

1、等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接

表中的所有列,包括其中的重复列。

2、不等连接: 在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些

运算符包括>、>=、<=、<、!>、!<和>。

3、自然连接:在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询

结果集合中所包括的列,并删除连接表中的重复列。

例,下面使用等值连接列出authors和publishers表中位于同一城市的作者和出版社:

SELECT *

FROM authors AS a INNER JOIN publishers AS p

ON a.city=p.city

又如使用自然连接,在选择列表中删除authors 和publishers 表中重复列(city和state):

SELECT a.*,p.pub_id,p.pub_name,p.country

FROM authors AS a INNER JOIN publishers AS p

ON a.city=p.city

(二)外连接

内连接时,返回查询结果集合中的仅是符合查询条件( WHERE 搜索条件或 HAVING 条件)和连接条件

的行。而采用外连接时,它返回到查询结果集合中的不仅包含符合连接条件的行,而且还包括左表(左外

连接时)、右表(右外连接时)或两个边接表(全外连接)中的所有数据行。

如下面使用左外连接将论坛内容和作者信息连接起来:

SELECT a.*,b.* FROM luntan LEFT JOIN usertable as b

ON a.username=b.username

下面使用全外连接将city表中的所有作者以及user表中的所有作者,以及他们所在的城市:

SELECT a.*,b.*

FROM city as a FULL OUTER JOIN user as b

ON a.username=b.username

(三)交叉连接

交叉连接不带WHERE 子句,它返回被连接的两个表所有数据行的笛卡尔积,返回到结果集合中的数

据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

例,titles表中有6类图书,而publishers表中有8家出版社,则下列交叉连接检索到的记录数将等

于6*8=48行。

SELECT type,pub_name

FROM titles CROSS JOIN publishers

ORDER BY type

篇6:Pro*C的使用数据库教程

一 Pro*C 程序概述:

1.什么是Pro*C程序

在ORACLE数据库管理和系统中, 有三种访问数据库的方法;

(1) 用SQL*Plus, 它有SQL命令以交互的应用程序访问数据库;

(2)用第四代语言应用开发工具开发的应用程序访问数据库,这些工具有SQL*Froms,QL*Reportwriter,SQL*Menu等;

(3) 利用在第三代语言内嵌入的SQL语言或ORACLE库函数调用来访问,

Pro*C就属于第三种开发工具之一, 它把过程化语言C和非过程化语言SQL最完善地结合起来,

具有完备的过程处理能力,又能完成任何数据库的处理品任务,使用户可以通过编程完成各种类型的报表。在Pro*C程序中可以嵌入SQL语言,

利用这些SQL语言可以完成动态地建立、修改和删除数据库中的表,也可以查询、插入、修改和删除数据库表中的行, 还可以实现事务的提交和回滚。

在Pro*C程序中还可以嵌入PL/SQL块, 以改进应用程序的性能, 特别是在网络环境下,可以减少网络传输和处理的总开销。

2.Pro*C的程序结构图

通俗来说,Pro*C程序实际是内嵌有SQL语句或PL/SQL块的C程序, 因此它的组成很类似C程序。 但因为它内嵌有SQL语句或PL/SQL块,

所以它还含有与之不同的成份。为了让大家对Pro*C有个感性的认识, 特将二者差别比较如下:

C的全程变量说明

C源程序 函数1:同函数K。

函数2:同函数K。

C的局部变量说明

函数K

可执行语句

应用程序首部 C的外部变量说明

外部说明段(ORACLE变量说明)

通讯区说明

Pro*C源程序 函数1:同函数K。

函数2:同函数K。

C局部变量说明

程序体 内部说明部分 内部说明段

通讯区说明

函数K C的可执行语句

可执行语句 SQL的可执行语句

或PL/SQL块

二.Pro*C程序的组成结构

每一个Pro*C程序都包括两部分:(1)应用程序首部;(2)应用程序体

应用程序首部定义了ORACLE数据库的有关变量,

为在C语言中操纵ORACLE数据库做好了准备。应用程序体基本上由Pro*C的SQL语句调用组成。主要指查询SELECT、INSERT、UPDATE、DELETE等语句。

应用程序的组成结构如图所示:

应用程序首部

描述部分

SQL通信区

应用程序体

EXEC SQL BEGIN DECLARE SECTION

(SQL变量的定义)

EXEC SQL END DECLARE SECTION;

EXEC SQL INCLUDE SQLLA;

EXEC SQL CONNECT:< 用户名>

IDENTIFIED BY: < 口令 >

SQL 语句及游标的使用

1. 应用程序首部

应用程序的首部就是Pro*C的开始部分。它包括以下三部分:

l C变量描述部分;

l SQL变量描述部分(DECLARE部分);

l SQL通信区。

(1) .DECLARE部分(描述部分)

描述部分说明程序的SQL变量, 定义部分以EXEC SQL BEGIN DECLARE SECTION ;开始和以 EXEC SQL END DECLARE

SECTION ;结束的。它可以出现在程序的主部,也可出现在局部

l SQL变量的说明和使用

在说明段能为SQL变量指定的数据类型如表所示:

数据类型描述

CHAR

CHAR(n)

INT

SHORT

LONG

FLOAT

DOUBLE

VARCHAR单字符

n个字符数组

整数

短整数

单精度浮点数

双精度浮点数

变长字符串

这些数据类型实际上就是C语言的数据类型, 其中VARCHAR中视为C数据类型的扩充。这在以后会谈到。

SQL变量的使用应注意以下几点:

l 必须在描述部分明确定义

l 必须使用与其定义相同的大小写格式

l 在SQL语句中使用时,必须在其之前加一个“:”(冒号),但在C语句中引用时不需加冒号。

l 不能是SQL命令中的保留字。

l 可以带指示变量。

例如:EXEC SQL BEGIN DECLARE SECTIONS;

VARCHAR programe[30];

Int porgsal, pempno;

EXEC SQL END DECLARE SECTION;

EXEC SQL SELECT ENAME , SAL

INTO: programe, : progsal

FROM EMP

WHERE EMPNO = : pempno;

(2). 指示器变量的说明和引用

指示变量实际上也是一类SQL变量,它被用来管理与其相关联的宿主变量(即在SQL语句中充

当输入或输出的变量)。每一个宿主变量都可定义一个指示器变量,主要用于处理空值(NULL)

指示器变量的说明基本同一般SQL变量一样, 但必须定义成2字节的整型,如SHORT、INT。在SQL语句中引用时,

其前也应加“:”(冒号),而且必须附在其相关联的宿主变量之后,在C语句中,可独立使用。当指示器变量为-1时,表示空值。例如:

EXEC SQL BEGIN DECLARE SECTION ;

INT dept- number;

SHORT ind – num;

CHAR emp –name;

EXEC SQL END DECLARE SECTION ;

Scanf(“90d %s”, & dept- number , dept – name );

If (dept – number ==0)

Ind – num = -1;

Else

Ind – num = 0;

EXEC SQL INSERT INTO DEPT (DEPTNO, DNAME)

VALUES(:dept – number : ind- num , :dept – name);

其中ind – num是dept – number 的指示器变量。当输入的dept – number 值是0时, 则向DEPT 表的DEPTNO列插入空值。

(3).指针SQL变量的说明和使用

指针SQL变量在引用前也必须在DECLARE

部分先说明。其说明格式同C语言。在SQL语句中引用时,指针名字前要加前缀“:”(冒号)而不加“*”(星号)。在C语句中用法如同C语言的指针变量。

(4).数组SQL变更的说明和引用

在SQL语句中引用数组时,只需写数组名(名字前加冒号), 不需写下标,在C语句中用法如同C语言的数组变量。

使用数组可大大降低网络传输开销。如要向一表插入100行数据,如果没有数组,就要重复100次, 而引用后,只须执行一次insert语句、便可一次性插入。例如:

EXEC SQL BEGIN DECLARE SECTION;

Int emp_number[100];

Char emp_name[100][15];

Float salary[100],commission[100];

Int dept_number;

EXEC SQL END DECLARE SECTION;

….

EXEC SQL SELECT EMPNO,ENAME,SAL,COMM

INTO :emp_number,:emp_name,:salary,:commission

FROM EMP

WHERE DEPTNO=:dept_number;

在使用数组时,应注意以下几点;

l 不支持指针数组

l 只支持一维数组, 而 emp-name [100][15]视为一维字符串

l 数组最大维数为32767

l 在一条SQL语句中引用多个数组时,这些数组维数应相同

l 在VALUES , SET, INTO 或WHERE子名中, 不允许把简单SQL变量与数组SQL变量混用

l 不能在DELARE部分初始化数组

例如:下面的引用是非法的

EXEC SQL BEGIN DECLARE SECTION;

Int dept – num [3] = {10,20,30};

EXEC SQL END DECLARE SECTION ;

EXEC SQL SELECT EMPNO, ENAME , SAL

INTO : emp – num [ i ], : emp – name [ i ], : salarg [ i ]

FROM EMP

(5) 伪类型VARCHAR的说明和引用

VARCHAR变量在引用之前也必须在说明段说明, 说明时必须指出串的最大

长度,如:

EXEC SQL BEGIN DECLARE SECTION;

Int book – number;

VARCHAR book – name [ 50 ];

EXEC SQL END DECLARE SECTION ;

在预编绎时, book – name 被翻译成C语言中的一个结构变量;

Struct { unsigned short len ;

Unsigned chart arr [ 20 ] ;

} boo – name

由此看出, VARCHAR变量实际上是含长度成员和数组成员的结构变量。在SQL语句中引用时,应引用以冒号为前缀的结构名, 而不加下标,在C语句 中引用结构成员。

VARCHAR变量在作输出变量时,由ORACLE自动设置, 在作为输入变量时,程序应先把字符串存入数组成员中,

其长度存入长度成员中,然后再在SQL语句中引用。例如:

Main( )

{ .......

scanf(“90s, 90d’, book – name .arr, & book – number );

book – name .len = strlen (book – name .arr);

EXEC SQL UPDATE BOOK

SET BNAME = : book – name ;

BDESC = : book – number ;

}

(6) SQL通信区

SQL 通信区是用下列语句描述的:

EXEC SQL INCLUDE SQLCA;

此部分提供了用户运行程序的成败记录和错误处理。

SQLCA的组成

SQLCA是一个结构类型的变量,它是ORACLE 和应用程序的一个接口。在执行 Pro*C程序时, ORACLE

把每一个嵌入SQL语句执行的状态信息存入SQLCA中, 根据这些信息,可判断SQL语句的执行是否成功,处理的行数,错误信息等,其组成如表所示:

Struct sqlca

{ char sqlcaid [ 8 ] ; ----à标识通讯区

long sqlabc; ---à 通讯区的长度

long sqlcode; ---à保留最近执行的SQL语句的状态码

struct { unsigned short sqlerrml; -----à信息文本长度

}sqlerrm;

char sqlerrp [ 8 ];

long sqlerrd [ 6 ];

char sqlwarn [ 8 ];

char sqlext [ 8 ];

}

struct sqlca sqlca;

其中, sqlcode在程序中最常用到,它保留了最近执行的SQL语句的状态码。程序员根据这些状态码做出相应的处理。这些状态码值如下:

0: 表示该SQL语句被正确执行,没有发生错误和例外。

>0:ORACLE执行了该语句,但遇到一个例外(如没找到任何数据)。

<0:表示由于数据库、系统、网络或应用程序的错误,ORACLE未执行该SQL语句。

当出现此类错误时,当前事务一般应回滚。

2.应用程序体

在Pro*C程序中, 能把SQL语句和C语句自由地混合书写,并能在SQL语句中使用SQL变量,嵌入式SQL语句的书写文法是:

l 以关键字EXEC SQL开始

l 以C语言的语句终结符(分号)终结

SQL语句的作用主要用于同数据库打交道。C语言程序用于控制,输入,输出和数据处理等。

(1) 连接到ORACLE数据库

在对数据库存取之前,必须先把程序与ORACLE数据库连接起来。即登录到ORACLE上。所连接命令应该是应用程序的第一个可执行命令。连接命令格式如下:

EXEC SQL CONNECT:< 用户名 > IDENTIFIED BY : < 口令 >

或EXEC SQL CONNECT: < 用户名 > / < 口令 >

在使用上述两种格式进行登入时, 应当首先在说明段定义包含用户名和口令的

SQL 变量,并在执行CONNECT之前设置它们,否则会造成登录失败。例如:

EXEC SQL BEGIN DECLARE SECTION ;

VARCHAR usename [20];

VARCHAR password[20];

EXEC SQL END DECLARE

..........

strcpy ( usename.arr, “CSOTT’);

usename.len = strlen (username.arr);

strcpy (password.arr , “TIGER’);

password .len = strlen( password .arr);

EXEC SQL WHENEVER SQLERROR GOTO SQLERR;

EXEC SQL CONNECT :username INDNTIFIED BY : password;

注意: 不能把用户名和口令直接编写到CONNECT语句中,或者把用引号(’)括起来的字母串在CONNECT 语句中, 如下面的语句是无效的。

EXEC SQL CONNECT SCOTT INENTIFIED BY TIGER;

EXEC SQL CONNECT ‘SCOTT’ IDENTIFIED BY ‘TIGER’;

(2). 插入、更新和删除

在讲述SQL语言时已详细讲过, 这里就不举例说明了。

(3). 数据库查询及游标的使用

在PRO*C中, 查询可分为两种类型:

l 返回单行或定行数的查询;

l 返回多行的查询.此种查询要求使用游标来控制每一行或每一组(主变量用数组).

1) 返回单行或定行数的查询

在PRO*C中的查询SQL SELECT语句由以下几个子句组成:

SELECT

INTO

FROM

WHERE

CONNECT BY

UNION

INTERSECT

MINUS

GROUP BY

HAVING

ORDER BY

其中WHERE子句中的查询条件可以是一个属性或多个属性的集合,在执行是赋值的主变量也可放在WHERE子句中.WHERE子句中所用的主变量称为输入主变量。如:

SELECT EMPNO, JOB, SAL

INTO:PNAME, :PJOB, :PSAL

FROM EMP

WHERE EMPNO=:PEMPNO;

若没有找到限定的行, 则SQLCA.SQLCODE返回”+1403”, 表明”没有找到”。

INTO从句中的主变量叫输出主变量,它提供了查询时所需要的信息。

在任何项送给主变量之前,都要求ORACLE把这些项转换成主变量的数据类型。对于数字是通过截断来完成的(如:9.23转换为9)。

如果已确定查询只返回一行,那么就不必使用游标,只给SELECT语句增加一个INTO子句即可。在语义上INTO语句在FROM之前的查询中有多少个选择项就有多少个输出主变量。若在SELECT项中表达式的数目不等于INTO子句中主变量的数目,就把SQLCA.SQLWARN[3]置为”W”。

2)多行查询及游标的使用

如果查询返回多行或不知道返回多少行,使用带有ORACLE游标(CURSOR)的SELECT语句。

游标是ORACLE和PRO*C存放查询结果的工作区域。一个游标(已命名的)与一条SELECT语句相关联。操作游标有由4条命令:(1)DECLARE

CURSOR;(2)OPEN CURSOR;(3)FETCH;(4)CLOSE CURSOR。

A. 定义游标

一个游标必须首先定义, 才能使用它。语法为:

EXEC SQL DECLARE 〈游标名〉CORSOR FOR

SELECT 〈列〉

FROM 〈表〉

例如:

EXEC SQL DECLARE CSOR, CURSOR FOR

SELECT ENAME , JOB, SAL

FROM EMP

WHERE DEPTNO=:DEPTNO;

当赋给一个与查询相关联的游标CURSOR之后, 当SELECT查询EMP时可从数据库中返回多行,这些行就是CURSOR的一个活动区域。

注意:

1) 定义游标必须在对游标操作之前完成;

2) PRO*C不能引用没有定义的游标;

3) 游标定义后,其作用范围是整个程序。所以对一个程序来讲, 同时定义两个相同的游标是错误的。

B. 打开游标

打开游标的OPEN语句主要用来输入主变量的内容,这些主要是WHERE中使用的主变量。打开游标的语句是:EXEC SQL OPEN 〈游标名〉

当打开游标后,可以从相关的查询中取出多于一行的结果。所有满足查询标准的行组成一集合,叫做“游标活动集”。通过取操作,活动集中的每一行或每一组是一个一个返回的,查询完成后,

游标就可关闭了。如图所示:

定义游标:DECLARE

开始查询:SELECT

打开游标:OPEN

从活动集取数据:FETCH

查询完成

关闭游标:CLOSE

注意:1)游标处于活动集的第一行前面;

2)若改变了输入主变量就必须重新打开游标。

C. 取数据

从活动集中取出一行或一组把结果送到输出主变量中的过程叫取数据。输出主变量的定义在取数据语句中。取数据的语句如下:

EXEC SQL FETCH〈游标名〉INTO:主变量1,主变量2,……

FETCH的工作过程如图所示:

查询结果

游标

FETCH

查询结果

在游标打开后

输出至当前

……

如图所示的查询结果指满足查询条件的查询结果,

使用FETCH应注意以下几点:

l 游标必须先定义再打开。

l 只有在游标打开之后才能取数据,即执行FETCH语句。

l

FETCH语句每执行一次,从当前行或当前组取数据一次,下一行或下一组向上移一次。游标每次所指的行或组都为当前行或当前组,而FETCH每次都是取游标所指定的行或组的数据。

l 当游标活动集空之后,ORCLE返回一个SQLCA。SQLCA(=1403)。

l 若希望此游标再操作, 必须先关闭再打开它。

l 在C程序中可以开辟一个内存空间,来存放操作结果,这样就能利用开辟的空间来灵活操纵查询的结果。

D.关闭游标

取完活动集中所有行后,必须关闭游标,以释放与该游标有关的资源。

关闭游标的格式为:

EXEC SQL CLOSE 游标名;

例如:

EXEC SQL CLOSE C1;

ORACLE V5.0版支持SQL格式“CURRENT OF CURSOR”。这条语句将指向一个游标中最新取出的行,

以用于修改和删除操作。该语句必须有取操作之后使用,它等同存储一个ROWID,并使用它。

(4).举例

EXEC SQL DECLARE SALESPEOPLE CURSOR FOR

SELECT SSNO, NAME, SALARY

FROM EMPLOYEE

WHERE DNAME=‘Sales’;

EXEC SQL OPEN SALESPEOPLE;

EXEC SQL FETCH SALESPEOPLE

INTO :SS,:NAME,:SAL;

EXEC SQL CLOSE SALESPEOPLE;

(5)SQL嵌套的方法及应用

嵌入SQL与交互式SQL在形式上有如下差别:

1) 在SQL语句前增加前缀“EXEC SQL”, 这一小小的差别其目的是在于预编译时容易识别出来,

以便把每一条SQL作为一条高级语言来处理。

2) 每一SQL语句分为说明性语句和可执行语句两大类。可执行语句又分为数据定义、数据控制、数据操纵、数据检索四大类。

可执行性SQL语句写在高级语言的可执行处;说明性SQL语句写在高级语言的说明性的地方。

例如:在PRO*C程序中建立一个名为BOOK的表结构,过程如下:

#include〈stdio.h〉

EXEC SQL BEGIN DECLARE SECTION;

VARCHAR uid[20], pwd[20];

EXEC SQL END DECLARE SECTION;

EXEC SQL INCLUDE SQLCA;

Main

{

/*login database*/

strcpy(uid.arr,’wu’);

uid.len=strlen(uid,arr);

strcpy(pwd.arr,’wu’);

pwd.len=strlen(pwd.arr);

EXEC SQL CONNECT:uid IDENTIFEED BY:pwd;

EXEC SQL CREATE TABLE book

( acqnum number, copies number , price number);

EXEC SQL COMMIT WORK RELEASE;

EXIT;

PRO*C可非常简便灵活地访问ORCLE数据库中的数据,同时又具有C语言高速的特点,因而可完成一些ORACLE产品不能完成的任务,例如以下一个固定的特殊格式输出结果。

SQL嵌套源程序示例

#unclude

typedef char asciz[20];

EXEC SQL BEGIN DECLARE SECTION;

EXEC SQL TYPE asciz IS STRING (20) REFERENCE;

asciz username;

asciz password;

asciz emp_name(5);

int emp_number(5a);

float salary[5];

EXEC SQL END DECLARE SECTION;

EXEC SQL INCLUDE sqlca;

Void print_rows;

Void sqlerror();

Main()

{

int num_ret;

strcpy(username,”SCOTT’);

strcpy(password, “TYGER”);

EXEC SQL WHENEVER SQLERROR DO sqlerror();

EXEC SQL CONNECT:username IDENTIFIED BY:password;

Print (“nConnected to ORACLE as user:%sn”, username);

EXEC SQL DECLARE c1 CURSOR FOR

SELECT EMPNO , ENAME , SAL FROM EMP;

EXEC SQL OPEN c1;

Num_ret = 0;

For(;;)

{

EXEC SQL WHENEVER NOT FOUND DO break;

EXEC SQL FETCH c1 INTO : emp_number , :emp_name , :salary;

Print_rows (sqlca.sqlerrd[2] – num_ret);

Num_ret=sqlca.sqlerrd[2];

}

if ((sqlca.sqlerrd[2] – num_ret)>0);

print _rows(sqlca.sqlerrd[2] –num_ret);

EXEC SQL CLOSE c1;

Printf(“Have a good day.n”);

EXEC SQL COMMIT WORK RELEASE;

}

void print_rows(n);

int n;

{

int i;

printf(“nNumber Employee Salaryn”);

printf(“------------------------------n”);

for (i=0;i printf(“% - 9d%- 8s%9.2fn”,emp-number[i], emp---name[i],salary[i];

}

void sqlerror()

{

EXEC SQL WHENEVER SQLERROR CONTINUE;

Printf(“noracle error detected:n”);

Printf(‘n%.70sn”, sqlca.sqlerrm.sqlerrmc);

EXEC SQL ROLLBACK WORK RELEASE;

Exit(1);

}

(6) 错误检测和恢复

在使用SQL语句和PRO*C对数据库进行操作时,常常有字段空值,无条件删除,无行返回,数据溢出和截断等现象发生,这种现象可以用SQLCA和指示器变量来检测。

1 SQLCA的结构

在PRO*C程序中SQLCA结构如下:

STRUCT SQLCA{

Char sqlcaid[8];

Long sqlabc;

Long sqlcode;

STRUCT{

Unsigned sqlerrm1;

Char sqlerrmc[10];

}sqlerrm;

Char sqlerrp[8];

Long sqlerrd[6];

Char sqlwarn[8];

Char sqlext[8];

}

其中:

1) SQLCA.sqlerrm.sqlerrmc:带有SQLCA。SQLCODE的错误正文。

2) SQLCA.sqlerrd:当前ORACLE的状态,只有SQLCA.SQLERRD[2]有意义,表示DML语句处理的行数。

3) SQLCA.sqlwarn:提供可能遇到的条件信息。

在每执行一个SQL语句后,ORACLE就把返回结果放入SQLCA中,但说明语句除外。

用SQLCA可以查看SQL语句的执行结果。往往有三种结果:

=0:执行成功;

SQLCA.SQLCODE= >0:执行成功的状态值;

<0:失败,不允许继续执行。

2 指示器变量

指示器变量有时也称指示变量.指示变量与一个主变量相关联,指出主变量的返回情况.

=0:返回值不为空, 未被截断,值放在主变量中;

返回值= >0:返回值为空, 忽略主变量的值;

<0:主变量长度不够就被截断。

使用指示变量要注意:

l 在WHERE子句中不能用指示变量。用NULL属性来测试空值。

例如下列子句:

SELECT…

FROM…

WHERE ENAME IS NULL;

是正确的,而

WHERE ENAME=:PEME:PEME1

是错误的。

l 指示变量在插入空值之前为—1

l 可输出空值。

3 WHENEVER语句

WHENEVER是说明语句,不返回SQLCODE, 只是根据SQLCA中的返回码指定相关的措施。格式为

EXEC SQL WHENEVER [SQLERROR|SQLWARNING|NOTFORUND]

[STOP|CONTINUE|GOTO<标号>];

其中

(1)[STOP|CONTINUE|GOT<标号>]的缺省值为CONTINUE。

(2)SQLERROR:SQLCA.SQLCODE<0;

(3)SQLWARNIGN:SQLCA.SQLWARN[0]=“W”;

(4)NOTFOUND:SQLCA.SQLCODE=1403;

下面给出一段程序来说明WHENEVER的用法:

EXEC SQL BEGIN DEELARE SECTION;

VARCHAR UID[20];

VARCHAR PASW[20];

……

EXEC SQL END DECLARE SECTION;

EXEC SQL INCLUDE SQLCA;

Main()

{

……

EXEC SQL WHENEVER SQLERROR GOTO ERR;

EXEC SQL CONNECT:UID/:PWD;

……

EXEC SQL DECLARE CSOR1 CURSOR FOR

SELECT 〈字段〉

FORM〈表〉

EXEC SQL OPEN CSOR1;

SQL

……

EXEC SQL WHENEVER NOT FOUND GOTO good;

For(;;)

EXEC SQL FETCH CSOR, INTO……

Good:

……

printf(“n查询结束n”);

EXEC SQL CLOSE C1;

EXEC SQL WHENEVER SQLERROR CONTINUE.

EXEC SQL COMMIT WORK RELEASE:

Exit();

Printf(“n%70s|n”, sqlca.sqlerrm.sqlerrmc);

EXEC SQL ROLLBACK WORK RELEASE:

Exit(1);

}

(7) 动态定义语句

SQL语句分动态定义语句和静态定义语句两种:

(1) 静态定义语句:SQL语句事先编入PRO*C中,在经过预编译器编译之后形成目标程序*。BOJ,然后执行目标程序预即可。

(2) 动态定义语句:有些语句不能事先嵌入到PRO*C程序中,要根据程序运行情况,用户自己从输入设备上(如终端上)实时输入即将执行的SQL语句。

动态定义语句有:

l EXECUTE IMMEDIATE;

l PREPARE 与EXECUTE;

l PREPARE与FETCH 和 OPEN ;

l BIND与DEFINE DESCRIPTOR。

1. EXECUTE IMMEDIATE语句

此语句表示立即执行, 并且只向SQLCA返回执行结果,无其它信息。例如:

EXEC SQL BEGIN DECLARE SECTION;

VARCHAR abcd[89];

VARCHAR deay[20];

EXEC SQL END DECLARE SECTION;

/** 输出字符串到abcd **/

EXEC SQL EXECUTE IMMEDIATE :abcd;

注意:

1) EXECUTE IMMEDIATE只能运行带一个参数的动态语句。其中,abcd是参数,不是关键字。

2) EXECUTE IMMEDIATE使用的先决条件是:SQL语句不能包含主变量;SQL语句不能是查询语句。

3) 可用任何主变量作为EXECUTE IMMEDIATE的参数;也可用字符串作为主变量。

2. PREPARE与EXECUTE语句

此语句表示“预编译/执行”。此语句能够预编译一次而执行多次。语法为:

EXEC SQL PREPARE 〈语句名〉FROM:主变量;

EXEC SQL EXECUTE〈语句名〉[USING:替换主变量];

PREPARE语句做两件事:

(1) 预编译SQL语句;

(2) 给出SQL语句的语句名。

注意:

l SQL语句不能是查询语句;

l PREPARE和EXECUTE可包含主变量;

l PREPARE不能多次执行。

例如:

#define USERNAME “SCOTT”

#define PASSWORD “TIGER”

#include

EXEC SQL INCLUDE sqlca;

EXEC SQL BEGIN DECLARE SECTION;

Char * username=USERNAME;

Char * password=PASSWORD;

VARCHAR sqlstmt[80];

Int emp_number;

VARCHAR emp_name[15];

VARCHAR job[50];

EXEC SQL END DECLARE SECTION;

Main()

{

EXEC SQL WHENEVER SQLERROR GOTO :sqlerror;

EXEC SQL CONNECT :username IDENTIFIED BY :password;

Sqlstmt.len=sprintf(sqlstmt.arr,”INSERT INTO EMP (EMPNO,ENAME,JOB,SAL)

VALUES(:V1,:V2,:V3,:V4)”);

Puts(sqlstmt.arr);

EXEC SQL PREPARE S FROM :sqlstmt;

For(;;)

{

printf(“nenter employee number:”);

scanf(“%d”,&emp_number);

if (emp_number==0) break;

printf(“nenter employee name:”);

scanf(“%s”,&emp_name.arr);

emp_name.len=strlen(emp_name.arr);

printf(“nenter employee job:”);

scanf(“%s”,job.arr);

job.len=strlen(job.arr);

printf(“nenter employee salary:”);

scanf(“%f”,&salary);

}

EXEC SQL EXECUTE S USING :emp_number,:emp_name,:job,:salary;

}

3. FETCH语句和OPEN语句

FETCH语句和OPEN语句这组动态语句是对游标进行操作的,其执行过程如下:

PREPARE〈语句名〉FROM 〈主变量字符串〉;

DECLARE〈游标名〉FOR〈语句名〉;

OPEN 〈游标名〉[USING:替换变量1[,:替换变量变…]]

FETCH〈游标名〉INTO: 主变量1[,:主变量2…]

CLOSE〈游标名〉

注意:

l SQL语句允许使用查询语句;

l SELECT子句中的列名不能动态改变,只能预置;

l WHERE和ORDER BY 子句可以动态改变条件。

一、 Pro*C的编译和运行

1.

先用ORACLE预编译器PROC对PRO*C程序进行预处理,该编译器将源程序中嵌入的SQL语言翻译成C语言,产生一个C语言编译器能直接编译的文件。生成文件的扩展名为

.C

2. 用C语言编译器CC 对扩展名为 .c的文件编译,产生目标码文件,其扩展名为 .o

3. 使用MAKE命令,连接目标码文件,生成可运行文件

例如: 对上面的example.pc进行编译运行

PROC iname=example.pc

CC example.c

MAKE EXE=example BJS=”example.o”

example

篇7:关于数据库解析不使用的五个理由

在我们实际工作中,往往会能听到很多关于不使用MySQL数据库的理由,当然也有一些是对MySQL(和PHP搭配之最佳组合)的误解,下面我将讲述的是5个不使用MySQL(和PHP搭配之最佳组合)的响亮理由。

首先我们要知道,或许有一项技术存在很多理由让我们可以选择使用它,但是让我们不使用它往往只要有一个理由就足够了。选择一个软件产品同样也是如此。 MySQL数据库虽然应用很广泛,受到大家的青睐,但MySQL数据库也有负面的作用,下面就介绍五个不适用 MySQL数据库的给力理由。

1、MySQL(和PHP搭配之最佳组合)的授权方式

MySQL(和PHP搭配之最佳组合)采用双重授权(Dual Licensed),它们是GPL和MySQL(和PHP搭配之最佳组合) AB制定的商业许可协议。

如果你在一个遵循GPL的自由(开源)项目中使用MySQL(和PHP搭配之最佳组合),那么你可以遵循GPL协议使用MySQL(和PHP搭配之最佳组合)。然而,如果你的项目不是在GPL协议下的话,你必须为使用MySQL(和PHP搭配之最佳组合)来支付许可费用,或者你可能因为这个因素而将你的项目改为遵循GPL,那么你需要处理因此带来的更多的支持工作,这有可能会带来成本上的提高。在这种情况下,一些软件发行商可能倾向于选择别的开源数据库,例如遵循BSD授权的PostgreSQL。

2、产品成熟性

到,甲骨文的数据库Oracle(大型网站数据库平台)已经诞生了30周年,而MySQL(和PHP搭配之最佳组合)却连它的一半时间都没有。微软的sql server(WINDOWS平台上强大的数据库平台)仅仅比MySQL(和PHP搭配之最佳组合)大两年,但是sql server(WINDOWS平台上强大的数据库平台)的发布是建立在Sybase的基础上,那时候Sybase已经诞生了6年的时间。至于其他值得关注的开源数据库,PostgreSQL将在20达到20岁的生日。虽然MySQL(和PHP搭配之最佳组合)并不是市场上最年轻的数据库,但是却有更多成熟的数据库可供我们选择。

当然,或许这并不是我们拒绝MySQL(和PHP搭配之最佳组合)的一个有说服力的理由,但是对于一些比较守旧的IT经理来说,在为一些关键业务选择平台的时候,平台的成熟性却是必须要考虑的一个因素,在这一点上,MySQL(和PHP搭配之最佳组合)无疑毫无优势。

3、功能设置成熟性

要想在MySQL(和PHP搭配之最佳组合)与其他数据库之间进行一个面面俱到的功能设置对比,并不是一件容易的事情。随着新软件版本的发布或一些补丁的推出,曾经的功能列表可能会迅速变得过时了。而且,有些功能对有的应用程序非常重要,但是对别的应用程序则不一定。

有的时候,一些缺失的功能可以通过别的办法来实现,例如,在MySQL(和PHP搭配之最佳组合) 4.1以前,你可以通过使用join方法来替代子查询的功能。在MySQL(和PHP搭配之最佳组合) 5.0中,大多数关系型数据库所要求的功能已经都具备,但是我们却有理由怀疑这些功能在MySQL(和PHP搭配之最佳组合) 5.0中的成熟性。充其量它们在MySQL(和PHP搭配之最佳组合)中被支持的时间也就一年左右,而在其他关系型数据库中则已经存在了近的时间。

4、认证的作用

尽管MySQL(和PHP搭配之最佳组合)也有一个认证培训项目,但是它的培训却要比Oracle(大型网站数据库平台)或MS-SQL相差很远。尽管有的使用MySQL(和PHP搭配之最佳组合)的用户表示,MySQL(和PHP搭配之最佳组合)很容易上手,但是对于具有企业级数据库需求的用户来说,无疑希望员工得到系统、有深度的培训,显然MySQL(和PHP搭配之最佳组合)在这一点上还做得很不够。

一个相关的问题是第三方支持的资格问题,尽管直接来自厂商的支持和服务可以一定程度上减缓这个问题,但是,对于有的企业来说,通过强有力的本地化支持显然更有吸引力。

5、关于可扩展的看法

关于这个理由我把它放在最后一位。在很多业界专家中有一个相当一致的观点:MySQL(和PHP搭配之最佳组合)不能很好的扩展。关于这点可能有很大的分歧,争论的焦点主要集中于水平可扩展性和垂直可扩展性上。MySQL(和PHP搭配之最佳组合)则更倾向于垂直可扩展性。

据我的观察,现在有一个趋势,那些经过正式培训的数据库管理员DBA更倾向于选择一个专有关系数据库,例如Oracle(大型网站数据库平台)。对于一些具有专门数据库管理员的比较大的环境来说,MySQL(和PHP搭配之最佳组合)很难得到宠爱,这时候,关于MySQL(和PHP搭配之最佳组合)是否真的具有良好的可扩展性的争论已经没有意义。

不可否认,MySQL(和PHP搭配之最佳组合)也是一个很好的关系型数据库,或许在技术上它与其他领先的关系数据库相差并不大,或不具有劣势。但是,对于一些企业环境来说,MySQL(和PHP搭配之最佳组合)显然不具有优势。 所以不要盲目随大流,也要根据其功能性能的好坏去选择,对MySQL数据库的选用也不是说一定不好,只是在上面这五点上做的不是很好,其他方面还是值得肯定的。

[关于数据库解析不使用的五个理由]

篇8:《告诉你个秘密》阅读答案

王举芳

暑热天气,便想着吃些清凉的菜。附近的小菜市场有家夫妻俩开的小店,专卖凉拌莱,我简单挑了几样,顺便买些时令蔬菜。蔬菜店的老板姓吴,是个憨厚的小伙儿,待人热情、实诚,我是他家的老主顾。

“姐,今天买的什么好吃的啊?”小吴问。“买了点凉菜。”我边说边挑蔬菜。

“姐,从哪家买的凉拌菜啊?”“拐过街角第一家。”我把挑好的眉豆递给他。

“姐,我告诉你个秘密。”他压低声音对我说。我有点意外,虽然彼此算是熟人,但我觉得没有熟到可以分享秘密的地步。

“姐,你可不要告诉别人哦,你自己心里有数就行了。”他声音轻轻的。

我点点头。他声音很低地说:“姐,街角这家卖凉拌菜的,你不要买,前几天这家男人的哥哥刚死了,你知道是什么病吗?肝炎,肝炎啊!你要吃凉拌菜,去南面的那家,那家干净。”我点点头,对他道了谢,提着菜走出店门。

因为知道了那个秘密,看看手中的凉拌菜,我的胃里不由得开始翻腾,赶紧像避瘟神般,快速把它们扔进了垃圾桶。

人的猜疑和想象力的后作用真是魔力无限。好些天,一说凉拌菜,我都觉得胃不舒服。

那天,去离家一里多地的农贸市场买菜,碰到刘姐,她做海鲜生意。我们住在一个小区不常见但也不陌生。

“你来买菜啊,不常见你来呢。”刘姐热情地跟我打招呼。

“我想买点百姓自家种的苋菜。”我说。

“哦,你去中间那家买,那个老太太种的菜不用乱七八糟的肥料。”我应答着,去刘姐说的摊位买了苋菜。往回走,刘姐喊住我,递给我一个板凳。

“你平时都去哪里买菜啊?”“我平时买菜就近,就去小吴那个店。”“小吴 的店啊?”“嗯。他人很好,不短斤少两的,卖的菜质量也行。”我实话实说。

“哦,这样啊。我本来不想说的,可是不告诉你,我良心过不去啊。”刘姐有些面露难色。其实我不喜欢知道很多事,知道的事情太多,,有时候会增添许多烦恼。

“你可不要告诉别人。知道吗?那个小吴最近生病了,肺结核哦,那天我在医院看到小吴进了传染病区,医生说他得的是肺结核。你说小吴有传染病,谁能保证他卖的菜不会携带传染病菌啊。以后别去小吴那里买菜了哈。”

谢了刘姐的好意,往家走。忽然觉得心里沉了很多,因为知道了这秘密。

一天去饭店吃饭,邻桌全是农贸市场和小菜市场的生鲜蔬菜商户,刘姐也在,唯独不见小吴。嗯,小吴有传染病,不能叫他到这公共场合来,我这样想。

去洗手间,听到刘姐在说话:“妈,小吴想抢我们的生意,没门。我妹妹和妹夫在小菜市场卖凉拌菜,碍他啥事了?我妹夫的哥哥是得肝炎死了,这并不代表我妹夫也有病是吧?不就是南面那个卖凉拌菜的女人是他未来的大姨子吗?他会到处跟人说秘密,我们也会 。你等着瞧吧,他那个店就快关门了。”

“小吴真得了肺结核吗?”

“没,是他家远房亲戚得了肺结核。我这叫以其人之道还治其人之身……”

“闺女,这你可做得不对,人家小吴没得肺结核你怎么可以说人家得了呢?”

“他跟好几个人都说我妹 妹家的凉拌菜不能买呢,我只是----”

“只是什么?唉,你这样冤冤相报何时了,咱们生意人,更不能这样昧着良心做事,人心是杆秤啊,以后你要是再说人家小吴得了肺结核,我就当众揭穿你,听到没?”

“可是----”“没什么可是的,我做了一辈子买卖,从没亏欠过自己的良心。人在做,天在看。公道自在人心。”听到她们走出来,我躲到了拐角。

原来卖苋菜的老太太是刘姐的母亲。这个秘密,却似一阵无比清爽的风吹向我的心田。顿时,眼前被滚滚暑热笼罩的世界,变得清凉、清亮起来。

(选自第4期《小说选刊》)

篇9:《告诉你个秘密》阅读答案

5.小说的结尾一段有何妙处?请结合全文简要分析。(6分)

6.(6分)⑴小说结尾揭示的最后一个秘密与前两个秘密的截然不同与偶然巧合形成情节上的突转,给读者带来意料之外、情理之中的艺术享受,颇为耐人寻味;⑵体现了社会主流价值,传递了正能量,契合人们心理上、精神上的期待与追求,令人感动、鼓舞,富有教育意义;⑶卒章显志,水到渠成、自然而然地借助“我”惬意、愉悦的感受点明并升华主题。(每点2分。)

告诉你

一种简单方便的权限管理方法使用菜单数据库教程

什么是数据仓库数据库教程

自定义链接后端数据库数据库教程

Building a TSQL Loop数据库教程

天天模拟器使用教程

音乐管家婆使用教程

NeroBurningRom简明使用教程

怎样去宣传数据仓库?数据库教程

oracle里的常用命令数据库教程

《告诉你使用SQL Server 的3个理由数据库教程(集锦9篇).doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式

点击下载本文文档