1. 程式人生 > >利用儲存過程和觸發器來管理資料庫

利用儲存過程和觸發器來管理資料庫

本文主要介紹如何在資料庫後臺利用儲存過程,觸發器來管理資料庫的技術,並以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;