由儲存過程談「配角」

2021-08-27 02:20:37 字數 3915 閱讀 9203

儲存過程是一組預先編譯好的sql語句。將他放在伺服器上面,由使用者通過指定儲存過程的名字來執行它。

儲存過程的優點:

封裝——可用於運算元據庫物件的方法,使用者只需要知道它的輸入輸出引數並理解其目的即可。

改善效能——已經預先編譯

減少網路流量——只返回最後的結果集

重要性——針對複雜邏輯,應用已經測試號的儲存過程,不容易發生錯誤。

安全性——如果資料庫擁有者dbo或者系統管理員sa編譯並儲存了儲存結構,儲存過程就有了對它使用的資料庫物件的所有訪問許可權。因此系統管理員可以向單獨的用於授予對資料物件的最小訪問許可權,而不是直接允許使用者使用資料庫物件。

這次專案開發中運用了不少的儲存過程,中間遇到了乙個小問題,大家可以看看:

事情是這樣的:我想根據卡號、教師編號、教師姓名、聯絡**這四個條件查詢教師編號,這四個條件可以不存在,可以只存在乙個,可以只存在兩個,可以只存在三個,可以存在四個。開始我寫的儲存過程是這樣的

create procedure [dbo].[proccardbymore]

@cardno varchar (50),

@teacherid varchar(50),

@name varchar(50),

@telephone varchar(50)

as declare @sql varchar(1000)

set @sql='select teacherid as 教師編號,name as 教師姓名,gradename as 所屬年級,cardno as 卡號,cash as 卡內餘額,realname as 管理員,opentime as 開卡時間,state as 狀態,telephone as 聯絡** from view_carddetail '

if(@cardno <>'')

begin

set @sql=@sql+'and cardno ='''+@cardno+''''

endif(@teacherid <>'')

begin

set @sql=@sql+'and teacherid ='''+@teacherid+''''

endif(@name <>'')

begin

set @sql=@sql+'and name ='''+@name +''''

endif(@name <>'')

begin

set @sql=@sql+'and telephone ='''+@telephone +''''

endexec(@sql)

這裡面假如卡號不為空的話,那麼寫出來的sql語句是這樣的:

select teacherid as 教師編號,name as 教師姓名,gradename as 所屬年級,cardno as 卡號,cash as 卡內餘額,realname as 管理員,opentime as 開卡時間,state as 狀態,telephone as 聯絡**from view_carddetail and  cardno ='@cardno』

這句話顯然是錯誤的,在查詢語句和條件的過渡的地方沒有where,而是突然來了個and。然而這個時候如果加上個必然條件那就完美了,接下來的儲存過程建立語句是這樣的:

create procedure [dbo].[proccardbymore]

@cardno varchar (50),

@teacherid varchar(50),

@name varchar(50),

@telephone varchar(50)

as declare @sql varchar(1000)

set @sql='select teacherid as 教師編號,name as 教師姓名,gradename as 所屬年級,cardno as 卡號,cash as 卡內餘額,realname as 管理員,opentime as 開卡時間,state as 狀態,telephone as 聯絡**from view_carddetail where 1=1 '

if(@cardno <>'')

begin

set @sql=@sql+'and cardno ='''+@cardno+''''

endif(@teacherid <>'')

begin

set @sql=@sql+'and teacherid ='''+@teacherid+''''

endif(@name <>'')

begin

set @sql=@sql+'and name ='''+@name +''''

endif(@name <>'')

begin

set @sql=@sql+'and telephone ='''+@telephone +''''

endexec(@sql)

這樣的話執行出來的結果是這樣的:

select teacherid as 教師編號,nameas 教師姓名,gradename as 所屬年級,cardno as 卡號,cashas 卡內餘額,realname as 管理員,opentime as 開卡時間,stateas 狀態,telephone as 聯絡**from view_carddetail where 1=1and  cardno ='+@cardno+'

必然條件在這裡充當了橋梁的作用,雖然我們沒有「1=1「的需求,但是它的存在卻恰好解決了兩者互不相容的尷尬局面。

受上面的啟發,下面的情況是這樣解決的:

需要根據教師編號和起始日期查詢教師的消費記錄情況,兩個條件的存在情況各自隨便。

儲存過程**如下:

create procedure [dbo].[procconsumebymore] 

@teacherid varchar(50),

@timestart datetime,

@timeend datetime

as declare @sql varchar(1000)

set @sql='select teacherid as 教師編號,name as 教師姓名,orderid as 訂單編號,adultnum as **數量,childnum as 兒童數量,consumecash as 消費金額,consumetime as 消費時間,userid as 管理員編號,realname as 管理員姓名from view_consumedetail where 1=1 '

if(@teacherid <>'')

begin

set @sql=@sql+'and teacherid ='''+@teacherid+''''

endif( @timestart<>null and @timeend<>null)

begin

set @sql=@sql+'and consumetime between '''+@timestart +''' and '''+@timeend+''''

endexec(@sql)

這裡當@timestart和@timeend為空的時候,空字串不能轉換成日期型別,這時候假如兩個變數為空,我可以給他們賦乙個完全的值:

exec procconsumebymore '', '1799-01-01','9999-12-29'

如上面的**就可以選擇出所有的消費記錄了。

上面兩件事情中必然事件這個配角起了不可忽視的作用,然而必然事件卻不是我們在查詢過程中需要的條件。

生活中配角並不意味著無趣和呆板,配角一樣可以靈動,只是它把對別人的善意放在第一位,不把張揚作為表達自己的方式。『上善若水,水善利萬物而不爭』,但是水又無處不在,其實就是這樣一種狀態。創造乙個最好的配角,並不比創造乙個主角容易。

由儲存過程談「配角」

儲存過程是一組預先編譯好的sql語句。將他放在伺服器上面,由使用者通過指定儲存過程的名字來執行它。儲存過程的優點 封裝 可用於運算元據庫物件的方法,使用者只需要知道它的輸入輸出引數並理解其目的即可。改善效能 已經預先編譯 減少網路流量 只返回最後的結果集 重要性 針對複雜邏輯,應用已經測試號的儲存過...

也談儲存過程分頁

最近我測試小春寫的儲存分頁,發現有些許問題 建立乙個test id,name,fid 向test添充幾十條資料,使id 1,2,3,4.即遞增的integer 其他任意 在t sql debugger給改儲存過程分別傳遞如下引數 querystr from test keyfield id page...

也談儲存過程分頁

最近我測試小春寫的儲存分頁,發現有些許問題 建立乙個test id,name,fid 向test添充幾十條資料,使id 1,2,3,4.即遞增的integer 其他任意 在t sql debugger給改儲存過程分別傳遞如下引數 querystr from test keyfield id page...