2012-06-14 40 views
0

我目前正在嘗試創建一個函數來解析錯誤消息,以使它們對最終用戶更有幫助。目前我正在使用SQLServer和VB.NET。SQLException外鍵錯誤獲取子表

現在我養的錯誤547,看起來像這樣:

DELETE statement conflicted with COLUMN REFERENCE 
constraint Constraint Name. The conflict occurred 
in database 'Database Name', table 'Table Name', 
column 'Column Name'. 

是提高它

DELETE FROM parentTable WHERE primaryKey = 5 

我能拉的每一條信息,我從不需要語句該錯誤消息除了parentTable的名稱之外。我已經確定SqlException不存儲導致異常的語句,並且據我所知它不存儲關於父表名稱的信息,而只存儲試圖引用它的表。

有沒有簡單的方法來獲取父表的名稱?

+1

看看http://stackoverflow.com/questions/3907879/sql-server -howto-GET-外鍵參考 - 從 - 信息架構 – a1ex07

回答

2

這是我開發了一個幾年前查詢指定表的臨時父/子關係例行:

--------------------------------------------------------------------- 
-- Name: FKRelationships 
-- Purpose: Map all parent/child relationships to the selected table 
-- Date: 1/19/2009 
-- Author: John W. Dewey 
-- Instructions: 1) Connect this script to the database containing 
--     the table you want to analyze 
--     2) Set the schema name and table name variables 
--     Initializations section below. Be sure the table 
--     name variable does not contain the schema name 
--     3) You will get two result sets; the first will show 
--     the relational parent tables to your selected table, and 
--     the second will show the relational children to your 
--     selected table. 
--------------------------------------------------------------------- 

--------------------------------------------------------------------- 
-- Declarations 
declare @TableName nvarchar(128) 
declare @SchemaName nvarchar(128) 
declare @ParentTableSchema nvarchar(128) 
declare @ParentTableName nvarchar(128) 
declare @FKName nvarchar(128) 
declare @Column nvarchar(128) 
declare @Table nvarchar(128) 
declare @Schema nvarchar(128) 
declare @FKColumnString nvarchar(max) 
declare @PKColumnString nvarchar(max) 
declare @result table (
    [Parent Table] nvarchar(128) 
    , [Child Table] nvarchar(128) 
    , [Constraint] nvarchar(128) 
    , [Relationship] nvarchar(max) 
) 
declare @FKTemp table (
    [id] int identity(1,1) 
    , [Child Schema Name] nvarchar(128) 
    , [Child Table Name] nvarchar(128) 
    , [Child FK Name] nvarchar(128) 
    , [Column Name] nvarchar(128) 
) 

--------------------------------------------------------------------- 
-- Initializations 
set @SchemaName = 'dbo' 
set @TableName = 'MyTable' 

--------------------------------------------------------------------- 
-- Tables referenced by the specified table's FKs 
declare c1 cursor for 
    select a.CONSTRAINT_NAME 
    from INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS a 
    inner join INFORMATION_SCHEMA.TABLE_CONSTRAINTS b 
     on a.CONSTRAINT_NAME = b.CONSTRAINT_NAME 
    where b.TABLE_NAME = @TableName 
    and b.CONSTRAINT_SCHEMA = @SchemaName 
open c1 
fetch next from c1 into @FKName 
while @@fetch_status=0 begin 

    -- Build a string of each FK's corresponding columns 
    set @FKColumnString = @SchemaName+'.'[email protected]+'.' 
    declare c2 cursor for 
     select a.COLUMN_NAME from INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE a 
     inner join INFORMATION_SCHEMA.COLUMNS b 
      on a.TABLE_NAME = b.TABLE_NAME 
      and a.COLUMN_NAME = b.COLUMN_NAME 
     where [email protected] 
     and a.TABLE_SCHEMA = @SchemaName 
     order by b.ORDINAL_POSITION 
    open c2 
    fetch next from c2 into @Column 
    while @@fetch_status=0 begin 
     set @FKColumnString = @FKColumnString + '+' + @Column 
     fetch next from c2 into @Column 
    end 
    set @FKColumnString = replace(@FKColumnString, '.+', '.') 
    close c2 
    deallocate c2 

    -- Build a string of each PK's corresponding columns 
    declare c3 cursor for 
     select distinct c.TABLE_SCHEMA 
      , c.table_name as [Parent Table Name] 
     from INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS a 
     inner join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE b 
      on a.CONSTRAINT_NAME = b.CONSTRAINT_NAME 
     inner join INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE c 
      on a.UNIQUE_CONSTRAINT_NAME = c.CONSTRAINT_NAME 
     where b.table_name = @TableName 
     and b.TABLE_SCHEMA = @SchemaName 
     and a.CONSTRAINT_NAME = @FKName 
    open c3 
    fetch next from c3 into @ParentTableSchema, @ParentTableName 
    while @@fetch_status=0 begin 
     set @PKColumnString = @ParentTableSchema+'.'[email protected]+'.' 
     declare c4 cursor for 
      select a.COLUMN_NAME from INFORMATION_SCHEMA.KEY_COLUMN_USAGE a 
       inner join INFORMATION_SCHEMA.TABLE_CONSTRAINTS b 
        on a.CONSTRAINT_NAME = b.CONSTRAINT_NAME 
        and b.CONSTRAINT_TYPE = 'PRIMARY KEY' 
       where a.TABLE_NAME = @ParentTableName 
       and a.TABLE_SCHEMA = @ParentTableSchema 
       order by a.ORDINAL_POSITION 
      open c4 
      fetch next from c4 into @Column 
      while @@fetch_status=0 begin 
       set @PKColumnString = @PKColumnString + '+' + @Column 
       fetch next from c4 into @Column 
      end 
      set @PKColumnString = replace(@PKColumnString, '.+', '.') 
     close c4 
     deallocate c4 
     fetch next from c3 into @ParentTableSchema, @ParentTableName 
     insert into @result ([Parent Table], [Child Table], [Constraint], [Relationship]) values (@ParentTableSchema+'.'[email protected], @SchemaName+'.'[email protected], @SchemaName+'.'[email protected]+'.'[email protected], @FKColumnString+' = '[email protected]) 
    end 
    close c3 
    deallocate c3 
    fetch next from c1 into @FKName 
end 
close c1 
deallocate c1 

-- Display results 
select 
    [Child Table] as [Selected Table as Child] 
    , [Parent Table] 
    , [Constraint] as [Child Constraint] 
    , [Relationship] as [Relationship to Parent] 
from @result 

--------------------------------------------------------------------- 
-- FKs pointing to the specified table 
delete from @result 
insert into @FKTemp ([Child Schema Name], [Child Table Name], [Child FK Name], [Column Name]) 
select b.TABLE_SCHEMA as [Child Schema Name] 
    , b.TABLE_NAME as [Child Table Name] 
    , a.CONSTRAINT_NAME as [Child FK Name] 
    , b.Column_Name as [Column Name] 
from INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS a 
inner join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE b 
    on a.CONSTRAINT_NAME = b.CONSTRAINT_NAME 
inner join INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE c 
    on a.UNIQUE_CONSTRAINT_NAME = c.CONSTRAINT_NAME 
     and c.TABLE_NAME = @TableName 
     and c.TABLE_SCHEMA = @SchemaName 
inner join INFORMATION_SCHEMA.COLUMNS d 
    on d.TABLE_SCHEMA = c.TABLE_SCHEMA 
     and d.TABLE_NAME = c.table_name 
     and d.COLUMN_NAME = b.COLUMN_NAME 
order by d.ORDINAL_POSITION 

-- Selected table's PK 
set @PKColumnString = @SchemaName+'.'[email protected]+'.' 
declare c1 cursor for 
    select a.COLUMN_NAME from INFORMATION_SCHEMA.KEY_COLUMN_USAGE a 
     inner join INFORMATION_SCHEMA.TABLE_CONSTRAINTS b 
      on a.CONSTRAINT_NAME = b.CONSTRAINT_NAME 
      and b.CONSTRAINT_TYPE = 'PRIMARY KEY' 
     where a.TABLE_NAME = @TableName 
     and a.TABLE_SCHEMA = @SchemaName 
     order by a.ORDINAL_POSITION 
    open c1 
    fetch next from c1 into @Column 
    while @@fetch_status=0 begin 
     set @PKColumnString = @PKColumnString + '+' + @Column 
     fetch next from c1 into @Column 
    end 
    set @PKColumnString = replace(@PKColumnString, '.+', '.') 
close c1 
deallocate c1 

-- Child tables' FKs 
declare c1 cursor for select distinct [Child Schema Name], [Child Table Name] from @FKTemp 
open c1 
fetch next from c1 into @Schema, @Table 
while @@fetch_status=0 begin 
    set @FKColumnString = @SchemaName+'.'[email protected]+'.' 
    declare c2 cursor for select [Child FK Name], [Column Name] 
    from @FKTemp 
    where [Child Table Name] = @Table 
    open c2 
    fetch next from c2 into @FKName, @Column 
    while @@fetch_status=0 begin 
     set @FKColumnString = @FKColumnString + '+' + @Column 
     fetch next from c2 into @FKName, @Column 
    end 
    close c2 
    deallocate c2 
    set @FKColumnString = replace(@FKColumnString, '.+', '.') + ' = ' + @PKColumnString 
    insert into @result ([Parent Table], [Child Table], [Constraint], [Relationship]) values (@SchemaName+'.'[email protected], @Schema+'.'[email protected], @Schema+'.'[email protected]+'.'[email protected], @FKColumnString) 
    fetch next from c1 into @Schema, @Table 
end 
close c1 
deallocate c1 

-- Display results 
select 
    [Parent Table] as [Selected Table as Parent] 
    , [Child Table] 
    , [Constraint] as [Child Constraint] 
    , [Relationship] as [Relationship Parent] 
from @result