2009-04-02 7 views
2

Je souhaite une requête qui renvoie une ligne pour chaque colonne dans une vue et une ligne pour la vue elle-même. Il doit y avoir une colonne basetable dans le résultat qui donne la table de base pour la colonne dans la ligne courante, et une colonne basefield dans le résultat qui donne le nom de la colonne dans la requête sous-jacente (pour les colonnes renommées). Ce serait un bonus si des calculs pouvaient également être inclus dans la colonne basefield.Requête SQL Server (2005+) pour renvoyer la table de base et la colonne de base (champ) pour chaque colonne (champ) d'une vue

Je ne pense pas que cela puisse être fait. Ai-je tort?

Dans l'exemple ci-dessous, «ce qui se passe ici» doit être remplacé par table1 ou table2 selon le cas dans la colonne de base, et a, b ou c selon le cas dans la colonne champ de base.

 
create table table1 (a int, b int) 
create table table2 (a int, c int) 
go 
create view view1 as select table1.a, table1.b, table2.c from table1 left join table2 on table1.a = table2.a 
go 

select * from 
(
select 'View' objecttype,O.name viewname,'' fieldname,0 column_id,'' typename,'' max_length,'' [precision], '' scale, '' is_identity, 
    'what goes here' basetable, '' basefield 
from sys.objects O where O.type='V' and O.[schema_id] = 1 

union all 

    select 'Field' objecttype,object_name(C.[object_id]) viewname,C.name fieldname,C.column_id,T.name typename,C.max_length,C.precision,C.scale,C.is_identity, 
    'what goes here' basetable, 'what goes here' basefield 
    from sys.columns C 
left join sys.types T on C.user_type_id=T.system_type_id 
where C.[object_id] in (select O.[object_id] from sys.objects O where O.type='V') 
) I 
where viewname in ('view1') 
order by viewname, column_id 

drop view view1 
drop table table1 
drop table table2 

Répondre

1

Il existe peu de tables dans le schéma d'informations que vous pouvez utiliser pour déduire les informations. Une requête de base qui vous donne un peu de données sera:

select * 
from INFORMATION_SCHEMA.VIEW_COLUMN_USAGE v 
    inner join INFORMATION_SCHEMA.COLUMNS v1 
     on v.VIEW_NAME=v1.TABLE_NAME and v.COLUMN_NAME=v1.COLUMN_NAME 
where v.VIEW_NAME='My_View' 

Les tables du schéma d'information sont:

select * from INFORMATION_SCHEMA.VIEWS 
select * from INFORMATION_SCHEMA.VIEW_TABLE_USAGE 
select * from INFORMATION_SCHEMA.VIEW_COLUMN_USAGE 

Donc, essayez d'utiliser ces.

Cependant, cela fonctionne uniquement lorsque vous utilisez des colonnes directement à partir des tabulations de base sans qu'aucune dérivation ne soit dérivée.

1

Vous connaissez peut-être pas la carte 1 à 1? Une colonne dans une vue peut être le résultat de plusieurs colonnes (ou même aucune!) De tables différentes. Cela dit, cela devrait être possible en analysant la source pour la vue. Mais le code sql serait de nature procédurale/impérative et pas du tout trivial.

+0

Yup, c'est le bonus: si ça pouvait revenir à moi avec le calcul des champs calculés. Je me demande simplement s'il existe un moyen basé sur l'analyse de SQL Server - le fait qu'il puisse exécuter la requête signifie que c'est possible. –

+0

Mais, ce qui pourrait être un moyen de l'obtenir compte tenu des vues sont une requête droite avec des jointures entre plusieurs tabbles? – Kangkan