下列语句部分是MsSql语句,不可以在access中使用。
SQL分类: DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE) DML—数据操纵语言(SELECT,DELETE,UPDATE,INSERT) DCL—数据控制语言(GRANT,REVOKE,COMMIT,ROLLBACK)
首先,简要介绍基础语句: 1、说明:创建数据库 CREATE DATABASE database-name 2、说明:删除数据库 drop database dbname 3、说明:备份sql server --- 创建 备份数据的 device USE master EXEC sp_addumpdevice 'disk', 'testBack', 'c:/mssql7backup/MyNwind_1.dat' --- 开始 备份 BACKUP DATABASE pubs TO testBack 4、说明:创建新表 create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..) 根据已有的表创建新表: A:create table tab_new like tab_old (使用旧表创建新表) B:create table tab_new as select col1,col2… from tab_old definition only 5、说明:删除新表 drop table tabname 6、说明:增加一个列 Alter table tabname add column col type 注:列增加后将不能删除。DB2中列加上后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。 7、说明:添加主键: Alter table tabname add primary key(col) 说明:删除主键: Alter table tabname drop primary key(col) 8、说明:创建索引:create [unique] index idxname on tabname(col….) 删除索引:drop index idxname 注:索引是不可更改的,想更改必须删除重新建。 9、说明:创建视图:create view viewname as select statement 删除视图:drop view viewname 10、说明:几个简单的基本的sql语句 选择:select * from table1 where 范围 插入:insert into table1(field1,field2) values(value1,value2) 删除:delete from table1 where 范围 更新:update table1 set field1=value1 where 范围 查找:select * from table1 where field1 like ’%value1%’ ---like的语法很精妙,查资料! 排序:select * from table1 order by field1,field2 [desc] 总数:select count * as totalcount from table1 求和:select sum(field1) as sumvalue from table1 平均:select avg(field1) as avgvalue from table1 最大:select max(field1) as maxvalue from table1 最小:select min(field1) as minvalue from table1 11、说明:几个高级查询运算词 A: UNION 运算符 UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表。当 ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2。 B: EXCEPT 运算符 EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当 ALL 随 EXCEPT 一起使用时 (EXCEPT ALL),不消除重复行。 C: INTERSECT 运算符 INTERSECT 运算符通过只包括 TABLE1 和 TABLE2 中都有的行并消除所有重复行而派生出一个结果表。当 ALL 随 INTERSECT 一起使用时 (INTERSECT ALL),不消除重复行。 注:使用运算词的几个查询结果行必须是一致的。 12、说明:使用外连接 A、left outer join: 左外连接(左连接):结果集几包括连接表的匹配行,也包括左连接表的所有行。 SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c B:right outer join: 右外连接(右连接):结果集既包括连接表的匹配连接行,也包括右连接表的所有行。 C:full outer join: 全外连接:不仅包括符号连接表的匹配行,还包括两个连接表中的所有记录。
其次,大家来看一些不错的sql语句 1、说明:复制表(只复制结构,源表名:a 新表名:b) (Access可用) 法一:select * into b from a where 1<>1 法二:select top 0 * into b from a
2、说明:拷贝表(拷贝数据,源表名:a 目标表名:b) (Access可用) insert into b(a, b, c) select d,e,f from b;
3、说明:跨数据库之间表的拷贝(具体数据使用绝对路径) (Access可用) insert into b(a, b, c) select d,e,f from b in ‘具体数据库’ where 条件 例子:..from b in '"&Server.MapPath(".")&"/data.mdb" &"' where..
4、说明:子查询(表名1:a 表名2:b) select a,b,c from a where a IN (select d from b ) 或者: select a,b,c from a where a IN (1,2,3)
5、说明:显示文章、提交人和最后回复时间 select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b
6、说明:外连接查询(表名1:a 表名2:b) select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
7、说明:在线视图查询(表名1:a ) select * from (SELECT a,b,c FROM a) T where t.a > 1;
8、说明:between的用法,between限制查询数据范围时包括了边界值,not between不包括 select * from table1 where time between time1 and time2 select a,b,c, from table1 where a not between 数值1 and 数值2
9、说明:in 的使用方法 select * from table1 where a [not] in (‘值1’,’值2’,’值4’,’值6’)
10、说明:两张关联表,删除主表中已经在副表中没有的信息 delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 )
11、说明:四表联查问题: select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....
12、说明:日程安排提前五分钟提醒 SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5
13、说明:一条sql 语句搞定数据库分页 select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段desc) a,表名 b where b.主键字段 = a.主键字段 order by a.排序字段
14、说明:前10条记录 select top 10 * form table1 where 范围
15、说明:选择在每一组b值相同的数据中对应的a最大的记录的所有信息(类似这样的用法可以用于论坛每月排行榜,每月热销产品分析,按科目成绩排名,等等.) select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b)
16、说明:包括所有在 TableA 中但不在 TableB和TableC 中的行并消除所有重复行而派生出一个结果表 (select a from tableA ) except (select a from tableB) except (select a from tableC)
17、说明:随机取出10条数据 select top 10 * from tablename order by newid()
18、说明:随机选择记录 select newid()
19、说明:删除重复记录 Delete from tablename where id not in (select max(id) from tablename group by col1,col2,...)
20、说明:列出数据库里所有的表名 select name from sysobjects where type='U'
21、说明:列出表里的所有的 select name from syscolumns where id=object_id('TableName')
22、说明:列示type、vender、pcs字段,以type字段排列,case可以方便地实现多重选择,类似select 中的case。 select type,sum(case vender when 'A' then pcs else 0 end),sum(case vender when 'C' then pcs else 0 end),sum(case vender when 'B' then pcs else 0 end) FROM tablename group by type 显示结果: type vender pcs 电脑 A 1 电脑 A 1 光盘 B 2 光盘 A 2 手机 B 3 手机 C 3
23、说明:初始化表table1 TRUNCATE TABLE table1
24、说明:选择从10到15的记录 select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc 随机选择数据库记录的方法(使用Randomize函数,通过SQL语句实现) 对存储在数据库中的数据来说,随机数特性能给出上面的效果,但它们可能太慢了些。你不能要求ASP“找个随机数”然后打印出来。实际上常见的解决方案是建立如下所示的循环: Randomize RNumber = Int(Rnd*499) +1 While Not objRec.EOF If objRec("ID") = RNumber THEN ... 这里是执行脚本 ... end if objRec.MoveNext Wend 这很容易理解。首先,你取出1到500范围之内的一个随机数(假设500就是数据库内记录的总数)。然后,你遍历每一记录来测试ID 的值、检查其是否匹配RNumber。满足条件的话就执行由THEN 关键字开始的那一块代码。假如你的RNumber 等于495,那么要循环一遍数据库花的时间可就长了。虽然500这个数字看起来大了些,但相比更为稳固的企业解决方案这还是个小型数据库了,后者通常在一个数据库内就包含了成千上万条记录。这时候不就死定了? 采用SQL,你就可以很快地找出准确的记录并且打开一个只包含该记录的recordset,如下所示: Randomize RNumber = Int(Rnd*499) + 1 SQL = "SELECT * FROM Customers WHERE ID = " & RNumber set objRec = ObjConn.Execute(SQL) Response.WriteRNumber & " = " & objRec("ID") & " " & objRec("c_email") 不必写出RNumber 和ID,你只需要检查匹配情况即可。只要你对以上代码的工作满意,你自可按需操作“随机”记录。Recordset没有包含其他内容,因此你很快就能找到你需要的记录这样就大大降低了处理时间。 再谈随机数 现在你下定决心要榨干Random 函数的最后一滴油,那么你可能会一次取出多条随机记录或者想采用一定随机范围内的记录。把上面的标准Random 示例扩展一下就可以用SQL应对上面两种情况了。 为了取出几条随机选择的记录并存放在同一recordset内,你可以存储三个随机数,然后查询数据库获得匹配这些数字的记录: SQL = "SELECT * FROM Customers WHERE ID = " & RNumber & " OR ID = " & RNumber2 & " OR ID = " & RNumber3 假如你想选出10条记录(也许是每次页面装载时的10条链接的列表),你可以用BETWEEN 或者数学等式选出第一条记录和适当数量的递增记录。这一操作可以通过好几种方式来完成,但是 SELECT 语句只显示一种可能(这里的ID 是自动生成的号码): SQL = "SELECT * FROM Customers WHERE ID BETWEEN " & RNumber & " AND " & RNumber & "+ 9"
注意:以上代码的执行目的不是检查数据库内是否有9条并发记录。
随机读取若干条记录,测试过 Access语法:SELECT top 10 * From 表名 ORDER BY Rnd(id) Sql server语法:select top n * from 表名 order by newid() MySql语法:Select * From 表名 Order By rand() Limit n Access左连接语法(最近开发要用左连接,Access帮助什么都没有,网上没有Access的SQL说明,只有自己测试, 现在记下以备后查) 语法:Select table1.fd1,table1,fd2,table2.fd2 From table1 left join table2 on table1.fd1,table2.fd1 where ... 使用SQL语句 用...代替过长的字符串显示 语法: SQL数据库:select case when len(field)>10 then left(field,10)+'...' else field end as news_name,news_id from tablename Access数据库:SELECT iif(len(field)>2,left(field,2)+'...',field) FROM tablename; Conn.Execute说明 Execute方法 该方法用于执行SQL语句。根据SQL语句执行后是否返回记录集,该方法的使用格式分为以下两种: 1.执行SQL查询语句时,将返回查询得到的记录集。用法为: Set 对象变量名=连接对象.Execute("SQL 查询语言") Execute方法调用后,会自动创建记录集对象,并将查询结果存储在该记录对象中,通过Set方法,将记录集赋给指定的对象保存,以后对象变量就代表了该记录集对象。
2.执行SQL的操作性语言时,没有记录集的返回。此时用法为: 连接对象.Execute "SQL 操作性语句" [, RecordAffected][, Option] ·RecordAffected 为可选项,此出可放置一个变量,SQL语句执行后,所生效的记录数会自动保存到该变量中。通过访问该变量,就可知道SQL语句队多少条记录进行了操作。 ·Option 可选项,该参数的取值通常为adCMDText,它用于告诉ADO,应该将Execute方法之后的第一个字符解释为命令文本。通过指定该参数,可使执行更高效。
·BeginTrans、RollbackTrans、CommitTrans方法 这三个方法是连接对象提供的用于事务处理的方法。BeginTrans用于开始一个事物;RollbackTrans用于回滚事务;CommitTrans用于提交所有的事务处理结果,即确认事务的处理。 事务处理可以将一组操作视为一个整体,只有全部语句都成功执行后,事务处理才算成功;若其中有一个语句执行失败,则整个处理就算失败,并恢复到处里前的状态。 BeginTrans和CommitTrans用于标记事务的开始和结束,在这两个之间的语句,就是作为事务处理的语句。判断事务处理是否成功,可通过连接对象的Error集合来实现,若Error集合的成员个数不为0,则说明有错误发生,事务处理失败。Error集合中的每一个Error对象,代表一个错误信息
|
1、建表格:
createtabletable_name(column1datatype[notnull][notnullprimarykey],column2datatype[notnull],...)
说明:
datatype--是资料的格式,详见表。 nutnull--可不可以允许资料有空的(尚未有资料填入)。 primarykey--是本表的主键。
2、更改表格
altertabletable_nameaddcolumncolumn_namedatatype
说明:增加一个栏位(没有删除某个栏位的语法。)
ltertabletable_nameaddprimarykey(column_name)
说明:更改表得的定义把某个栏位设为主键。 altertabletable_namedropprimarykey(column_name)
说明:把主键的定义删除。
3、建立索引
createindexindex_nameontable_name(column_name)
说明:对某个表格的栏位建立索引以增加查询时的速度。
4、删除
droptable_name
dropindex_name
二、资料形态datatypes
smallint 16位元的整数。
interger 32位元的整数。
decimal(p,s) p精确值和s大小的十进位整数,精确值p是指全部有几个数(digits)大小值,s是指小数後有几位数。如果没有特别指定,则系统会设为p=5;s=0。
float 32位元的实数。
double 64位元的实数。
char(n) n长度的字串,n不能超过254。
varchar(n) 长度不固定且其最大长度为n的字串,n不能超过4000。
|
SQL语句功能
--数据操作 SELECT--从数据库表中检索数据行和列 INSERT--向数据库表添加新数据行 DELETE--从数据库表中删除数据行 UPDATE--更新数据库表中的数据
--数据定义 CREATETABLE--创建一个数据库表 DROPTABLE--从数据库中删除表 ALTERTABLE--修改数据库表结构 CREATEVIEW--创建一个视图 DROPVIEW--从数据库中删除视图 CREATEINDEX--为数据库表创建一个索引 DROPINDEX--从数据库中删除索引 CREATEPROCEDURE--创建一个存储过程 DROPPROCEDURE--从数据库中删除存储过程 CREATETRIGGER--创建一个触发器 DROPTRIGGER--从数据库中删除触发器 CREATESCHEMA--向数据库添加一个新模式 DROPSCHEMA--从数据库中删除一个模式 CREATEDOMAIN--创建一个数据值域 ALTERDOMAIN--改变域定义 DROPDOMAIN--从数据库中删除一个域
--数据控制 GRANT--授予用户访问权限 DENY--拒绝用户访问 REVOKE--解除用户访问权限
--事务控制 COMMIT--结束当前事务 ROLLBACK--中止当前事务 SETTRANSACTION--定义当前事务数据访问特征
--程序化SQL DECLARE--为查询设定游标 EXPLAN--为查询描述数据访问计划 OPEN--检索查询结果打开一个游标 FETCH--检索一行查询结果 CLOSE--关闭游标 PREPARE--为动态执行准备SQL语句 EXECUTE--动态地执行SQL语句 DESCRIBE--描述准备好的查询
---局部变量 declare@idchar(10) --set@id=’10010001’ select@id=’10010001’
---全局变量 ---必须以@@开头 --IFELSE declare@xint@yint@zint select@x=1@y=2@z=3 if@x>@y print’x>y’--打印字符串’x>y’ elseif@y>@z print’y>z’ elseprint’z>y’ --CASE usepangu updateemployee sete_wage= case whenjob_level=’1’thene_wage*1.08 whenjob_level=’2’thene_wage*1.07 whenjob_level=’3’thene_wage*1.06 elsee_wage*1.05 end --WHILECONTINUEBREAK declare@xint@yint@cint select@x=1@y=1 while@x<3 begin print@x--打印变量x的值 while@y<3 begin select@c=100*@x+@y print@c--打印变量c的值 select@y=@y+1 end select@x=@x+1 select@y=1 end
|
--WAITFOR --例等待1小时2分零3秒后才执行SELECT语句 waitfordelay’01:02:03’ select*fromemployee --例等到晚上11点零8分后才执行SELECT语句 waitfortime’23:08:00’ select*fromemployee
***SELECT*** select*(列名)fromtable_name(表名)wherecolumn_nameoperatorvalue ex:(宿主) select*fromstock_informationwherestockid=str(nid) stockname=’str_name’ stocknamelike’%findthis%’ stocknamelike’[a-zA-Z]%’---------([]指定值的范围) stocknamelike’[^F-M]%’---------(^排除指定范围) ---------只能在使用like关键字的where子句中使用通配符) orstockpath=’stock_path’ orstocknumber<1000 andstockindex=24 notstocksex=’man’ stocknumberbetween20and100 stocknumberin(10,20,30) orderbystockiddesc(asc)---------排序,desc-降序,asc-升序 orderby1,2---------by列号 stockname=(selectstocknamefromstock_informationwherestockid=4) ---------子查询 ---------除非能确保内层select只返回一个行的值, ---------否则应在外层where子句中用一个in限定符 selectdistinctcolumn_nameformtable_name---------distinct指定检索独有的列值,不重复 selectstocknumber,"stocknumber+10"=stocknumber+10fromtable_name selectstockname,"stocknumber"=count(*)fromtable_namegroupbystockname ---------groupby将表按行分组,指定列中有相同的值 havingcount(*)=2---------having选定指定的组 select* fromtable1,table2 wheretable1.id*=table2.id--------左外部连接,table1中有的而table2中没有得以null表示 table1.id=*table2.id--------右外部连接 selectstocknamefromtable1 union[all]-----union合并查询结果集,all-保留重复行 selectstocknamefromtable2 ***insert*** insertintotable_name(Stock_name,Stock_number)value("xxx","xxxx") value(selectStockname,StocknumberfromStock_table2)---value为select语句 ***update*** updatetable_namesetStockname="xxx"[whereStockid=3] Stockname=default Stockname=null Stocknumber=Stockname+4 ***delete*** deletefromtable_namewhereStockid=3 truncatetable_name-----------删除表中所有行,仍保持表的完整性 droptabletable_name---------------完全删除表 ***altertable***---修改数据库表结构 altertabledatabase.owner.table_nameaddcolumn_namechar(2)null..... sp_helptable_name----显示表已有特征 createtabletable_name(namechar(20),agesmallint,lnamevarchar(30)) insertintotable_nameselect.........-----实现删除列的方法(创建新表) altertabletable_namedropconstraintStockname_default----删除Stockname的default约束
|
***function(/*常用函数*/)***
----统计函数---- AVG--求平均值 COUNT--统计数目 MAX--求最大值 MIN--求最小值 SUM--求和 --AVG usepangu selectavg(e_wage)asdept_avgWage fromemployee groupbydept_id --MAX --求工资最高的员工姓名 usepangu selecte_name fromemployee wheree_wage= (selectmax(e_wage) fromemployee) --STDEV() --STDEV()函数返回表达式中所有数据的标准差 --STDEVP() --STDEVP()函数返回总体标准差 --VAR() --VAR()函数返回表达式中所有值的统计变异数 --VARP() --VARP()函数返回总体变异数
----算术函数---- /***三角函数***/ SIN(float_expression)--返回以弧度表示的角的正弦 COS(float_expression)--返回以弧度表示的角的余弦 TAN(float_expression)--返回以弧度表示的角的正切 COT(float_expression)--返回以弧度表示的角的余切 /***反三角函数***/ ASIN(float_expression)--返回正弦是FLOAT值的以弧度表示的角 ACOS(float_expression)--返回余弦是FLOAT值的以弧度表示的角 ATAN(float_expression)--返回正切是FLOAT值的以弧度表示的角 ATAN2(float_expression1,float_expression2) --返回正切是float_expression1/float_expres-sion2的以弧度表示的角 DEGREES(numeric_expression) --把弧度转换为角度返回与表达式相同的数据类型可为 --INTEGER/MONEY/REAL/FLOAT类型 RADIANS(numeric_expression)--把角度转换为弧度返回与表达式相同的数据类型可为 --INTEGER/MONEY/REAL/FLOAT类型 EXP(float_expression)--返回表达式的指数值 LOG(float_expression)--返回表达式的自然对数值 LOG10(float_expression)--返回表达式的以10为底的对数值 SQRT(float_expression)--返回表达式的平方根 /***取近似值函数***/ CEILING(numeric_expression)--返回>=表达式的最小整数返回的数据类型与表达式相同可为 --INTEGER/MONEY/REAL/FLOAT类型 FLOOR(numeric_expression)--返回<=表达式的最小整数返回的数据类型与表达式相同可为 --INTEGER/MONEY/REAL/FLOAT类型 ROUND(numeric_expression)--返回以integer_expression为精度的四舍五入值返回的数据 --类型与表达式相同可为INTEGER/MONEY/REAL/FLOAT类型 ABS(numeric_expression)--返回表达式的绝对值返回的数据类型与表达式相同可为 --INTEGER/MONEY/REAL/FLOAT类型 SIGN(numeric_expression)--测试参数的正负号返回0零值1正数或-1负数返回的数据类型 --与表达式相同可为INTEGER/MONEY/REAL/FLOAT类型 PI()--返回值为π即3.1415926535897936 RAND([integer_expression])--用任选的[integer_expression]做种子值得出0-1间的随机浮点数
----字符串函数---- ASCII()--函数返回字符表达式最左端字符的ASCII码值 CHAR()--函数用于将ASCII码转换为字符 --如果没有输入0~255之间的ASCII码值CHAR函数会返回一个NULL值 LOWER()--函数把字符串全部转换为小写 UPPER()--函数把字符串全部转换为大写 STR()--函数把数值型数据转换为字符型数据 LTRIM()--函数把字符串头部的空格去掉 RTRIM()--函数把字符串尾部的空格去掉 LEFT(),RIGHT(),SUBSTRING()--函数返回部分字符串 CHARINDEX(),PATINDEX()--函数返回字符串中某个指定的子串出现的开始位置 SOUNDEX()--函数返回一个四位字符码 --SOUNDEX函数可用来查找声音相似的字符串但SOUNDEX函数对数字和汉字均只返回0值 DIFFERENCE()--函数返回由SOUNDEX函数返回的两个字符表达式的值的差异 --0两个SOUNDEX函数返回值的第一个字符不同 --1两个SOUNDEX函数返回值的第一个字符相同 --2两个SOUNDEX函数返回值的第一二个字符相同 --3两个SOUNDEX函数返回值的第一二三个字符相同 --4两个SOUNDEX函数返回值完全相同
QUOTENAME()--函数返回被特定字符括起来的字符串 /*selectquotename(’abc’,’{’)quotename(’abc’) 运行结果如下 ----------------------------------{ {abc}[abc]*/ REPLICATE()--函数返回一个重复character_expression指定次数的字符串 /*selectreplicate(’abc’,3)replicate(’abc’,-2) 运行结果如下 ---------------------- abcabcabcNULL*/ REVERSE()--函数将指定的字符串的字符排列顺序颠倒 REPLACE()--函数返回被替换了指定子串的字符串 /*selectreplace(’abc123g’,’123’,’def’) 运行结果如下 ---------------------- abcdefg*/ SPACE()--函数返回一个有指定长度的空白字符串 STUFF()--函数用另一子串替换字符串指定位置长度的子串
----数据类型转换函数---- CAST()函数语法如下 CAST()(<expression>AS<data_type>[length]) CONVERT()函数语法如下 CONVERT()(<data_type>[length],<expression>[,style]) selectcast(100+99aschar)convert(varchar(12),getdate()) 运行结果如下 ------------------------------------------ 199Jan152000
----日期函数---- DAY()--函数返回date_expression中的日期值 MONTH()--函数返回date_expression中的月份值 YEAR()--函数返回date_expression中的年份值 DATEADD(<datepart>,<number>,<date>) --函数返回指定日期date加上指定的额外日期间隔number产生的新日期 DATEDIFF(<datepart>,<number>,<date>) --函数返回两个指定日期在datepart方面的不同之处 DATENAME(<datepart>,<date>)--函数以字符串的形式返回日期的指定部分 DATEPART(<datepart>,<date>)--函数以整数值的形式返回日期的指定部分 GETDATE()--函数以DATETIME的缺省格式返回系统当前的日期和时间
----系统函数---- APP_NAME()--函数返回当前执行的应用程序的名称 COALESCE()--函数返回众多表达式中第一个非NULL表达式的值 COL_LENGTH(<’table_name’>,<’column_name’>)--函数返回表中指定字段的长度值 COL_NAME(<table_id>,<column_id>)--函数返回表中指定字段的名称即列名 DATALENGTH()--函数返回数据表达式的数据的实际长度 DB_ID([’database_name’])--函数返回数据库的编号 DB_NAME(database_id)--函数返回数据库的名称 HOST_ID()--函数返回服务器端计算机的名称 HOST_NAME()--函数返回服务器端计算机的名称 IDENTITY(<data_type>[,seedincrement])[AScolumn_name]) --IDENTITY()函数只在SELECTINTO语句中使用用于插入一个identitycolumn列到新表中 /*selectidentity(int,1,1)ascolumn_name intonewtable fromoldtable*/ ISDATE()--函数判断所给定的表达式是否为合理日期 ISNULL(<check_expression>,<replacement_value>)--函数将表达式中的NULL值用指定值替换 ISNUMERIC()--函数判断所给定的表达式是否为合理的数值 NEWID()--函数返回一个UNIQUEIDENTIFIER类型的数值 NULLIF(<expression1>,<expression2>) --NULLIF函数在expression1与expression2相等时返回NULL值若不相等时则返回expression1的值
|
sql中的保留字
actionaddaggregateall alterafterandas ascavgavg_row_lengthauto_increment betweenbigintbitbinary blobboolbothby cascadecasecharcharacter changecheckchecksumcolumn columnscommentconstraintcreate crosscurrent_datecurrent_timecurrent_timestamp datadatabasedatabasesdate datetimedayday_hourday_minute day_seconddayofmonthdayofweekdayofyear decdecimaldefaultdelayed delay_key_writedeletedescdescribe distinctdistinctrowdoubledrop endelseescapeescaped enclosedenumexplainexists fieldsfilefirstfloat float4float8flushforeign fromforfullfunction globalgrantgrantsgroup havingheaphigh_priorityhour hour_minutehour_secondhostsidentified ignoreinindexinfile innerinsertinsert_idint integerintervalint1int2 int3int4int8into ifisisamjoin keykeyskilllast_insert_id leadingleftlengthlike lineslimitloadlocal locklogslonglongblob longtextlow_prioritymaxmax_rows matchmediumblobmediumtextmediumint middleintmin_rowsminuteminute_second modifymonthmonthnamemyisam naturalnumericnonot nullonoptimizeoption optionallyororderouter outfilepack_keyspartialpassword precisionprimaryprocedureprocess processlistprivilegesreadreal referencesreloadregexprename replacerestrictreturnsrevoke rlikerowrowssecond selectsetshowshutdown smallintsonamesql_big_tablessql_big_selects sql_low_priority_updatessql_log_offsql_log_updatesql_select_limit sql_small_resultsql_big_resultsql_warningsstraight_join startingstatusstringtable tablestemporaryterminatedtext thentimetimestamptinyblob tinytexttinyinttrailingto typeuseusingunique unlockunsignedupdateusage valuesvarcharvariablesvarying varbinarywithwritewhen whereyearyear_monthzerofill
|
|
|
1.SQL存储过程概述
在大型数据库系统中,存储过程和触发器具有很重要的作用。无论是存储过程还是触发器,都是SQL语句和流程控制语句的集合。就本质而言,触发器也是一种存储过程。存储过程在运算时生成执行方式,所以,以后对其再运行时其执行速度很快。SQLServer2000不仅提供了用户自定义存储过程的功能,而且也提供了许多可作为工具使用的系统存储过程。
存储过程的概念
存储过程(StoredProcedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库。中用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。
在SQLServer的系列版本中存储过程分为两类:系统提供的存储过程和用户自定义存储过程。系统过程主要存储在master数据库中并以sp_为前缀,并且系统存储过程主要是从系统表中获取信息,从而为系统管理员管理SQLServer提供支持。通过系统存储过程,MSSQLServer中的许多管理性或信息性的活动(如了解数据库对象、数据库信息)都可以被顺利有效地完成。尽管这些系统存储过程被放在master数据库中,但是仍可以在其它数据库中对其进行调用,在调用时不必在存储过程名前加上数据库名。而且当创建一个新数据库时,一些系统存储过程会在新数据库中被自动创建。用户自定义存储过程是由用户创建并能完成某一特定功能(如查询用户所需数据信息)的存储过程。在本章中所涉及到的存储过程主要是指用户自定义存储过程。
存储过程的优点
当利用MSSQLServer创建一个应用程序时,Transaction-SQL是一种主要的编程语言。若运用Transaction-SQL来进行编程,有两种方法。其一是,在本地存储Transaction-SQL程序,并创建应用程序向SQLServer发送命令来对结果进行处理。其二是,可以把部分用Transaction-SQL编写的程序作为存储过程存储在SQLServer中,并创建应用程序来调用存储过程,对数据结果进行处理存储过程能够通过接收参数向调用者返回结果集,结果集的格式由调用者确定;返回状态值给调用者,指明调用是成功或是失败;包括针对数据库的操作语句,并且可以在一个存储过程中调用另一存储过程。
我们通常更偏爱于使用第二种方法,即在SQLServer中使用存储过程而不是在客户计算机上调用Transaction-SQL编写的一段程序,原因在于存储过程具有以下优点:
(1)存储过程允许标准组件式编程
存储过程在被创建以后可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。而且数据库专业人员可随时对存储过程进行修改,但对应用程序源代码毫无影响(因为应用程序源代码只包含存储过程的调用语句),从而极大地提高了程序的可移植性。
(2)存储过程能够实现较快的执行速度
如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的,在首次运行一个存储过程时,查询优化器对其进行分析、优化,并给出最终被存在系统表中的执行计划。而批处理的Transaction-SQL语句在每次运行时都要进行编译和优化,因此速度相对要慢一些。
(3)存储过程能够减少网络流量
对于同一个针对数据数据库对象的操作(如查询、修改),如果这一操作所涉及到的Transaction-SQL语句被组织成一存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,否则将是多条SQL语句,从而大大增加了网络流量,降低网络负载。
|
(4)存储过程可被作为一种安全机制来充分利用
系统管理员通过对执行某一存储过程的权限进行限制,从而能够实现对相应的数据访问权限的限制,避免非授权用户对数据的访问,保证数据的安全。(我们将在14章“SQLServer的用户和安全性管理”中对存储过程的这一应用作更为清晰的介绍)
注意:存储过程虽然既有参数又有返回值,但是它与函数不同。存储过程的返回值只是指明执行是否成功,并且它不能像函数那样被直接调用,也就是在调用存储过程时,在存储过程名字前一定要有EXEC保留字。
2.SQL存储过程创建
创建存储过程,存储过程是保存起来的可以接受和返回用户提供的参数的Transact-SQL语句的集合。
可以创建一个过程供永久使用,或在一个会话中临时使用(局部临时过程),或在所有会话中临时使用(全局临时过程)。
也可以创建在Microsoft?SQLServer?启动时自动运行的存储过程。
语法 CREATEPROC[EDURE]procedure_name[;number] [{@parameterdata_type} [VARYING][=default][OUTPUT] ][,...n]
[WITH {RECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTION}]
[FORREPLICATION]
ASsql_statement[...n] 参数
procedure_name
新存储过程的名称。过程名必须符合标识符规则,且对于数据库及其所有者必须唯一。 要创建局部临时过程,可以在procedure_name前面加一个编号符(#procedure_name),要创建全局临时过程,可以在procedure_name前面加两个编号符(##procedure_name)。完整的名称(包括#或##)不能超过128个字符。指定过程所有者的名称是可选的。
;number
是可选的整数,用来对同名的过程分组,以便用一条DROPPROCEDURE语句即可将同组的过程一起除去。例如,名为orders的应用程序使用的过程可以命名为orderproc;1、orderproc;2等。DROPPROCEDUREorderproc语句将除去整个组。如果名称中包含定界标识符,则数字不应包含在标识符中,只应在procedure_name前后使用适当的定界符。
@parameter
过程中的参数。在CREATEPROCEDURE语句中可以声明一个或多个参数。用户必须在执行过程时提供每个所声明参数的值(除非定义了该参数的默认值)。存储过程最多可以有2.100个参数。
使用@符号作为第一个字符来指定参数名称。参数名称必须符合标识符的规则。每个过程的参数仅用于该过程本身;相同的参数名称可以用在其它过程中。默认情况下,参数只能代替常量,而不能用于代替表名、列名或其它数据库对象的名称。 data_type
参数的数据类型。所有数据类型(包括text、ntext和image)均可以用作存储过程的参数。不过,cursor数据类型只能用于OUTPUT参数。如果指定的数据类型为cursor,也必须同时指定VARYING和OUTPUT关键字。
说明 对于可以是cursor数据类型的输出参数,没有最大数目的限制。
VARYING
指定作为输出参数支持的结果集(由存储过程动态构造,内容可以变化)。仅适用于游标参数。
|
default
参数的默认值。如果定义了默认值,不必指定该参数的值即可执行过程。默认值必须是常量或NULL。如果过程将对该参数使用LIKE关键字,那么默认值中可以包含通配符(%、_、[]和[^])。
OUTPUT
表明参数是返回参数。该选项的值可以返回给EXEC[UTE]。使用OUTPUT参数可将信息返回给调用过程。Text、ntext和image参数可用作OUTPUT参数。使用OUTPUT关键字的输出参数可以是游标占位符。
n
表示最多可以指定2.100个参数的占位符。
{RECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTION}
RECOMPILE表明SQLServer不会缓存该过程的计划,该过程将在运行时重新编译。在使用非典型值或临时值而不希望覆盖缓存在内存中的执行计划时,请使用RECOMPILE选项。
ENCRYPTION表示SQLServer加密syscomments表中包含CREATEPROCEDURE语句文本的条目。使用ENCRYPTION可防止将过程作为SQLServer复制的一部分发布。
说明 在升级过程中,SQLServer利用存储在syscomments中的加密注释来重新创建加密过程。
FORREPLICATION
指定不能在订阅服务器上执行为复制创建的存储过程。.使用FORREPLICATION选项创建的存储过程可用作存储过程筛选,且只能在复制过程中执行。本选项不能和WITHRECOMPILE选项一起使用。
AS
指定过程要执行的操作。
sql_statement
过程中要包含的任意数目和类型的Transact-SQL语句。但有一些限制。
n
是表示此过程可以包含多条Transact-SQL语句的占位符。
注释 存储过程的最大大小为128MB。 用户定义的存储过程只能在当前数据库中创建(临时过程除外,临时过程总是在tempdb中创建)。在单个批处理中,CREATEPROCEDURE语句不能与其它Transact-SQL语句组合使用。
默认情况下,参数可为空。如果传递NULL参数值并且该参数在CREATE或ALTERTABLE语句中使用,而该语句中引用的列又不允许使用NULL,则SQLServer会产生一条错误信息。为了防止向不允许使用NULL的列传递NULL参数值,应向过程中添加编程逻辑或为该列使用默认值(使用CREATE或ALTERTABLE的DEFAULT关键字)。
建议在存储过程的任何CREATETABLE或ALTERTABLE语句中都为每列显式指定NULL或NOTNULL,例如在创建临时表时。ANSI_DFLT_ON和ANSI_DFLT_OFF选项控制SQLServer为列指派NULL或NOTNULL特性的方式(如果在CREATETABLE或ALTERTABLE语句中没有指定的话)。如果某个连接执行的存储过程对这些选项的设置与创建该过程的连接的设置不同,则为第二个连接创建的表列可能会有不同的为空性,并且表现出不同的行为方式。如果为每个列显式声明了NULL或NOTNULL,那么将对所有执行该存储过程的连接使用相同的为空性创建临时表。
在创建或更改存储过程时,SQLServer将保存SETQUOTED_IDENTIFIER和SETANSI_NULLS的设置。执行存储过程时,将使用这些原始设置。因此,所有客户端会话的SETQUOTED_IDENTIFIER和SETANSI_NULLS设置在执行存储过程时都将被忽略。在存储过程中出现的SETQUOTED_IDENTIFIER和SETANSI_NULLS语句不影响存储过程的功能。
其它SET选项(例如SETARITHABORT、SETANSI_WARNINGS或SETANSI_PADDINGS)在创建或更改存储过程时不保存。如果存储过程的逻辑取决于特定的设置,应在过程开头添加一条SET语句,以确保设置正确。从存储过程中执行SET语句时,该设置只在存储过程完成之前有效。之后,设置将恢复为调用存储过程时的值。这使个别的客户端可以设置所需的选项,而不会影响存储过程的逻辑。
|
说明 SQLServer是将空字符串解释为单个空格还是解释为真正的空字符串,由兼容级别设置控制。 如果兼容级别小于或等于65,SQLServer就将空字符串解释为单个空格。 如果兼容级别等于70,则SQLServer将空字符串解释为空字符串。 获得有关存储过程的信息 若要显示用来创建过程的文本,请在过程所在的数据库中执行sp_helptext,并使用过程名作为参数。
说明 使用ENCRYPTION选项创建的存储过程不能使用sp_helptext查看。
若要显示有关过程引用的对象的报表,请使用sp_depends。
若要为过程重命名,请使用sp_rename。
引用对象
SQLServer允许创建的存储过程引用尚不存在的对象。在创建时,只进行语法检查。执行时,如果高速缓存中尚无有效的计划,则编译存储过程以生成执行计划。只有在编译过程中才解析存储过程中引用的所有对象。因此,如果语法正确的存储过程引用了不存在的对象,则仍可以成功创建,但在运行时将失败,因为所引用的对象不存在。 延迟名称解析和兼容级别 SQLServer允许Transact-SQL存储过程在创建时引用不存在的表。这种能力称为延迟名称解析。不过,如果Transact-SQL存储过程引用了该存储过程中定义的表,而兼容级别设置(通过执行sp_dbcmptlevel来设置)为65,则在创建时会发出警告信息。而如果在运行时所引用的表不存在,将返回错误信息。
执行存储过程
成功执行CREATEPROCEDURE语句后,过程名称将存储在sysobjects系统表中,而CREATEPROCEDURE语句的文本将存储在syscomments中。第一次执行时,将编译该过程以确定检索数据的最佳访问计划。
使用cursor数据类型的参数
存储过程只能将cursor数据类型用于OUTPUT参数。如果为某个参数指定了cursor数据类型,也必须指定VARYING和OUTPUT参数。如果为某个参数指定了VARYING关键字,则数据类型必须是cursor,并且必须指定OUTPUT关键字。
说明 cursor数据类型不能通过数据库API(例如OLEDB、ODBC、ADO和DB-Library)绑定到应用程序变量上。因为必须先绑定OUTPUT参数,应用程序才可以执行存储过程,所以带有cursorOUTPUT参数的存储过程不能通过数据库API调用。只有将cursorOUTPUT变量赋值给Transact-SQL局部cursor变量时,才可以通过Transact-SQL批处理、存储过程或触发器调用这些过程。
Cursor输出参数 在执行过程时,以下规则适用于cursor输出参数:
对于只进游标,游标的结果集中返回的行只是那些存储过程执行结束时处于或超出游标位置的行,例如: 在过程中的名为RS的100行结果集上打开一个非滚动游标。
过程提取结果集RS的头5行。
过程返回到其调用者。
返回到调用者的结果集RS由RS的第6到100行组成,调用者中的游标处于RS的第一行之前。 对于只进游标,如果存储过程完成后,游标位于第一行的前面,则整个结果集将返回给调用批处理、存储过程或触发器。返回时,游标将位于第一行的前面。
对于只进游标,如果存储过程完成后,游标的位置超出最后一行的结尾,则为调用批处理、存储过程或触发器返回空结果集。
说明 空结果集与空值不同。
对于可滚动游标,在存储过程执行结束时,结果集中的所有行均会返回给调用批处理、存储过程或触发器。返回时,游标保留在过程中最后一次执行提取时的位置。
对于任意类型的游标,如果游标关闭,则将空值传递回调用批处理、存储过程或触发器。如果将游标指派给一个参数,但该游标从未打开过,也会出现这种情况。
说明 关闭状态只有在返回时才有影响。例如,可以在过程中关闭游标,稍后再打开游标,然后将该游标的结果集返回给调用批处理、存储过程或触发器。
|
临时存储过程
SQLServer支持两种临时过程:局部临时过程和全局临时过程。局部临时过程只能由创建该过程的连接使用。全局临时过程则可由所有连接使用。局部临时过程在当前会话结束时自动除去。全局临时过程在使用该过程的最后一个会话结束时除去。通常是在创建该过程的会话结束时。
临时过程用#和##命名,可以由任何用户创建。创建过程后,局部过程的所有者是唯一可以使用该过程的用户。执行局部临时过程的权限不能授予其他用户。如果创建了全局临时过程,则所有用户均可以访问该过程,权限不能显式废除。只有在tempdb数据库中具有显式CREATEPROCEDURE权限的用户,才可以在该数据库中显式创建临时过程(不使用编号符命名)。可以授予或废除这些过程中的权限。
说明 频繁使用临时存储过程会在tempdb中的系统表上产生争用,从而对性能产生负面影响。建议使用sp_executesql代替。sp_executesql不在系统表中存储数据,因此可以避免这一问题。
自动执行存储过程
SQLServer启动时可以自动执行一个或多个存储过程。这些存储过程必须由系统管理员创建,并在sysadmin固定服务器角色下作为后台过程执行。这些过程不能有任何输入参数。
对启动过程的数目没有限制,但是要注意,每个启动过程在执行时都会占用一个连接。如果必须在启动时执行多个过程,但不需要并行执行,则可以指定一个过程作为启动过程,让该过程调用其它过程。这样就只占用一个连接。
在启动时恢复了最后一个数据库后,即开始执行存储过程。若要跳过这些存储过程的执行,请将启动参数指定为跟踪标记4022。如果以最低配置启动SQLServer(使用-f标记),则启动存储过程也不会执行。 若要创建启动存储过程,必须作为sysadmin固定服务器角色的成员登录,并在master数据库中创建存储过程。
使用sp_procoption可以:
将现有存储过程指定为启动过程。
停止在SQLServer启动时执行过程。
查看SQLServer启动时执行的所有过程的列表。 存储过程嵌套 存储过程可以嵌套,即一个存储过程可以调用另一个存储过程。在被调用过程开始执行时,嵌套级将增加,在被调用过程执行结束后,嵌套级将减少。如果超出最大的嵌套级,会使整个调用过程链失败。可用@@NESTLEVEL函数返回当前的嵌套级。
若要估计编译后的存储过程大小,请使用下列性能监视计数器。
*各种分类的高速缓存对象均可以使用这些计数器,包括特殊sql、准备sql、过程、触发器等。
sql_statement限制 除了SETSHOWPLAN_TEXT和SETSHOWPLAN_ALL之外(这两个语句必须是批处理中仅有的语句),任何SET语句均可以在存储过程内部指定。所选择的SET选项在存储过程执行过程中有效,之后恢复为原来的设置。
|
|
|
如果其他用户要使用某个存储过程,那么在该存储过程内部,一些语句使用的对象名必须使用对象所有者的名称限定。这些语句包括:
ALTERTABLE
CREATEINDEX
CREATETABLE
所有DBCC语句
DROPTABLE
DROPINDEX
TRUNCATETABLE
UPDATESTATISTICS 权限 CREATEPROCEDURE的权限默认授予sysadmin固定服务器角色成员和db_owner和db_ddladmin固定数据库角色成员。sysadmin固定服务器角色成员和db_owner固定数据库角色成员可以将CREATEPROCEDURE权限转让给其他用户。执行存储过程的权限授予过程的所有者,该所有者可以为其它数据库用户设置执行权限。 示例 A.使用带有复杂SELECT语句的简单过程 下面的存储过程从四个表的联接中返回所有作者(提供了姓名)、出版的书籍以及出版社。该存储过程不使用任何参数。
USEpubs IFEXISTS(SELECTnameFROMsysobjects WHEREname=/’au_info_all/’ANDtype=/’P/’) DROPPROCEDUREau_info_all GO CREATEPROCEDUREau_info_all AS SELECTau_lname,au_fname,title,pub_name FROMauthorsaINNERJOINtitleauthorta ONa.au_id=ta.au_idINNERJOINtitlest ONt.title_id=ta.title_idINNERJOINpublishersp ONt.pub_id=p.pub_id GO
au_info_all存储过程可以通过以下方法执行:
EXECUTEau_info_all --Or EXECau_info_all
如果该过程是批处理中的第一条语句,则可使用:
au_info_all
|
|