SQL2000系統表、儲存過程、函式的功能介紹及應用2009年01月21日 星期三 11:38雖然使用系統儲存過程、系統函式與資訊架構檢視已經可以為我們提供了相當豐富的元資料資訊,但是對於某些特殊的元資料資訊,我們仍然需要直接對系統表進行查詢。因為SQL
雖然使用系統儲存過程、系統函式與資訊架構檢視已經可以為我們提供了相當豐富的元資料資訊,但是對於某些特殊的元資料資訊,我們仍然需要直接對系統表進行查詢。因為SQL Server 將所有資料庫物件的資訊均存放在系統表中,作為 SQL Server 的管理、開發人員,瞭解各個系統表的作用將有助於我們瞭解 SQL Server 的內在工作原理。
SQL Server 的系統表非常多,其中最常用的與元資料查詢有關的表有如下一些:
系統表 | 描述 |
syscolumns | 儲存每個表和檢視中的每一列的資訊以及儲存過程中的每個引數的資訊。 |
syscomments | 儲存包含每個檢視、規則、預設值、觸發器、CHECK 約束、DEFAULT 約束和儲存過程的原始 SQL 文字語句。 |
sysconstraints | 儲存當前資料庫中每一個約束的基本資訊。 |
sysdatabases | 儲存當前伺服器上每一個數據庫的基本資訊。 |
sysindexes | 儲存當前資料庫中的每個索引的資訊。 |
sysobjects | 儲存資料庫內的每個物件(約束、預設值、日誌、規則、儲存過程等)的基本資訊。 |
sysreferences | 儲存所有包括 FOREIGN KEY 約束的列。 |
systypes | 儲存系統提供的每種資料型別和使用者定義資料型別的詳細資訊。 |
將系統儲存過程、系統函式、資訊架構檢視與系統表結合使用,可以方便地讓我們獲得所有需要的元資料資訊。
示例:
1、 獲得當前資料庫所有使用者表的名稱。
SELECT OBJECT_NAME (id)
FROM sysobjects
WHERE xtype = 'U' AND OBJECTPROPERTY (id, 'IsMSShipped') = 0
其中主要用到了系統表 sysobjects以及其屬性 xtype,還有就是用到了 OBJECTPROPERTY 系統函式來判斷是不是安裝 SQL Server 的過程中建立的物件。
2、 獲得指定表上所有的索引名稱
SELECT name FROM sysindexes
WHERE id = OBJECT_ID ('mytable') AND indid > 0
----系統儲存過程----------------------------------------------------------------------------------------------------
系統儲存過程 |
描述 |
sp_columns | 返回指定表或檢視的列的詳細資訊。 |
sp_databases | 返回當前伺服器上的所有資料庫的基本資訊。 |
sp_fkeys | 若引數為帶有主鍵的表,則返回包含指向該表的外來鍵的所有表;若引數為帶有外來鍵的表名,則返回所有同過主鍵/外來鍵關係與該外來鍵相關聯的所有表。 |
sp_pkeys | 返回指定表的主鍵資訊。 |
sp_server_info | 返回當前伺服器的各種特性及其對應取值。 |
sp_sproc_columns | 返回指定儲存過程的的輸入、輸出引數的資訊。 |
sp_statistics | 返回指定的表或索引檢視上的所有索引以及統計的資訊。 |
sp_stored_procedures | 返回當前資料庫的儲存過程列表,包含系統儲存過程。 |
sp_tables | 返回當前資料庫的所有表和檢視,包含系統表。 |
----系統函式----------------------------------------------------------------------------------------------------
COLUMNPROPERTY | 返回有關列或過程引數的資訊,如是否允許空值,是否為計算列等。 |
COL_LENGTH | 返回指定資料庫的指定屬性值,如是否處於只讀模式等。 |
DATABASEPROPERTYEX | 返回指定資料庫的指定選項或屬性的當前設定,如資料庫的狀態、恢復模型等。 |
OBJECT_ID | 返回指定資料庫物件名的標識號 |
OBJECT_NAME | 返回指定資料庫物件標識號的物件名。 |
OBJECTPROPERTY | 返回指定資料庫物件標識號的有關資訊,如是否為表,是否為約束等。 |
fn_listextendedproperty | 返回資料庫物件的擴充套件屬性值,如物件描述、格式規則、輸入掩碼等。 |
----使用資訊架構檢視訪問元資料---------------------------------------------------------------------------------------------------
資訊架構檢視基於 SQL-92 標準中針對架構檢視的定義,這些檢視獨立於系統表,提供了關於 SQL Server 元資料的內部檢視。資訊架構檢視的最大優點是,即使我們對系統表進行了重要的修改,應用程式也可以正常地使用這些檢視進行訪問。因此對於應用程式來說,只要是符合 SQL-92 標準的資料庫系統,使用資訊架構檢視總是可以正常工作的。
常用的資訊架構檢視有以下一些:
資訊架構檢視 | 描述 |
INFORMATION_SCHEMA .CHECK_CONSTRAINTS | 返回有關列或過程引數的資訊,如是否允許空值,是否為計算列等。 |
INFORMATION_SCHEMA .COLUMNS | 返回當前資料庫中當前使用者可以訪問的所有列及其基本資訊。 |
INFORMATION_SCHEMA .CONSTRAINT_COLUMN_USAGE | 返回當前資料庫中定義了約束的所有列及其約束名。 |
INFORMATION_SCHEMA .CONSTRAINT_TABLE_USAGE | 返回當前資料庫中定義了約束的所有表及其約束名。 |
INFORMATION_SCHEMA .KEY_COLUMN_USAGE | 返回當前資料庫中作為主鍵/外來鍵約束的所有列。 |
INFORMATION_SCHEMA .SCHEMATA | 返回當前使用者具有許可權的所有資料庫及其基本資訊。 |
INFORMATION_SCHEMA .TABLES | 返回當前使用者具有許可權的當前資料庫中的所有表或者檢視及其基本資訊。 |
INFORMATION_SCHEMA .VIEWS | 返回當前資料庫中的當前使用者可以訪問的檢視及其所有者、定義等資訊。 |
由於這些資訊架構都是以檢視的方式存在的,因此我們可以很方便地獲得並利用需要的資訊。
例如,我們要得到某個表有多少列,可以使用以下語句:
SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME='mytable'
----應用-------------------------------------------------------------------------------------------------------------------
--1:獲取當前資料庫中的所有使用者表
select Name from sysobjects where xtype='u' and status>=0
--2:獲取某一個表的所有欄位
select name from syscolumns where id=object_id(N'表名')
--3:檢視與某一個表相關的檢視、儲存過程、函式
select a.* from sysobjects a, syscomments b where a.id = b.id and b.text like N'%表名%'
--4:檢視當前資料庫中所有儲存過程
select name as 儲存過程名稱 from sysobjects where xtype='P'
--5:查詢使用者建立的所有資料庫
select * from master..sysdatabases D where sid not in(select sid from master..syslogins where name='sa')
或者
select dbid, name AS DB_NAME from master..sysdatabases where sid <> 0x01
--6:查詢某一個表的欄位和資料型別
select column_name,data_type from information_schema.columns
where table_name = N'表名'
--7:獲取資料庫檔案路徑
select ltrim(rtrim(filename)) from 資料庫名..sysfiles where charindex('MDF',filename)>0
or
select ltrim(rtrim(filename)) from 資料庫名..sysfiles where charindex('LDF',filename)>0
--8:獲取某一個表的基本資訊
sp_MShelpcolumns N'表名'
--9:獲取某一個表的主鍵、外來鍵資訊
exec sp_pkeys N'表名'
exec sp_fkeys N'表名'
--10:判斷某一個表是否存在某一列(欄位)
if exists(select 1 from syscolumns where id=object_id(N'表名) and name=N'欄位')
print N'存在'
else
print N'不存在'
下面給出了一個儲存過程,它的作用是自動將當前資料庫的使用者儲存過程加密。
DECLARE @sp_name nvarchar(400)
DECLARE @sp_content nvarchar(2000)
DECLARE @asbegin int
declare @now datetime
select @now = getdate()
DECLARE sp_cursor CURSOR FOR
SELECT object_name(id)
FROM sysobjects
WHERE xtype = 'P'
AND type = 'P'
AND crdate < @now
AND OBJECTPROPERTY(id, 'IsMSShipped')=0
OPEN sp_cursor
FETCH NEXT FROM sp_cursor
INTO @sp_name
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @sp_content = text FROM syscomments WHERE id = OBJECT_ID(@sp_name)
SELECT @asbegin = PATINDEX ( '%AS' + char(13) + '%', @sp_content)
SELECT @sp_content = SUBSTRING(@sp_content, 1, @asbegin - 1)
+ ' WITH ENCRYPTION AS'
+ SUBSTRING (@sp_content, @asbegin+2, LEN(@sp_content))
SELECT @sp_name = 'DROP PROCEDURE [' + @sp_name + ']'
EXEC sp_executesql @sp_name
EXEC sp_executesql @sp_content
FETCH NEXT FROM sp_cursor
INTO @sp_name
END
CLOSE sp_cursor
DEALLOCATE sp_cursor
該儲存過程利用了 sysobjects 和 syscomments 表,並巧妙地修改了原儲存過程的 SQL 定義語句,將 AS 修改為了 WITH ENCRYPTION AS,從而達到了加密儲存過程的目的。本儲存過程在 SQL Server 2000 上通過。