落魄joker  
why so serious

受益匪浅:

http://www.cnblogs.com/skylaugh/archive/2006/06/09/421937.html

关于多表连接查询的文章:

http://www.cnblogs.com/cfanllm/articles/1270496.html

一、基础

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 范围
ep:delete from producttemp where productid in('314')
更新: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:
全外连接:不仅包括符号连接表的匹配行,还包括两个连接表中的所有记录。

二、提升

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

三、技巧

1、1=1,1=2的使用,在SQL语句组合时用的较多

“where 1=1” 是表示选择全部   “where 1=2”全部不选,
如:
if @strWhere !=''
begin
set @strSQL = 'select count(*) as Total from [' + @tblName + '] where ' + @strWhere
end
else
begin
set @strSQL = 'select count(*) as Total from [' + @tblName + ']'
end

我们可以直接写成
set @strSQL = 'select count(*) as Total from [' + @tblName + '] where 1=1 安定 '+ @strWhere

2、收缩数据库
--重建索引
DBCC REINDEX
DBCC INDEXDEFRAG
--收缩数据和日志
DBCC SHRINKDB
DBCC SHRINKFILE

3、压缩数据库
dbcc shrinkdatabase(dbname)

4、转移数据库给新用户以已存在用户权限
exec sp_change_users_login 'update_one','newname','oldname'
go

5、检查备份集
RESTORE VERIFYONLY from disk='E:"dvbbs.bak'

6、修复数据库
ALTER DATABASE [dvbbs] SET SINGLE_USER
GO
DBCC CHECKDB('dvbbs',repair_allow_data_loss) WITH TABLOCK
GO
ALTER DATABASE [dvbbs] SET MULTI_USER
GO

7、日志清除
SET NOCOUNT ON
DECLARE @LogicalFileName sysname,
        @MaxMinutes INT,
        @NewSize INT


USE     tablename             -- 要操作的数据库名
SELECT  @LogicalFileName = 'tablename_log',  -- 日志文件名
@MaxMinutes = 10,               -- Limit on time allowed to wrap log.
        @NewSize = 1                  -- 你想设定的日志文件的大小(M)

-- Setup / initialize
DECLARE @OriginalSize int
SELECT @OriginalSize = size
  FROM sysfiles
  WHERE name = @LogicalFileName
SELECT 'Original Size of ' + db_name() + ' LOG is ' +
        CONVERT(VARCHAR(30),@OriginalSize) + ' 8K pages or ' +
        CONVERT(VARCHAR(30),(@OriginalSize*8/1024)) + 'MB'
  FROM sysfiles
  WHERE name = @LogicalFileName
CREATE TABLE DummyTrans
  (DummyColumn char (8000) not null)


DECLARE @Counter   INT,
        @StartTime DATETIME,
        @TruncLog  VARCHAR(255)
SELECT  @StartTime = GETDATE(),
        @TruncLog = 'BACKUP LOG ' + db_name() + ' WITH TRUNCATE_ONLY'

DBCC SHRINKFILE (@LogicalFileName, @NewSize)
EXEC (@TruncLog)
-- Wrap the log if necessary.
WHILE     @MaxMinutes > DATEDIFF (mi, @StartTime, GETDATE()) -- time has not expired
      AND @OriginalSize = (SELECT size FROM sysfiles WHERE name = @LogicalFileName) 
      AND (@OriginalSize * 8 /1024) > @NewSize 
  BEGIN -- Outer loop.
    SELECT @Counter = 0
    WHILE  ((@Counter < @OriginalSize / 16) AND (@Counter < 50000))
      BEGIN -- update
        INSERT DummyTrans VALUES ('Fill Log') 
        DELETE DummyTrans
        SELECT @Counter = @Counter + 1
      END  
    EXEC (@TruncLog) 
  END  
SELECT 'Final Size of ' + db_name() + ' LOG is ' +
        CONVERT(VARCHAR(30),size) + ' 8K pages or ' +
        CONVERT(VARCHAR(30),(size*8/1024)) + 'MB'
  FROM sysfiles
  WHERE name = @LogicalFileName
DROP TABLE DummyTrans
SET NOCOUNT OFF

8、说明:更改某个表
exec sp_changeobjectowner 'tablename','dbo'

9、存储更改全部表

CREATE PROCEDURE dbo.User_ChangeObjectOwnerBatch
 @OldOwner as NVARCHAR(128),
 @NewOwner as NVARCHAR(128)
AS

DECLARE @Name   as NVARCHAR(128)
DECLARE @Owner  as NVARCHAR(128)
DECLARE @OwnerName  as NVARCHAR(128)

DECLARE curObject CURSOR FOR
 select 'Name'   = name,
  'Owner'   = user_name(uid)
 from sysobjects
 where user_name(uid)=@OldOwner
 order by name

OPEN  curObject
FETCH NEXT FROM curObject INTO @Name, @Owner
WHILE(@@FETCH_STATUS=0)
BEGIN    
 if @Owner=@OldOwner
 begin
  set @OwnerName = @OldOwner + '.' + rtrim(@Name)
  exec sp_changeobjectowner @OwnerName, @NewOwner
 end
-- select @name,@NewOwner,@OldOwner

 FETCH NEXT FROM curObject INTO @Name, @Owner
END

close curObject
deallocate curObject
GO


10、SQL SERVER中直接循环写入数据
declare @i int
set @i=1
while @i<30
begin
   insert into test (userid) values(@i)
   set @i=@i+1

end

 索引,视图,事物......

 

/******************************************************************************************************************************************/


--       SQL-server 数据库相关知识   事务、索引、视图  

 


--( 一 问题阐述 举例:银行的转账业务就是典型的一个事务事例)

-- 一、二部分的代码建议分开执行,更容易理解


use master
go
--判断是否已经存在银行数据库Bank 如果存在了就删除那个数据库,
if exists(select *from sysdatabases where name='bank')
begin
drop database bank
end
go
--在E盘新建一个文件夹存放数据库文件
exec xp_cmdshell 'md e:"ChinaBank'
go
--建立一个简单的银行数据库
create database Bank
on primary
(
name='Bank_Date',
filename='e:"ChinaBank"bank_date.MDF',
SIZE=1MB,
MAXSIZE=100MB,
FILEGROWTH=1%
)
LOG ON
(
name='Bank_LOG',
filename='e:"ChinaBank"bank_log.LDF',
SIZE=1MB,
MAXSIZE=100MB,
FILEGROWTH=1%
)
GO
use Bank
go
--建立银行用户信息表
create table userInfo
(
customerName char(10) not null,
customerBalance money not null
)
go


/*--添加约束:根据银行规定,账户余额不能低于1元,否则视于销户---*/
alter table userInfo
add constraint ck_userInfo_customerBalance check(customerBalance>=1)
go

/*---插入测试数据-----*/
insert userInfo(customerName,customerBalance)
select '张三',1000 union
select '李四',1
select *from userInfo
go

/*现在开始模拟转账,张三转账一千元到李四账户里,那么张三的账户里应该只剩下1元,李四账户应该有1001元*/
update userInfo set customerBalance=CustomerBalance-1000 where customerName='张三'
update userInfo set customerBalance=CustomerBalance+1000 where customerName='李四'
select *from userInfo
go
--问题出来了,看见没?张三的账户余额并没有减少,而李四却多出1000元??????????

--这里就体现了事务的概念,事务是单个的工作单元,如果某一事务成功,则在该事务中进行的所有数据更改均会提交,成为数据库
--中永久组成部份,如果事务中遇到了错误且必须取消和回滚,则所有数据更改均被清除,换句话说,你所作的操作均会被撤销,


--事务也是一种机制,是一个操作序列,它包含了一组数据库操作命令,并且所有的命令作为一个整体一起向系统提交或撤消操作请求,
--即这一组操作命令,要么都执行要么都不执行..

 


--上面的代码执行一次.看看表记录.你会发现我所说的.....

--下面的代码执行一次.证明事务是不可分割的工作逻辑单元

 

 

---( 二 )下面重新来操作刚才的转账行为

--恢复账户数据 张三1000元,李四1元

update userInfo set customerBalance=1000 where customerName='张三'
update userInfo set customerBalance=1 where customerName='李四'
select *from UserInfo
go


--开始事务(表示事务从此开始.面的T-SQL语句都是一个整体)
begin transaction
--定义一个变量,用于累积事务执行过程中的错误
declare @errorSum int
set @errorSum=0 --(计数器)初始化为0表示没有错误发生!
/*现在开始转账操作*/
update userInfo set customerBalance=CustomerBalance-1000 where customerName='张三'
--累积是否有错,(在张三的账户中减去1000元,看是否执行成功,如果失败,那么@@error就能捕捉到一个错误,@@error是SQL-Server系统中定义的全局变量
set @errorSum=@errorSum+@@error
update userInfo set customerBalance=CustomerBalance+1000 where customerName='李四'
set @errorSum=@errorSum+@@error
/*根据事务过程中的错误,来确认事务是提交还是撤消*/
--如果计数器不为0就说明这项转账事务中有错误
if @errorSum<>0
begin
   --交易失败!回滚事务..
   rollback transaction
end
else
begin
   --交易成功,提交事务
   commit transaction
end
go

select *from userInfo
--再次查看表记录,发现数据依然是原来的.没有改变,再次证明了事务是一个不可分割的工作逻辑单元


--如果出现如下提示:是正常的.因为我们的表约束了账户余额必须大于1.否则认为是销户,
--张三的账户中转账1000到李四账户中.那么张三账户就只有0元了.所以就有如下出错提示,如果我们改为转账800,就不会出错了


--服务器: 消息 547,级别 16,状态 1,行 1
--UPDATE 语句与 COLUMN CHECK 约束 'ck_userInfo_customerBalance' 冲突。该冲突发生于数据库 'Bank',表 'userInfo', column 'customerBalance'。
--语句已终止。

 

 

/******************************************************************************************************************************************/


--        下面讲解索引

--索引是提供指针以指向存储在表中指定列的数据值,然后然后根据指定的排序次序排列这些指针,就好像一本书的目录一样,通过搜索索引找到特定的值,然后跟随指针
--到达包含该值的行。

--索引:是SQL-Server编排数据的内部方法,它为SQL-Server提供一种方法来编排查询数据的路由.

 

-- 在此借用上面建好的bank数据库做讲解


--新建一张表存储学号成绩
create table studentScore
(
name varchar(10) not null,
score float not null
)
go
--初始化数据
insert studentScore(name,score)
select '张小',90 union
select '张三',84 union
select '李三',29 union
select '五三',45 union
select '王三',90 union
select '赵三',82 union
select '李四',20 union
select '陈三',84 union
select '何五',30
go
select *from studentScore

go
--下面以 为成绩表 建立非聚集索引 为例 ,因为成绩有可能重复


/*先来检测一下是否已经存在该索引,如果存在就删除该索引,重新建一个*/

if exists(select *from sysindexes where name='ix_studentScore_score')
begin
drop index studentScore.ix_studentScore_score
end

create nonclustered index ix_studentScore_score
on studentScore(score)
with fillfactor=10

--指定索引查询,按ix_studentScore_score ,查出成绩在40到90之间的学员姓名

select name from studentScore
(index=ix_studentScore_score)
where score between 40 and 90

--这里我们可以指定按那个索引进行查询,但是一般情况下不需要人工指定,SQL-server将会自动根据所创建的索引,优化查询

--另外SQL-Server中还包括唯一索引,主键索引,聚集索引等,上例中使用的是非聚集索引

--唯一索引:不允许两行具有相同的索引值,如果建有唯一约束,那么自动就创建了唯一索引。
--主键索引:在数据库关系图中为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型.
--聚集索引: 在聚集索引中,表中各行的物理顺序与键值的逻辑(索引)顺序相同,表中只能有一个聚集索引.但可以有多个非聚集索引,
--         设置某列为主键,该列默认为聚集索引.

 

go
/******************************************************************************************************************************************/

 

 


--                                                  下面讲解 视图


--视图:使用视图的好处:1、出于安全考虑,用户不必看到整个数据库结构,而隐藏部分数据;2、符合用户日常业务逻辑,使他们对数据更容易理解

--视图是一种虚拟表,通常是作为来自一个或多个表的行或列的子集创建的,同时也可以包含全部列和行。


--我们依然采用T-SQL语句来创建视图


--

use Bank
go
---检测是否存在该视图,如果存在就删除该视图


if exists (select *FROM SYSOBJECTS WHERE name='view_studentScore_score')
begin

drop view view_studentScore_score

end

/**创建视图   这里用的内联接 涉及到了上面银行客户信息表*/

go

create view view_studentScore_score
as select 姓名=name,成绩=studentScore.score from studentScore
inner join userInfo
on studentScore.name=userInfo.customerName

--视图是一个虚拟表,可以像物理表一样打开,同样支持增删改查操作,但在实际应用中仅做查询使用....

select *from view_studentScore_score

 

 

 

 

 

select * from authors

--声明游标
declare @au_lname varchar(20)
declare mycursor cursor for select au_lname from authors

--打开

S2-ATM取款机SQL 2000脚本
2007年12月20日 星期四 18:33

use master
go
--判断是否存在bankDB数据库,如果存在就删除它,另外建立一个

if exists (select *from sysdatabases where name='bankDB')
begin
drop database ChinaBank
end

go
--在E盘建立一个bankDB文件夹
exec xp_cmdshell 'md e:"bankDB'
go
create database ChinaBank
on primary
(
name='Bank_Date',
filename='e:"bankDB"bank_date.MDF',
SIZE=1MB,
MAXSIZE=100MB,
FILEGROWTH=15%
)
LOG ON
(
name='Bank_LOG',
filename='e:"bankDB"bank_log.LDF',
SIZE=1MB,
MAXSIZE=100MB,
FILEGROWTH=15%
)
GO

 

 

 


posted on 2008-11-12 11:02  bravecheese  阅读(375)  评论(0编辑  收藏  举报