SQLServer之建立存儲過程

建立存儲過程注意事項

在 SQL Server、 Azure SQL Database、Azure SQL 數據倉庫和並行數據庫中建立 Transact-SQL 或公共語言運行時 (CLR) 存儲過程,存儲過程與其餘編程語言中的過程相似。sql

能夠在當前數據庫中建立永久過程,或者在 tempdb 數據庫中建立臨時程序。數據庫

存儲過程能夠:編程

接受輸入參數並以輸出參數的格式向調用過程或批處理返回多個值。緩存

包含用於在數據庫中執行操做(包括調用其餘過程)的編程語句。安全

向調用過程或批處理返回狀態值,以指明成功或失敗(以及失敗的緣由)。服務器

通常備註

一個過程沒有預約義的最大大小。架構

在過程當中指定的變量能夠是用戶定義變量或系統變量,如 @@SPID。編程語言

第一次執行某個過程時,將編譯該過程以肯定檢索數據的最優訪問計劃。 若是已經生成的計劃仍保留在 數據庫引擎計劃緩存中,則該過程隨後執行的操做可能從新使用該計劃。函數

SQL Server 啓動時能夠自動執行一個或多個過程。 這些過程必須由系統管理員在 master 數據庫中建立,並以 sysadmin 固定服務器角色做爲後臺進程執行。 這些過程不能有任何輸入或輸出參數。 有關詳細信息,請參閱執行存儲過程。工具

當一個過程經過引用 CLR 例程、類型或聚合來調用另外一個過程或執行託管代碼時,過程將被嵌套。 過程和託管代碼引用的嵌套最高可達 32 級。 每當調用的過程或託管代碼引用開始執行,嵌套級別就增長一級;執行完成後,嵌套級別就減小一級。 從託管代碼內部調用的方法不根據嵌套級別限制進行計數。 可是,當一個 CLR 存儲過程經過 SQL Server 託管訪問接口執行數據訪問操做時,在從託管代碼到 SQL 的轉換中將添加一級嵌套。

試圖超過最高級的嵌套將致使整個調用鏈失敗。 可使用 @@NESTLEVEL 函數返回當前存儲過程執行的嵌套級別。

使用SSMS數據庫管理工具建立存儲過程語法和T-SQL腳本建立存儲過程語法相同。

使用T-SQL腳本建立存儲過程

語法:

--聲明數據庫引用

use 數據庫名;

go

--判斷是否存在存儲過程,若是存在則刪除

if exists(select * from sys.procedures where name=存儲過程名稱)

drop procedure 存儲過程名稱;

go

--建立存儲過程

create procedure [schema_name][.]procedure_name [;number]

[{ @parameter [type_schema_name.] data_type} [ null | not null ][varying] [ = default ] [ out| output ] [readonly] ] [,......n]

with [encryption][,][recompile][,][execute as clause]

for replication

as

begin

sql_statement;

end

go

語法解析:

--schema_name

--過程所屬架構的名稱。 過程是綁定到架構的。若是在建立過程時未指定架構名稱,則自動分配正在建立過程的用戶的默認架構。

--procedure_name

--過程的名稱。 過程名稱必須遵循有關標識符的規則,而且在架構中必須惟一。

--在命名過程時避免使用 sp_ 前綴。 此前綴由 SQL Server 用來指定系統過程。 若是存在同名的系統過程,則使用前綴可能致使應用程序代碼中斷。

--可在 procedure_name 前面使用一個數字符號 (#procedure_name) 來建立局部臨時程序,使用兩個數字符號 (##procedure_name) 來建立全局臨時程序。

--局部臨時程序僅對建立了它的鏈接可見,而且在關閉該鏈接後將被刪除。 全局臨時程序可用於全部鏈接,而且在使用該過程的最後一個會話結束時將被刪除。 對於 CLR 過程,不能指定臨時名稱。

--過程或全局臨時程序的完整名稱(包括 ##)不能超過 128 個字符。 局部臨時程序的完整名稱(包括 #)不能超過 116 個字符。

--; number

--適用範圍: SQL Server 2008 到 SQL Server 2017 和 Azure SQL Database。

--用於對同名的過程分組的可選整數。 使用一個 DROP PROCEDURE 語句可將這些分組過程一塊兒刪除。

--@parameter

--在過程當中聲明的參數。 經過將 at 符號 (@) 用做第一個字符來指定參數名稱。 參數名稱必須符合標識符規則。 每一個過程的參數僅用於該過程自己;其餘過程當中可使用相同的參數名稱。

--可聲明一個或多個參數;最大值是 2,100。 除非定義了參數的默認值或者將參數設置爲等於另外一個參數,不然用戶必須在調用過程時爲每一個聲明的參數提供值。

--若是過程包含表值參數,而且該參數在調用中缺失,則傳入空表。 參數只能代替常量表達式,而不能用於代替表名、列名或其餘數據庫對象的名稱。 有關詳細信息,請參閱 EXECUTE (Transact-SQL)。

--若是指定了 FOR REPLICATION,則沒法聲明參數。

--[type_schema_name. [ =] data_type

--參數的數據類型以及該數據類型所屬的架構。

--針對 Transact-SQL 過程的準則:

--全部 Transact-SQL 數據類型均可以用做參數。

--您可使用用戶定義的表類型建立表值參數。 表值參數只能是 INPUT 參數,而且這些參數必須帶有 READONLY 關鍵字。 有關詳細信息,請參閱使用表值參數(數據引擎)

--遊標數據類型只能是 OUTPUT 參數,而且必須帶有 VARYING 關鍵字。

--針對 CLR 過程的準則:

--在託管代碼中具備等效值的全部本機 SQL Server 數據類型均可以用做參數。 有關 CLR 類型與 SQL Server 系統數據類型之間關係的詳細信息,請參閱映射 CLR 參數數據。 有關 SQL Server 系統數據類型及其語法的詳細信息,請參閱數據類型 (Transact-SQL)。

--表值或遊標數據類型不能用做參數。

--若是參數的數據類型爲 CLR 用戶定義類型,則必須對此類型有 EXECUTE 權限。

--varying

--指定做爲輸出參數支持的結果集。 該參數由過程動態構造,其內容可能發生改變。 僅適用於遊標參數。 該選項對於 CLR 過程無效。

--default

--參數的默認值。 若是爲參數定義了默認值,則無需指定此參數的值便可執行過程。 默認值必須是常量或 NULL。 該常量值能夠採用通配符的形式,這使其能夠在將該參數傳遞到過程時使用 LIKE 關鍵字。

--只有 CLR 過程的默認值記錄在 sys.parameters.default 列中。 對於 Transact-SQL 過程參數,該列將爲 NULL。

--out|output

--指示參數是輸出參數。 使用 OUTPUT 參數將值返回給過程的調用方。 除非是 CLR 過程,不然 text、ntext 和 image 參數不能用做 OUTPUT 參數。 OUTPUT 參數能夠爲遊標佔位符,CLR 過程除外。 不能將表值數據類型指定爲過程的 OUTPUT 參數。

--readonly

--指示不能在過程的主體中更新或修改參數。 若是參數類型爲表值類型,則必須指定 READONLY。

--encryption

--適用範圍:SQL Server( SQL Server 2008 到 SQL Server 2017)、 Azure SQL Database。

--指示 SQL Server 將 CREATE PROCEDURE 語句的原始文本轉換爲模糊格式。 模糊代碼的輸出在 SQL Server 的任何目錄視圖中都不能直接顯示。 對系統表或數據庫文件沒有訪問權限的用戶不能檢索模糊文本。

--可是,能夠經過 DAC 端口訪問系統表的特權用戶或直接訪問數據文件的特權用戶可使用此文本。 此外,可以向服務器進程附加調試器的用戶可在運行時從內存中檢索已解密的過程。 有關如何訪問系統元數據的詳細信息,請參閱元數據可見性配置。

--該選項對於 CLR 過程無效。

--使用此選項建立的過程不能做爲 SQL Server 複製的一部分發布。

--recompile

--指示 數據庫引擎不緩存此過程的查詢計劃,這強制在每次執行此過程時都對該過程進行編譯。 有關強制從新編譯的緣由的詳細信息,請參閱從新編譯存儲過程。 在指定了 FOR REPLICATION 或者用於 CLR 過程時不能使用此選項。

--若要指示 數據庫引擎放棄過程內單個查詢的查詢計劃,請在該查詢的定義中使用 RECOMPILE 查詢提示。 有關詳細信息,請參閱查詢提示 (Transact-SQL)。

--execute as 子句

--指定在其中執行過程的安全上下文。

--對於本機編譯存儲過程(從 SQL Server 2016 (13.x) 開始和在 Azure SQL Database 中),EXECUTE AS 子句沒有任何限制。 在 SQL Server 2014 (12.x) 中,對於本機編譯的存儲過程,支持 SELF、OWNER 和 ‘user_name’ 子句。

--有關詳細信息,請參閱 EXECUTE AS 子句 (Transact-SQL)。

--SELF

--EXECUTE AS SELF 與 EXECUTE AS user_name 等價,其中指定用戶是建立或更改模塊的用戶。 建立或更改模塊的用戶的實際用戶 ID 存儲在 sys.sql_modules 或 sys.service_queues 目錄視圖的 execute_as_principal_id 列中。

--OWNER

--指定模塊內的語句在模塊的當前全部者上下文中執行。 若是模塊沒有指定的全部者,則使用模塊架構的全部者。 不能爲 DDL 或登陸觸發器指定 OWNER。

--' user_name '

--指定模塊內的語句在 user_name 指定的用戶的上下文中執行。 將根據 user_name 來驗證對模塊內任意對象的權限。 不能爲具備服務器做用域的 DDL 觸發器或登陸觸發器指定 user_name。 請改用 login_name。

--user_name 必須存在於當前數據庫中,而且必須是單一實例賬戶。 user_name 不能爲組、角色、證書、密鑰或內置賬戶,如 NT AUTHORITY\LocalService、NT AUTHORITY\NetworkService 或 NT AUTHORITY\LocalSystem。

--執行上下文的用戶 ID 存儲在元數據中,能夠在 sys.sql_modules 或 sys.assembly_modules 目錄視圖的 execute_as_principal_id 列查看。

--' login_name '

--指定模塊內的語句在 login_name 指定的 SQL Server 登陸的上下文中執行。 將根據 login_name 來驗證對模塊內任意對象的權限。 只能爲具備服務器做用域的 DDL 觸發器或登陸觸發器指定 login_name。

--login_name 不能爲組、角色、證書、密鑰或內置賬戶,如 NT AUTHORITY\LocalService、NT AUTHORITY\NetworkService 或 NT AUTHORITY\LocalSystem。

--for replication

--適用範圍:SQL Server( SQL Server 2008 到 SQL Server 2017)、 Azure SQL Database。

--指定爲複製建立該過程。 所以,它不能在訂閱服務器上執行。 使用 FOR REPLICATION 選項建立的過程可用做過程篩選器,且僅在複製過程當中執行。 若是指定了 FOR REPLICATION,則沒法聲明參數。 對於 CLR 過程,不能指定 FOR REPLICATION。 對於使用 FOR REPLICATION 建立的過程,忽略 RECOMPILE 選項。

--FOR REPLICATION 過程在 sys.objects 和 sys.procedures 中包含 RF 對象類型。

--{ [ BEGIN ] sql_statement [;] [ ...n ] [ END ] }

--構成過程主體的一個或多個 Transact-SQL 語句。 您可使用可選的 BEGIN 和 END 關鍵字將這些語句括起來。 有關信息,請參閱後面的「最佳實踐」、「通常備註」以及「限制和侷限」部分。

示例:

--聲明數據庫引用

use testss;

go

--判斷是否存在存儲過程,若是存在則刪除

if exists(select * from sys.procedures where name='noreference')

drop procedure noreference;

go

--建立存儲過程

create procedure noreference

;1

@testid int=NULL,@outparameter varchar(100) out

with encryption,recompile,execute as owner

--for replication

as

begin

if @testid is not null

begin

select * from test1 where id=@testid; set @outparameter='有參數指定輸出';

end

else

begin

select * from test1; set @outparameter='無參數輸出所有';

end

end

go

示例結果:截圖依次顯示建立結果和調用結果。

相關文章
相關標籤/搜索