儲存過程獲取表被引用的資訊
可能題目取得不是很好,但我想看了文章就知道什麼意思。
當你想刪除一個表時,可能被其他表作為外來鍵被引用,此時你想刪除此表是刪除不掉的。你必須把那引用此表為外來鍵的表刪掉,才能把你要刪的表的刪掉。可能文字不好表達。我就舉個例子
當b,c表引用a表作為外來鍵,你想刪a表的某些資料,就一定要刪除相關的b,c中引用a表的資料。可是b,c表可能又被其他表引用,這樣肯定會導致一個遞迴。
如果按正常方法去刪a表,你可能寫刪除語句來刪除a表,但執行時會報錯說那個表引用了此表,此時你根據報錯資訊會找到引用的表,又刪除,又報錯,又根據資訊查詢,此時我感覺很麻煩。
我就自己寫了個儲存過程。
CREATE PROCEDURE dbo.usp_GetFeferenceTableInfo
@TableName nvarchar (50)
AS
SET NOCOUNT ON
CREATE TABLE #ForeignKeyTABLEInfo
(
PKTABLE_QUALIFIER sysname collate database_default NULL,
PKTABLE_OWNER sysname collate database_default NULL,
PKTABLE_NAME sysname collate database_default NOT NULL,
PKCOLUMN_NAME sysname collate database_default NOT NULL,
FKTABLE_QUALIFIER sysname collate database_default NULL,
FKTABLE_OWNER sysname collate database_default NULL,
FKTABLE_NAME sysname collate database_default NOT NULL,
FKCOLUMN_NAME sysname collate database_default NOT NULL,
KEY_SEQ smallint NOT NULL,
UPDATE_RULE smallint NULL,
DELETE_RULE smallint NULL,
FK_NAME sysname collate database_default NULL,
PK_NAME sysname collate database_default NULL,
DEFERRABILITY smallint null
)
DECLARE @Level int
DECLARE @ParentGetSubForNull int
DECLARE @SQL nvarchar (max)
SET @Level=0
SET @ParentGetSubForNull=1000
WHILE @ParentGetSubForNull<>0
BEGIN
PRINT @Level
IF @Level<>0
BEGIN
SET @SQL=''
SELECT @SQL=@SQL+'INSERT INTO #ForeignKeyTABLEInfo EXEC sp_fkeys '+FKTABLE_NAME+''+CHAR(13)+CHAR(10) FROM #ForeignKeyTABLEInfo WHERE UPDATE_RULE=@Level
EXEC(@SQL)
PRINT @SQL
END
ELSE
INSERT INTO #ForeignKeyTABLEInfo EXEC sp_fkeys @TableName
SELECT @ParentGetSubForNull=COUNT(*) FROM #ForeignKeyTABLEInfo WHERE KEY_SEQ=1
IF EXISTS (SELECT 1 FROM #ForeignKeyTABLEInfo WHERE KEY_SEQ=1)
BEGIN
UPDATE #ForeignKeyTABLEInfo SET UPDATE_RULE=@Level+1 WHERE KEY_SEQ=1
UPDATE #ForeignKeyTABLEInfo SET KEY_SEQ=2
END
SET @Level=@Level+1
END
SELECT PKTABLE_NAME,PKCOLUMN_NAME,[Level]=UPDATE_RULE,FK_NAME,PK_NAME FROM #ForeignKeyTABLEInfo
SET NOCOUNT OFF
當你想刪除一個表時,可能被其他表作為外來鍵被引用,此時你想刪除此表是刪除不掉的。你必須把那引用此表為外來鍵的表刪掉,才能把你要刪的表的刪掉。可能文字不好表達。我就舉個例子
當b,c表引用a表作為外來鍵,你想刪a表的某些資料,就一定要刪除相關的b,c中引用a表的資料。可是b,c表可能又被其他表引用,這樣肯定會導致一個遞迴。
如果按正常方法去刪a表,你可能寫刪除語句來刪除a表,但執行時會報錯說那個表引用了此表,此時你根據報錯資訊會找到引用的表,又刪除,又報錯,又根據資訊查詢,此時我感覺很麻煩。
我就自己寫了個儲存過程。
按理來說要獲取引用表的資訊應該用遞迴來解決最好,但我試過,感覺在資料庫中運用得沒有c#好,才改變策略用過程來寫。
程式碼如下
CREATE PROCEDURE dbo.usp_GetFeferenceTableInfo
@TableName nvarchar (50)
AS
SET NOCOUNT ON
CREATE TABLE #ForeignKeyTABLEInfo
(
PKTABLE_QUALIFIER sysname collate database_default NULL,
PKTABLE_OWNER sysname collate database_default NULL,
PKTABLE_NAME sysname collate database_default NOT NULL,
PKCOLUMN_NAME sysname collate database_default NOT NULL,
FKTABLE_QUALIFIER sysname collate database_default NULL,
FKTABLE_OWNER sysname collate database_default NULL,
FKTABLE_NAME sysname collate database_default NOT NULL,
FKCOLUMN_NAME sysname collate database_default NOT NULL,
KEY_SEQ smallint NOT NULL,
UPDATE_RULE smallint NULL,
DELETE_RULE smallint NULL,
FK_NAME sysname collate database_default NULL,
PK_NAME sysname collate database_default NULL,
DEFERRABILITY smallint null
)
DECLARE @Level int
DECLARE @ParentGetSubForNull int
DECLARE @SQL nvarchar (max)
SET @Level=0
SET @ParentGetSubForNull=1000
WHILE @ParentGetSubForNull<>0
BEGIN
PRINT @Level
IF @Level<>0
BEGIN
SET @SQL=''
SELECT @SQL=@SQL+'INSERT INTO #ForeignKeyTABLEInfo EXEC sp_fkeys '+FKTABLE_NAME+''+CHAR(13)+CHAR(10) FROM #ForeignKeyTABLEInfo WHERE UPDATE_RULE=@Level
EXEC(@SQL)
PRINT @SQL
END
ELSE
INSERT INTO #ForeignKeyTABLEInfo EXEC sp_fkeys @TableName
SELECT @ParentGetSubForNull=COUNT(*) FROM #ForeignKeyTABLEInfo WHERE KEY_SEQ=1
IF EXISTS (SELECT 1 FROM #ForeignKeyTABLEInfo WHERE KEY_SEQ=1)
BEGIN
UPDATE #ForeignKeyTABLEInfo SET UPDATE_RULE=@Level+1 WHERE KEY_SEQ=1
UPDATE #ForeignKeyTABLEInfo SET KEY_SEQ=2
END
SET @Level=@Level+1
END
SELECT PKTABLE_NAME,PKCOLUMN_NAME,[Level]=UPDATE_RULE,FK_NAME,PK_NAME FROM #ForeignKeyTABLEInfo
SET NOCOUNT OFF
返回的結果有幾個欄位,其中Level表示表被引用的深度,就是b,c引用a,d引用b,f引用c,則b,c表的深度是1,d,f表的深度是2.此時刪a表直接可以從d,f開始刪,從深度高到低來刪表。還一個欄位是PK_NAME表示那些表引用了要刪的表。其他欄位應該很清楚。
不知道誰能用遞迴實現此功能
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16436858/viewspace-608983/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PostgreSQL獲取建表語句儲存過程SQL儲存過程
- shell中獲取儲存過程返回值儲存過程
- 儲存過程——異常捕獲&列印異常資訊儲存過程
- 獲取某庫某個儲存過程內容儲存過程
- Sql儲存過程分頁--臨時表儲存SQL儲存過程
- 查詢儲存過程報錯資訊儲存過程
- SQL SERVER 儲存過程 獲取三個數中的最大值SQLServer儲存過程
- db2刪除已經儲存的表儲存過程DB2儲存過程
- GreenPlum 獲取表儲存大小的方法推薦
- 如何檢測被鎖住的Oracle儲存過程Oracle儲存過程
- 從sybase的儲存過程轉向oracle的儲存過程儲存過程Oracle
- MySQL儲存過程詳解 mysql 儲存過程MySql儲存過程
- .NET用使用儲存過程獲取輸出引數的程式碼示例!儲存過程
- mysql 儲存過程 procedure 批次建表MySql儲存過程
- 用儲存過程動態建立表儲存過程
- 儲存過程儲存過程
- 在儲存過程A中呼叫儲存過程B的結果儲存過程
- MyBatis 呼叫Oracle儲存過程,傳參、返回遊標的值獲取--示例MyBatisOracle儲存過程
- MySQL儲存過程中捕獲異常的方法MySql儲存過程
- oracle的儲存過程Oracle儲存過程
- 修改的儲存過程儲存過程
- mysql的儲存過程MySql儲存過程
- 編譯儲存過程時被卡死的處理方法編譯儲存過程
- 儲存過程被鎖無法編譯的解決儲存過程編譯
- MySql儲存過程—2、第一個MySql儲存過程的建立MySql儲存過程
- 儲存過程呼叫其他模式的儲存過程需要注意的地方儲存過程模式
- MySQL 儲存過程進行切換表MySql儲存過程
- SQL 儲存過程裡呼叫另一個儲存過程SQL儲存過程
- MySQL儲存過程詳解 mysql 儲存過程linkMySql儲存過程
- Oracle儲存過程乾貨(一):儲存過程基礎Oracle儲存過程
- 在儲存過程中建立表的兩種方法儲存過程
- Mysql 的儲存過程和儲存函式MySql儲存過程儲存函式
- 儲存過程與儲存函式儲存過程儲存函式
- Oracle儲存過程Oracle儲存過程
- 使用儲存過程儲存過程
- sybase儲存過程儲存過程
- java儲存過程Java儲存過程
- 管理儲存過程儲存過程