一、基礎
<b>1、說明:建立資料庫</b>
create database database-name
<b>2</b><b>、說明:删除資料庫</b>
drop database dbname
<b>3、說明:備份sql server</b>
--- 建立 備份資料的 device
use master
exec sp_addumpdevice 'disk', 'testback', 'c:\mssql7backup\mynwind_1.dat'
--- 開始 備份
backup database pubs to testback
<b>4、說明:建立新表</b>
create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)
<b>根據已有的表建立新表: </b>
<b>a:create table tab_new like tab_old (使用舊表建立新表)</b>
<b>b</b><b>:create table tab_new as select col1,col2… from tab_old definition only</b>
<b>5、說明:删除新表</b>
drop table tabname
<b>6、說明:增加一個列</b>
alter table tabname add column col type
<b>注</b>:列增加後将不能删除。db2中列加上後資料類型也不能改變,唯一能改變的是增加varchar類型的長度。
<b>7、說明:添加主鍵</b>: <b>alter table tabname add primary key(col)</b>
說明:删除主鍵:<b> alter table tabname drop primary key(col) </b>
<b>8、說明:建立索引</b>:<b>create [unique] index idxname on tabname(col….)</b>
删除索引:<b>drop index idxname</b>
注:索引是不可更改的,想更改必須删除重建立。
<b>9</b><b>、說明:建立視圖</b>:create view viewname as select statement
<b>删除視圖</b>:drop view viewname
<b>10</b><b>、說明:幾個簡單的基本的sql語句</b>
選擇:select * from table1 where 範圍
<b>插入:</b>insert into table1(field1,field2) values(value1,value2)
<b>删除:</b>delete from table1 where 範圍<b></b>
更新:update table1 set field1=value1 where 範圍
<b>查找</b>:select * from table1 where field1 like ’%value1%’ ---like的文法很精妙,查資料!
<b>排序</b>:select * from table1 order by field1,field2 [desc]
<b>總數</b>:select count as totalcount from table1
<b>求和</b>:select sum(field1) as sumvalue from table1
<b>平均</b>:select avg(field1) as avgvalue from table1
<b>最大</b>:select max(field1) as maxvalue from table1
<b>最小</b>:select min(field1) as minvalue from table1
<b>11、說明:幾個進階查詢運算詞</b>
a: union 運算符
union 運算符通過組合其他兩個結果表(例如 table1 和 table2)并消去表中任何重複行而派生出一個結果表。當 all 随 union 一起使用時(即 union all),不消除重複行。兩種情況下,派生表的每一行不是來自 table1 就是來自 table2。
<b>b: except 運算符</b>
except 運算符通過包括所有在 table1 中但不在 table2 中的行并消除所有重複行而派生出一個結果表。當 all 随 except 一起使用時 (except all),不消除重複行。
<b>c: intersect 運算符</b>
intersect 運算符通過隻包括 table1 和 table2 中都有的行并消除所有重複行而派生出一個結果表。當<b>all</b> 随 intersect 一起使用時 (intersect all),不消除重複行。
<b>注:</b>使用運算詞的幾個查詢結果行必須是一緻的。
<b>12</b><b>、說明:使用外連接配接</b>
a、<b>left (outer) join</b>:
左外連接配接(左連接配接):結果集幾包括連接配接表的比對行,也包括左連接配接表的所有行。
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>b:right (outer) join: </b>
右外連接配接(右連接配接):結果集既包括連接配接表的比對連接配接行,也包括右連接配接表的所有行。
<b>c:full/cross (outer) join</b>:
全外連接配接:不僅包括符号連接配接表的比對行,還包括兩個連接配接表中的所有記錄。
<b>12</b><b>、分組:group by:</b>
一張表,一旦分組 完成後,查詢後隻能得到組相關的資訊。
<b>組相關的資訊:</b>(統計資訊) count,sum,max,min,avg <b> </b><b>分組的标準)</b>
<b> 在sqlserver中分組時:不能以text,ntext,image類型的字段作為分組依據</b>
在selecte統計函數中的字段,不能和普通的字段放在一起;
<b>13、對資料庫進行操作:</b>
分離資料庫:<b> sp_detach_db; 附加資料庫</b>:<b>sp_attach_db </b>後接表明,附加需要完整的路徑名
<b>14.</b><b>如何修改資料庫的名稱:</b>
sp_renamedb 'old_name', 'new_name'
<b> </b>
<b>二、提升</b>
<b>1、說明:複制表(隻複制結構,源表名:a 新表名:b) (access可用)</b>
法一:select * into b from a where 1<>1(僅用于sqlserver)
<b>法二:</b>select top 0 * into b from a
<b>2、說明:拷貝表(拷貝資料,源表名:a 目标表名:b) (access可用)</b>
insert into b(a, b, c) select d,e,f from b;
<b>3、說明:跨資料庫之間表的拷貝(具體資料使用絕對路徑) (access可用)</b>
insert into b(a, b, c) select d,e,f from b in ‘具體資料庫’ where 條件
例子:..from b in '"&server.mappath(".")&"\data.mdb" &"' where..
<b>4、說明:子查詢(表名1:a 表名2:b)</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)
<b>5、說明:顯示文章、送出人和最後回複時間</b>
select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b
<b>6、說明:外連接配接查詢(表名1:a 表名2:b)</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
<b>7、說明:線上視圖查詢(表名1:a )</b>
select * from (select a,b,c from a) t where t.a > 1;
<b>8、說明:between的用法,between限制查詢資料範圍時包括了邊界值,not between不包括</b>
select * from table1 where time between time1 and time2
select a,b,c, from table1 where a not between 數值1 and 數值2
<b>9、說明:in 的使用方法</b>
select * from table1 where a [not] in (‘值1’,’值2’,’值4’,’值6’)
<b>10、說明:兩張關聯表,删除主表中已經在副表中沒有的資訊</b>
delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 )
<b>11、說明:四表聯查問題:</b>
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 .....
<b>12、說明:日程安排提前五分鐘提醒</b>
sql: select * from 日程安排 where datediff('minute',f開始時間,getdate())>5
<b>13</b><b>、說明:一條</b><b>sql </b><b>語句搞定資料庫分頁</b><b></b>
select top 10 b.* from (select top 20 主鍵字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主鍵字段 = a.主鍵字段 order by a.排序字段
<b>具體實作:</b>
關于資料庫分頁:
declare @start int,@end int
@sql nvarchar(600)
set @sql=’select top’+str(@end-@start+1)+’+from t where rid not in(select top’+str(@str-1)+’rid from t where rid>-1)’
exec sp_executesql @sql
<b>注意:在</b><b>top</b><b>後不能直接跟一個變量,是以在實際應用中隻有這樣的進行特殊的處理。</b><b>rid</b><b>為一個辨別列,如果</b><b>top</b><b>後還有具體的字段,這樣做是非常有好處的。因為這樣可以避免</b><b> top</b><b>的字段如果是邏輯索引的,查詢的結果後實際表中的不一緻(</b><b>邏輯索引中的資料有可能和資料表中的不一緻,而查詢時如果處在索引則首先查詢索引</b><b>)</b>
<b>14、說明:前10條記錄</b>
select top 10 * form table1 where 範圍
<b>15、說明:選擇在每一組b值相同的資料中對應的a最大的記錄的所有資訊(類似這樣的用法可以用于論壇每月排行榜,每月熱銷産品分析,按科目成績排名,等等.)</b>
select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b)
<b>16、說明:包括所有在 tablea 中但不在 tableb和tablec 中的行并消除所有重複行而派生出一個結果表</b>
(select a from tablea ) except (select a from tableb) except (select a from tablec)
<b>17、說明:随機取出10條資料</b>
select top 10 * from tablename order by <b>newid()</b>
<b>18、說明:随機選擇記錄</b>
select newid()
<b>19、說明:删除重複記錄</b>
1),delete from tablename where id not in (select max(id) from tablename group by col1,col2,...)
<b>2)</b>,select distinct * into temp from tablename
delete from tablename
insert into tablename select * from temp
<b>評價: 這種操作牽連大量的資料的移動,這種做法不适合大容量但資料操作</b>
3),例如:在一個外部表中導入資料,由于某些原因第一次隻導入了一部分,但很難判斷具體位置,這樣隻有在下一次全部導入,這樣也就産生好多重複的字段,怎樣删除重複字段
alter table tablename
--添加一個自增列
add column_b int identity(1,1)
delete from tablename where column_b not in(
select max(column_b) from tablename group by column1,column2,...)
alter table tablename drop column column_b
<b>20、說明:列出資料庫裡所有的表名</b>
select name from sysobjects where type='u' // u代表使用者
<b>21、說明:列出表裡的所有的列名</b>
select name from syscolumns where id=object_id('tablename')
<b>22、說明:列示type、vender、pcs字段,以type字段排列,case可以友善地實作多重選擇,類似select 中的case。</b>
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
<b>顯示結果:</b>
type vender pcs
電腦 a 1
CD光牒 b 2
CD光牒 a 2
手機 b 3
手機 c 3
<b>23、說明:初始化表table1</b>
truncate table table1
<b>24、說明:選擇從10到15的記錄</b>
select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc
<b>三、技巧</b>
<b>1、1=1,1=2的使用,在sql語句組合時用的較多</b>
<b>“where 1=1” 是表示選擇全部 “where 1=2”全部不選,</b>
如:
if @strwhere !=''
begin
set @strsql = 'select count(*) as total from [' + @tblname + '] where ' + @strwhere
end
else
set @strsql = 'select count(*) as total from [' + @tblname + ']'
<b>我們可以直接寫成</b>
錯誤!未找到目錄項。<b></b>
set @strsql = 'select count(*) as total from [' + @tblname + '] where 1=1 安定 '+ @strwhere 2、收縮資料庫
--重建索引
dbcc reindex
dbcc indexdefrag
--收縮資料和日志
dbcc shrinkdb
dbcc shrinkfile
<b>3、壓縮資料庫</b>
dbcc shrinkdatabase(dbname)
<b>4、轉移資料庫給新使用者以已存在使用者權限</b>
exec sp_change_users_login 'update_one','newname','oldname'
go
<b>5、檢查備份集</b>
restore verifyonly from disk='e:\dvbbs.bak'
<b>6、修複資料庫</b>
alter database [dvbbs] set single_user
dbcc checkdb('dvbbs',repair_allow_data_loss) with tablock
alter database [dvbbs] set multi_user
<b>7、日志清除</b>
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'
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
select 'final size of ' + db_name() + ' log is ' +
convert(varchar(30),size) + ' 8k pages or ' +
convert(varchar(30),(size*8/1024)) + 'mb'
drop table dummytrans
set nocount off
<b>8、說明:更改某個表</b>
exec sp_changeobjectowner 'tablename','dbo'
<b>9、存儲更改全部表</b>
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)
if @owner=@oldowner
set @ownername = @oldowner + '.' + rtrim(@name)
exec sp_changeobjectowner @ownername, @newowner
-- select @name,@newowner,@oldowner
close curobject
deallocate curobject
<b>10、sql server中直接循環寫入資料</b>
declare @i int
set @i=1
while @i<30
insert into test (userid) values(@i)
set @i=@i+1
<b>案例</b><b>:</b>
<b>有如下表,要求就裱中所有沒有及格的成績,在每次增長0.1的基礎上,使他們剛好及格:</b>
name score
zhangshan 80
lishi 59
wangwu 50
songquan 69
<b>while((select </b><b>min</b><b>(score) from tb_table)<</b><b>60</b><b>)</b>
<b>begin</b>
<b>update tb_table set score </b><b>=</b><b>score*</b><b>1.01</b>
<b>where score</b><b><60</b>
<b>if (select </b><b>min</b><b>(score) from tb_table)</b><b>>60</b>
<b> break</b>
<b> else</b>
<b> continue</b>
<b>end</b>
<b>資料開發-經典</b>
<b>1.按姓氏筆畫排序:</b>
select * from tablename order by customername collate chinese_prc_stroke_ci_as //從少到多
<b>2.資料庫加密:</b><b></b>
select encrypt('原始密碼')
select pwdencrypt('原始密碼')
select pwdcompare('原始密碼','加密後密碼') = 1--相同;否則不相同 encrypt('原始密碼')
select pwdcompare('原始密碼','加密後密碼') = 1--相同;否則不相同
<b>3.取回表中字段:</b>
declare @list varchar(1000),
@sql nvarchar(1000)
select @list=@list+','+b.name from sysobjects a,syscolumns b where a.id=b.id and a.name='表a'
set @sql='select '+right(@list,len(@list)-1)+' from 表a'
exec (@sql)
<b>4.檢視硬碟分區:</b>
exec master..xp_fixeddrives
<b>5.比較a,b表是否相等:</b>
if (select checksum_agg(binary_checksum(*)) from a)
=
(select checksum_agg(binary_checksum(*)) from b)
print '相等'
print '不相等'
<b>6.殺掉所有的事件探察器程序:</b>
declare hcforeach cursor global for select 'kill '+rtrim(spid) from master.dbo.sysprocesses
where program_name in('sql profiler',n'sql 事件探查器')
exec sp_msforeach_worker '?'
<b>7.</b><b>記錄搜尋</b><b>:</b>
<b>開頭到</b><b>n</b><b>條記錄</b><b></b>
select top n * from 表
-------------------------------
<b>n</b><b>到</b><b>m</b><b>條記錄</b><b>(</b><b>要有主索引</b><b>id)</b>
select top m-n * from 表 where id in (select top m id from 表) order by id desc
----------------------------------
<b>n</b><b>到結尾記錄</b><b></b>
select top n * from 表 order by id desc
<b>案例</b>
<b>例如1:一張表有一萬多條記錄,表的第一個字段 recid 是自增長字段, 寫一個sql語句, 找出表的第</b><b>31</b><b>到第</b><b>40</b><b>個記錄。</b>
select top 10 recid from a where recid not in(select top 30 recid from a)
分析:如果這樣寫會産生某些問題,如果recid在表中存在邏輯索引。
select top 10 recid from a where……是從索引中查找,而後面的select top 30 recid from a則在資料表中查找,這樣由于索引中的順序有可能和資料表中的不一緻,這樣就導緻查詢到的不是本來的欲得到的資料。
<b>解決方案</b>
<b>1, </b><b>用order by </b>select top 30 recid from a order by ricid <b>如果該字段不是自增長,就會出現問題</b>
<b>2, </b><b>在那個子查詢中也加條件:</b>select top 30 recid from a where recid>-1
<b>例2</b><b>:查詢表中的最後以條記錄,并不知道這個表共有多少資料,</b><b>以及表結構。</b>
set @s = 'select top 1 * from t where pid not in (select top ' + str(@count-1) + ' pid from t)'
<b>print @s exec sp_executesql @s</b>
<b>9:擷取目前資料庫中的所有使用者表</b>
select name from sysobjects where xtype='u' and status>=0
<b>10:擷取某一個表的所有字段</b>
select name from syscolumns where id=object_id('表名')
select name from syscolumns where id in (select id from sysobjects where type = 'u' and name = '表名')
兩種方式的效果相同
<b>11:檢視與某一個表相關的視圖、存儲過程、函數</b><b></b>
select a.* from sysobjects a, syscomments b where a.id = b.id and b.text like '%表名%'
<b>12:檢視目前資料庫中所有存儲過程</b>
select name as 存儲過程名稱 from sysobjects where xtype='p'
<b>13:查詢使用者建立的所有資料庫</b>
select * from master..sysdatabases d where sid not in(select sid from master..syslogins where name='sa')
或者
select dbid, name as db_name from master..sysdatabases where sid <> 0x01
<b>14:查詢某一個表的字段和資料類型</b>
select column_name,data_type from information_schema.columns
where table_name = '表名'
<b>15</b><b>:不同伺服器資料庫之間的資料操作</b>
<b>--</b><b>建立連結伺服器</b>
exec sp_addlinkedserver 'itsv ', ' ', 'sqloledb ', '遠端伺服器名或ip位址 '
exec sp_addlinkedsrvlogin 'itsv ', 'false ',null, '使用者名 ', '密碼 '
--查詢示例
select * from itsv.資料庫名.dbo.表名
--導入示例
select * into 表 from itsv.資料庫名.dbo.表名
<b>--</b><b>以後不再使用時删除連結伺服器</b>
exec sp_dropserver 'itsv ', 'droplogins '
<b>--</b><b>連接配接遠端/區域網路資料</b>(openrowset/openquery/opendatasource)
--1、openrowset
select * from openrowset( 'sqloledb ', 'sql伺服器名 '; '使用者名 '; '密碼 ',資料庫名.dbo.表名)
--生成本地表
select * into 表 from openrowset( 'sqloledb ', 'sql伺服器名 '; '使用者名 '; '密碼 ',資料庫名.dbo.表名)
--把本地表導入遠端表
insert openrowset( 'sqloledb ', 'sql伺服器名 '; '使用者名 '; '密碼 ',資料庫名.dbo.表名)
select *from 本地表
--更新本地表
update b
set b.列a=a.列a
from openrowset( 'sqloledb ', 'sql伺服器名 '; '使用者名 '; '密碼 ',資料庫名.dbo.表名)as a inner join 本地表 b
on a.column1=b.column1
--openquery用法需要建立一個連接配接
--首先建立一個連接配接建立連結伺服器
--查詢
select *
from openquery(itsv, 'select * from 資料庫.dbo.表名 ')
insert openquery(itsv, 'select * from 資料庫.dbo.表名 ')
select * from 本地表
set b.列b=a.列b
from openquery(itsv, 'select * from 資料庫.dbo.表名 ') as a
inner join 本地表 b on a.列a=b.列a
--3、opendatasource/openrowset
from opendatasource( 'sqloledb ', 'data source=ip/servername;user id=登陸名;password=密碼 ' ).test.dbo.roy_ta
insert opendatasource( 'sqloledb ', 'data source=ip/servername;user id=登陸名;password=密碼 ').資料庫.dbo.表名
sql server基本函數
<b>1.字元串函數 </b>長度與分析用
<b>1,datalength</b>(char_expr) 傳回字元串包含字元數,但不包含後面的空格
<b>2,substring</b>(expression,start,length) 取子串,字元串的下标是從“1”,start為起始位置,length為字元串長度,實際應用中以len(expression)取得其長度
<b>3,right</b>(char_expr,int_expr) 傳回字元串右邊第int_expr個字元,還用<b>left</b>于之相反
<b>4,isnull( </b>check<b>_</b>expression <b>,</b> replacement_value <b>)</b>如果check_expression為空,則傳回replacement_value的值,不為空,就傳回check_expression字元操作類
<b>5,sp_addtype</b> 自定義數據類型
例如:<code>exec sp_addtype birthday, datetime, 'null'</code>