SQL的触发器
作者:admin 日期:2010-03-17
- [1].触发器的概念
- 触发器是一种特殊类型的存储过程,当指定表中的数据发生变化时触发器自动生效。它与表紧密相连,可以看做是表定义的一部分。触发器不能通过名称被直接调用,更不允许设置参数。
- 在SQL Server中一张表可以有多个触发器。用户可以跟据Insert、Update或Delete语句对触发器进行设置,也可以对一张表上的特定操作设置多个触发器。触发器可以包含复杂的Transact-SQL语句。不论触发器所进行的操作有多复杂,触发器都只作为一个独立的单元被执行,被看作是一个事务。如果在执行触发器的过程中发生了错误,则整个事务将会自动回滚。
- [2].触发器的优点
- 1.触发器自动执行
- 对表中的数据进行修改后,触发器立即被激活。
- 2.可以调用存储过程
- 为了实现复杂的数据库更新操作,触发器可以调用一个或多个存储过程,甚至可以通过调用外部过程(不是数据库管理系统本身)完成相应的操作。
- 3.可以强化数据条件约束
- 触发器能够实现比CHECK约束更为复杂的数据完整性约束。在数据库中,为了实现数据完整性约束,可以使用CHECK约束或触发器。CHECK约束不允许引用其他表中的列来完成检查工作,而触发器可以引用其他表中的列。它更适合在大型数据库管理系统中用来约束数据的完整性。
- 4.触发器可以楚止或回滚违反引用完整性的更改
- 触发器可以检测数据库内的操作,从而取消了数据库未经许可的更新操作,使数据库修改、更新操作更安全,数据库的运行也更稳定。
- 5.级联、并行运行
- 触发器能够对数据库中的相关表实现级联更改。触发器是基于一个表创建的,但是可以针对多个表进行操作,实现数据库中相关表的级联更改。
- 6.同表多触发器
- 一个表中可以同时存在3个不同操作的触发器(Insert、Update和Delete)。
- [3].触发器的种类
- SQL Server支持两种类型的触发器:AFTER触发器和INSTEAD OF触发器。
- AFTER触发器又称为后触发器,该类触发器是在引起触发器执行的修改语句成功完成后执行。此类触发器只有在执行某一操作(Insert、Update和Delete)之后,触发器才被触发,如果修改语句错误,触发器将不会执行。AFTER触发器只能定义在表上,不能创建在视图上,但可以为针对表的同一操作定义多个触发器。可使用 sp_settriggerorder指定表上第一个和最后一个执行的AFTER触发器,在表上只能为每个INSETR、Update和Delete操作规程指定第一个执行和最后一个执行的AFTER触发器。
- INSTEAD OF触发器又称为替代触发器,当引起触发器执行的修改语句停止时,该类触发器代替触发操作执行。它可以在表上定义,也可以在视图上定义。对于每个触发操作(Insert、Update和Delete),只能定义一个INSTEAD OF触发器。
- INSTEAD OF触发器与AFTER触发器的最大不同之处在于INSTEAD OF触发器并不是在执行预定义的操作(如Insert、Update和Delete)时被触发,而仅仅是执行触发器本身。
- [4].触发器的创建
- 1.使用企业管理器创建触发器
- 在企业管理器中为数据库“MR_SQL”中的“MR_Stu_XX”表创建一个名为 “TRI_StuXX_Insert”的触发器,实现在“MR_Stu_XX”表中添加数据时,在“TRI_pp”表中自动添加数据。
- 操作步骤如下:
- (1)在操作系统的任务栏中单击“开始”菜单,选择“程序”→“Microsoft SQL Server”→“企业管理器” 命令,打开控制台目录。
- (2)在控制台目录中依次展开Microsoft SQL Server、SQL Server组、服务器、数据库的节点。
- (3)选择指定数据库中的指定表,单击鼠标右键,在快捷菜单中选择“所有任务”→“管理触发器”命令。
- (4)执行“管理触发器”命令后,打开“触发器属性”对话框,如图1所示。在“名称”文本框中输入触发器的名称,例如用触发器名“TRI_StuXX_Insert”替换[TRIGGER NAME],如图2所示。
- (5)删除FOR关键字后面的Update和Delete,使触发器具有添加(Insert)功能,如果让触发器具有更新或删除的功能,在FOR关键字后面保留Update或 Delete,Insert 、Update和Delete可以同时使用。
- (6)在“文本”文本框中输入触发器文本,SQL语句如下。
- Insert INTO TRI_pp (MR_id,MR_name,MR_char,MR_sum,MR_eng) VALUES ('001','张三',0.0,0.0,0.0)
- (7)如果没有任何错误,单击“应用”按钮,将触发器保存到数据库中。
- 2.使用Transact-SQL创建触发器
- Create TRIGGER语句用于创建触发器,触发器是一种特殊的存储过程,在用户试图对指定的表执行指定的数据修改语句时自动执行。 SQL Server 允许为任何给定的Insert、Update或Delete语句创建多个触发器。
- 语法:
- Create TRIGGER trigger_name
- ON { table | view }
- [ WITH ENCRYPTION ]
- {
- { { FOR | AFTER | INSTEAD OF } { [ Insert ] [ , ] [ Update ] }
- [ WITH APPEND ]
- [ NOT FOR REPLICATION ]
- AS
- [ { IF Update ( column )
- [ { AND | or } Update ( column ) ]
- [ ...n ]
- | IF ( COLUMNS_UpdateD ( ) { bitwise_operator } updated_bitmask )
- { comparison_operator } column_bitmask [ ...n ]
- } ]
- sql_statement [ ...n ]
- }
- }
- 参数说明:
- l trigger_name:触发器的名称。触发器名称必须符合标识符规则,并且在数据库中必须惟一。可以选择是否指定触发器所有者名称。
- l table | view:执行触发器的表或视图,有时称为触发器表或触发器视图。可以选择是否指定表或视图的所有者名称。
- l AFTER:指定触发器只有在触发SQL语句中指定的所有操作都已成功执行后才被激活。所有的引用级联操作和约束检查也必须成功完成后,才能执行此触发器。
- l INSTEAD OF:指定执行触发器而不是执行触发 SQL 语句,从而替代触发语句的操作。
- l WITH APPEND:指定应该添加现有类型的其他触发器。只有当兼容级别是65或更低时,才需要使用该可选子句。
- l NOT FOR REPLICATION:表示当复制进程更改触发器所涉及的表时,不应执行该触发器。
- l AS:触发器要执行的操作。
- l sql_statement:触发器的条件和操作。触发器条件指定其他准则,以确定Delete、Insert或Update语句是否导致执行触发器操作。
- l column:要测试 Insert或Update操作的列名。该列可以是SQL Server支持的任何数据类型。
- l bitwise_operator:用于比较运算的位运算符。
- l updated_bitmask:整型位掩码,表示实际更新或插入的列。
- l comparison_operator:比较运算符。使用等号(=)检查updated_bitmask中指定的所有列是否都实际进行了更新。使用大于号(>)检查 updated_bitmask中指定的任一列或某些列是否已更新。
- l column_bitmask:要检查的列的整型位掩码,用来检查是否已更新或插入了这些列。
- 本示例是建立两个相关表“MR_Stu_XX”和“MR_Stu_CJ”,它们都有“学生编号”和 “学生姓名”字段,并且类型相同。在“MR_Stu_XX”表中创建三个触发器,在对“MR_Stu_XX”表进行添加修改的同时,对 “MR_Stu_CJ”表也进行相应的操作。
- 操作步骤如下:
- (1)在“MR_SQL”数据库中创建“MR_Stu_CJ”表和 “MR_Stu_XX”表。
- (2)为“MR_Stu_XX”表创建触发器,SQL语句如下:
- 用Insert语句创建触发器,当在 “MR_Stu_XX”表中添加数据时,“MR_Stu_CJ”表也添加相应的数据。SQL语句如下:
- USE MR_SQL
- GO
- Create TRIGGER TRI_StuXX_Insert ON dbo.MR_Stu_XX
- FOR Insert
- AS
- DECLARE @id Char(4),@name Char(10)
- Select @id=学生编号,@name=学生姓名 from inserted
- Insert INTO MR_Stu_CJ (学生编号,学生姓名,语文,数学,英语) VALUES (@id,@name,0.0,0.0,0.0)
- GO
- 注意:在表中添加数据时,将添加的数据存放在系统临时表“inserted”中。
- 用Delete语句创建触发器,当在 “MR_Stu_XX”表中删除数据时,“MR_Stu_CJ”表也删除相应的数据。SQL语句如下:
- USE MR_SQL
- GO
- Create TRIGGER TRI_StuXX_Delete ON [dbo].[MR_Stu_XX]
- FOR Delete
- AS
- DECLARE @id char(4),@name char(10)
- select @id=学生编号,@name=学生姓名 from deleted
- Delete MR_Stu_CJ where 学生编号=@id and 学生姓名=@name
- GO
- 注意:在表中删除数据时,将删除的数据存放在系统临时表deleted中。
- 用Update语句创建触发器,当在“MR_Stu_XX”表中更新数据时,“MR_Stu_CJ”表也更新相应的数据。SQL语句如下:
- USE MR_SQL
- GO
- Create TRIGGER TRI_StuXX_Uudate ON [dbo].[MR_Stu_XX]
- FOR Update
- AS
- DECLARE @id char(4),@name char(10)
- select @id=学生编号 from deleted
- select @name=学生姓名 from Inserted
- Update MR_Stu_CJ SET 学生姓名=@name Where 学生编号 = @id
- GO
- 注意:在表中更新数据时,将更新前的数据存放在系统临时表“deleted”中,将更新后的数据存放在系统临时表“inserted”中。
- 3.创建触发器的注意事项
- (1)触发器是一个数据库对象,它的命名必须符合SQL Server 2000的标识符命名规则。
- (2)Create TRIGGER语句必须是批处理中的第一个语句。也就是说,如果该语句前面还有其他语句,应该使用批处理结束符GO隔开。
- (3)不能在临时表或系统表上创建触发器,但是在触发器中可以引用临时表,不能引用系统表。
- (4)创建触发器的权限默认分配给表的所有者,且不能将该权限转给其他用户。
- (5)触发器可以引用当前数据库以外的对象,但只能在当前数据库中创建触发器。
- (6)在含有用 Delete或Update操作定义的外键的表中,不能定义INSTEAD OF和INSTEAD OF Update触发器。
- (7)WRITETEXT 语句不会引发Insert或Update触发器。
- (8)TRUNCATE TABLE语句不能引发Delete触发器,因为该语句没有记录。
SQLSEREVER测试题
作者:admin 日期:2010-03-16
SQLSEREVER测试题(上)
一 SQLSERVER管理部分
1 请讲出身份验证模式与登录帐号的关系及如何用各种帐号进行登录,并画出示意图
2 请讲出登录帐号、数据库用户及数据库角色之间的关系,并画出示意图
3 请讲出数据库用户、数据库角色与数据库对象之间的关系,并画出直接对用户授权与间接对用户授权(系统权限与对象权限)的方法
4 请讲出服务器角色、数据库角色、标准角色与应用程序角色的区别与验证其权限的方法
5 请讲出数据库还原模型对数据库的影响
6 有一个执行关键任务的数据库,请设计一个数据库备份策略
7 请使用文件与文件组恢复的方式恢复数据库
8 请使用事务日志恢复数据库到一个时间点
9 请设计作业进行周期性的备份数据库
10 如何监控数据库的阻塞,并实现数据库的死锁测试
11 如何监控数据库的活动,并能使用索引优化向导生成索引
12 理解数据库框图的作用并可以设计表与表之间的关系
- SQLSEREVER测试题(中)
- 二 SQLSERVER的实现部分
- 1 有订单表,需要实现它的编号,格式如下:200211030001……200222039999等
- 2 有表T1,T2,现有一事务,在向表T1添加数据时,同时也必须向T2也添加数据,如何实现该事务
- 3 如何向T1中的编号字段(code varchar(20))添加一万条记录,不充许重复,规则如下:编号的数据必须从小写的a-z之间取值
- 4 如何删除表中的重复数据,请使用游标与分组的办法
- 5 如何求表中相邻的两条记录的某字段的值之差
- 6 如何统计数据库中所有用户表的数据,显示格式如下:
- 表名 记录数
- sales 23
- 7 如何删除数据库中的所有用户表(表与表之间有外键关系)
- 8 表A editor_id lb2_id
- 123 000
- 123 003
- 123 003
- 456 007
- 456 006
- 表B lb2_id lb2_name
- 000 a
- 003 b
- 006 c
- 007 d
- 显示 a 共1条 (表A内lb2_id为000的条数)
- b 共2条(表A内lb2_id为003的条数)
- 9 人员情况表(employee):里面有一字段文化程度(wh):包括四种情况(本科以上,大专,高中,初中以下),现在我要根据年龄字段查询统计出:表中文化程度为本科以上,大专,高中,初中以下,各有多少人,占总人数多少。
- Select wh AS 学历,age as 年龄, Count(*) AS 人数,
- Count(*) * 100 /(Select Count(*) FROM employee) AS 百分比
- FROM employee GROUP BY wh,age
- 学历 年龄 人数 百分比
- 本科以上 20 34 14
- 大专 20 33 13
- 高中 20 33 13
- 初中以下 20 100 40
- 本科以上 21 50 20
- 10 现在有三个表student:(FID 学生号,FName 姓名),
- subject:(FSubID 课程号,FSubName 课程名),
- Score(FScoreId 成绩记录号,FSubID 课程号,FStdID 学生号,FScore 成绩)
- 怎么能实现这个表:
- 姓名 英语 数学 语文 历史
- 张萨 78 67 89 76
- 王强 89 67 84 96
- Select a.FName AS 姓名,
- 英语 = SUM(CASE b.FSubName WHEN '英语' THEN c.FScore END),
- 数学 = SUM(CASE b.FSubName WHEN '数学' THEN c.FScore END),
- 语文 = SUM(CASE b.FSubName WHEN '语文' THEN c.FScore END),
- 历史 = SUM(CASE b.FSubName WHEN '历史' THEN c.FScore END)
- FROM Student a, Subject b, Score c
- Where a.FID = c.FStdId AND b.FSubID = c.FsubID GROUP BY a.FName
- 11 原始表的数据如下:
- PID PTime PNo
- 111111 2003-01-28 04:30:09
- 111111 2003-01-28 18:30:00
- 222222 2003-01-28 04:31:09
- 333333 2003-01-28 04:32:09
- 111111 2003-02-09 03:35:25
- 222222 2003-02-09 03:36:25
- 333333 2003-02-09 03:37:25
- 查询生成表
- PDate 111111 222222 333333 ......
- 2003-01-28 04:30:09 04:31:09 04:32:09 ......
- 2003-01-28 18:30:00
- 2003-02-09 03:35:25 03:36:25 03:37:25 ......
- 12 表一(AAA)
- 商品名称mc 商品总量sl
- A 100
- B 120
- 表二(BBB)
- 商品名称mc 出库数量sl
- A 10
- A 20
- B 10
- B 20
- B 30
- 用一条SQL语句算出商品A,B目前还剩多少?
- 一
- declare @AAA table (商品名称 varchar(10), 商品总量 int)
- insert into @AAA values('A',100)
- insert into @AAA values('B',120)
- declare @BBB table (商品名称 varchar(10), 出库数量 int)
- insert into @BBB values('A', 10)
- insert into @BBB values('A', 20)
- insert into @BBB values('B', 10)
- insert into @BBB values('B', 20)
- insert into @BBB values('B', 30)
- select TA.商品名称,A-B AS 剩余数量 FROM
- (select 商品名称,sum(商品总量) AS A
- from @AAA
- group by 商品名称)TA,
- (select 商品名称,sum(出库数量) AS B
- from @BBB
- group by 商品名称)TB
- where TA.商品名称=TB.商品名称
- 二
- select 商品名称,sum(商品总量) 剩余数量 from (select * from @aaa union all select 商品名称,-出库数量 from @bbb) a group by 商品名称
- 13 优化这句SQL语句
- Update tblExlTempYear
- SET tblExlTempYear.GDQC = tblExlTempMonth.GDQC
- FROM tblExlTempYear,tblExlTempMonth
- where tblExlTempMonth.GDXM=tblExlTempYear.GDXM and tblExlTempMonth.TXDZ=tblExlTempYear.TXDZ
- (1)、加索引:
- tblExlTempYear(GDXM,TXDZ)
- tblExlTempMonth (GDXM,TXDZ)
- (2)、删除无用数据
- (3)、转移过时数据
- (4)、加服务器内存,升级服务器
- (5)、升级网络系统
- Update tblExlTempYear
- SET tblExlTempYear.GDQC = tblExlTempMonth.GDQC
- FROM tblExlTempYear (index indexY),tblExlTempMonth (index indexM)
- where tblExlTempMonth.GDXM=tblExlTempYear.GDXM and tblExlTempMonth.TXDZ=tblExlTempYear.TXDZ
- 14 品种 日期 数量
- P0001 2002-1-10 10
- P0001 2002-1-10 11
- P0001 2002-1-10 50
- P0001 2002-1-12 9
- P0001 2002-1-12 8
- P0001 2002-1-12 7
- P0002 2002-10-10 5
- P0002 2002-10-10 7
- P0002 2002-10-12 0.5
- P0003 2002-10-10 5
- P0003 2002-10-12 7
- P0003 2002-10-12 9
- 结果要先按照品种汇总,再按照日期汇总,结果如下:
- P0001 2002-1-10 71
- P0001 2002-1-12 24
- P0002 2002-10-10 12
- P0002 2002-10-12 0.5
- P0003 2002-10-10 5
- P0003 2002-10-12 16
- SQL SERVER能做出这样的汇总吗…
- 15 在分組查循中with{cube|rollup}的區別是什么?
- 如:
- use pangu
- select firm_id,p_id,sum(o_price_quantity)as sum_values
- from orders
- group by firm_id,p_id
- with cube
- 與
- use pangu
- select firm_id,p_id,sum(o_price_quantity)as sum_values
- from orders
- group by firm_id,p_id
- with rollup
- 的區別是什么?
- CUBE 和 ROLLUP 之间的区别在于:
- CUBE 生成的结果集显示了所选列中值的所有组合的聚合。
- ROLLUP 生成的结果集显示了所选列中值的某一层次结构的聚合。
- 例如,简单表 Inventory 中包含:
- Item Color Quantity
- -------------------- -------------------- --------------------------
- Table Blue 124
- Table Red 223
- Chair Blue 101
- Chair Red 210
- 下列查询将生成小计报表:
- Select CASE WHEN (GROUPING(Item) = 1) THEN 'ALL'
- ELSE ISNULL(Item, 'UNKNOWN')
- END AS Item,
- CASE WHEN (GROUPING(Color) = 1) THEN 'ALL'
- ELSE ISNULL(Color, 'UNKNOWN')
- END AS Color,
- SUM(Quantity) AS QtySum
- FROM Inventory
- GROUP BY Item, Color WITH ROLLUP
- Item Color QtySum
- -------------------- -------------------- --------------------------
- Chair Blue 101.00
- Chair Red 210.00
- Chair ALL 311.00
- Table Blue 124.00
- Table Red 223.00
- Table ALL 347.00
- ALL ALL 658.00
- (7 row(s) affected)
- 如果查询中的 ROLLUP 关键字更改为 CUBE,那么 CUBE 结果集与上述结果相同,只是在结果集的末尾还会返回下列两行:
- ALL Blue 225.00
- ALL Red 433.00
- CUBE 操作为 Item 和 Color 中值的可能组合生成行。例如,CUBE 不仅报告与 Item 值 Chair 相组合的 Color 值的所有可能组合(Red、Blue 和 Red + Blue),而且报告与 Color 值 Red 相组合的 Item 值的所有可能组合(Chair、Table 和 Chair + Table)。对于 GROUP BY 子句中右边的列中的每个值,ROLLUP 操作并不报告左边一列(或左边各列)中值的所有可能组合。例如,ROLLUP 并不对每个 Color 值报告 Item 值的所有可能组合。ROLLUP 操作的结果集具有类似于 COMPUTE BY 所返回结果集的功能;然而,
- ROLLUP 具有下列优点: ROLLUP 返回单个结果集;COMPUTE BY 返回多个结果集,而多个结果集会增加应用程序代码的复杂性。ROLLUP 可以在服务器游标中使用;COMPUTE BY 不可以。有时,查询优化器为 ROLLUP 生成的执行计划比为 COMPUTE BY 生成的更为高效。
- 16 假如我有两个表
- 表1(电话号码,是否存在)
- 表2(电话号码,是否拨打)
- 想查找表1中的电话号码是否在表2中存在,如果存在就更新表1中的是否存在字段为1。
- Update 表1 SET 是否存在=1
- Where EXISTS(Select * FROM 表2 Where 表2.电话号码 = 表1.电话号码)
- 17 用存储过程调用外部程序.
- 不过要做成com控件
- 用sp_OACreate存储过程)
- DECLARE @object int
- DECLARE @hr int
- DECLARE @src varchar(255), @desc varchar(255)
- EXEC @hr = sp_OACreate 'SQLDMO.SQLServer', @object OUT
- IF @hr <> 0
- BEGIN
- EXEC sp_OAGetErrorInfo @object, @src OUT, @desc OUT
- Select hr=convert(varbinary(4),@hr), Source=@src, Description=@desc
- RETURN
- END
找些不错的sql面试题-2
作者:admin 日期:2010-03-16
- 问题描述:
- 本题用到下面三个关系表:
- CARD 借书卡。 CNO 卡号,NAME 姓名,CLASS 班级
- BOOKS 图书。 BNO 书号,BNAME 书名,AUTHOR 作者,PRICE 单价,QUANTITY 库存册数
- BORROW 借书记录。 CNO 借书卡号,BNO 书号,RDATE 还书日期
- 备注:限定每人每种书只能借一本;库存册数随借书、还书而改变。
- 要求实现如下15个处理:
- 1. 写出建立BORROW表的SQL语句,要求定义主码完整性约束和引用完整性约束。
- 2. 找出借书超过5本的读者,输出借书卡号及所借图书册数。
- 3. 查询借阅了"水浒"一书的读者,输出姓名及班级。
- 4. 查询过期未还图书,输出借阅者(卡号)、书号及还书日期。
- 5. 查询书名包括"网络"关键词的图书,输出书号、书名、作者。
- 6. 查询现有图书中价格最高的图书,输出书名及作者。
- 7. 查询当前借了"计算方法"但没有借"计算方法习题集"的读者,输出其借书卡号,并按卡号降序排序输出。
- 8. 将"C01"班同学所借图书的还期都延长一周。
- 9. 从BOOKS表中删除当前无人借阅的图书记录。
- 10.如果经常按书名查询图书信息,请建立合适的索引。
- 11.在BORROW表上建立一个触发器,完成如下功能:如果读者借阅的书名是"数据库技术及应用",就将该读者的借阅记录保存在BORROW_SAVE表中(注ORROW_SAVE表结构同BORROW表)。
- 12.建立一个视图,显示"力01"班学生的借书信息(只要求显示姓名和书名)。
- 13.查询当前同时借有"计算方法"和"组合数学"两本书的读者,输出其借书卡号,并按卡号升序排序输出。
- 14.假定在建BOOKS表时没有定义主码,写出为BOOKS表追加定义主码的语句。
- 15.对CARD表做如下修改:
- a. 将NAME最大列宽增加到10个字符(假定原为6个字符)。
- b. 为该表增加1列NAME(系名),可变长,最大20个字符。
- 1. 写出建立BORROW表的SQL语句,要求定义主码完整性约束和引用完整性约束
- --实现代码:
- Create TABLE BORROW(
- CNO int FOREIGN KEY REFERENCES CARD(CNO),
- BNO int FOREIGN KEY REFERENCES BOOKS(BNO),
- RDATE datetime,
- PRIMARY KEY(CNO,BNO))
- 2. 找出借书超过5本的读者,输出借书卡号及所借图书册数
- --实现代码:
- Select CNO,借图书册数=COUNT(*)
- FROM BORROW
- GROUP BY CNO
- HAVING COUNT(*)>5
- 3. 查询借阅了"水浒"一书的读者,输出姓名及班级
- --实现代码:
- Select * FROM CARD c
- Where EXISTS(
- Select * FROM BORROW a,BOOKS b
- Where a.BNO=b.BNO
- AND b.BNAME=N'水浒'
- AND a.CNO=c.CNO)
- 4. 查询过期未还图书,输出借阅者(卡号)、书号及还书日期
- --实现代码:
- Select * FROM BORROW
- Where RDATE<GETDATE()
- 5. 查询书名包括"网络"关键词的图书,输出书号、书名、作者
- --实现代码:
- Select BNO,BNAME,AUTHOR FROM BOOKS
- Where BNAME LIKE N'%网络%'
- 6. 查询现有图书中价格最高的图书,输出书名及作者
- --实现代码:
- Select BNO,BNAME,AUTHOR FROM BOOKS
- Where PRICE=(
- Select MAX(PRICE) FROM BOOKS)
- 7. 查询当前借了"计算方法"但没有借"计算方法习题集"的读者,输出其借书卡号,并按卡号降序排序输出
- --实现代码:
- Select a.CNO
- FROM BORROW a,BOOKS b
- Where a.BNO=b.BNO AND b.BNAME=N'计算方法'
- AND NOT EXISTS(
- Select * FROM BORROW aa,BOOKS bb
- Where aa.BNO=bb.BNO
- AND bb.BNAME=N'计算方法习题集'
- AND aa.CNO=a.CNO)
- ORDER BY a.CNO DESC
- 8. 将"C01"班同学所借图书的还期都延长一周
- --实现代码:
- Update b SET RDATE=DATEADD(Day,7,b.RDATE)
- FROM CARD a,BORROW b
- Where a.CNO=b.CNO
- AND a.CLASS=N'C01'
- 9. 从BOOKS表中删除当前无人借阅的图书记录
- --实现代码:
- Delete A FROM BOOKS a
- Where NOT EXISTS(
- Select * FROM BORROW
- Where BNO=a.BNO)
- 10. 如果经常按书名查询图书信息,请建立合适的索引
- --实现代码:
- Create CLUSTERED INDEX IDX_BOOKS_BNAME ON BOOKS(BNAME)
- 11. 在BORROW表上建立一个触发器,完成如下功能:如果读者借阅的书名是"数据库技术及应用",就将该读者的借阅记录保存在BORROW_SAVE表中(注ORROW_SAVE表结构同BORROW表)
- --实现代码:
- Create TRIGGER TR_SAVE ON BORROW
- FOR Insert,Update
- AS
- IF @@ROWCOUNT>0
- Insert BORROW_SAVE Select i.*
- FROM InsertED i,BOOKS b
- Where i.BNO=b.BNO
- AND b.BNAME=N'数据库技术及应用'
- 12. 建立一个视图,显示"力01"班学生的借书信息(只要求显示姓名和书名)
- --实现代码:
- Create VIEW V_VIEW
- AS
- Select a.NAME,b.BNAME
- FROM BORROW ab,CARD a,BOOKS b
- Where ab.CNO=a.CNO
- AND ab.BNO=b.BNO
- AND a.CLASS=N'力01'
- 13. 查询当前同时借有"计算方法"和"组合数学"两本书的读者,输出其借书卡号,并按卡号升序排序输出
- --实现代码:
- Select a.CNO
- FROM BORROW a,BOOKS b
- Where a.BNO=b.BNO
- AND b.BNAME IN(N'计算方法',N'组合数学')
- GROUP BY a.CNO
- HAVING COUNT(*)=2
- ORDER BY a.CNO DESC
- 14. 假定在建BOOKS表时没有定义主码,写出为BOOKS表追加定义主码的语句
- --实现代码:
- Alter TABLE BOOKS ADD PRIMARY KEY(BNO)
- 15.1 将NAME最大列宽增加到10个字符(假定原为6个字符)
- --实现代码:
- Alter TABLE CARD Alter COLUMN NAME varchar(10)
- 15.2 为该表增加1列NAME(系名),可变长,最大20个字符
- --实现代码:
- Alter TABLE CARD ADD 系名 varchar(20)
- 问题描述:
- 为管理岗位业务培训信息,建立3个表:
- S (S#,SN,SD,SA) S#,SN,SD,SA 分别代表学号、学员姓名、所属单位、学员年龄
- C (C#,CN ) C#,CN 分别代表课程编号、课程名称
- SC ( S#,C#,G ) S#,C#,G 分别代表学号、所选修的课程编号、学习成绩
- 要求实现如下5个处理:
- 1. 使用标准SQL嵌套语句查询选修课程名称为’税收基础’的学员学号和姓名
- 2. 使用标准SQL嵌套语句查询选修课程编号为’C2’的学员姓名和所属单位
- 3. 使用标准SQL嵌套语句查询不选修课程编号为’C5’的学员姓名和所属单位
- 4. 使用标准SQL嵌套语句查询选修全部课程的学员姓名和所属单位
- 5. 查询选修了课程的学员人数
- 6. 查询选修课程超过5门的学员学号和所属单位
- 1. 使用标准SQL嵌套语句查询选修课程名称为’税收基础’的学员学号和姓名
- --实现代码:
- Select SN,SD FROM S
- Where [S#] IN(
- Select [S#] FROM C,SC
- Where C.[C#]=SC.[C#]
- AND CN=N'税收基础')
- 2. 使用标准SQL嵌套语句查询选修课程编号为’C2’的学员姓名和所属单位
- --实现代码:
- Select S.SN,S.SD FROM S,SC
- Where S.[S#]=SC.[S#]
- AND SC.[C#]='C2'
- 3. 使用标准SQL嵌套语句查询不选修课程编号为’C5’的学员姓名和所属单位
- --实现代码:
- Select SN,SD FROM S
- Where [S#] NOT IN(
- Select [S#] FROM SC
- Where [C#]='C5')
- 4. 使用标准SQL嵌套语句查询选修全部课程的学员姓名和所属单位
- --实现代码:
- Select SN,SD FROM S
- Where [S#] IN(
- Select [S#] FROM SC
- RIGHT JOIN C ON SC.[C#]=C.[C#]
- GROUP BY [S#]
- HAVING COUNT(*)=COUNT(DISTINCT [S#]))
- 5. 查询选修了课程的学员人数
- --实现代码:
- Select 学员人数=COUNT(DISTINCT [S#]) FROM SC
- 6. 查询选修课程超过5门的学员学号和所属单位
- --实现代码:
- Select SN,SD FROM S
- Where [S#] IN(
- Select [S#] FROM SC
- GROUP BY [S#]
- HAVING COUNT(DISTINCT [C#])>5)
找些不错的sql面试题-1
作者:admin 日期:2010-03-16
- Student(S#,Sname,Sage,Ssex) 学生表
- Course(C#,Cname,T#) 课程表
- SC(S#,C#,score) 成绩表
- Teacher(T#,Tname) 教师表
- 问题:
- 1、查询“001”课程比“002”课程成绩高的所有学生的学号;
- select a.S# from (select s#,score from SC where C#='001') a,(select s#,score
- from SC where C#='002') b
- where a.score>b.score and a.s#=b.s#;
- 2、查询平均成绩大于60分的同学的学号和平均成绩;
- select S#,avg(score)
- from sc
- group by S# having avg(score) >60;
- 3、查询所有同学的学号、姓名、选课数、总成绩;
- select Student.S#,Student.Sname,count(SC.C#),sum(score)
- from Student left Outer join SC on Student.S#=SC.S#
- group by Student.S#,Sname
- 4、查询姓“李”的老师的个数;
- select count(distinct(Tname))
- from Teacher
- where Tname like '李%';
- 5、查询没学过“叶平”老师课的同学的学号、姓名;
- select Student.S#,Student.Sname
- from Student
- where S# not in (select distinct( SC.S#) from SC,Course,Teacher where SC.C#=Course.C# and Teacher.T#=Course.T# and Teacher.Tname='叶平');
- 6、查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;
- select Student.S#,Student.Sname from Student,SC where Student.S#=SC.S# and SC.C#='001'and exists( Select * from SC as SC_2 where SC_2.S#=SC.S# and SC_2.C#='002');
- 7、查询学过“叶平”老师所教的所有课的同学的学号、姓名;
- select S#,Sname
- from Student
- where S# in (select S# from SC ,Course ,Teacher where SC.C#=Course.C# and Teacher.T#=Course.T# and Teacher.Tname='叶平' group by S# having count(SC.C#)=(select count(C#) from Course,Teacher where Teacher.T#=Course.T# and Tname='叶平'));
- 8、查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;
- Select S#,Sname from (select Student.S#,Student.Sname,score ,(select score from SC SC_2 where SC_2.S#=Student.S# and SC_2.C#='002') score2
- from Student,SC where Student.S#=SC.S# and C#='001') S_2 where score2 <score;
- 9、查询所有课程成绩小于60分的同学的学号、姓名;
- select S#,Sname
- from Student
- where S# not in (select Student.S# from Student,SC where S.S#=SC.S# and score>60);
- 10、查询没有学全所有课的同学的学号、姓名;
- select Student.S#,Student.Sname
- from Student,SC
- where Student.S#=SC.S# group by Student.S#,Student.Sname having count(C#) <(select count(C#) from Course);
- 11、查询至少有一门课与学号为“1001”的同学所学相同的同学的学号和姓名;
- select S#,Sname from Student,SC where Student.S#=SC.S# and C# in select C# from SC where S#='1001';
- 12、查询至少学过学号为“001”同学所有一门课的其他同学学号和姓名;
- select distinct SC.S#,Sname
- from Student,SC
- where Student.S#=SC.S# and C# in (select C# from SC where S#='001');
- 13、把“SC”表中“叶平”老师教的课的成绩都更改为此课程的平均成绩;
- update SC set score=(select avg(SC_2.score)
- from SC SC_2
- where SC_2.C#=SC.C# ) from Course,Teacher where Course.C#=SC.C# and Course.T#=Teacher.T# and Teacher.Tname='叶平');
- 14、查询和“1002”号的同学学习的课程完全相同的其他同学学号和姓名;
- select S# from SC where C# in (select C# from SC where S#='1002')
- group by S# having count(*)=(select count(*) from SC where S#='1002');
- 15、删除学习“叶平”老师课的SC表记录;
- Delect SC
- from course ,Teacher
- where Course.C#=SC.C# and Course.T#= Teacher.T# and Tname='叶平';
- 16、向SC表中插入一些记录,这些记录要求符合以下条件:没有上过编号“003”课程的同学学号、2、
- 号课的平均成绩;
- Insert SC select S#,'002',(Select avg(score)
- from SC where C#='002') from Student where S# not in (Select S# from SC where C#='002');
- 17、按平均成绩从高到低显示所有学生的“数据库”、“企业管理”、“英语”三门的课程成绩,按如下形式显示: 学生ID,,数据库,企业管理,英语,有效课程数,有效平均分
- Select S# as 学生ID
- ,(Select score FROM SC Where SC.S#=t.S# AND C#='004') AS 数据库
- ,(Select score FROM SC Where SC.S#=t.S# AND C#='001') AS 企业管理
- ,(Select score FROM SC Where SC.S#=t.S# AND C#='006') AS 英语
- ,COUNT(*) AS 有效课程数, AVG(t.score) AS 平均成绩
- FROM SC AS t
- GROUP BY S#
- ORDER BY avg(t.score)
- 18、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分
- Select L.C# As 课程ID,L.score AS 最高分,R.score AS 最低分
- FROM SC L ,SC AS R
- Where L.C# = R.C# and
- L.score = (Select MAX(IL.score)
- FROM SC AS IL,Student AS IM
- Where L.C# = IL.C# and IM.S#=IL.S#
- GROUP BY IL.C#)
- AND
- R.Score = (Select MIN(IR.score)
- FROM SC AS IR
- Where R.C# = IR.C#
- GROUP BY IR.C#
- );
- 19、按各科平均成绩从低到高和及格率的百分数从高到低顺序
- Select t.C# AS 课程号,max(course.Cname)AS 课程名,isnull(AVG(score),0) AS 平均成绩
- ,100 * SUM(CASE WHEN isnull(score,0)>=60 THEN 1 ELSE 0 END)/COUNT(*) AS 及格百分数
- FROM SC T,Course
- where t.C#=course.C#
- GROUP BY t.C#
- ORDER BY 100 * SUM(CASE WHEN isnull(score,0)>=60 THEN 1 ELSE 0 END)/COUNT(*) DESC
- 20、查询如下课程平均成绩和及格率的百分数(用"1行"显示): 企业管理(001),马克思(002),OO&UML (003),数据库(004)
- Select SUM(CASE WHEN C# ='001' THEN score ELSE 0 END)/SUM(CASE C# WHEN '001' THEN 1 ELSE 0 END) AS 企业管理平均分
- ,100 * SUM(CASE WHEN C# = '001' AND score >= 60 THEN 1 ELSE 0 END)/SUM(CASE WHEN C# = '001' THEN 1 ELSE 0 END) AS 企业管理及格百分数
- ,SUM(CASE WHEN C# = '002' THEN score ELSE 0 END)/SUM(CASE C# WHEN '002' THEN 1 ELSE 0 END) AS 马克思平均分
- ,100 * SUM(CASE WHEN C# = '002' AND score >= 60 THEN 1 ELSE 0 END)/SUM(CASE WHEN C# = '002' THEN 1 ELSE 0 END) AS 马克思及格百分数
- ,SUM(CASE WHEN C# = '003' THEN score ELSE 0 END)/SUM(CASE C# WHEN '003' THEN 1 ELSE 0 END) AS UML平均分
- ,100 * SUM(CASE WHEN C# = '003' AND score >= 60 THEN 1 ELSE 0 END)/SUM(CASE WHEN C# = '003' THEN 1 ELSE 0 END) AS UML及格百分数
- ,SUM(CASE WHEN C# = '004' THEN score ELSE 0 END)/SUM(CASE C# WHEN '004' THEN 1 ELSE 0 END) AS 数据库平均分
- ,100 * SUM(CASE WHEN C# = '004' AND score >= 60 THEN 1 ELSE 0 END)/SUM(CASE WHEN C# = '004' THEN 1 ELSE 0 END) AS 数据库及格百分数
- FROM SC
- 21、查询不同老师所教不同课程平均分从高到低显示
- Select max(Z.T#) AS 教师ID,MAX(Z.Tname) AS 教师姓名,C.C# AS 课程ID,MAX(C.Cname) AS 课程名称,AVG(Score) AS 平均成绩
- FROM SC AS T,Course AS C ,Teacher AS Z
- where T.C#=C.C# and C.T#=Z.T#
- GROUP BY C.C#
- ORDER BY AVG(Score) DESC
- 22、查询如下课程成绩第 3 名到第 6 名的学生成绩单:企业管理(001),马克思(002),UML (003),数据库(004)
- [学生ID],[学生姓名],企业管理,马克思,UML,数据库,平均成绩
- Select DISTINCT top 3
- SC.S# As 学生学号,
- Student.Sname AS 学生姓名 ,
- T1.score AS 企业管理,
- T2.score AS 马克思,
- T3.score AS UML,
- T4.score AS 数据库,
- ISNULL(T1.score,0) + ISNULL(T2.score,0) + ISNULL(T3.score,0) + ISNULL(T4.score,0) as 总分
- FROM Student,SC LEFT JOIN SC AS T1
- ON SC.S# = T1.S# AND T1.C# = '001'
- LEFT JOIN SC AS T2
- ON SC.S# = T2.S# AND T2.C# = '002'
- LEFT JOIN SC AS T3
- ON SC.S# = T3.S# AND T3.C# = '003'
- LEFT JOIN SC AS T4
- ON SC.S# = T4.S# AND T4.C# = '004'
- Where student.S#=SC.S# and
- ISNULL(T1.score,0) + ISNULL(T2.score,0) + ISNULL(T3.score,0) + ISNULL(T4.score,0)
- NOT IN
- (Select
- DISTINCT
- TOP 15 WITH TIES
- ISNULL(T1.score,0) + ISNULL(T2.score,0) + ISNULL(T3.score,0) + ISNULL(T4.score,0)
- FROM sc
- LEFT JOIN sc AS T1
- ON sc.S# = T1.S# AND T1.C# = 'k1'
- LEFT JOIN sc AS T2
- ON sc.S# = T2.S# AND T2.C# = 'k2'
- LEFT JOIN sc AS T3
- ON sc.S# = T3.S# AND T3.C# = 'k3'
- LEFT JOIN sc AS T4
- ON sc.S# = T4.S# AND T4.C# = 'k4'
- ORDER BY ISNULL(T1.score,0) + ISNULL(T2.score,0) + ISNULL(T3.score,0) + ISNULL(T4.score,0) DESC);
- 23、统计列印各科成绩,各分数段人数:课程ID,课程名称,[100-85],[85-70],[70-60],[ <60]
- Select SC.C# as 课程ID, Cname as 课程名称
- ,SUM(CASE WHEN score BETWEEN 85 AND 100 THEN 1 ELSE 0 END) AS [100 - 85]
- ,SUM(CASE WHEN score BETWEEN 70 AND 85 THEN 1 ELSE 0 END) AS [85 - 70]
- ,SUM(CASE WHEN score BETWEEN 60 AND 70 THEN 1 ELSE 0 END) AS [70 - 60]
- ,SUM(CASE WHEN score < 60 THEN 1 ELSE 0 END) AS [60 -]
- FROM SC,Course
- where SC.C#=Course.C#
- GROUP BY SC.C#,Cname;
- 24、查询学生平均成绩及其名次
- Select 1+(Select COUNT( distinct 平均成绩)
- FROM (Select S#,AVG(score) AS 平均成绩
- FROM SC
- GROUP BY S#
- ) AS T1
- Where 平均成绩 > T2.平均成绩) as 名次,
- S# as 学生学号,平均成绩
- FROM (Select S#,AVG(score) 平均成绩
- FROM SC
- GROUP BY S#
- ) AS T2
- ORDER BY 平均成绩 desc;
- 25、查询各科成绩前三名的记录:(不考虑成绩并列情况)
- Select t1.S# as 学生ID,t1.C# as 课程ID,Score as 分数
- FROM SC t1
- Where score IN (Select TOP 3 score
- FROM SC
- Where t1.C#= C#
- ORDER BY score DESC
- )
- ORDER BY t1.C#;
- 26、查询每门课程被选修的学生数
- select c#,count(S#) from sc group by C#;
- 27、查询出只选修了一门课程的全部学生的学号和姓名
- select SC.S#,Student.Sname,count(C#) AS 选课数
- from SC ,Student
- where SC.S#=Student.S# group by SC.S# ,Student.Sname having count(C#)=1;
- 28、查询男生、女生人数
- Select count(Ssex) as 男生人数 from Student group by Ssex having Ssex='男';
- Select count(Ssex) as 女生人数 from Student group by Ssex having Ssex='女';
- 29、查询姓“张”的学生名单
- Select Sname FROM Student Where Sname like '张%';
- 30、查询同名同性学生名单,并统计同名人数
- select Sname,count(*) from Student group by Sname having count(*)>1;;
- 31、1981年出生的学生名单(注:Student表中Sage列的类型是datetime)
- select Sname, CONVERT(char (11),DATEPART(year,Sage)) as age
- from student
- where CONVERT(char(11),DATEPART(year,Sage))='1981';
- 32、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列
- Select C#,Avg(score) from SC group by C# order by Avg(score),C# DESC ;
- 33、查询平均成绩大于85的所有学生的学号、姓名和平均成绩
- select Sname,SC.S# ,avg(score)
- from Student,SC
- where Student.S#=SC.S# group by SC.S#,Sname having avg(score)>85;
- 34、查询课程名称为“数据库”,且分数低于60的学生姓名和分数
- Select Sname,isnull(score,0)
- from Student,SC,Course
- where SC.S#=Student.S# and SC.C#=Course.C# and Course.Cname='数据库'and score <60;
- 35、查询所有学生的选课情况;
- Select SC.S#,SC.C#,Sname,Cname
- FROM SC,Student,Course
- where SC.S#=Student.S# and SC.C#=Course.C# ;
- 36、查询任何一门课程成绩在70分以上的姓名、课程名称和分数;
- Select distinct student.S#,student.Sname,SC.C#,SC.score
- FROM student,Sc
- Where SC.score>=70 AND SC.S#=student.S#;
- 37、查询不及格的课程,并按课程号从大到小排列
- select c# from sc where scor e <60 order by C# ;
- 38、查询课程编号为003且课程成绩在80分以上的学生的学号和姓名;
- select SC.S#,Student.Sname from SC,Student where SC.S#=Student.S# and Score>80 and C#='003';
- 39、求选了课程的学生人数
- select count(*) from sc;
- 40、查询选修“叶平”老师所授课程的学生中,成绩最高的学生姓名及其成绩
- select Student.Sname,score
- from Student,SC,Course C,Teacher
- where Student.S#=SC.S# and SC.C#=C.C# and C.T#=Teacher.T# and Teacher.Tname='叶平' and SC.score=(select max(score)from SC where C#=C.C# );
- 41、查询各个课程及相应的选修人数
- select count(*) from sc group by C#;
- 42、查询不同课程成绩相同的学生的学号、课程号、学生成绩
- select distinct A.S#,B.score from SC A ,SC B where A.Score=B.Score and A.C# <>B.C# ;
- 43、查询每门功成绩最好的前两名
- Select t1.S# as 学生ID,t1.C# as 课程ID,Score as 分数
- FROM SC t1
- Where score IN (Select TOP 2 score
- FROM SC
- Where t1.C#= C#
- ORDER BY score DESC
- )
- ORDER BY t1.C#;
- 44、统计每门课程的学生选修人数(超过10人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,查询结果按人数降序排列,若人数相同,按课程号升序排列
- select C# as 课程号,count(*) as 人数
- from sc
- group by C#
- order by count(*) desc,c#
- 45、检索至少选修两门课程的学生学号
- select S#
- from sc
- group by s#
- having count(*) > = 2
- 46、查询全部学生都选修的课程的课程号和课程名
- select C#,Cname
- from Course
- where C# in (select c# from sc group by c#)
- 47、查询没学过“叶平”老师讲授的任一门课程的学生姓名
- select Sname from Student where S# not in (select S# from Course,Teacher,SC where Course.T#=Teacher.T# and SC.C#=course.C# and Tname='叶平');
- 48、查询两门以上不及格课程的同学的学号及其平均成绩
- select S#,avg(isnull(score,0)) from SC where S# in (select S# from SC where score <60 group by S# having count(*)>2)group by S#;
- 49、检索“004”课程分数小于60,按分数降序排列的同学学号
- select S# from SC where C#='004'and score <60 order by score desc;
- 50、删除“002”同学的“001”课程的成绩
- delete from Sc where S#='001'and C#='001';
整理精华帖子
作者:admin 日期:2010-03-16
行列转换:
http://topic.csdn.net/u/20080614/17/22e73f33-f071-46dc-b9bf-321204b1656f.html?33238(总 结帖子)
http://topic.csdn.net/u/20090912/14/25d2e1b2-f352-4713-8618-d3433ba27bef.html?99104(经 典帖子)
合并分拆表:
http://topic.csdn.net/u/20080612/22/c850499f-bce3-4877-82d5-af2357857872.html?23514
果果字符串整理系列
处理表重复记录
http://topic.csdn.net/u/20080626/00/43d0d10c-28f1-418d-a05b-663880da278a.html?85256
SSAS系列:
过渡到SSAS之一:简单模型认识
过渡到SSAS之二:服务的发布
和尚翻译的SSRS的帖子
SSIS系列:
小梁系列之SSIS遍历记录查询邮件
小梁系列之SSIS表达式
小梁系列之SSIS “查找组件” 查找范围内的数据
小梁系列之SSIS 同步和异步转换
小梁系列之SSIS中 “条件拆分”组件中 ISNUMERIC的问题
小梁系列之脚本任务中访问记录集 RecordSet
小梁系列之SSIS中数据源和数据目标中 的”保留空值”
有关SQL注入的帖子:
SQL注入专题
http://topic.csdn.net/u/20090326/11/5e584897-2dd7-4e10-af1b-9b48b146af8e.html?95281
http://topic.csdn.net/u/20090523/19/72041932-b65c-49c1-ad36-d2c63b38b174.html?96607
经典代码系列:
经典短小代码
第一季
第二季
最近的一个
http://topic.csdn.net/u/20080605/15/ca6b25f3-3e60-4b95-ac7e-7d7dc02354e6.html?87229
T-SQL常见基础疑点问答整理(1)
T-SQL常见基础疑点问答整理(2)
石头系列之2005事务与锁定系列
事务与锁定第一篇
事务与锁定第二篇
事务与锁定第三篇
事务与锁定第四篇
事务与锁定第五篇
事务与锁定第六篇
石头系列之数据库引擎结构
数据库引擎结构一
数据库引擎结构二
数据库引擎结构三
各种进制的转换:(来自影子)
http://topic.csdn.net/u/20090707/16/9a7b8e46-1467-4373-a195-39d80b826827.html?28501
关于数据库的同步的帖子:
http://topic.csdn.net/u/20080523/11/08e4624a-13d1-4a6c-a9bc-7cfdd721a351.html?4574
http://topic.csdn.net/u/20080801/11/2f79d062-8049-4ade-a884-01dbaa429135.html?63426
http://topic.csdn.net/u/20090520/22/2267467b-0c40-4a5e-8b71-24838be0ff64.html?10943
两台服务器的相互同步
数据的导入导出部分:
CSV文件批量导入数据库
http://topic.csdn.net/u/20091009/11/5f3ebd1a-de5f-4d92-bc76-0f2103a34b5a.html?48287
excel导入SQL
http://topic.csdn.net/u/20090724/00/a479a979-8a20-4abb-a184-8a0ee56608c2.html?86864
BCP:
http://topic.csdn.net/u/20090720/21/b27734aa-c091-4a6b-96db-f234e2699385.html?84209
http://topic.csdn.net/u/20090720/21/b27734aa-c091-4a6b-96db-f234e2699385.html?2600
数据的转移
一个比较巧的导法
数据的分页:
http://topic.csdn.net/u/20090416/02/4e3cb6d6-707a-4f42-b295-3e9fd5df7691.html?52379
SQL查询与性能优化系列:
SQL性能优化综述
SQL Server查询优化
SQL优化之执行计划
五种提高SQL性能的方法
SQL开发的二十一条军规
一千万条数据的优化
如何提高sql查询100万条数据 count(*)汇总的速度
数据库优化汇总
海量数据库的相关处理
索引系列:
全文索引
查看索引信息/生成创建索引脚本
聚焦索引与非聚焦索引及其查询效率
递归函数系列:
BOM:
其他:
http://topic.csdn.net/u/20090807/08/19f980a3-3830-4261-90ca-0f85ec628492.html?62247
如何判断一个IP地址在一个IP地址段
身份证号码的转化
2005CLR系列:
环比运算
树结构
天气服务
正则表达式
数据库的并发性以及锁相关的帖子:
一个简单的存储过程产生死锁
单条Update语句是否加事务与锁的关系
分析死锁并整理
触发器、存储过程等
触发器综述
触发器删除的一个问题
分组求前N条数据:
分组求前N条数据
数据库的备份与恢复等问题
数据库的备份与恢复等问题
还原指定文件夹下的备份
作业:
自动备份数据库作业
SQL常见的安装问题
SQL常见的安装问题
SQL不能连接的完美解决方案
远程连接操作 整理帖子
远程连接操作 整理帖子
自动生成流水号
自动生成流水号
求每行的最小的那个字母
数据库的加密
数据库的加密
根据时间求某个月所有日期或者某天的所有时间段
根据时间求某个月所有日期或者某天的所有时间段
如何查漏号字段
如何查漏号字段
多列求最大值或者最小值
多列求最大值或者最小值
总结一下,免得每次都得去查看别人的东西
作者:admin 日期:2010-03-16
- 1:replace 函数
- 第一个参数你的字符串,第二个参数你想替换的部分,第三个参数你要替换成什么
- select replace('lihan','a','b')
- -----------------------------
- lihbn
- (所影响的行数为 1 行)
- =========================================================
- 2:substring函数
- 第一个参数你的字符串,第二个是开始替换位置,第三个结束替换位置
- select substring('lihan',0,3);
- -----
- li
- (所影响的行数为 1 行)
- =========================================================
- 3:charindex函数
- 第一个参数你要查找的char,第二个参数你被查找的字符串 返回参数一在参数二的位置
- select charindex('a','lihan')
- -----------
- 4
- (所影响的行数为 1 行)
- ===========================================================
- 4:ASCII函数
- 返回字符表达式中最左侧的字符的 ASCII 代码值。
- select ASCII('lihan')
- -----------
- 108
- (所影响的行数为 1 行)
- ================================================================
- 5:nchar函数
- 根据 Unicode 标准的定义,返回具有指定的整数代码的 Unicode 字符。
- 参数是介于 0 与 65535 之间的正整数。如果指定了超出此范围的值,将返回 NULL。
- select nchar(3213)
- ----
- unicode字符
- (所影响的行数为 1 行)
- =========================================================
- 6:soundex
- 返回一个由四个字符组成的代码 (SOUNDEX),用于评估两个字符串的相似性。
- Select SOUNDEX ('lihan'), SOUNDEX ('lihon');
- ----- -----
- L546 L542
- (所影响的行数为 1 行)
- =========================================================
- 7:char
- 参数为介于 0 和 255 之间的整数。如果该整数表达式不在此范围内,将返回 NULL 值。
- Select char(125)
- ----
- }
- (所影响的行数为 1 行)
- ==========================================================
- 8:str函数
- 第一个参数必须为数字,第二个参数表示转化成char型占的位置,小于参数一位置返回*,大于右对齐
- Select str(12345,3)
- ----
- ***
- (所影响的行数为 1 行)
- Select str(12345,12)
- ------------
- 12345
- (所影响的行数为 1 行)
- ===========================================================
- 9:difference函数
- 返回一个整数值,指示两个字符表达式的 SOUNDEX 值之间的差异。
- 返回的整数是 SOUNDEX 值中相同字符的个数。返回的值从 0 到 4 不等:0 表示几乎不同或完全不同,4 表示几乎相同或完全相同。
- Select difference('lihan','liha')
- -----------
- 3
- (所影响的行数为 1 行)
- ==================================================================
- 10:stuff函数(四个参数)
- 函数将字符串插入另一字符串。它在第一个字符串中从开始位置删除指定长度的字符;然后将第二个字符串插入第一个字符串的开始位置。
- Select stuff('lihan',2,3,'lihan')
- --------
- llihann
- (所影响的行数为 1 行)
- ===============================================================
- 11:left函数
- 返回最左边N个字符,由参数决定
- select left('lihan',4)
- -----
- liha
- (所影响的行数为 1 行)
- ================================================================
- 12 right函数
- 返回最右边N个字符,由参数决定
- select right('lihan',4)
- -----
- ihan
- (所影响的行数为 1 行)
- ================================================================
- 13:replicate函数
- 我的认为是把参数一复制参数二次
- select replicate('lihan',4)
- --------------------
- lihanlihanlihanlihan
- (所影响的行数为 1 行)
- ================================================================
- 14:len函数
- 返回参数长度
- select len('lihan')
- -----------
- 5
- (所影响的行数为 1 行)
- ================================================================
- 15:reverse函数
- 反转字符串
- select reverse('lihan')
- -----
- nahil
- (所影响的行数为 1 行)
- =================================================================
- 16:lower和upper函数
- 参数大小写转化
- select lower(upper('lihan'))
- --------------------
- lihan
- (所影响的行数为 1 行)
- ====================================================================
- 17:ltrim和rtrim函数
- 删除左边空格和右面空格
- select ltrim(' lihan ')
- --------------------------
- lihan
- (所影响的行数为 1 行)
- select rtrim(' lihan')
- ---------
- lihan
- (所影响的行数为 1 行)
SQL Server数据库开发的二十一条军规(SQL收藏)
作者:admin 日期:2010-03-16
如果你正在负责一个基于SQL Server的项目,或者你刚刚接触SQL Server,你都有可能要面临一些数据库性能的问题,这篇文章会为你提供一些有用的指导(其中大多数也可以用于其它的DBMS)。
在这里,我 不打算介绍使用SQL Server的窍门,也不能提供一个包治百病的方案,我所做的是总结一些经验----关于如何形成一个好的设计。这些经验来自我过去几年中经受的教训,一 直来,我看到许多同样的设计错误被一次又一次的重复。
一、了解你用的工具
不要轻视这一点,这是我在这篇文章中讲述的最关键的一条。也许你 也看到有很多的SQL Server程序员没有掌握全部的T-SQL命令和SQL Server提供的那些有用的工具。
“什么?我要浪费一个月的 时间来学习那些我永远也不会用到的SQL命令???”,你也许会这样说。对的,你不需要这样做。但是你应该用一个周末浏览所有的T-SQL命令。在这里, 你的任务是了解,将来,当你设计一个查询时,你会记起来:“对了,这里有一个命令可以完全实现我需要的功能”,于是,到MSDN查看这个命令的确切语法。
二、 不要使用游标
让我再重复一遍:不要使用游标。如果你想破坏整个系统的性能的话,它们倒是你最有效的首选办法。大多数的初学者都使用游标,而没有意 识到它们对性能造成的影响。它们占用内存,还用它们那些不可思议的方式锁定表,另外,它们简直就像蜗牛。而最糟糕的是,它们可以使你的DBA所能做的一切 性能优化等于没做。不知你是否知道每执行一次FETCH就等于执行一次Select命令?这意味着如果你的游标有10000条记录,它将执行10000次 Select!如果你使用一组Select、Update或者Delete来完成相应的工作,那将有效率的多。
初学者一般认为使用游标是一种比较 熟悉和舒适的编程方式,可很不幸,这会导致糟糕的性能。显然,SQL的总体目的是你要实现什么,而不是怎样实现。
我曾经用T-SQL重写了一个基 于游标的存储过程,那个表只有100,000条记录,原来的存储过程用了40分钟才执行完毕,而新的存储过程只用了10秒钟。在这里,我想你应该可以看到 一个不称职的程序员究竟在干了什么!!!
我们可以写一个小程序来取得和处理数据并且更新数据库,这样做有时会更有效。记住:对于循环,T-SQL 无能为力。
我再重新提醒一下:使用游标没有好处。除了DBA的工作外,我从来没有看到过使用游标可以有效的完成任何工作。
三、规范化你的 数据表
为什么不规范化数据库?大概有两个借口:出于性能的考虑和纯粹因为懒惰。至于第二点,你迟早得为此付出代价。而关于性能的问题,你不需要优 化根本就不慢的东西。我经常看到一些程序员“反规范化”数据库,他们的理由是“原来的设计太慢了”,可结果却常常是他们让系统更慢了。DBMS被设计用来 处理规范数据库的,因此,记住:按照规范化的要求设计数据库。
四、不要使用Select *
这点不太容易做到,我太了解了,因为我自己 就经常这样干。可是,如果在Select中指定你所需要的列,那将会带来以下的好处:
1 减少内存耗费和网络的带宽
2 你可以得到更安全的设计
3 给查询优化器机会从索引读取所有需要的列
五、了解你将要对数据进行的操作
为你的数据库创建一个健壮的 索引,那可是功德一件。可要做到这一点简直就是一门艺术。每当你为一个表添加一个索引,Select会更快了,可Insert和Delete却大大的变慢 了,因为创建了维护索引需要许多额外的工作。显然,这里问题的关键是:你要对这张表进行什么样的操作。这个问题不太好把握,特别是涉及Delete和 Update时,因为这些语句经常在Where部分包含Select命令。
六、不要给“性别”列创建索引
首先,我们必须了解索引是如何加 速对表的访问的。你可以将索引理解为基于一定的标准上对表进行划分的一种方式。如果你给类似于“性别”这样的列创建了一个索引,你仅仅是将表划分为两部 分:男和女。你在处理一个有1,000,000条记录的表,这样的划分有什么意义?记住:维护索引是比较费时的。当你设计索引时,请遵循这样的规则:根据 列可能包含不同内容的数目从多到少排列,比如:姓名+省份+性别。
七、使用事务
请使用事务,特别是当查询比较耗时。如果系统出现问题,这 样做会救你一命的。一般有些经验的程序员都有体会-----你经常会碰到一些不可预料的情况会导致存储过程崩溃。
八、小心死锁
按照一定的 次序来访问你的表。如果你先锁住表A,再锁住表B,那么在所有的存储过程中都要按照这个顺序来锁定它们。如果你(不经意的)某个存储过程中先锁定表B,再 锁定表A,这可能就会导致一个死锁。如果锁定顺序没有被预先详细的设计好,死锁是不太容易被发现的。
九、不要打开大的数据集
一个经常被提 出的问题是:我怎样才能迅速的将100000条记录添加到ComboBox中?这是不对的,你不能也不需要这样做。很简单,你的用户要浏览100000条 记录才能找到需要的记录,他一定会诅咒你的。在这里,你需要的是一个更好的UI,你需要为你的用户显示不超过100或200条记录。
十、不要使用 服务器端游标
与服务器端游标比起来,客户端游标可以减少服务器和网络的系统开销,并且还减少锁定时间。
十一、使用参数查询
有时, 我在CSDN技术论坛看到类似这样的问题:“Select * FROM a Where a.id='A'B,因为单引号查询发生异常,我该怎么办?”,而普遍的回答是:用两个单引号代替单引号。这是错误的。这样治标不治本,因为你还会在其他 一些字符上遇到这样的问题,更何况这样会导致严重的bug,除此以外,这样做还会使SQL Server的缓冲系统无法发挥应有的作用。使用参数查询, 釜底抽薪,这些问题统统不存在了。
十二、在程序编码时使用大数据量的数据库
程序员在开发中使用的测试数据库一般数据量都不大,可经常的是 最终用户的数据量都很大。我们通常的做法是不对的,原因很简单:现在硬盘不是很贵,可为什么性能问题却要等到已经无可挽回的时候才被注意呢?
十 三、不要使用Insert导入大批的数据
请不要这样做,除非那是必须的。使用UTS或者BCP,这样你可以一举而兼得灵活性和速度。
十 四、注意超时问题
查询数据库时,一般数据库的缺省都比较小,比如15秒或者30秒。而有些查询运行时间要比这长,特别是当数据库的数据量不断变大 时。
十五、不要忽略同时修改同一记录的问题
有时候,两个用户会同时修改同一记录,这样,后一个修改者修改了前一个修改者的操作,某些更新 就会丢失。处理这种情况不是很难:创建一个timestamp字段,在写入前检查它,如果允许,就合并修改,如果存在冲突,提示用户。
十六、在细 节表中插入纪录时,不要在主表执行Select MAX(ID)
这是一个普遍的错误,当两个用户在同一时间插入数据时,这会导致错误。你可以使用 SCOPE_IDENTITY,IDENT_CURRENT和IDENTITY。如果可能,不要使用IDENTITY,因为在有触发器的情况下,它会引起 一些问题(详见这里的讨论)。
十七、避免将列设为NULLable
如果可能的话,你应该避免将列设为NULLable。系统会为 NULLable列的每一行分配一个额外的字节,查询时会带来更多的系统开销。另外,将列设为NULLable使编码变得复杂,因为每一次访问这些列时都 必须先进行检查。
我并不是说NULLS是麻烦的根源,尽管有些人这样认为。我认为如果你的业务规则中允许“空数据”,那么,将列设为 NULLable有时会发挥很好的作用,但是,如果在类似下面的情况中使用NULLable,那简直就是自讨苦吃。
CustomerName1
CustomerAddress1
CustomerEmail1
CustomerName2
CustomerAddress2
CustomerEmail3
CustomerName1
CustomerAddress2
CustomerEmail3
如 果出现这种情况,你需要规范化你的表了。
十八、尽量不要使用TEXT数据类型
除非你使用TEXT处理一个很大的数据,否则不要使用它。因 为它不易于查询,速度慢,用的不好还会浪费大量的空间。一般的,VARCHAR可以更好的处理你的数据。
十九、尽量不要使用临时表
尽量不 要使用临时表,除非你必须这样做。一般使用子查询可以代替临时表。使用临时表会带来系统开销,如果你是用COM+进行编程,它还会给你带来很大的麻烦,因 为COM+使用数据库连接池而临时表却自始至终都存在。SQL Server提供了一些替代方案,比如Table数据类型。
二十、学会分析查询
SQL Server查询分析器是你的好伙伴,通过它你可以了解查询和索引是如何影响性能的。
二十一、使用参照完整性
定义主健、唯一性约束和外 键,这样做可以节约大量的时间。







