触发器是一中特殊的存储过程,主要是通过事件来触发而被执行的。
它可以强化约束,来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化。可以联级运算。
如,某表上的触发器上包含对另一个表的数据操作,而该操作又会导致该表触发器被触发。
存储过程是一个预编译的SQL 语句,
优点是允许模块化的设计,就是说只需创建一次,以后在该程序中就可以调用多次。
如果某次操作需要执行多次SQL ,使用存储过程比单纯SQL 语句执行要快。
可以用一个命令对象来调用存储过程。
索引就一种特殊的查询表,数据库的搜索引擎可以利用它加速对数据的检索。
它很类似与现实生活中书的目录,不需要查询整本书内容就可以找到想要的数据。
索引可以是唯一的,创建索引允许指定单个列或者是多个列。
缺点是它减慢了数据录入的速度,同时也增加了数据库的尺寸大小。
我是这样做的,尽可能使用约束,如check, 主键,外键,非空字段等来约束,这样做效率最高,也最方便。
其次是使用触发器,这种方法可以保证,无论什么业务系统访问数据库都可以保证数据的完整新和一致性。
最后考虑的是自写业务逻辑,但这样做麻烦,编程复杂,效率低下。
事务:
被绑定在一起作为一个逻辑工作单元的SQL 语句分组,
如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前状态,或者是上有个节点。
为了确保要么执行,要么不执行,就可以使用事务。
要将有组语句作为事务考虑,就需要通过ACID 测试,
即原子性,一致性,隔离性和持久性。
锁:
在所以的 DBMS中,锁是实现事务的关键,锁可以保证事务的完整性和并发性。与现实生活中锁一样,它可以使某些数据的拥有者,在某段时间内不能使用某些数据或数据结构。当然锁还分级别的。
视图:
一种虚拟的表,具有和物理表相同的功能。
可以对视图进行增,改,查,操作,试图通常是有一个表或者多个表的行或列的子集。
对视图的修改不影响基本表。
它使得我们获取数据更容易,相比多表查询。
游标:
是对查询出来的结果集作为一个单元来有效的处理。
游标可以定在该单元中的特定行,从结果集的当前行检索一行或多行。
可以对结果集当前行做修改。
一般不使用游标,但是需要逐条处理数据的时候,游标显得十分重要。
表格、
视图、
用户定义的函数,
存储过程,
触发器
…
等等
NULL(空)这个值是数据库世界里一个非常难缠的东西,所以有不少应聘者会在这个问题上跌跟头您也不要觉得意外。
NULL这个值表示UNKNOWN(未知):它不表示“”(空字符串)。
假设您的SQL Server数据库里有ANSI_NULLS,当然在默认情况下会有,对NULL这个值的任何比较都会生产一个NULL值。
您不能把任何值与一个 UNKNOWN值进行比较,并在逻辑上希望获得一个答案。
您必须使用IS NULL操作符。
简单地说,索引是一个数据结构,用来快速访问数据库表格或者视图里的数据。
聚集索引
聚集索引在索引的叶级保存数据。这意味着不论聚集索引里有表格的哪个(或哪些)字段,这些字段都会按顺序被保存在表格。由于存在这种排序,所以每个表格只会有一个聚集索引。
非聚集索引
非聚集索引在索引的叶级有一个行标识符。这个行标识符是一个指向磁盘上数据的指针。它允许每个表格有多个非聚集索引。
主键是表格里的(一个或多个)字段,只用来定义表格里的行;主键里的值总是唯一的。
外键是一个用来建立两个表格之间关系的约束。这种关系一般都涉及一个表格里的主键字段与另外一个表格(尽管可能是同一个表格)里的一系列相连的字段。那么这些相连的字段就是外键。
触发器是一种专用类型的存储过程,它被捆绑到SQL Server 2000的表格或者视图上。在SQL Server 2000里,有INSTEAD-OF和AFTER两种触发器。
INSTEAD-OF触发器是替代数据操控语言(Data Manipulation Language,DML)语句对表格执行语句的存储过程。
例如,如果我有一个用于TableA的INSTEAD-OF-UPDATE触发器,同时对这个表格执行一个更新语句,那么INSTEAD-OF-UPDATE触发器里的代码会执行,而不是我执行的更新语句则不会执行操作。
AFTER触发器要在DML语句在数据库里使用之后才执行。这些类型的触发器对于监视发生在数据库表格里的数据变化十分好用。
第一个答案(而且是您希望听到的答案)是使用外键限制。外键限制用来维护引用的完整性。它被用来确保表格里的字段只保存有已经在不同的(或者相同的)表格里的另一个字段里定义了的值。这个字段就是候选键(通常是另外一个表格的主键)。
另外一种答案是触发器。触发器可以被用来保证以另外一种方式实现与限制相同的作用,但是它非常难设置与维护,而且性能一般都很糟糕。由于这个原因,微软建议开发人员使用外键限制而不是触发器来维护引用的完整性。
对一个表格的索引越多,数据库引擎用来更新、插入或者删除数据所需要的时间就越多,
因为在数据操控发生的时候索引也必须要维护。
这个问题可以用多种方式来回答,但是只有一个答案是“好”答案。
您希望听到的回答是 Check限制,它在数据库表格里被定义,用来限制输入该列的值。
触发器也可以被用来限制数据库表格里的字段能够接受的值,但是这种办法要求触发器在表格里被定义,这可能会在某些情况下影响到性能。因此,微软建议使用Check限制而不是其他的方式来限制域的完整性。
相关子查询是一种包含子查询的特殊类型的查询。
查询里包含的子查询会真正请求外部查询的值,从而形成一个类似于循环的状况。
name | kecheng | fenshu |
---|---|---|
张三 | 语文 | 81 |
张三 | 数学 | 75 |
李四 | 语文 | 76 |
李四 | 数学 | 90 |
王五 | 语文 | 81 |
王五 | 数学 | 100 |
王五 | 英语 | 90 |
select distinct name from table
where name not in
(select distinct name from table where fenshu<=80)
select name from table group by name having min(fenshu)>80
自动编号 | 学号 | 姓名 | 课程编号 | 课程名称 | 分数 |
---|---|---|---|---|---|
1 | 2005001 | 张三 | 0001 | 数学 | 69 |
2 | 2005002 | 李四 | 0001 | 数学 | 89 |
3 | 2005001 | 张三 | 0001 | 数学 | 69 |
delete tablename where 自动编号
not in (
select min(自动编号) from tablename group by 学号, 姓名, 课程编号, 课程名称, 分数
)
一个叫 team 的表,
里面只有一个字段name,
一共有4 条纪录,分别是a,b,c,d, 对应四个球队,
现在四个球队进行比赛,用一条sql 语句显示所有可能的比赛组合.
select a.name, b.name
from team a, team b
where a.name < b.name
从TestDB 数据表中查询出所有月份的发生额都比101 科目相应月份的发生额高的科目。
请注意:TestDB 中有很多科目,都有1 -12 月份的发生额。
AccID :科目代码,Occmonth :发生额月份,DebitOccur :发生额。
数据库名:JcyAudit
select a.*
from TestDB a
,(select Occmonth,max(DebitOccur) Debit101ccur from TestDB where AccID='101' group by Occmonth) b
where a.Occmonth = b.Occmonth and a.DebitOccur > b.Debit101ccur
year | month | amount |
---|---|---|
1 | Java | 70 |
1991 | 1 | 1.1 |
1991 | 2 | 1.2 |
1991 | 3 | 1.3 |
1991 | 4 | 1.4 |
1992 | 1 | 2.1 |
1992 | 2 | 2.2 |
1992 | 3 | 2.3 |
1992 | 4 | 2.4 |
查成这样一个结果
year | m1 | m2 | m3 | m4 |
---|---|---|---|---|
1991 | 1.1 | 1.2 | 1.3 | 1.4 |
1992 | 2.1 | 2.2 | 2.3 | 2.4 |
select year,
(select amount from aaa m where month=1 and m.year=aaa.year) as m1,
(select amount from aaa m where month=2 and m.year=aaa.year) as m2,
(select amount from aaa m where month=3 and m.year=aaa.year) as m3,
(select amount from aaa m where month=4 and m.year=aaa.year) as m4
from aaa group by year
有两个表A 和B ,均有key 和value 两个字段,
如果B 的key 在A 中也有,就把B 的value 换为A 中对应的value
这道题的SQL 语句怎么写?
update b
set b.value=(select a.value from a where a.key=b.key)
where b.id in
(select b.id from b,a where b.key=a.key)
insert into b (a, b, c) select d,e,f from a;
select a.title,a.username,b.adddate
from table a, ( select max(adddate) adddate from table where table.title = a.title) b
select * from 日程安排 where datediff('minute',f 开始时间,getdate())>5
Delete from info
where not exists ( select * from infobz where info.infid=infobz.infid )
原表
courseid | coursename | score |
---|---|---|
1 | Java | 70 |
2 | oracle | 90 |
3 | xml | 40 |
4 | jsp | 30 |
5 | servlet | 80 |
为了便于阅读, 查询此表后的结果显式如下( 及格分数为60):
courseid | coursename | score | mark |
---|---|---|---|
1 | Java | 70 | pass |
2 | oracle | 90 | pass |
3 | xml | 40 | fail |
4 | jsp | 30 | fail |
5 | servlet | 80 | pass |
select courseid, coursename ,score ,decode(sign(score-60),-1,'fail','pass') as mark from course
id | department |
---|---|
1 | 设计 |
2 | 市场 |
3 | 售后 |
id | dptID | name |
---|---|---|
1 | 1 | 张三 |
2 | 1 | 李四 |
3 | 2 | 王五 |
4 | 3 | 彭六 |
5 | 4 | 陈七 |
用一条SQL语句,怎么显示如下结果
id | dptID | department | name |
---|---|---|---|
1 | 1 | 设计 | 张三 |
2 | 1 | 设计 | 李四 |
3 | 2 | 市场 | 王五 |
4 | 3 | 售后 | 彭六 |
5 | 4 | 黑人 | 陈七 |
SELECT testtable2.* , ISNULL(department,'黑人')
FROM testtable1
right join testtable2 on testtable2.dptID = testtable1.ID
表A,结构如下:
p_ID | p_Num | s_id |
---|---|---|
1 | 10 | 01 |
1 | 12 | 02 |
2 | 8 | 01 |
3 | 11 | 01 |
3 | 8 | 03 |
其中:p_ID为产品ID,p_Num为产品库存量,s_id为仓库ID。请用SQL语句实现将上表中的数据合并,合并后的数据为:
p_ID | s1_id | s2_id | s3_id |
---|---|---|---|
1 | 10 | 12 | 0 |
2 | 8 | 0 | 0 |
3 | 11 | 0 | 8 |
其中:s1_id为仓库1的库存量,s2_id为仓库2的库存量,s3_id为仓库3的库存量。如果该产品在某仓库中无库存量,那么就是0代替。
select p_id ,
sum(case when s_id=1 then p_num else 0 end) as s1_id
,sum(case when s_id=2 then p_num else 0 end) as s2_id
,sum(case when s_id=3 then p_num else 0 end) as s3_id
from myPro group by p_id
为管理业务培训信息,建立3个表:
S表
S#学号 | SN学员姓名 | SD所属单位 | SA学员年龄 |
---|
C表
C#课程编号 | CN课程名称 |
---|
SC表
S#学号 | C#所选的课程编号 | G学习成绩 |
---|
select s# ,sn from s where S# in(select S# from c,sc where c.c#=sc.c# and cn=’税收基础’)
select sn,sd from s,sc where s.s#=sc.s# and sc.c#=’c2’
select sn,sd from s where s# not in(select s# from sc where c#=’c5’)
select 学员人数=count(distinct s#) from sc
select sn,sd from s where s# in(select s# from sc group by s# having count(distinct c#)>5)
select top 10 * from A
where ID >(select max(ID) from (select top 30 ID from A order by A ) T) order by A
select * from(select count(ID) as count from table group by ID)T
where T.count>3