注册 登录
编程论坛 SQL Server论坛

[经验]SQL应用实例

Kendy123456 发布于 2007-01-30 16:43, 6512 次点击

开这篇贴的目的是让大家就实例来交流SQL中, 那些平常不怎么被人所使用而其实很有用的命令.

希望大家把自己的心得和经验都贡献出来 然后让版主固顶.

我先来抛块砖:

一. 创建表的时候 使用计算列
CREATE TABLE t1
(P int IDENTITY(1,1),
C int NOT NULL,
M int NOT NULL,
T AS (C+ M)
)

insert into t1 values(1,2)
select t from t1

P C M T
----------- ----------- ----------- -----------
1 1 2 3

(1 row(s) affected)

这里T就是一个计算列. Insert Update语句都不能对计算列字段操作,但是select语句可以从该列取得值.
创建计算列有什么用呢? 可以用于视图的触发器中.
一个视图,是多个表的数据结合在一起显示的.
比如我们创建2个表,存放Employee的FirstName和LastName:

create table name1
(
EmployeeID int PRIMARY KEY,
Firstname varchar(100)
)
create table name2
(
EmployeeID int,
Lastname varchar(100)
)
再创建一个显示Employee全名的view
CREATE VIEW vw_Employee_FullName
AS
SELECT a.EmployeeID, FirstName + ';' + LastName AS FullName
FROM Name1 a join Name2 b on a.EmployeeID =b.EmployeeID

这时候设计一个视图的update操作的instead of触发器
CREATE TRIGGER InsteadInsertName on vw_Employee_FullName
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO Name1 (EmployeeID,Firstname)
SELECT EmployeeID,LEFT(FullName,(CHARINDEX(';', FullName) - 1))
FROM inserted

INSERT INTO Name2 (EmployeeID,Lastname)
SELECT EmployeeID,RIGHT(FullName,LEN(FullName)-CHARINDEX(';', FullName))
FROM inserted
END

这样 从前台插入employee新数据的时候,我们只要把向view中插入就可以了,由view的触发器来向2个表中插入数据
insert into vw_Employee_FullName values (1,'George;Bush')
select * from name1
select * from name2

EmployeeID Firstname
----------- ----------------------------------------------------------------------------------------------------
1 George

(1 row(s) affected)

EmployeeID Lastname
----------- ----------------------------------------------------------------------------------------------------
1 Bush

(1 row(s) affected)


二. 外键之间的级联操作
通常情况下,我们使用外键时,在插入和删除数据的时候一定要注意顺序,插入时要先主表再从表, 删除时要先从表再主表,更新时还不能任意更新外键中的列.
外键也是约束,这些限制是为了保证数据库数据的完整性和一致性,写代码的时候往往一不注意就会得到异常.
实际上系统也允许另外一种工作方式: 更改外键的列时候,主动更新外键关联的其它表的相关列.
创建外键时 用 ON DELETE { CASCADE | NO ACTION },ON Update { CASCADE | NO ACTION }声明是否启用级联操作 默认是NO Action.
ON DELETE NO ACTION
指定如果试图删除某行,而该行含有由其它表的现有行中的外键所引用的键,则产生错误并回滚 DELETE。

ON UPDATE NO ACTION
指定如果试图更新某行中的键值,而该行含有由其它表的现有行中的外键所引用的键,则产生错误并回滚 UPDATE。

ON DELETE CASCADE
指定如果试图删除某行,而该行含有由其它表的现有行中的外键所引用的键,则也将删除所有包含那些外键的行。如果在目标表上也定义了级联引用操作,则对从那些表中删除的行同样采取指定的级联操作。

ON UPDATE CASCADE
指定如果试图更新某行中的键值,而该行的键值由其它表的现有行中的外键所引用,则所有外键值也将更新成为该键指定的新值。如果在目标表上也定义了级联引用操作,则对在那些表中更新的键值同样采取指定的级联操作。

仍然以上面的例子,重新创建name2 并建立外键
Drop table name2
CREATE TABLE Name2
(
EmployeeID int primary key FOREIGN KEY REFERENCES Name1(EmployeeID) ON DELETE Cascade ON Update Cascade,
Lastname varchar(100)
)

update name1 set EmployeeID = 3 where EmployeeID = 1

select * from name1
select * from name2

(1 row(s) affected)

EmployeeID Firstname
----------- ----------------------------------------------------------------------------------------------------
3 George

(1 row(s) affected)

EmployeeID Lastname
----------- ----------------------------------------------------------------------------------------------------
3 Bush

(1 row(s) affected)

****注意 不要试图去update name2, 那是不合法的. 仅仅允许更新外键中主表的列, 并且更新自动传递到子表.

delete name1 where EmployeeID = 3

select * from name1
select * from name2

EmployeeID Firstname
----------- ----------------------------------------------------------------------------------------------------

(0 row(s) affected)

EmployeeID Lastname
----------- ----------------------------------------------------------------------------------------------------

(0 row(s) affected)

**** 注意 这里delete name2也是合法的 但是不会影响到主表name1.

级联是允许多级的, 假如还有表name3, 以name2为主表建立了外键:

CREATE TABLE Name3
(
EmployeeID int FOREIGN KEY REFERENCES Name2(EmployeeID) ON DELETE Cascade ON Update Cascade,
MiddleName varchar(100)
)

那么对name1 的EmployeeID做update, 或者删除行的会, name3也会做同样操作
SQL帮助上是这样描述的:
由单个 DELETE 或 UPDATE 触发的一系列级联引用操作必须构成不包含循环引用的树。
在 DELETE 或 UPDATE 所产生的所有级联引用操作的列表中,每个表只能出现一次。
级联引用操作树到任何给定表的路径必须只有一个。
树的任何分支在遇到指定了 NO ACTION 或默认为 NO ACTION 的表时终止。

43 回复
#2
accpfriend2007-01-30 16:46
#3
棉花糖ONE2007-01-30 16:49
楼主帅哥,怎么固顶啊,不会
#4
Kendy1234562007-01-30 16:54
楼上的...IE右下角... 管理选项: 专题管理 | 锁定 | 提升 | 沉底 | 跟贴管理 | 删除 | 移动 | 设置固顶 | 发布公告
#5
zjcyzw2007-02-02 09:30
好啊
#6
gangdou19982007-02-02 17:05
支持下!
#7
ninggang2007-02-05 12:54

哈哈,又熟悉了一遍
支持!!!

#8
maggie_822007-03-12 12:43

学习中

#9
帅哥一条虫2007-03-17 14:26
#10
bayishi2007-03-18 10:59

这几天才开始SQL所以有点看不懂..不过我会努力向上的

#11
cyyu_ryh2007-03-23 14:33

我晕才发现这篇文章
评价:还过得去

#12
songyuyu2007-03-28 13:47
现在还看不懂,以后就看懂的
#13
daidaidai2007-04-10 17:12
楼上的真牛啊!!
#14
daidaidai2007-04-10 18:01

我试试了下,真的不错,实用!

顶!

#15
feiya2007-04-17 12:34
#16
IceWater2007-04-19 22:21
不错啊,,,经典...
#17
IceWater2007-04-19 22:36
查询技巧共享
1.要显示customerid的第一位为A到M,后面任意的记录
SELECT * from orders where customerid LIKE ‘[A-M]%’
2.也可以改为这样(表示最后一位为A到M,前面任意)
SELECT * from orders where customerid LIKE ‘%[A-M]’
3.如要固定开头或中间或结尾也可以像下面这样
SELECT * from orders where customerid LIKE ‘[A]%’
SELECT * from orders where customerid LIKE ‘[ABC]%’
SELECT * from orders where customerid LIKE ‘%[A-M]%’
SELECT * from orders where customerid LIKE ‘%[A-DH]’
多谢捧场...
#18
hpp9322007-04-28 18:00
还得继续努力学习呀,知识在不断的更新那。
#19
lxb35052007-05-08 14:48
学习中
#20
cqlpyyx2007-05-14 16:04
这天我才装上SQL2005 不能登录服务器,是怎么回事啊????还请指教一下???
#21
觉雨2007-05-17 09:18

~~~~~~~~~~

#22
laoshu12007-05-22 17:44
不错!学习了!顶!支持
#23
solo2142007-05-27 19:35

不错...今天看不完,顶一下,明天看

#24
figowei2007-05-29 15:01
#25
figowei2007-05-29 15:42
看不懂
#26
sosocattle2007-05-30 17:44

谢谢分享

#27
双面人2007-05-30 23:00
最近又要用SQL了,刚好复习一下,顶!
#28
ccf2007-05-31 08:38
我顶。。。。。。。。。。。。。。。
#29
白菜粉条2007-05-31 09:06

报汗下自己,平时只想用简单的sql语句!不过,还好,可以看懂楼主的文章!

#30
lijibao2007-06-02 17:05

一个,好!

#31
yuyunliuhen2007-06-03 20:49
漫漫消化!!
#32
Princeli11252007-06-11 22:16
向见恨晚啊,这个论坛真好!
#33
wehooooo2007-06-15 23:21

again up

#34
水是冰的眼泪2007-06-18 12:48

好强哦~我就属于菜中菜的那个~~

#35
Princeli11252007-06-19 17:14
支持,顶!
#36
haimo2007-07-03 21:23
嗯,俺有收获,谢谢楼主
#37
linghe3012007-07-08 09:02
学习。。。。。。。。。。。。
#38
yuminbai2007-07-09 14:37
回复:(Kendy123456)[经验]SQL应用实例
有一个好人
#39
jony2007-08-23 23:35
前人经验 ,可以借鉴。
#40
hancai882007-08-24 12:00

谢谢,我都没太用到这些。

#41
hope3119872007-09-01 13:52

我也是新学 大家多多关照

#42
fanhuaxing2007-09-04 16:30

学习下

#43
枫林晴雨2007-09-20 21:37
我晕!!!不是固顶了吗?怎么在这?!!才看见,一个字:赞!
#44
GOHIGE2007-09-23 23:13

谢谢!
1