----系統資料表----------------------------------------------------------------------------------------------------
雖然使用系統預存程序、系統函數與資訊架構視圖已經可以為我們提供了相當豐富的中繼資料資訊,但是對於某些特殊的中繼資料資訊,我們仍然需要直接對系統資料表進行查詢。因為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 上通過。