2012-08-01 5 views
11

Come trovare oggetti che dipendono da una particolare colonna di tabella.Trova dipendenza colonna

Es:

Tabella: SomeTable

Cols: col1 pk, col2, col3

voglio trovare tutti gli oggetti che dipendono col1 (Pk)

risposta

10

Prova questa query, ti fornirà alcuni risultati che penso tu stia cercando.
Per filtrare, cercare il valore nella colonna c1.name o c2.name.
Per cercare tutti i riferimenti ad una determinata colonna, utilizzare il c2.name per il nome della colonna e l'OBJECT_NAME (k.referenced_object_id) come la tabella che contiene la colonna c2 :)

Good Luck!


    select OBJECT_NAME(k.parent_object_id) as parentTable 
      , c1.name as parentColumn 
      , OBJECT_NAME(k.referenced_object_id) as referencedTable 
      , c2.name as referencedColumn 
    from sys.foreign_keys k 
      inner join sys.foreign_key_columns f 
       on f.parent_object_id = k.parent_object_id 
       and f.constraint_object_id = k.object_id 
      inner join sys.columns c1 
       on c1.column_id = f.parent_column_id 
       and c1.object_id = k.parent_object_id 
      inner join sys.columns c2 
       on c2.column_id = f.referenced_column_id 
       and c2.object_id = k.referenced_object_id 
    where c2.name = 'Column' 
    and  OBJECT_NAME(k.referenced_object_id) = 'Table' 
+0

Nota: manca una condizione di join, vedere lo script modificato di seguito da @ christopher-cullum per la correzione! – gerrod

+0

Ho modificato lo script con la condizione di join mancante. Divertente che dopo più di 5 anni questo script sia ancora usato :) –

+0

Non hai idea di quanto utile l'ho trovato ieri !! :-) – gerrod

1

Prova questo: questo darà tutti i nomi degli oggetti che fanno riferimento al Pk del tuo tavolo.

select OBJECT_NAME(parent_object_id) from sys.foreign_keys where referenced_object_id = OBJECT_ID('YourTableName') 
5

Sostituire semplicemente {0} e {1}!

declare @tbl_nme as varchar(50) 
declare @col_nme as varchar(50) 
declare @level int 
set @level = 1 
set @tbl_nme= '{0}' --TableName 
set @col_nme= '{1}' --ColumnName 



select 
    obj.name as obj_nm 
, col.name as col_nm 
, depobj.name as dep_obj_nm 
, CASE depobj.type 
    WHEN 'C' THEN 'CHECK constraint' 
    WHEN 'D' THEN 'Default' 
    WHEN 'F' THEN 'FOREIGN KEY' 
    WHEN 'FN' THEN 'Scalar function' 
    WHEN 'IF' THEN 'In-lined table-function' 
    WHEN 'K' THEN 'PRIMARY KEY' 
    WHEN 'L' THEN 'Log' 
    WHEN 'P' THEN 'Stored procedure' 
    WHEN 'R' THEN 'Rule' 
    WHEN 'RF' THEN 'Replication filter stored procedure' 
    WHEN 'S' THEN 'System table' 
    WHEN 'TF' THEN 'Table function' 
    WHEN 'TR' THEN 'Trigger' 
    WHEN 'U' THEN 'User table' 
    WHEN 'V' THEN 'View' 
    WHEN 'X' THEN 'Extended stored procedure' 
    END as dep_obj_type 
, null as dep_col_nm 
, depobj.type as dep_obj_typeID 
, @level as level 
into #temp 
from sysobjects obj 
    join syscolumns col on obj.id = col.id 
    left join (sysdepends dep join sysobjects depobj on depobj.id = dep.id) 
     on obj.id = dep.depid 
     and col.colid = dep.depnumber 
where obj.name = @tbl_nme 
    and col.name = @col_nme 


while (@@rowcount > 0) 
begin 
set @level = @level + 1 
insert into #temp 
select 
    obj.name as obj_nm 
, col.name as col_nm 
, depobj.name as dep_obj_nm 
, CASE depobj.type 
    WHEN 'C' THEN 'CHECK constraint' 
    WHEN 'D' THEN 'Default' 
    WHEN 'F' THEN 'FOREIGN KEY' 
    WHEN 'FN' THEN 'Scalar function' 
    WHEN 'IF' THEN 'In-lined table-function' 
    WHEN 'K' THEN 'PRIMARY KEY' 
    WHEN 'L' THEN 'Log' 
    WHEN 'P' THEN 'Stored procedure' 
    WHEN 'R' THEN 'Rule' 
    WHEN 'RF' THEN 'Replication filter stored procedure' 
    WHEN 'S' THEN 'System table' 
    WHEN 'TF' THEN 'Table function' 
    WHEN 'TR' THEN 'Trigger' 
    WHEN 'U' THEN 'User table' 
    WHEN 'V' THEN 'View' 
    WHEN 'X' THEN 'Extended stored procedure' 
    END as dep_obj_type 
, null as dep_col_nm 
, depobj.type as dep_obj_typeID 
, @level as level 
from sysobjects obj 
    join syscolumns col on obj.id = col.id 
    left join (sysdepends dep join sysobjects depobj on depobj.id = dep.id) 
     on obj.id = dep.depid 
     and col.colid = dep.depnumber 
where exists(select 1 from #temp a where obj.name = a.dep_obj_nm and 
col.name = a.dep_col_nm and level = @level - 1 and dep_col_nm is not null) 
end 

select 
    obj_nm AS 'TABLE', 
    col_nm AS 'COLUMN', 
    dep_obj_nm AS 'USAGE_OBJECT', 
    dep_obj_type AS 'USAGE_OBJECTTYPE', 
    dep_obj_typeID AS 'USAGE_OBJECTTYPEID' 
from #temp 
drop table #temp 
+0

Questo è quello che cercavo, grazie –

0

Questo dovrebbe fare il trucco:

SELECT OBJECT_NAME (referencing_id), referencing_id, referenced_id 
FROM sys.sql_expression_dependencies d 
WHERE OBJECT_NAME(d.referenced_id) = '<TABLE_NAME>' 
     AND OBJECT_DEFINITION(referencing_id) = '<COLUMN_NAME>'; 

fonte: http://www.mssqltips.com/sqlservertip/2999/different-ways-to-find-sql-server-object-dependencies/

o, per mostrare tutte le dipendenze su un tavolo, usare

EXEC sp_depends <TABLE_NAME> 

fonte: https://msdn.microsoft.com/en-us/library/ms189487.aspx

8

Questo dovrebbe funzionare!

 -- Search in All Objects 
SELECT OBJECT_NAME(OBJECT_ID),definition 
FROM sys.sql_modules 
WHERE definition LIKE '%' + 'ColumnToBeSearched' + '%' 
Order by 1 
GO 

-- Search in Stored Procedure Only 
SELECT DISTINCT OBJECT_NAME(OBJECT_ID), 
object_definition(OBJECT_ID) 
FROM sys.Procedures 
WHERE object_definition(OBJECT_ID) LIKE '%' + 'ColumnToBeSearched' + '%' 
GO 
+0

Devo chiedere cosa fa l'ordine di 1' in questo caso? – Peter

+1

Ordinerà il risultato impostato dalla prima colonna in ordine crescente. –

+0

Grazie a @Arpan, non lo sapevo! – Peter

0

Trova specifiche dipendenze colonna

 
SELECT OBJECT_NAME(referencing_id), 
    referenced_database_name, 
    referenced_schema_name, 
    referenced_entity_name 
FROM sys.sql_expression_dependencies 
WHERE OBJECT_NAME(referenced_id) = 'table_name' 
    AND OBJECT_DEFINITION(referencing_id) LIKE '%field_name%'; 
3

Lo SQL fornita nel accepted answer above dovrebbero includere una condizione aggiuntiva join tra sys.foreign_keys e sys.foreign_key_columns. Vedere riga che inizia con "e" qui sotto:

from sys.foreign_keys k 
     inner join sys.foreign_key_columns f 
      on f.parent_object_id = k.parent_object_id 
       and f.constraint_object_id = k.object_id 

Per riferimento, ecco l'intero script con la versione modificata join:

select OBJECT_NAME(k.parent_object_id) as parentTable 
     , c1.name as parentColumn 
     , OBJECT_NAME(k.referenced_object_id) as referencedTable 
     , c2.name as referencedColumn 
from sys.foreign_keys k 
     inner join sys.foreign_key_columns f 
      on f.parent_object_id = k.parent_object_id 
      and f.constraint_object_id = k.object_id 
     inner join sys.columns c1 
      on c1.column_id = f.parent_column_id 
      and c1.object_id = k.parent_object_id 
     inner join sys.columns c2 
      on c2.column_id = f.referenced_column_id 
      and c2.object_id = k.referenced_object_id 
where c2.name = 'GUID' 
and  OBJECT_NAME(k.referenced_object_id) = 'AuthDomain' 
+1

Vai avanti e fai la tua risposta da sola - supponi che nessuno abbia letto la risposta accettata. – rrauenza

4

@ sceneggiatura di NoFuchsGavin solito funziona alla grande, ma ha alcune limitazioni a causa di problemi con sysdepends (vedi this blog post by Pinal Dave per un esempio in cui questo dà risultati errati).

Microsoft suggerisce inoltre di evitare l'utilizzo di sysdepends in un nuovo lavoro di sviluppo.

Possiamo quindi utilizzare sys.dm_sql_referencing_entities e sys.dm_sql_referenced_entities come suggerito here.

Tuttavia, ho notato che questo a volte esclude i riferimenti di colonna dovuti a referenced_minor_name NULL. Ho quindi aggiunto un'altra condizione che può introdurre falsi positivi ma assicura che i riferimenti di colonna non vengano omessi dal set di risultati.

DECLARE @SchemaName sysname = '{0}'; 
DECLARE @TableName sysname = '{1}'; 
DECLARE @ColumnName sysname = '{2}'; 

SELECT 
    @SchemaName + '.' + @TableName          AS [USED_OBJECT], 
    @ColumnName               AS [COLUMN], 
    referencing.referencing_schema_name + '.' + referencing_entity_name AS USAGE_OBJECT, 
    CASE so.type 
     WHEN 'C' THEN 'CHECK constraint' 
     WHEN 'D' THEN 'Default' 
     WHEN 'F' THEN 'FOREIGN KEY' 
     WHEN 'FN' THEN 'Scalar function' 
     WHEN 'IF' THEN 'In-lined table-function' 
     WHEN 'K' THEN 'PRIMARY KEY' 
     WHEN 'L' THEN 'Log' 
     WHEN 'P' THEN 'Stored procedure' 
     WHEN 'R' THEN 'Rule' 
     WHEN 'RF' THEN 'Replication filter stored procedure' 
     WHEN 'S' THEN 'System table' 
     WHEN 'TF' THEN 'Table function' 
     WHEN 'TR' THEN 'Trigger' 
     WHEN 'U' THEN 'User table' 
     WHEN 'V' THEN 'View' 
     WHEN 'X' THEN 'Extended stored procedure' 
    END            AS USAGE_OBJECTTYPE, 
    so.[type]          AS USAGE_OBJECTTYPEID 
FROM sys.dm_sql_referencing_entities 
    (
     @SchemaName + '.' + @TableName, 
     'object' 
    ) referencing 
    INNER JOIN sys.objects so 
     ON referencing.referencing_id = so.object_id 
WHERE 
    EXISTS 
    (
     SELECT 
      * 
     FROM 
      sys.dm_sql_referenced_entities 
      (
       referencing_schema_name + '.' + referencing_entity_name, 
       'object' 
      ) referenced 
     WHERE 
      referenced_entity_name = @TableName 
      AND 
      (
       referenced.referenced_minor_name LIKE @ColumnName 
       -- referenced_minor_name is sometimes NULL 
       -- therefore add below condition (can introduce False Positives) 
       OR 
       (
        referenced.referenced_minor_name IS NULL 
        AND 
        OBJECT_DEFINITION 
        (
         OBJECT_ID(referencing_schema_name + '.' + referencing_entity_name) 
        ) LIKE '%' + @ColumnName + '%' 
       ) 
      ) 
    ) 
ORDER BY 
    USAGE_OBJECTTYPE, 
    USAGE_OBJECT 

Sopra script è basato su di @ NoFuchsGavin risposta e this blog post.

Sono interessato a sapere se qualcuno è riuscito a trovare un modo migliore che non introduce falsi negativi o positivi.

+0

Funziona per me! Grazie per referenziare le migliori pratiche! – Colin

Problemi correlati