利用儲存過程和觸發器來管理資料庫
本文主要介紹如何在資料庫後臺利用儲存過程,觸發器來管理資料庫的技術,並以Delphi做前臺,SQL Server做後臺的模式給出具體的實現程式碼。
一、SQL互動式資料庫查詢語言
互動式資料庫查詢語言SQL中有關表操作基本的SQL語句有如下四種:(下面分別出給四種語句的語法形式及其說明)
(1)查詢表命令
SELECT[ALL|DISTINCT]select_list [INTO[new_table_name]] [FROM{table_name|view_name} [WHERE clause] [GROUP BY clause] [HAVING clause] [ORDER BY clause] [COMPUTE clause] |
其中:
select_list指定列 (ALL則為所有列,DISTINCT為不選相同記錄 new_table_name指定目標表名 table_name|view_name指定源表名或源檢視名 WHERE clause給出選擇條件 GROUP BY clause按clause分組處理 HAVING clause給出分組處理的條件 ORDER BY clause按clause排序 COMPUTE clause則產生新行 |
(2)插入記錄命令
INSERT[INTO] {table_name|view_name}[(cohurnn_list)] {DEFAULT VALUES|values_list|select_statement} |
其中:
table_name|view_name指定新表名或新檢視名 values_list|select_statement指定列或子查詢 |
(3)修改表令命
UPDATE{table_name|view_name} SET[{table_name|view_name} {column_list|variable_list| variable_and_column_list} [WHERE clause] |
其中:
table_name|view_name指定源表名或源檢視名 column_list|variable_list指出列或變數名 WHERE clause給修改條件 |
(4)刪除命令
DELETE[FROM]{table_name|view_name} [WHERE clause] |
其中:
table_name|view_name指定源表名或源檢視名 WHERE clause給出修改條件 |
二、SQL Server中儲存過程和觸發器的使用
儲存過程是儲存在伺服器上的預先編譯好的SQL 語句在使用時要考慮以下問題:
1.儲存過程在第一次編譯時進行語法檢查,編譯好的儲存過程儲存在快取記憶體中用於呼叫,這樣執行的速度和效率較高。
2.儲存過程由應用程式啟用,不由SQL Server自動執行。
3.一個儲存過程可以用於收集資料和修改資料,但是不能同時用於兩者。
儲存過程的優點是:
1.在執行重複任務時能提高效率;
2.使前端的應用程式共享應用邏輯;
3.可以永久建立,也可以臨時建立;
4.可以在SQL Server啟動時自動執行。
儲存過程的建立語句語法為:
CREATE PROCedure[owner.]procedure_name[;number] [(parameter1[,parameter2]...[parameter255])] [{FOR REPLICATION}|{WITH RECOMPILE} [{[WITH]|{,}ENCRYPTION]] AS sql_statements |
其中:
proceddure_name〓〓為過程名稱
;number〓〓用於在過程名稱重複時進行編號
[(parameter1[,parameter2]...[parameter255])]〓〓為引數序列
WHTH RECOMPILE〓〓執行計劃不儲存的快取記憶體中,每次執行過程需要重新編譯
ENCRYPTION〓〓加密syscomments表的內容,syscomments表中包含CREATE PROCedure的文字,保證無論何時都不刪除syscomments表
FOR REPLICATION〓〓過程在前臺執行,不在伺服器上執行
下面的SQL語句在MYDATABASE資料庫上建立儲存過程my_store_pro1
USE MYDATABASE
以下須是一個獨立的查詢模組,因為CREATE PROCDURE語句須是查詢模組的首行。
CREATE PROCDURE my_store_pro1 @my_paral char, @my_para2 int AS SELECT*FROM my_table1 WHERE [email protected]_para1 AND my_table.1no2<[email protected]_para2 GO 執行儲存過my_store_pro1 EXEC my_store_pro1'12',23 |
觸發器是一種特殊的儲存過程,無論何時要對它所保護的表進行修改時它就自動執行。觸發器由SQL Server自動執行,不能由應用程式呼叫,便於保護資料庫的完整性和完全性。其語法結構為:
CREATE TRIGGER [owner.]trigger_name ON[owner.]table_name FOR {INSERT,UPDATE,DELETE} [WITH ENCR YPTION] AS IF UPDATE(column_name) [{AND|OR}UPDATE(column_name)...]sql_statements 其中: trigger_name〓〓指定觸發器的名稱 table_name〓〓指定觸發器所在的表名 INSERT,UPDATE,DELETE〓〓指定觸發條件 |
ENCRYPTION〓〓加密syscomments表的內容,syscomments表中包含CREATEPROCedure的文字,保證無論何時都不刪除syscomments表,sql_statementw是在表的內容有修改(UPDATE)時引起的動作以下是一個修改觸發器,如果my_tabel的nolmy_table1欄位有修改,給出錯誤提示。
CREATE TRIGGER test ON my_tablel FOR UPDATE AS IF UPDATE(nol) BEGIN PRINT(不能修改此列資料’) END |
以下插入觸發器在TITLE_L有資料增加時,給末對NO_LOCAL賦值的記錄賦值,其值是現有記錄中NO_LOCAL的最大值加1(NO_LOCAL為字串型別)
CREATE TRIGGER add_no ON TITLE_L FOR INSERT AS DECLARE @tmpl int SELECT @tmpl=MAX(CONVERT(int,NO_LOCAL))FROM TITLB_L SELECT @[email protected]+1 DECLARE @tmpstr char(4) SELECT @tmpstr=CONVERRT(varchar(4),@tmpl) UPDATE TITLE_L SET [email protected] WHERE NO_LOCAL=NULL |
三、應用例項介紹
以下給出的程式段功能為:在前臺Delphi環境下呼叫儲存過程,在伺服器由表dbo.all選出符合使用者身份的記錄生成表dbo.today;由觸發器刪除部分不合日期要求的記錄;再從前臺用批量記錄移動把dbo.today的內容下載的本地LOCALDATA資料庫上data.dbf表。
{在伺服器的MYDATA資料庫上建立儲存過程my_store_prol:}
CREATE PROCDURE my_store_prol @secu_id int AS SELECT*FROM all WHERE my_table1.no1<[email protected]_id GO {在MYDATA資料庫的表dbo.today上建立觸發器:} CREATE TRLGGER add_no ON today FOR INSERT AS DELETE*FORM today WHERE riqi GO |
{在前臺程式中執行儲存過程my_store_prol:}
Databasel.AliasName:='MYDATA'; Databasel.DatabaseName;='my_database'; Database1.connected;=True; SourceTable1.DatabaseName;='my_database'; SourceTable1.TableName='dbo.today'; SourceTable1.Active;=True; StoredProc1.DatabaseName;='My_database'; StoredProc1.StoredProcName:='my_proc'; StoredProc1.Params.Clear; StoredProc1.Params.CreateParam(ftInteger,'secu_id',ptInput); StoredProc1.Prepare; StoredProc1.ExecProc; |
{在前臺程式中下載dbo.today的內容到data.dbf表:}
Database2.AliasName:='LOCALDATA'; Database2.DatabaseName:='local_data'; Database2.connectde:=True; DestinTable1.DatabaseName:='local_data'; DestinTable1.TableName:='data.dbf; DestinTable1.Active:=True; BatchMovel.Mode:=batAppend; BatchMovel.RecordCount:=0 BatchMovel.Source:=SourceTable1; BatchMovel.Destination:=DestinTable1; BatchMovel.Execute; |