下面通過(guò)實(shí)例來(lái)對(duì)Select的通常用法加以介紹。 例1:選擇所有的列,語(yǔ)法為select * from table_list 如:select * from publishers 例2:選擇指定的列,語(yǔ)法為 select column_name[,column_name]… from table_name 如:select pub_id,pub_name from publishers 例3:重命名查詢結(jié)果中的列,語(yǔ)法為 select column_heading= column_name from table_name 如:select Publisher=pub_name,pub_id from publishers 例4:select列表中的計(jì)算值,可以對(duì)select列表中的數(shù)值數(shù)據(jù)進(jìn)行計(jì)算,下面列出了算術(shù)運(yùn)算符。
符號(hào)運(yùn)算 +加 -減 /除 *乘 %取模 如select title_id,total_sales,total_sales*2 from titles 例5:使用distinct消除重復(fù)的查詢結(jié)果 可選的關(guān)鍵詞消除select語(yǔ)句的結(jié)果中的重復(fù)行。若不指定distinct,缺省值為all,將檢索出包含重復(fù)行的所有行數(shù)據(jù)。 如:select distinct au_id from titleauthor 例6:選擇行——where語(yǔ)句 select語(yǔ)句中的確切指定要檢索哪些行的準(zhǔn)則,其一般格式為: select select_list from table_list where search_conditions where子句中的搜索條件(或稱限制)包括: ·比較運(yùn)算符(=,<,>,!=等= 如:where advance*2>total_sales*price ·范圍(between和not between) 如:where total_sales between 5000 and 10000 ·列表(in和not in) 如:where state in(“CA”,”IN”,”MD”) ·匹配字符(like和not like) 如:where phone like “0535%” ·未知值(is null和is not null) 如:where advance is null ·以上各項(xiàng)的組合(and, or) 如:where advance<5000 or total_sales between 500 and 1000 例7:用集合函數(shù)小結(jié)查詢結(jié)果 集合函數(shù)用特定列的數(shù)據(jù)來(lái)計(jì)算小結(jié)值。 集合函數(shù)結(jié) 果 Sum([all|distinct]expression)數(shù)值列中(不重復(fù))值的總和 Avg([all|distinct]expression)數(shù)值列中(不重復(fù))值的平均 count([all|distinct]expression)列中(不重復(fù))非空值的數(shù)目 Count(*)選定的行數(shù) Max(expression)Expression的最大值 Min(expression)Expression的最小值 如:select avg(advance),sum(total_sales) from titles where type=”as” select count(*) from titles select avg(distinct price) from titles select max(price) from books 例8:分組組織查詢結(jié)果——group by 子句 group by 子句用在select語(yǔ)句中將一張表分成若干組。 如:select type, advance from titles group by type 例9:選擇分組數(shù)據(jù)——having子句 having為group by 子句設(shè)置條件,與where為select語(yǔ)句設(shè)置條件一樣。Having搜索條件與where相同,但having可包括集合函數(shù),而where不能包括。 下列語(yǔ)句使用帶集合函數(shù)having子句的例子。它把title表中的行按類型分組,但去掉了那只包含一本書的分組。 Select type from titles group by type having count(*)>1 下面是一個(gè)不帶集合函數(shù)的having子句的例子。它把title表中的行按類型分組,但去掉了那些不以字母“p”開(kāi)頭的類型。 Select type from titles group by type having type like “p%” 例10:查詢結(jié)果排序——order by子句 Order by子句允許按一列或多列對(duì)查詢結(jié)果排序。每個(gè)排序可以是升序的(asc)或降序的(desc)。若不特別指明,則按升序進(jìn)行。下列查詢返回按pub_id排序的結(jié)果: Select pub_id,type,title_id from titles order by pub_id 例11:連接——從多張表中檢索數(shù)據(jù) 連接兩張或兩張以上的表是這樣一個(gè)過(guò)程:比較指定字段中的數(shù)據(jù),根據(jù)比較結(jié)果用符合條件的行組成一張新表。 舉例: select publishers.pub_id,publishers.pub_name,authors.* from publishers,authors where publishers.city=authors.city 例12:分組計(jì)算子句 Compute是Sybase對(duì)SQL標(biāo)準(zhǔn)中Group子句的擴(kuò)充,可以將其看作帶聚集計(jì)算的Group子句。例如: Select type,price,advance From titles Order by type Compute sum(price),sum(advance) by type 2.Insert語(yǔ)句 用Insert命令向數(shù)據(jù)庫(kù)中添加行有兩種方法:使用關(guān)鍵詞values或使用select語(yǔ)句。 Insert語(yǔ)句的基本語(yǔ)法為: Insert[into]表名[(字段列表)] {values(值列表)|select_statement} 舉例:insert into publishers values(‘1622’,’Jardin,Inc.’,’Camden’,’NJ’) Insert into publishers(pub_id,pub_name) values(‘1756’,’The Health Center’) Insert authors select * from newauthors Insert authors(au_id,address,au_lname,au_fname) Select * from newauthors 3.Delect語(yǔ)句 Delect可以對(duì)一行或多行進(jìn)行操作。 Delect語(yǔ)句的基本語(yǔ)法為: Delect 表名 [from 表名列表] [where條件表達(dá)式] 舉例:Delect publishers where pub_name=”Jardin,Inc.” Delect titles From authors, titles Where titles.title_id=authors.title_id 4.Update語(yǔ)句 可以使用Update命令來(lái)改動(dòng)表中的單個(gè)行、一組行或所有行。 Update語(yǔ)句的基本語(yǔ)法為: Update表名 Set column_name1={expression1|null|(select_statement)} [,column_name2={expression2|null|(select_statement)}] [……] [from 表名列表] [where 條件表達(dá)式] 舉例: update authors set_au_lname=”Health”,aufname=”Goodbody” where au_lname=”Bloth” update titles set total_sales=total_sales + qty from titles,sales where titles.title_id=sales.title_id 六、Sybase預(yù)定義函數(shù) 1.聚集函數(shù) sum([all|distinct]表達(dá)式) avg([all|distinct]表達(dá)式) count([all|distinct]表達(dá)式) count(*) max(表達(dá)式) min(表達(dá)式) 2.字符串函數(shù) upper(字符表達(dá)式) lower(字符表達(dá)式) char(整型表達(dá)式) char_length(字符表達(dá)式) ltrim(字符表達(dá)式) rtrim(字符表達(dá)式) …… 3.?dāng)?shù)學(xué)函數(shù) abs(精確小數(shù)型表達(dá)式) floor(精確小數(shù)型表達(dá)式)求小于或等于給定表達(dá)式值的最大整數(shù)(取底) rand([整數(shù)型] round(精確小數(shù)型表達(dá)式,整數(shù)) sign(精確小數(shù)型表達(dá)式) power(精確小數(shù)型表達(dá)式,整數(shù)冪) …… 4.日期函數(shù) getdate() datepart(日期部分,日期) datediff(日期部分,日期1,日期2) dateadd(日期部分,數(shù)值表達(dá)式,日期) 5.類型轉(zhuǎn)換函數(shù) convert(數(shù)據(jù)類型,表達(dá)式[,格式]) 6.系統(tǒng)函數(shù) db_name([數(shù)據(jù)庫(kù)ID]) host_name() isnull(表達(dá)式1,表達(dá)式2) …… 七、數(shù)據(jù)控制語(yǔ)言 用來(lái)控制數(shù)據(jù)的安全性,如權(quán)限控制語(yǔ)句GRANT和REVOKE等。
第七講 數(shù)據(jù)庫(kù)編程基礎(chǔ)
一、批處理 SQL Server可以處理作為一批而提交的多個(gè)SQL語(yǔ)句,既可以是交互式的,也可以是一個(gè)文件。批處理SQL語(yǔ)句由批結(jié)束標(biāo)志終止,該標(biāo)志指示SQL Server從前面開(kāi)始執(zhí)行該批處理語(yǔ)句,對(duì)于獨(dú)立的SQL實(shí)用程序isql而言,其批結(jié)束標(biāo)志為單獨(dú)占一行的“go”。 舉例:選擇表title及表authors的行數(shù) select count(*) from titles select count(*) from authors go 二、流程控制語(yǔ)言 1.變量聲明與賦值 全局變量由系統(tǒng)預(yù)定義,以符號(hào)@@打頭。 局部變量聲明使用Declare語(yǔ)句,這個(gè)變量必須以符號(hào)@開(kāi)頭,后跟一個(gè)標(biāo)識(shí)符。 Declare @變量名 數(shù)據(jù)類型[,@變量名 數(shù)據(jù)類型,……] 變量賦值使用Select語(yǔ)句,未賦值的變量其值為Null。 舉例: Declare @msg char(50) Select @msg=’How are you?’ Select @msg=emp_name from employee Where emp_id=12345678 2.SQL語(yǔ)句塊 Begin Statement Block/*多個(gè)順序執(zhí)行的SQL 語(yǔ)句*/ End 3.條件語(yǔ)句 If 條件表達(dá)式 語(yǔ)句(塊) Else 語(yǔ)句(塊) 舉例: if(select max(id) from sysobjects)<50 print ‘?dāng)?shù)據(jù)庫(kù)里沒(méi)有用戶創(chuàng)建的對(duì)象‘ else select name,type,id from sysobjects where id>50 4.循環(huán)語(yǔ)句 While 條件表達(dá)式 語(yǔ)句(塊) ●兩個(gè)特殊的循環(huán)控制語(yǔ)句: Continue 執(zhí)行下一次循環(huán) Break 退出當(dāng)前循環(huán) 舉例: While(select avg(price) from titles)>$20 Begin Update titles set price=price/2 If(select avg(price) from titles)<$40 Break Else Continue End 5.其它控制語(yǔ)句 ◇Return語(yǔ)句——無(wú)條件結(jié)束當(dāng)前過(guò)程,并可返回給調(diào)用者的一個(gè)狀態(tài)值:Return[整數(shù)表達(dá)式] ◇Print語(yǔ)句 ◇RaiseError語(yǔ)句 ◇Waitfor語(yǔ)句 三、存儲(chǔ)過(guò)程 存儲(chǔ)過(guò)程是存儲(chǔ)在服務(wù)器端的一類數(shù)據(jù)庫(kù)對(duì)象,它實(shí)質(zhì)上是一段用SQL語(yǔ)言編寫的程序,它在服務(wù)器端預(yù)先經(jīng)過(guò)編譯,并確定出執(zhí)行計(jì)劃,因此與同樣功能的批處理語(yǔ)句相比,它的執(zhí)行速度較快。 基本語(yǔ)法: Create Procedure[owner.]過(guò)程名 [@參數(shù)名 數(shù)據(jù)類型[=默認(rèn)值][Output]] [,@參數(shù)名 數(shù)據(jù)類型[=默認(rèn)值][Output]] [……] AS Begin SQL語(yǔ)句(塊) End 存儲(chǔ)過(guò)程是數(shù)據(jù)庫(kù)對(duì)象,和表、索引是一個(gè)級(jí)別的;是SQL語(yǔ)句和控制流語(yǔ)言的集合,存儲(chǔ)過(guò)程在首次運(yùn)行時(shí)被編譯,并駐留在過(guò)程高速緩存的內(nèi)存中,所以存儲(chǔ)過(guò)程的招待非???。存儲(chǔ)過(guò)程可以帶參數(shù),可以調(diào)用其他過(guò)程,返回狀態(tài)值,返回參數(shù)值,并且可以在遠(yuǎn)程SQL Server執(zhí)行??梢栽谶h(yuǎn)程SQL Server執(zhí)行對(duì)數(shù)據(jù)庫(kù)設(shè)計(jì)有特別重要的意義。SQL Server提供的存儲(chǔ)過(guò)程稱為系統(tǒng)過(guò)程。 存儲(chǔ)過(guò)程大大增強(qiáng)了SQL的能力、效率和靈活性,經(jīng)過(guò)編譯的存儲(chǔ)過(guò)程極大地改善SQL語(yǔ)句和批處理的性能。 存儲(chǔ)過(guò)程有很多優(yōu)點(diǎn): ●存儲(chǔ)過(guò)程在第一次執(zhí)行時(shí)編譯,并存儲(chǔ)在過(guò)程高速緩存的內(nèi)存中。編譯時(shí)系統(tǒng)對(duì)其進(jìn)行優(yōu)化,以選擇最佳的路徑來(lái)訪問(wèn)數(shù)據(jù)集中的數(shù)據(jù),這種優(yōu)化考慮了數(shù)據(jù)集的實(shí)際數(shù)據(jù)結(jié)構(gòu)。因此存儲(chǔ)過(guò)程大大提高了系統(tǒng)的性能。 ●存儲(chǔ)過(guò)程可以跨服務(wù)器運(yùn)行。這一點(diǎn)是通過(guò)觸發(fā)器來(lái)實(shí)現(xiàn)的,當(dāng)然,首先存儲(chǔ)過(guò)程要能登錄到該遠(yuǎn)程服務(wù)器。 ●應(yīng)用程序也能執(zhí)行存儲(chǔ)過(guò)程,從而實(shí)現(xiàn)服務(wù)器和客戶之間的協(xié)同作業(yè)。 ●存儲(chǔ)過(guò)程減少了網(wǎng)絡(luò)的交通。這是因?yàn)榇鎯?chǔ)過(guò)程的文本存儲(chǔ)在數(shù)據(jù)庫(kù)里,調(diào)用存儲(chǔ)過(guò)程時(shí)通過(guò)網(wǎng)絡(luò)的只是存儲(chǔ)過(guò)程的過(guò)程名。 ●利用存儲(chǔ)過(guò)程可以提供一個(gè)附加的安全層。 如(該例子取自pubs2數(shù)據(jù)庫(kù)): Create proc titleid_proc(@title_id varchar(80)) As Begin Select @title_id=lower(@title_id)+”%” Select title,title_id,price Form titles Where lower(title_id) like @title_id Return @@rowcount End 注意例子中的黑體部分,這實(shí)際上是一條賦值語(yǔ)句。該存儲(chǔ)過(guò)程有返回值。 存儲(chǔ)過(guò)程可以變得非常復(fù)雜。我們認(rèn)為,創(chuàng)建存儲(chǔ)過(guò)程還是要遵循“最簡(jiǎn)單就是最好”的原則。建議在創(chuàng)建存儲(chǔ)過(guò)程時(shí)采用縮進(jìn)風(fēng)格,否則創(chuàng)建的存儲(chǔ)過(guò)程三天之后連自己都看不懂。 需要對(duì)存儲(chǔ)過(guò)程作些說(shuō)明: ●Create procedure 語(yǔ)句不能和其他語(yǔ)句在同一個(gè)批命令里。 ●Create procedure 語(yǔ)句不能包括下列語(yǔ)句: use Create View Create default Create rule Create trigger Create procedure 不能使用use語(yǔ)句好理解,存儲(chǔ)過(guò)程是針對(duì)數(shù)據(jù)庫(kù)的,不能在一個(gè)數(shù)據(jù)庫(kù)里訪問(wèn)另外的數(shù)據(jù)庫(kù)。如果在存儲(chǔ)過(guò)程里訪問(wèn)另外的數(shù)據(jù)庫(kù),則數(shù)據(jù)庫(kù)表的參照完整性難于得到保障。 從另外幾條語(yǔ)句看,在存儲(chǔ)過(guò)程里一般不能創(chuàng)建新的數(shù)據(jù)庫(kù)對(duì)象。但可以創(chuàng)建表和索引,以及和表相關(guān)聯(lián)的鍵,表是臨時(shí)表,在存儲(chǔ)過(guò)程結(jié)束后不能看見(jiàn)創(chuàng)建的臨時(shí)表;否則的話每運(yùn)行一次存儲(chǔ)過(guò)程就創(chuàng)建一個(gè)表,結(jié)果可想而知。 存儲(chǔ)過(guò)程里不能創(chuàng)建一個(gè)對(duì)象,刪除它;然后又在同一存儲(chǔ)過(guò)程里用相同的名字創(chuàng)建新的對(duì)象。實(shí)際上,SQL Server在存儲(chǔ)過(guò)程運(yùn)行時(shí)而不是在編譯時(shí)創(chuàng)建對(duì)象的。 ●如果存儲(chǔ)過(guò)程調(diào)用另外的存儲(chǔ)過(guò)程,則第二個(gè)存儲(chǔ)過(guò)程可以調(diào)用在第一個(gè)存儲(chǔ)過(guò)程里創(chuàng)建的對(duì)象。 ●存儲(chǔ)過(guò)程包含的最多參數(shù)為255個(gè),對(duì)存儲(chǔ)過(guò)程里的局部和全局變量沒(méi)有限制。 最后討論一下系統(tǒng)存儲(chǔ)過(guò)程。系統(tǒng)存儲(chǔ)過(guò)程以sp_開(kāi)頭,當(dāng)然用戶創(chuàng)建的存儲(chǔ)過(guò)程也可以以sp_開(kāi)頭;?/span> |
|