存儲過程(Stored Procedure)是在大型數據庫系統中,一組爲了完成特定功能的SQL 語句集,存儲在數據庫中,通過第一次編譯後再次調用不須要再次編譯,用戶經過指定存儲過程的名字並給出參數(若是該存儲過程帶有參數)來執行它。存儲過程是數據庫中的一個重要對象。數據庫
CREATE proc | procedure procedure_name [{@參數數據類型} [=默認值] [output], {@參數數據類型} [=默認值] [output], .... ] as SQL_statements go
1.提升性能安全
SQL語句在建立過程時進行分析和編譯。 存儲過程是預編譯的,在首次運行一個存儲過程時,查詢優化器對其進行分析、優化,並給出最終被存在系統表中的存儲計劃,這樣,在執行過程時即可節省此開銷。
2.下降網絡開銷服務器
存儲過程調用時只需用提供存儲過程名和必要的參數信息,從而可下降網絡的流量。
3.便於進行代碼移植網絡
數據庫專業人員能夠隨時對存儲過程進行修改,但對應用程序源代碼卻毫無影響,從而極大的提升了程序的可移植性。
4.更強的安全性函數
1)系統管理員能夠對執行的某一個存儲過程進行權限限制,避免非受權用戶對數據的訪問 2)在經過網絡調用過程時,只有對執行過程的調用是可見的。 所以,惡意用戶沒法看到表和數據庫對象名稱、嵌入本身的 Transact-SQL 語句或搜索關鍵數據 3)使用過程參數有助於避免 SQL 注入攻擊。 由於參數輸入被視做文字值而非可執行代碼,因此,攻擊者將命令插入過程內的 Transact-SQL 語句並損害安全性將更爲困難 4)能夠對過程進行加密,這有助於對源代碼進行模糊處理
1.存儲過程須要專門的數據庫開發人員進行維護
2.設計邏輯變動,修改存儲過程沒有SQL靈活性能
N後字符串的數據類型爲NChar或是NVarchar優化
在服務器上執行的代碼中(例如在存儲過程和觸發器中)顯示的 Unicode 字符串常量必須以大寫字母 N 爲前綴。即便所引用的列已定義爲 Unicode 類型,也應如此。如不使用 N 前綴,字符串將轉換爲數據庫的默認代碼頁。可能致使不識別某些字符加密
EXECUTE Product_Info @name = N'Chain'
使用 N 前綴的要求適用於在服務器上生成的和客戶端發送的字符串常量設計
--查詢存儲過程 IF OBJECT_ID (N'PROC_SELECT_STUDENTS_COUNT', N'P') IS NOT NULL DROP procedure PROC_SELECT_STUDENTS_COUNT; GO CREATE procedure PROC_SELECT_STUDENTS_COUNT AS SELECT COUNT(ID) FROM Students GO
--執行 EXEC PROC_SELECT_STUDENTS_COUNT
--查詢存儲過程,根據城市查詢總數 IF OBJECT_ID (N'PROC_SELECT_STUDENTS_BY_CITY_COUNT', N'P') IS NOT NULL DROP procedure PROC_SELECT_STUDENTS_BY_CITY_COUNT; GO CREATE procedure PROC_SELECT_STUDENTS_BY_CITY_COUNT(@city nvarchar(50)) AS SELECT COUNT(ID) FROM Students WHERE City = @city GO
--執行 EXEC PROC_SELECT_STUDENTS_BY_CITY_COUNT N'Beijing'
在參數值賦值時,加上相應的通配符code
--查詢姓氏爲李的學生信息,含通配符 IF OBJECT_ID (N'PROC_SELECT_STUDENTS_BY_SURNNAME', N'P') IS NOT NULL DROP procedure PROC_SELECT_STUDENTS_BY_SURNNAME; GO CREATE procedure PROC_SELECT_STUDENTS_BY_SURNNAME @surnName nvarchar(20)='林%' --默認值 AS SELECT ID, Name, Age FROM Students WHERE Name like @surnName GO
--執行 EXEC PROC_SELECT_STUDENTS_BY_SURNNAME EXEC PROC_SELECT_STUDENTS_BY_SURNNAME N'林%' EXEC PROC_SELECT_STUDENTS_BY_SURNNAME N'%林%'
--根據姓名查詢的學生信息,返回學生的城市及年齡 IF OBJECT_ID (N'PROC_SELECT_STUDENTS_BY_NAME', N'P') IS NOT NULL DROP procedure PROC_SELECT_STUDENTS_BY_NAME; GO CREATE procedure PROC_SELECT_STUDENTS_BY_NAME @name nvarchar(50), --輸入參數 @city nvarchar(20) out, --輸出參數 @age int output --輸入輸出參數 AS SELECT @city = City, @age = Age FROM Students WHERE Name = @name AND Age = @age GO
--執行 declare @name nvarchar(50), @city nvarchar(20), @age int; set @name = N'PG ONE'; set @age = 23; exec PROC_SELECT_STUDENTS_BY_NAME @name, @city out, @age output; select @city, @age;
--存儲過程:新增學生信息 IF OBJECT_ID (N'PROC_INSERT_STUDENT', N'P') IS NOT NULL DROP procedure PROC_INSERT_STUDENT; GO CREATE procedure PROC_INSERT_STUDENT @id int, @name nvarchar(20), @age int, @city nvarchar(20) AS INSERT INTO Students(ID,Name,Age,City) VALUES(@id,@name,@age,@city) GO
--執行 EXEC PROC_INSERT_STUDENT 1001, N'GAI', 29, 'ChengDu'
--根據學生ID,更新學生信息 IF OBJECT_ID (N'PROC_UPDATE_STUDENT', N'P') IS NOT NULL DROP procedure PROC_UPDATE_STUDENT; GO CREATE procedure PROC_UPDATE_STUDENT @id int, @name nvarchar(20), @age int, @city nvarchar(20) AS UPDATE Students SET Name=@name, Age=@age, City=@city WHERE ID=@id GO --執行 EXEC PROC_UPDATE_STUDENT 1001, N'Jony J', 28, 'NanChang'
--存儲過程:刪除學生信息 IF OBJECT_ID (N'PROC_DELETE_STUDENT_BY_ID', N'P') IS NOT NULL DROP procedure PROC_DELETE_STUDENT_BY_ID; GO CREATE procedure PROC_DELETE_STUDENT_BY_ID @id int AS DELETE FROM Students WHERE ID=@id GO
--執行 EXEC PROC_DELETE_STUDENT_BY_ID 1001
--分頁查詢 IF OBJECT_ID (N'PROC_SELECT_BY_PAGE', N'P') IS NOT NULL DROP procedure PROC_SELECT_BY_PAGE; GO CREATE procedure PROC_SELECT_BY_PAGE @startIndex int, @endIndex int AS SELECT * FROM (SELECT ID,Name,Age,City,ROW_NUMBER() OVER(ORDER BY ID DESC) AS RowNumber FROM Students) AS Temp WHERE Temp.RowNumber BETWEEN @startIndex AND @endIndex GO
--執行 EXEC PROC_SELECT_BY_PAGE 1,10
--使用TOP分頁 IF OBJECT_ID (N'PROC_SELECT_BY_PAGE_WITH_TOP', N'P') IS NOT NULL DROP procedure PROC_SELECT_BY_PAGE_WITH_TOP; GO CREATE procedure PROC_SELECT_BY_PAGE_WITH_TOP @pageIndex int, @pageSize int AS SELECT TOP(@pageSize) * FROM Students WHERE ID >=(SELECT MAX(ID) FROM (SELECT TOP(@pageSize*(@pageIndex-1) + 1) ID FROM Students ORDER BY ID) AS Temp) GO
--執行 EXEC PROC_SELECT_BY_PAGE_WITH_TOP 1,2
--存儲過程,重複編譯 IF OBJECT_ID (N'PROC_SELECT_STUDENTS_WITH_RECOMPILE', N'P') IS NOT NULL DROP procedure PROC_SELECT_STUDENTS_WITH_RECOMPILE; GO CREATE procedure PROC_SELECT_STUDENTS_WITH_RECOMPILE with recompile --重複編譯 AS SELECT * FROM Students GO
加密後,不能查看和修改源腳本
--查詢存儲過程,進行加密 IF OBJECT_ID (N'PROC_SELECT_STUDENTS_WITH_ENCRYPTION', N'P') IS NOT NULL DROP procedure PROC_SELECT_STUDENTS_WITH_ENCRYPTION; GO CREATE procedure PROC_SELECT_STUDENTS_WITH_ENCRYPTION with encryption --加密 AS SELECT * FROM Students GO
--執行 EXEC PROC_SELECT_STUDENTS_WITH_ENCRYPTION