① sybase 存儲過程
存儲過程是存儲在伺服器端的一類資料庫對象,它實質上是一段用sql語言編寫的程序,它在伺服器端預先經過編譯,並確定出執行計劃,因此與同樣功能的批處理語句相比,它的執行速度較快。基本語法:Create Procere[owner.]過程名[@參數名 數據類型[=默認值][Output]][,@參數名 數據類型[=默認值][Output]][……]ASBeginSQL語句(塊)End存儲過程是資料庫對象,和表、索引是一個級別的;是SQL語句和控制流語言的集合,存儲過程在首次運行時被編譯,並駐留在過程高速緩存的內存中,所以存儲過程的招待非常快。存儲過程可以帶參數,可以調用其他過程,返回狀態值,返回參數值,並且可以在遠程SQL Server執行。可以在遠程SQL Server執行對資料庫設計有特別重要的意義。SQL Server提供的存儲過程稱為系統過程。存儲過程大大增強了悶氏斗SQL的能力、效率和靈活性,經過編譯的存儲過程極大地改善SQL語句和批處理的性能。存儲過程有很多優點:●存儲過程在第一次執行時編譯,並存儲在過程高速緩存的內存中。編譯時系統對其進行優化,以選擇最佳的路徑來訪問數據集中的數據,這種優化考慮了數據集的實際數據結構。因此存儲過程大大提高了系統的性能。●存儲過程可以跨伺服器運行。這一點是通過觸發器來實現的,當然,首先存儲過程要能登錄到該遠程伺服器。●應用程序也能執行存儲過程,從而實現伺服器和客戶之間的協同作業。●存儲過程減少了網路的交通。這是因為存儲過程的文本存儲在資料庫里,調用存儲過程時通過網路的只是存儲過程的過程名。●利用存儲過程可以提供一個附加的安全層。如(該例子取自pubs2資料庫):Create proc titleid_proc(@title_id varchar(80))AsBeginSelect @title_id=lower(@title_id) 」%」Select title,title_id,priceForm titlesWhere lower(title_id) like @title_idReturn @@rowcountEnd注意例子中的黑體部分,這實際上是一條賦值語句。該存儲過程有返回值。存儲過程可以變得非常復雜。我們認為,創建存儲過程還是要遵循「最簡單就是最好」的原則。建議在創建存儲過程時採用縮進風格,否則創建的存儲過程三天之後連自己都看不懂。需要對存儲過程作些說明:●Create procere 語句不能和其他語句在同一個批命令里。●Create procere 語句不能包括下列語句:useCreate ViewCreate defaultCreate ruleCreate triggerCreate procere不能使用use語句好理解,存核鏈儲過程是針對資料庫的,不能在一個資料庫里訪問另外的資料庫。如果在存儲過程里訪問另外的資料庫,則資料庫表的參照完整性難於得到保障。從另外幾條語句看,在存儲過程里一般不能創建新的資料庫對象。但可以創建表和索引,以及和表相關聯的鍵,表是臨時表,在存儲過程結束後不能看見創建的臨時表;否則的話每運行一次存儲過程就創建一個表,結果可想而知。存儲過程里不能創建一個對象,刪除它;然後又在同一存儲過程里用相同的名字創建新的對象。實際上,SQL Server在存儲過程運行時而不是在編螞磨譯時創建對象的。●如果存儲過程調用另外的存儲過程,則第二個存儲過程可以調用在第一個存儲過程里創建的對象。●存儲過程包含的最多參數為255個,對存儲過程里的局部和全局變數沒有限制。最後討論一下系統存儲過程。系統存儲過程以sp_開頭,當然用戶創建的存儲過程也可以以sp_開頭;系統過程保存在sybsystemprocs資料庫里。系統過程的使用有許可權,如果打入系統過程名但沒有出現預期的結果,要麼是命令名錯,要麼是使用者沒有該過程的許可權。一般可通過系統管理員或資料庫所有者對系統過程的execute授權。系統過程繁多,大致有幾類:a. 用戶標志和授權。這一類的過程主要由於:增加、刪除或報告在SQL Server上的登錄,增加、刪除或報告某資料庫的用戶、分組或別名等。這類過程有sp_addlogin,sp_adser,sp_helpgroup,sp_dropuser等。b. 遠程過程的調用。這類過程用於:增加、刪除或報告能存取本SQL Server的遠程伺服器;增加能從遠程伺服器上存取本SQL Server的用戶名。這類過程有:sp_addremotelogin,sp_addserver,sp_dropserver等。c. 數據定義和資料庫對象。這類存儲過程用於:連接和定義規則和預設值,增加、刪除或報告主碼、外碼和公共碼;增加、刪除或報告用戶定義的數據類型。這類存儲過程有:sp_bindfault, sp_bindrule, sp_help, sp_helpdb, sp_foreignkey, sp_helptext等。d. 系統管理。這類存儲過程用於:增加、刪除或報告資料庫及轉儲設備;報告鎖;設置的資料庫選擇及用戶正進行的進程;修改及報告配置變數;監控SQL Server的活動。這類過程有:sp_admpdevice,sp_dropdevice, sp_helpdevice等。
② SQL SERVER的存儲過程裡面,聲明的臨時表是需要在存儲過程結束的時候手動drop掉的么
不需要手動Drop,#(本地臨時表)臨時表只在存儲過程里有效 (僅會話可以使用)
這主要根據個人的習慣,如果希望TempDB馬上回收資源,可以在結束時加上。這不影響存儲過程的調用
臨時表有兩種類型:本地表和全局表。在與首次創建或引用表時相同的 SQL Server 實例連接期間,本地臨時表只對於創建者是可見的。當用戶與 SQL Server 實例斷開連接後,將刪除本地臨時表。全局臨時表在創建後對任何用戶和任何連接都是可見的,當引用該表的所有用戶都與 SQL Server 實例斷開連接後,將刪除全局臨時表。
參照:
③ SELECT INTO 語句可以創建本地或全局臨時表嗎
可以。
SQL Server臨時表有兩種類型:本地和全局。它們在名稱、可見性以及可用性上有區別。本地臨時表的名稱以單個數字元號 (#)
打頭;它們僅對當前的用戶連接是可見的;當用戶從 SQL Server 實例斷開連接時被刪除。全局臨時表的名稱以兩個數字元號 (##)
打頭,創建後對任何用戶都是可見的,當所有引用該表的用戶從 SQL Server 斷開連接時被刪除。
如果資料庫會話創建了本地臨時表 #temtable,則僅會話可以使用該表,會話斷開連接後就將該表刪除。如果創建了
##temtable全局臨時表,則資料庫中的任何用戶均可使用該表。如果該表在您創建後沒有其他用戶使用,則當您斷開連接時該表刪除。如果您創建該表後另一個用戶在使用該表,則SQL Server 將在您斷開連接並且所有其他會話不再使用該表時將其刪除。
如果本地臨時表由存儲過程創建或由多個用戶同時執行的應用程序創建,則SQL Server 必須能夠區分由不同用戶創建的表。為此,SQL Server 在內部為每個本地臨時表的表名追加一個數字後綴。存儲在tempdb 資料庫的 sysobjects 表中的臨時表,其全名由 CREATE TABLE 語句中指定的表名和系統生成的數字後綴組成。為了允許追加後綴,為本地臨時表指定的表名table_name不能超過 116 個字元。
當存儲過程完成時,將自動除去在存儲過程中創建的本地臨時表。由創建表的存儲過程執行的所有嵌套存儲過程都可以引用此表。但調用創建此表的存儲過程的進程無法引用此表。
臨時表位於tempdb系統資料庫。
使用SELECT INTO語句可以把任何查詢結果集放置到一個新表中,還可以通過使用SELECT
INTO語句解決復雜的問題。例如,需要從不同數據源中得到數據集,如果一開始先創建一個臨時表,那麼在該表上執行查詢比在多表或多資料庫中執行查詢更簡單。
在使用SELECT INTO語句時,應該注意如下的事項和原則:
可以使用SELECT INTO語句創建一個表並且在單獨操作中向表中插入行。確保在SELECT INTO語句中指定的表名是惟一的。如果表名出現重復,SELECT
INTO語句將失敗。
可以創建本地或全局臨時表。要創建一個本地臨時表,需要在表名前加符號(#);要創建一個全局臨時表,需要在表名前加兩個符號(##)。本地臨時表只在當前的會話中可見,全局臨時表在所有的會話中都可見。
當使用者結束會話時,本地臨時表的空間會被回收。
當創建表的會話結束且當前參照表的最後一個Transact-SQL語句完成時,全局臨時表的空間會被回收。
使用SELECT INTO語句的基本語法如下:
SELECT <select_list>
INTO new_table
FROM {<table_source>}[,…n]
WHERE <search_condition>
例如:select * into #newTable from news where s_date>'2010-3-1'
利用SQL Server的全局臨時表防止用戶重復登錄
在我們開發商務軟體的時候,常常會遇到這樣的一個問題:怎樣防止用戶重復登錄我們的系統?特別是對於銀行或是財務部門,更是要限制用戶以其工號身份多次登入。
可能會有人說在用戶信息表中加一欄位判斷用戶工號登錄的狀態,登錄後寫1,退出時寫0,且登錄時判斷其標志位是否為1,如是則不讓該用戶工號登錄。但是這樣那勢必會帶來新的問題:如發生象斷電之類不可預知的現象,系統是非正常退出,無法將標志位置為0,那麼下次以該用戶工號登錄則不可登入,這該怎麼辦呢?
或許我們可以換一下思路:有什麼東西是在connection斷開後可以被系統自動回收的呢?對了,SQL
Server的臨時表具備這個特性!但是我們這里的這種情況不能用局部臨時表,因為局部臨時表對於每一個connection來說都是一個獨立的對象,因此只能用全局臨時表來達到我們的目的。
好了,情況已經明朗話了,我們可以寫一個象下面這樣簡單的存儲過程:
create procere gp_findtemptable -- 2001/10/26 21:36 zhuchao in nanjing
/* 尋找以操作員工號命名的全局臨時表
* 如無則將out參數置為0並創建該表,如有則將out參數置為1
* 在connection斷開連接後,全局臨時表會被SQL Server自動回收
* 如發生斷電之類的意外,全局臨時表雖然還存在於tempdb中,但是已經失去活性
* 用object_id函數去判斷時會認為其不存在. */
@v_userid varchar(6), -- 操作員工號
@i_out int out -- 輸出參數 0:沒有登錄 1:已經登錄
as
declare @v_sql varchar(100)
if object_id('tempdb.dbo.##'+@v_userid) is null
begin
set @v_sql = 'create table ##'+@v_userid+'(userid varchar(6))'
exec (@v_sql)
set @i_out = 0
end
else
set @i_out = 1
在這個過程中,我們看到如果以用戶工號命名的全局臨時表不存在時過程會去創建一張並把out參數置為0,如果已經存在則將out參數置為1。
這樣,我們在我們的應用程序中調用該過程時,如果取得的out參數為1時,我們可以毫不客氣地跳出一個message告訴用戶說」對不起,此工號正被使用!」
判斷方法範例:
select @sTmpWareA="tempdb..[##MARWareA"+ @ComputerName+"]"
if exists (select * from tempdb..sysobjects where id = object_id(@sTmpWareA) and
type = "U")
begin
set @sTmpWareA="[##MARWareA"+ @ComputerName+"]"
exec( "drop table " )
end
else
set @sTmpWareA="[##MARWareA"+ @ComputerName+"]"
@sTmpWareA 就是臨時表的名稱,過程中使用exec來操作
④ oracle資料庫的存儲過程的結束符必須是'/'嗎 如果存儲過程中間有'/',怎麼區分是否已經結束
/是區分存儲過程的,程序可以通過/判斷一個存儲過程執行完了
⑤ sqlserver 存儲過程執行完成後 returnvalue的含義
不回答我難受,把我知道的都寫上:
在DELETE時刪除了0行,他返回了一個0.刪除了多少行他返回多少.
UPDATE時,更新了多少行,他就返回多少.
SELECT時,returnvalue這時應該是-1的.
其它的我也不知道了
⑥ 如何編寫存儲過程
設計存儲過程
幾乎任何可寫成批處理的 Transact-SQL 代碼都可用於創建存儲過程。
存儲過程的設計規則
存儲過程的設計規則包括:
CREATE PROCEDURE 定義本身可包括除下列 CREATE 語句以外的任何數量和類型的 SQL 語句,存儲過程中的任意地方都不能使用下列語句: CREATE DEFAULT CREATE TRIGGER
CREATE PROCEDURE CREATE VIEW
CREATE RULE
可在存儲過程中創建其它資料庫對象。可以引用在同一存儲過程中創建的對象,前提是在創建對象後再引用對象。
可以在存儲過程內引用臨時表。
如果在存儲過程內創建本地臨時表,則該臨時表僅為該存儲過程而存在;退出該存儲過程後,臨時表即會消失。
如果執行調用其它存儲過程的存儲過程,那麼被調用存儲過程可以訪問由第一個存儲過程創建的、包括臨時表在內的所有對象。
如果執行在遠程 Microsoft® SQL Server™ 2000 實例上進行更改的遠程存儲過程,則不能回滾這些更改。遠程存儲過程不參與事務處理。
存儲過程中參數的最大數目為 2100。
存儲過程中局部變數的最大數目僅受可用內存的限制。
根據可用內存的不同,存儲過程的最大大小可達 128 MB。
有關創建存儲過程的規則的更多信息,請參見 CREATE PROCEDURE。
限定存儲過程內的名稱
在存儲過程內部,如果用於諸如 SELECT 或 INSERT 這樣的語句的對象名沒有限定用戶,那麼用戶將默認為該存儲過程的所有者。在存儲過程內部,如果創建存儲過程的用戶沒有限定 SELECT、INSERT、UPDATE 或 DELETE 語句中引用的表名,那麼通過該存儲過程對這些表進行的訪問將默認地受到該過程的創建者許可權的限制。
如果有其他用戶要使用存儲過程,則用於語句 ALTER TABLE、CREATE TABLE、DROP TABLE、TRUNCATE TABLE、CREATE INDEX、DROP INDEX、UPDATE STATISTICS 和 DBCC 的對象名必須用該對象所有者的名稱限定。例如,Mary 擁有表 marytab,如果她希望其他用戶能夠執行使用該表的存儲過程,必須在該表用於上述某一條語句時對其表名進行限定。
此規則是必需的,因為運行存儲過程時將解析對象的名稱。如果未限定 marytab,而 John 試圖執行該過程,SQL Server 將查找 John 所擁有的名為 marytab 的表。
加密過程定義
如果要創建存儲過程,並且希望確保其他用戶無法查看該過程的定義,那麼可以使用 WITH ENCRYPTION 子句。這樣,過程定義將以不可讀的形式存儲。
存儲過程一旦加密其定義即無法解密,任何人(包括存儲過程的所有者或系統管理員)都將無法查看存儲過程定義。
SET 語句選項
當 ODBC 應用程序與 SQL Server 連接時,伺服器將自動設置會話的下列選項:
SET QUOTED_IDENTIFIER ON
SET TEXTSIZE 2147483647
SET ANSI_DEFAULTS ON
SET CURSOR_CLOSE_ON_COMMIT OFF
SET IMPLICIT_TRANSACTIONS OFF
這些設置將提高 ODBC 應用程序的可移植性。由於基於 DB-Library 的應用程序通常不設置這些選項,所以應在上述所列 SET 選項打開和關閉的情況下都對存儲過程進行測試。這樣可確保存儲過程始終能正確工作,而不管特定的連接在喚醒調用該存儲過程時可能設置的選項。需要特別設置其中一個選項的存儲過程,應在開始該存儲過程時發出一條 SET 語句。此 SET 語句將只對該存儲過程的執行保持有效,當該存儲過程結束時,將恢復原設置。
示例
A. 創建使用參數的存儲過程
下例創建一個在 pubs 資料庫中很有用的存儲過程。給出一個作者的姓和名,該存儲過程將顯示該作者的每本書的標題和出版商。
CREATE PROC au_info @lastname varchar(40), @firstname varchar(20)
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors INNER JOIN titleauthor ON authors.au_id = titleauthor.au_id
JOIN titles ON titleauthor.title_id = titles.title_id
JOIN publishers ON titles.pub_id = publishers.pub_id
WHERE au_fname = @firstname
AND au_lname = @lastname
GO
將出現一條說明該命令未返回任何數據也未返回任何行的消息,這表示已創建該存儲過程。
現在執行 au_info 存儲過程:
EXECUTE au_info Ringer, Anne
GO
下面是結果集:
au_lname au_fname title pub_name
--------- --------- --------------------- ----------------
Ringer Anne The Gourmet Microwave Binnet & Hardley
Ringer Anne Is Anger the Enemy? New Moon Books
(2 row(s) affected)
B. 創建使用參數默認值的存儲過程
下例創建一個存儲過程 pub_info2,該存儲過程顯示作為參數給出的出版商所出版的某本書的作者姓名。如果未提供出版商的名稱,該存儲過程將顯示由 Algodata Infosystems 出版的書籍的作者。
CREATE PROC pub_info2 @pubname varchar(40) = 'Algodata Infosystems'
AS
SELECT au_lname, au_fname, pub_name
FROM authors a INNER JOIN titleauthor ta ON a.au_id = ta.au_id
JOIN titles t ON ta.title_id = t.title_id
JOIN publishers p ON t.pub_id = p.pub_id
WHERE @pubname = p.pub_name
執行未指定參數的 pub_info2:
EXECUTE pub_info2
GO
下面是結果集:
au_lname au_fname pub_name
---------------- ---------------- --------------------
Green Marjorie Algodata Infosystems
Bennet Abraham Algodata Infosystems
O'Leary Michael Algodata Infosystems
MacFeather Stearns Algodata Infosystems
Straight Dean Algodata Infosystems
Carson Cheryl Algodata Infosystems
Dull Ann Algodata Infosystems
Hunter Sheryl Algodata Infosystems
Locksley Charlene Algodata Infosystems
(9 row(s) affected)
C. 執行用顯式值替代參數默認值的存儲過程
在下例中,存儲過程 showind2 的 @table 參數默認值是 titles。
CREATE PROC showind2 @table varchar(30) = 'titles'
AS
SELECT TABLE_NAME = sysobjects.name,
INDEX_NAME = sysindexes.name, INDEX_ID = indid
FROM sysindexes INNER JOIN sysobjects ON sysobjects.id = sysindexes.id
WHERE sysobjects.name = @table
列標題(例如,TABLE_NAME)可使結果更具可讀性。下面是該存儲過程顯示的 authors 表的情況:
EXECUTE showind2 authors
GO
TABLE_NAME INDEX_NAME INDEX_ID
---------- ---------- ----------
authors UPKCL_auidind 1
authors aunmind 2
(2 row(s) affected)
如果用戶未提供值,則 SQL Server 將使用默認表 titles:
EXECUTE showind2
GO
下面是結果集:
TABLE_NAME INDEX_NAME INDEX_ID
---------- ---------- ----------
titles UPKCL_titleidind 1
titles titleind 2
(2 row(s) affected)
D. 使用參數默認值 NULL 創建存儲過程
參數默認值可以是 NULL 值。在這種情況下,如果未提供參數,則 SQL Server 將根據存儲過程的其它語句執行存儲過程。不會顯示錯誤信息。
過程定義還可指定當不給出參數時要採取的其它某種措施。例如:
CREATE PROC showind3 @table varchar(30) = NULL
AS IF @table IS NULL
PRINT 'Give a table name'
ELSE
SELECT TABLE_NAME = sysobjects.name,
INDEX_NAME = sysindexes.name, INDEX_ID = indid
FROM sysindexes INNER JOIN sysobjects
ON sysobjects.id = sysindexes.id
WHERE sysobjects.name = @table
E. 使用包含通配符的參數默認值創建存儲過程
如果存儲過程將參數用於 LIKE 關鍵字,那麼默認值可包括通配符(%、_、[] 和 [^])。例如,可將 showind 修改為當不提供參數時顯示有關系統表的信息:
CREATE PROC showind4 @table varchar(30) = 'sys%'
AS SELECT TABLE_NAME = sysobjects.name,
INDEX_NAME = sysindexes.name, INDEX_ID = indid
FROM sysindexes INNER JOIN sysobjects
ON sysobjects.id = sysindexes.id
WHERE sysobjects.name LIKE @table
在存儲過程 au_info 的下列變化形式中,兩個參數都有帶通配符的默認值:
CREATE PROC au_info2 @lastname varchar(30) = 'D%',
@firstname varchar(18) = '%'
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors INNER JOIN titleauthor ON authors.au_id = titleauthor.au_id
JOIN titles ON titleauthor.title_id = titles.title_id
JOIN publishers ON titles.pub_id = publishers.pub_id
WHERE au_fname LIKE @firstname
AND au_lname LIKE @lastname
如果執行 au_info2 時不指定參數,將顯示姓以字母 D 開頭的所有作者:
EXECUTE au_info2
GO
下面是結果集:
au_lname au_fname title pub_name
-------- -------- --------------------- -------------------
Dull Ann Secrets of Silicon Val Algodata Infosystems
del Castillo Innes Silicon Val Gastrono Binnet & Hardley
DeFrance Michel The Gourmet Microwave Binnet & Hardley
(3 row(s) affected)
下例在兩個參數的默認值已定義的情況下,省略了第二個參數,因此可找到姓為 Ringer 的所有作者的書和出版商:
EXECUTE au_info2 Ringer
GO
au_lname au_fname title pub_name
--------- --------- ---------------------- ----------------
Ringer Anne The Gourmet Microwave Binnet & Hardley
Ringer Anne Is Anger the Enemy? New Moon Books
Ringer Albert Is Anger the Enemy? New Moon Books
Ringer Albert Life Without Fear New Moon Books
(4 row(s) affected)