1. 程式人生 > >T-SQL 中 CREATE PROCEDURE 語法

T-SQL 中 CREATE PROCEDURE 語法

CREATE PROCEDURE

建立儲存過程,儲存過程是儲存起來的可以接受和返回使用者提供的引數的 Transact-SQL 語句的集合。

可以建立一個過程供永久使用,或在一個會話中臨時使用(區域性臨時過程),或在所有會話中臨時使用(全域性臨時過程)。

也可以建立在 Microsoft® SQL Server™ 啟動時自動執行的儲存過程。

語法

CREATE PROC [ EDURE ] procedure_name [ ; number ]
    [ { @parameter data_type }[ VARYING ] [ = default ] [ OUTPUT ]] [ ,...n

]

[ WITH
    { RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ]

[ FOR REPLICATION ]

AS sql_statement [ ...n ]

引數

procedure_name

新儲存過程的名稱。過程名必須符合識別符號規則,且對於資料庫及其所有者必須唯一。有關更多資訊,請參見使用識別符號

要建立區域性臨時過程,可以在 procedure_name 前面加一個編號符 (#procedure_name),要建立全域性臨時過程,可以在 procedure_name 前面加兩個編號符 (##procedure_name

)。完整的名稱(包括 # 或 ##)不能超過 128 個字元。指定過程所有者的名稱是可選的。

;number

是可選的整數,用來對同名的過程分組,以便用一條 DROP PROCEDURE 語句即可將同組的過程一起除去。例如,名為 orders 的應用程式使用的過程可以命名為 orderproc;1、orderproc;2 等。DROP PROCEDURE orderproc 語句將除去整個組。如果名稱中包含定界識別符號,則數字不應包含在識別符號中,只應在 procedure_name 前後使用適當的定界符。

@parameter

過程中的引數。在 CREATE PROCEDURE 語句中可以宣告一個或多個引數。使用者必須在執行過程時提供每個所宣告引數的值(除非定義了該引數的預設值)。儲存過程最多可以有 2.100 個引數。

使用 @ 符號作為第一個字元來指定引數名稱。引數名稱必須符合識別符號的規則。每個過程的引數僅用於該過程本身;相同的引數名稱可以用在其它過程中。預設情況下,引數只能代替常量,而不能用於代替表名、列名或其它資料庫物件的名稱。有關更多資訊,請參見 EXECUTE

data_type

引數的資料型別。所有資料型別(包括 textntextimage)均可以用作儲存過程的引數。不過,cursor 資料型別只能用於 OUTPUT 引數。如果指定的資料型別為 cursor,也必須同時指定 VARYING 和 OUTPUT 關鍵字。有關 SQL Server 提供的資料型別及其語法的更多資訊,請參見資料型別

說明  對於可以是 cursor 資料型別的輸出引數,沒有最大數目的限制。

VARYING

指定作為輸出引數支援的結果集(由儲存過程動態構造,內容可以變化)。僅適用於遊標引數。

default

引數的預設值。如果定義了預設值,不必指定該引數的值即可執行過程。預設值必須是常量或 NULL。如果過程將對該引數使用 LIKE 關鍵字,那麼預設值中可以包含萬用字元(%、_、[] 和 [^])。

OUTPUT

表明引數是返回引數。該選項的值可以返回給 EXEC[UTE]。使用 OUTPUT 引數可將資訊返回給呼叫過程。Textntextimage 引數可用作 OUTPUT 引數。使用 OUTPUT 關鍵字的輸出引數可以是遊標佔位符。

n

表示最多可以指定 2.100 個引數的佔位符。

{RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION}

RECOMPILE 表明 SQL Server 不會快取該過程的計劃,該過程將在執行時重新編譯。在使用非典型值或臨時值而不希望覆蓋快取在記憶體中的執行計劃時,請使用 RECOMPILE 選項。

ENCRYPTION 表示 SQL Server 加密 syscomments 表中包含 CREATE PROCEDURE 語句文字的條目。使用 ENCRYPTION 可防止將過程作為 SQL Server 複製的一部分發布。

說明  在升級過程中,SQL Server 利用儲存在 syscomments 中的加密註釋來重新建立加密過程。

FOR REPLICATION

指定不能在訂閱伺服器上執行為複製建立的儲存過程。.使用 FOR REPLICATION 選項建立的儲存過程可用作儲存過程篩選,且只能在複製過程中執行。本選項不能和 WITH RECOMPILE 選項一起使用。

AS

指定過程要執行的操作。

sql_statement

過程中要包含的任意數目和型別的 Transact-SQL 語句。但有一些限制。

n

是表示此過程可以包含多條 Transact-SQL 語句的佔位符。

註釋

儲存過程的最大大小為 128 MB。

使用者定義的儲存過程只能在當前資料庫中建立(臨時過程除外,臨時過程總是在 tempdb 中建立)。在單個批處理中,CREATE PROCEDURE 語句不能與其它 Transact-SQL 語句組合使用。

預設情況下,引數可為空。如果傳遞 NULL 引數值並且該引數在 CREATE 或 ALTER TABLE 語句中使用,而該語句中引用的列又不允許使用 NULL,則 SQL Server 會產生一條錯誤資訊。為了防止向不允許使用 NULL 的列傳遞 NULL 引數值,應向過程中新增程式設計邏輯或為該列使用預設值(使用 CREATE 或 ALTER TABLE 的 DEFAULT 關鍵字)。

建議在儲存過程的任何 CREATE TABLE 或 ALTER TABLE 語句中都為每列顯式指定 NULL 或 NOT NULL,例如在建立臨時表時。ANSI_DFLT_ON 和 ANSI_DFLT_OFF 選項控制 SQL Server 為列指派 NULL 或 NOT NULL 特性的方式(如果在 CREATE TABLE 或 ALTER TABLE 語句中沒有指定的話)。如果某個連線執行的儲存過程對這些選項的設定與建立該過程的連線的設定不同,則為第二個連線建立的表列可能會有不同的為空性,並且表現出不同的行為方式。如果為每個列顯式聲明瞭 NULL 或 NOT NULL,那麼將對所有執行該儲存過程的連線使用相同的為空性建立臨時表。

在建立或更改儲存過程時,SQL Server 將儲存 SET QUOTED_IDENTIFIER 和 SET ANSI_NULLS 的設定。執行儲存過程時,將使用這些原始設定。因此,所有客戶端會話的 SET QUOTED_IDENTIFIER 和 SET ANSI_NULLS 設定在執行儲存過程時都將被忽略。在儲存過程中出現的 SET QUOTED_IDENTIFIER 和 SET ANSI_NULLS 語句不影響儲存過程的功能。

其它 SET 選項(例如 SET ARITHABORT、SET ANSI_WARNINGS 或 SET ANSI_PADDINGS)在建立或更改儲存過程時不儲存。如果儲存過程的邏輯取決於特定的設定,應在過程開頭新增一條 SET 語句,以確保設定正確。從儲存過程中執行 SET 語句時,該設定只在儲存過程完成之前有效。之後,設定將恢復為呼叫儲存過程時的值。這使個別的客戶端可以設定所需的選項,而不會影響儲存過程的邏輯。

說明  SQL Server 是將空字串解釋為單個空格還是解釋為真正的空字串,由相容級別設定控制。如果相容級別小於或等於 65,SQL Server 就將空字串解釋為單個空格。如果相容級別等於 70,則 SQL Server 將空字串解釋為空字串。有關更多資訊,請參見sp_dbcmptlevel

獲得有關儲存過程的資訊

若要顯示用來建立過程的文字,請在過程所在的資料庫中執行 sp_helptext,並使用過程名作為引數。

說明  使用 ENCRYPTION 選項建立的儲存過程不能使用 sp_helptext 檢視。

若要顯示有關過程引用的物件的報表,請使用 sp_depends

若要為過程重新命名,請使用 sp_rename

引用物件

SQL Server 允許建立的儲存過程引用尚不存在的物件。在建立時,只進行語法檢查。執行時,如果快取記憶體中尚無有效的計劃,則編譯儲存過程以生成執行計劃。只有在編譯過程中才解析儲存過程中引用的所有物件。因此,如果語法正確的儲存過程引用了不存在的物件,則仍可以成功建立,但在執行時將失敗,因為所引用的物件不存在。有關更多資訊,請參見延遲名稱解析和編譯

延遲名稱解析和相容級別

SQL Server 允許 Transact-SQL 儲存過程在建立時引用不存在的表。這種能力稱為延遲名稱解析。不過,如果 Transact-SQL 儲存過程引用了該儲存過程中定義的表,而相容級別設定(通過執行 sp_dbcmptlevel 來設定)為 65,則在建立時會發出警告資訊。而如果在執行時所引用的表不存在,將返回錯誤資訊。有關更多資訊,請參見 sp_dbcmptlevel延遲名稱解析和編譯

執行儲存過程

成功執行 CREATE PROCEDURE 語句後,過程名稱將儲存在 sysobjects 系統表中,而 CREATE PROCEDURE 語句的文字將儲存在 syscomments 中。第一次執行時,將編譯該過程以確定檢索資料的最佳訪問計劃。

使用 cursor 資料型別的引數

儲存過程只能將 cursor 資料型別用於 OUTPUT 引數。如果為某個引數指定了 cursor 資料型別,也必須指定 VARYING 和 OUTPUT 引數。如果為某個引數指定了 VARYING 關鍵字,則資料型別必須是 cursor,並且必須指定 OUTPUT 關鍵字。

說明  cursor 資料型別不能通過資料庫 API(例如 OLE DB、ODBC、ADO 和 DB-Library)繫結到應用程式變數上。因為必須先繫結 OUTPUT 引數,應用程式才可以執行儲存過程,所以帶有 cursor OUTPUT 引數的儲存過程不能通過資料庫 API 呼叫。只有將 cursor OUTPUT 變數賦值給 Transact-SQL 區域性 cursor 變數時,才可以通過 Transact-SQL 批處理、儲存過程或觸發器呼叫這些過程。

Cursor 輸出引數

在執行過程時,以下規則適用於 cursor 輸出引數:

  1. 對於只進遊標,遊標的結果集中返回的行只是那些儲存過程執行結束時處於或超出遊標位置的行,例如:
    1. 在過程中的名為 RS 的 100 行結果集上開啟一個非滾動遊標。

    2. 過程提取結果集 RS 的頭 5 行。

    3. 過程返回到其呼叫者。

    4. 返回到呼叫者的結果集 RS 由 RS 的第 6 到 100 行組成,呼叫者中的遊標處於 RS 的第一行之前。
  2. 對於只進遊標,如果儲存過程完成後,遊標位於第一行的前面,則整個結果集將返回給呼叫批處理、儲存過程或觸發器。返回時,遊標將位於第一行的前面。

  3. 對於只進遊標,如果儲存過程完成後,遊標的位置超出最後一行的結尾,則為呼叫批處理、儲存過程或觸發器返回空結果集。

    說明  空結果集與空值不同。

  4. 對於可滾動遊標,在儲存過程執行結束時,結果集中的所有行均會返回給呼叫批處理、儲存過程或觸發器。返回時,遊標保留在過程中最後一次執行提取時的位置。

  5. 對於任意型別的遊標,如果遊標關閉,則將空值傳遞迴呼叫批處理、儲存過程或觸發器。如果將遊標指派給一個引數,但該遊標從未開啟過,也會出現這種情況。

說明  關閉狀態只有在返回時才有影響。例如,可以在過程中關閉遊標,稍後再開啟遊標,然後將該遊標的結果集返回給呼叫批處理、儲存過程或觸發器。

臨時儲存過程

SQL Server 支援兩種臨時過程:區域性臨時過程和全域性臨時過程。區域性臨時過程只能由建立該過程的連線使用。全域性臨時過程則可由所有連線使用。區域性臨時過程在當前會話結束時自動除去。全域性臨時過程在使用該過程的最後一個會話結束時除去。通常是在建立該過程的會話結束時。

臨時過程用 # 和 ## 命名,可以由任何使用者建立。建立過程後,區域性過程的所有者是唯一可以使用該過程的使用者。執行區域性臨時過程的許可權不能授予其他使用者。如果建立了全域性臨時過程,則所有使用者均可以訪問該過程,許可權不能顯式廢除。只有在 tempdb 資料庫中具有顯式 CREATE PROCEDURE 許可權的使用者,才可以在該資料庫中顯式建立臨時過程(不使用編號符命名)。可以授予或廢除這些過程中的許可權。

說明  頻繁使用臨時儲存過程會在 tempdb 中的系統表上產生爭用,從而對效能產生負面影響。建議使用 sp_executesql 代替。sp_executesql 不在系統表中儲存資料,因此可以避免這一問題。

自動執行儲存過程

SQL Server 啟動時可以自動執行一個或多個儲存過程。這些儲存過程必須由系統管理員建立,並在 sysadmin 固定伺服器角色下作為後臺過程執行。這些過程不能有任何輸入引數。

對啟動過程的數目沒有限制,但是要注意,每個啟動過程在執行時都會佔用一個連線。如果必須在啟動時執行多個過程,但不需要並行執行,則可以指定一個過程作為啟動過程,讓該過程呼叫其它過程。這樣就只佔用一個連線。

在啟動時恢復了最後一個數據庫後,即開始執行儲存過程。若要跳過這些儲存過程的執行,請將啟動引數指定為跟蹤標記 4022。如果以最低配置啟動 SQL Server(使用 -f 標記),則啟動儲存過程也不會執行。有關更多資訊,請參見跟蹤標記

若要建立啟動儲存過程,必須作為 sysadmin 固定伺服器角色的成員登入,並在 master 資料庫中建立儲存過程。

使用 sp_procoption 可以:

  1. 將現有儲存過程指定為啟動過程。

  2. 停止在 SQL Server 啟動時執行過程。

  3. 檢視 SQL Server 啟動時執行的所有過程的列表。
儲存過程巢狀

儲存過程可以巢狀,即一個儲存過程可以呼叫另一個儲存過程。在被呼叫過程開始執行時,巢狀級將增加,在被呼叫過程執行結束後,巢狀級將減少。如果超出最大的巢狀級,會使整個呼叫過程鏈失敗。可用 @@NESTLEVEL 函式返回當前的巢狀級。

若要估計編譯後的儲存過程大小,請使用下列效能監視計數器。

效能監視器物件名 效能監視計數器名稱
SQLServer:緩衝區管理器 快取記憶體大小(頁面數)
SQLServer:快取記憶體管理器 快取記憶體命中率
快取記憶體頁
快取記憶體物件計數*

* 各種分類的快取記憶體物件均可以使用這些計數器,包括特殊 sql、準備 sql、過程、觸發器等。

sql_statement 限制

除了 SET SHOWPLAN_TEXT 和 SET SHOWPLAN_ALL 之外(這兩個語句必須是批處理中僅有的語句),任何 SET 語句均可以在儲存過程內部指定。所選擇的 SET 選項在儲存過程執行過程中有效,之後恢復為原來的設定。

如果其他使用者要使用某個儲存過程,那麼在該儲存過程內部,一些語句使用的物件名必須使用物件所有者的名稱限定。這些語句包括:

  1. ALTER TABLE

  2. CREATE INDEX

  3. CREATE TABLE

  4. 所有 DBCC 語句

  5. DROP TABLE

  6. DROP INDEX

  7. TRUNCATE TABLE

  8. UPDATE STATISTICS
許可權

CREATE PROCEDURE 的許可權預設授予 sysadmin 固定伺服器角色成員和 db_ownerdb_ddladmin 固定資料庫角色成員。sysadmin 固定伺服器角色成員和 db_owner 固定資料庫角色成員可以將 CREATE PROCEDURE 許可權轉讓給其他使用者。執行儲存過程的許可權授予過程的所有者,該所有者可以為其它資料庫使用者設定執行許可權。

示例
A. 使用帶有複雜 SELECT 語句的簡單過程

下面的儲存過程從四個表的聯接中返回所有作者(提供了姓名)、出版的書籍以及出版社。該儲存過程不使用任何引數。

USE pubs
IF EXISTS (SELECT name FROM sysobjects 
         WHERE name = 'au_info_all' AND type = 'P')
   DROP PROCEDURE au_info_all
GO
CREATE PROCEDURE au_info_all
AS
SELECT au_lname, au_fname, title, pub_name
   FROM authors a INNER JOIN titleauthor ta
      ON a.au_id = ta.au_id INNER JOIN titles t
      ON t.title_id = ta.title_id INNER JOIN publishers p
      ON t.pub_id = p.pub_id
GO

au_info_all 儲存過程可以通過以下方法執行:

EXECUTE au_info_all
-- Or
EXEC au_info_all

如果該過程是批處理中的第一條語句,則可使用:

au_info_all
B. 使用帶有引數的簡單過程

下面的儲存過程從四個表的聯接中只返回指定的作者(提供了姓名)、出版的書籍以及出版社。該儲存過程接受與傳遞的引數精確匹配的值。

USE pubs
IF EXISTS (SELECT name FROM sysobjects 
         WHERE name = 'au_info' AND type = 'P')
   DROP PROCEDURE au_info
GO
USE pubs
GO
CREATE PROCEDURE au_info 
   @lastname varchar(40), 
   @firstname varchar(20) 
AS 
SELECT au_lname, au_fname, title, pub_name
   FROM authors a INNER JOIN titleauthor ta
      ON a.au_id = ta.au_id INNER JOIN titles t
      ON t.title_id = ta.title_id INNER JOIN publishers p
      ON t.pub_id = p.pub_id
   WHERE  au_fname = @firstname
      AND au_lname = @lastname
GO

au_info 儲存過程可以通過以下方法執行:

EXECUTE au_info 'Dull', 'Ann'
-- Or
EXECUTE au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
EXECUTE au_info @firstname = 'Ann', @lastname = 'Dull'
-- Or
EXEC au_info 'Dull', 'Ann'
-- Or
EXEC au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
EXEC au_info @firstname = 'Ann', @lastname = 'Dull'

如果該過程是批處理中的第一條語句,則可使用:

au_info 'Dull', 'Ann'
-- Or
au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
au_info @firstname = 'Ann', @lastname = 'Dull'
C. 使用帶有萬用字元引數的簡單過程

下面的儲存過程從四個表的聯接中只返回指定的作者(提供了姓名)、出版的書籍以及出版社。該儲存過程對傳遞的引數進行模式匹配,如果沒有提供引數,則使用預設的預設值。

USE pubs
IF EXISTS (SELECT name FROM sysobjects 
      WHERE name = 'au_info2' AND type = 'P')
   DROP PROCEDURE au_info2
GO
USE pubs
GO
CREATE PROCEDURE au_info2
   @lastname varchar(30) = 'D%',
   @firstname varchar(18) = '%'
AS 
SELECT au_lname, au_fname, title, pub_name
FROM authors a INNER JOIN titleauthor ta
   ON a.au_id = ta.au_id INNER JOIN titles t
   ON t.title_id = ta.title_id INNER JOIN publishers p
   ON t.pub_id = p.pub_id
WHERE au_fname LIKE @firstname
   AND au_lname LIKE @lastname
GO

au_info2儲存過程可以用多種組合執行。下面只列出了部分組合:

EXECUTE au_info2
-- Or
EXECUTE au_info2 'Wh%'
-- Or
EXECUTE au_info2 @firstname = 'A%'
-- Or
EXECUTE au_info2 '[CK]ars[OE]n'
-- Or
EXECUTE au_info2 'Hunter', 'Sheryl'
-- Or
EXECUTE au_info2 'H%', 'S%'
D. 使用 OUTPUT 引數

OUTPUT 引數允許外部過程、批處理或多條 Transact-SQL 語句訪問在過程執行期間設定的某個值。下面的示例建立一個儲存過程 (titles_sum),並使用一個可選的輸入引數和一個輸出引數。

首先,建立過程:

USE pubs
GO
IF EXISTS(SELECT name FROM sysobjects
      WHERE name = 'titles_sum' AND type = 'P')
   DROP PROCEDURE titles_sum
GO
USE pubs
GO
CREATE PROCEDURE titles_sum @@TITLE varchar(40) = '%', @@SUM money OUTPUT
AS
SELECT 'Title Name' = title
FROM titles 
WHERE title LIKE @@TITLE 
SELECT @@SUM = SUM(price)
FROM titles
WHERE title LIKE @@TITLE
GO

接下來,將該 OUTPUT 引數用於控制流語言。

說明  OUTPUT 變數必須在建立表和使用該變數時都進行定義。

引數名和變數名不一定要匹配,不過資料型別和引數位置必須匹配(除非使用 @@SUM = variable 形式)。

DECLARE @@TOTALCOST money
EXECUTE titles_sum 'The%', @@TOTALCOST OUTPUT
IF @@TOTALCOST < 200 
BEGIN
   PRINT ' '
   PRINT 'All of these titles can be purchased for less than $200.'
END
ELSE
   SELECT 'The total cost of these titles is $' 
         + RTRIM(CAST(@@TOTALCOST AS varchar(20)))

下面是結果集:

Title Name                                                               
------------------------------------------------------------------------ 
The Busy Executive's Database Guide
The Gourmet Microwave
The Psychology of Computer Cooking

(3 row(s) affected)

Warning, null value eliminated from aggregate.
 
All of these titles can be purchased for less than $200.
E. 使用 OUTPUT 遊標引數

OUTPUT 遊標引數用來將儲存過程的區域性遊標傳遞迴呼叫批處理、儲存過程或觸發器。

首先,建立以下過程,在 titles 表上宣告並開啟一個遊標:

USE pubs
IF EXISTS (SELECT name FROM sysobjects 
      WHERE name = 'titles_cursor' and type = 'P')
DROP PROCEDURE titles_cursor
GO
CREATE PROCEDURE titles_cursor @titles_cursor CURSOR VARYING OUTPUT
AS
SET @titles_cursor = CURSOR
FORWARD_ONLY STATIC FOR
SELECT *
FROM titles

OPEN @titles_cursor
GO

接下來,執行一個批處理,宣告一個區域性遊標變數,執行上述過程以將遊標賦值給區域性變數,然後從該遊標提取行。

USE pubs
GO
DECLARE @MyCursor CURSOR
EXEC titles_cursor @titles_cursor = @MyCursor OUTPUT
WHILE (@@FETCH_STATUS = 0)
BEGIN
   FETCH NEXT FROM @MyCursor
END
CLOSE @MyCursor
DEALLOCATE @MyCursor
GO
F. 使用 WITH RECOMPILE 選項

如果為過程提供的引數不是典型的引數,並且新的執行計劃不應快取記憶體或儲存在記憶體中,WITH RECOMPILE 子句會很有幫助。

USE pubs
IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'titles_by_author' AND type = 'P')
   DROP PROCEDURE titles_by_author
GO
CREATE PROCEDURE titles_by_author @@LNAME_PATTERN varchar(30) = '%'
WITH RECOMPILE
AS
SELECT RTRIM(au_fname) + ' ' + RTRIM(au_lname) AS 'Authors full name',
   title AS Title
FROM authors a INNER JOIN titleauthor ta 
   ON a.au_id = ta.au_id INNER JOIN titles t
   ON ta.title_id = t.title_id
WHERE au_lname LIKE @@LNAME_PATTERN
GO
G. 使用 WITH ENCRYPTION 選項

WITH ENCRYPTION 子句對使用者隱藏儲存過程的文字。下例建立加密過程,使用 sp_helptext 系統儲存過程獲取關於加密過程的資訊,然後嘗試直接從 syscomments表中獲取關於該過程的資訊。

IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'encrypt_this' AND type = 'P')
   DROP PROCEDURE encrypt_this
GO
USE pubs
GO
CREATE PROCEDURE encrypt_this
WITH ENCRYPTION
AS
SELECT * 
FROM authors
GO

EXEC sp_helptext encrypt_this

下面是結果集:

The object's comments have been encrypted.

接下來,選擇加密儲存過程內容的標識號和文字。

SELECT c.id, c.text 
FROM syscomments c INNER JOIN sysobjects o
   ON c.id = o.id
WHERE o.name = 'encrypt_this'

下面是結果集:

說明  text 列的輸出顯示在單獨一行中。執行時,該資訊將與 id 列資訊出現在同一行中。

id         text                                                        
---------- ------------------------------------------------------------
1413580074 ?????????????????????????????????e??????????????????????????????????????????????????????????????????????????

(1 row(s) affected)
H. 建立使用者定義的系統儲存過程

下面的示例建立一個過程,顯示錶名以 emp 開頭的所有表及其對應的索引。如果沒有指定引數,該過程將返回表名以 sys 開頭的所有表(及索引)。

IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'sp_showindexes' AND type = 'P')
   DROP PROCEDURE sp_showindexes
GO
USE master
GO
CREATE PROCEDURE sp_showindexes
   @@TABLE varchar(30) = 'sys%'
AS 
SELECT o.name AS TABLE_NAME,
   i.name AS INDEX_NAME, 
   indid AS INDEX_ID
FROM sysindexes i INNER JOIN sysobjects o
   ON o.id = i.id 
WHERE o.name LIKE @@TABLE
GO         
USE pubs
EXEC sp_showindexes 'emp%'
GO

下面是結果集:

TABLE_NAME       INDEX_NAME       INDEX_ID 
---------------- ---------------- ----------------
employee         employee_ind     1
employee         PK_emp_id        2

(2 row(s) affected)
I. 使用延遲名稱解析

下面的示例顯示四個過程以及延遲名稱解析的各種可能使用方式。儘管引用的表或列在編譯時不存在,但每個儲存過程都可建立。

IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'proc1' AND type = 'P')
   DROP PROCEDURE proc1
GO
-- Creating a procedure on a nonexistent table.
USE pubs
GO
CREATE PROCEDURE proc1
AS
   SELECT *
   FROM does_not_exist
GO  
-- Here is the statement to actually see the text of the procedure.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c 
   ON o.id = c.id
WHERE o.type = 'P' AND o.name = 'proc1'
GO
USE master
GO
IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'proc2' AND type = 'P')
   DROP PROCEDURE proc2
GO
-- Creating a procedure that attempts to retrieve information from a
-- nonexistent column in an existing table.
USE pubs
GO
CREATE PROCEDURE proc2
AS
   DECLARE @middle_init char(1)
   SET @middle_init = NULL
   SELECT au_id, middle_initial = @middle_init
   FROM authors
GO  
-- Here is the statement to actually see the text of the procedure.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c 
   ON o.id = c.id
WHERE o.type = 'P' and o.name = 'proc2'

相關推薦

T-SQL CREATE PROCEDURE 語法

CREATE PROCEDURE 建立儲存過程,儲存過程是儲存起來的可以接受和返回使用者提供的引數的 Transact-SQL 語句的集合。 可以建立一個過程供永久使用,或在一個會話中臨時使用(區域性臨時過程),或在所有會話中臨時使用(全域性臨時過程)。 也可以建立在 Microsoft® SQL Serv

關於T-SQLexists或者not exists子查詢的“偽優化”的做法

png tro ges width 9.png 當前 color 盡心 alt 問題起源 在使用t-sql中的exists(或者not exists)子查詢的時候,不知道什麽時候開始,發現一小部分人存在一種“偽優化”的一些做法,並且向不明真相

T-SQL的十大註意事項

() 重要 變量 hash 圖片 search 有一種 where 不必要 轉載自:http://www.cnblogs.com/CareySon/archive/2012/10/11/2719598.html 1.在生產環境中不要出現Select * 這一點我想

T-SQL的where 1=1

拼接字符串 tab 直接 class ava string SQ 字符 代碼 這段代碼應該是在程序(例如在Java或者C#)中生成的,where條件中1=1之後的條件是通過if塊動態變化的。例如(對於拼接字符串的情況): String sql="select * fr

T-SQL的APPLY用法

原文出處:http://www.sqlservercentral.com/articles/Stairway+Series/121318/   從SQL Server 2005開始,微軟添加了一個新的運算子用於關聯一個帶有函式的結果集,並把函式應用於表/檢視中的每一個限定行中。這個運算子就是AP

如何在T-sql 實現陣列的功能

T-SQL象陣列一樣處理字串、分割字串    在日常的程式設計過程中,陣列是要經常使用到的。在利用SQL對資料庫進行操作時,有時就想在SQL使用陣列,比如將1,2,3,4,5拆分成陣列。可惜的是在T-SQL中不支援陣列。不過還是有變通的辦法。我們可以自己編寫兩函式Get

T-SQL的Vlookup

有兩張表,結構、資料如下圖: demo_county表: demo_countyCode表: demo_county表的county匹配demo_countyCode表的countyVal,並把demo_countyCode表相應的code插入到demo_c

T-SQL 的CROSS JOIN用法(半翻譯)

 突然發現個很吊的連結,我們來看看學習資料庫要做些什麼,膽小慎點:DBA工作內容!!!!今天來翻譯一篇關於T-SQL的文章,本文可供微軟認證70-461:QueryingMicrosoft SQL Server 2012的學習和練習之用。本文以翻譯為主,引出個人工作中的一些思

T-SQL的布林值以及怎樣在C#中將bit轉換為bool

1. T-SQL中的布林值在T-SQL中,使用bit來表達布林值。(bit在SQL Server中並不一定儲存為一位;在實際情況中,往往bit被儲存為一個位元組和多個位。)在SQL Server Browser (2008)中可以直接使用True/False作為bit列的輸入

SQLServer--T-SQL的其他函式

datediff函式計算倆個日期差 floor函式返回一個小於或等於當前值的最大整數 use StuManageDB go --定義變數 declare @birthday datetime

語法SQL的case when then else end用法-解決一個字段根據條件取不同值

where 運行 pos 功能 enter cnblogs logs wro img Case具有兩種格式。簡單Case函數和Case搜索函數。 --簡單Case函數 CASE sex WHEN ‘1‘ THEN ‘男‘ WHEN

T-SQL DML 三級的階梯:在SQL server實現關系模型

有一個 records 建數據庫 外鍵約束 ast base 成功 還需要 lin 作者: Gregory Larsen, 2017/08/02 (第一次出版: 2011/11/09) 翻譯:謝雪妮,許雅莉,賴慧芳,劉瓊濱 譯文: 系列 該文章是階梯系列的一部分:T-

T-SQL語句訪問遠程數據庫

school 本地 customer its date rom rowset update 登陸名 1、啟用Ad Hoc Distributed Queries 在使用openrowset/opendatasource前搜先要啟用Ad Hoc Distributed Que

學習筆記之T-SQL插入數據INSERT語法和數據庫編程實戰技巧[圖]

INSERT 數據庫 IT 編程 學習 一直以來就有寫博客的習慣,記錄一下學習心得、生活點滴等等,感覺也蠻好的,去年開始萌生了建立一個讀書和文學博客的想法,於是就開始實施了,中途也遇到不少難題,不過還好,都逐漸解決了,雖然我在技術方面有欠缺,但好在有同學們幫忙。 今天想和大家分享的學習筆記

T-SQL查詢進階--理解SQL Server索引的概念,原理以及其他

工具 def microsoft 需要 blog b- eve 實現 中一 簡介 在SQL Server中,索引是一種增強式的存在,這意味著,即使沒有索引,SQL Server仍然可以實現應有的功能。但索引可以在大多數情況下大大提升查詢性能,在OLAP

T-SQL查詢進階--SQL Server的事務與鎖

錯誤 span 設備 限制 數據復制 默認 base 數據 insert 為什麽需要鎖在任何多用戶的數據庫中,必須有一套用於數據修改的一致的規則,當兩個不同的進程試圖同時修改同一份數據時,數據庫管理系統(DBMS)負責解決它們之間潛在的沖突。任何關系數據庫必須支持事務的AC

SQL 語法順序與執行順序

SQL 語句的語法順序是: SELECT DISTINCT < select_list > FROM < left_table > < join_type > JOIN < right_table > ON < join_conditio

sql server create synonym 用同義詞解決程序升級過程架構名稱改變的問題

USE [master] GO CREATE DATABASE [isoft_Avon_20170730] CONTAINMENT = NONE ON PRIMARY ( NAME = N'isoft_Avon_20170730', FILENAME = N'd:\Program Files\Micr

SQLSQLyog外來鍵設定----------語法

外來鍵設定三種方法:   1.直接寫sql語句.  2.用SQLyog 選擇外來鍵表 ,點選右鍵 選擇關聯/外來鍵,然後再選擇主表,外來鍵.  3.在表 vet_specialties 上點選右鍵 ,然後找到Relationships/ForeignKeys中,然後選擇相

mysql sql語句 create table時 報錯table doesn't exist

用sql還原一個年代久遠的專案時候發現create table執行時報表不存在。。(這不廢話,不存在我才要create啊)刪了庫重來還是報錯, 對於這個神奇的現象百之,無。谷之,中文網頁無。英文找到了,方法是先新建一個空表,然後刪除,再然後就可以用sql建立其他內容的表了