2012-04-06 2 views
11

Пусть у меня есть представление, в котором некоторые из имен столбцов являются псевдонимами, как «ФАМИЛИЯ» в этом примере:Найти настоящее имя столбца псевдонима, используемого в представлении?

CREATE VIEW myView AS 
    SELECT 
      firstName, 
      middleName, 
      you.lastName surName 
    FROM 
      myTable me 
      LEFT OUTER JOIN yourTable you 
      ON me.code = you.code 
GO 

Я могу получить некоторую информацию о представлении, используя мнения INFORMATION_SCHEMA.
Например, запрос

SELECT column_name AS ALIAS, data_type AS TYPE 
FROM information_schema.columns 
WHERE table_name = 'myView' 

выходы:

 
---------------- 
|ALIAS  |TYPE | 
---------------- 
|firstName |nchar| 
|middleName|nchar| 
|surName |nchar| 
---------------- 

Однако, я хотел бы знать фактическое имя столбца, а также. В идеале:

 
--------------------------- 
|ALIAS  |TYPE |REALNAME | 
--------------------------- 
|firstName |nchar|firstName | 
|middleName|nchar|middleName| 
|surName |nchar|lastName | 
--------------------------- 

Как я могу определить, что реальное имя столбца на основе псевдонима? Должен быть какой-то способ использовать таблицы sys и/или INFORMATION_SCHEMA для получения этой информации.


EDIT: я могу сблизиться с этой мерзостью, которая похожа на ответ Arion в:

SELECT 
    c.name AS ALIAS, 
    ISNULL(type_name(c.system_type_id), t.name) AS DATA_TYPE, 
    tablecols.name AS REALNAME 
FROM 
    sys.views v 
    JOIN sys.columns c ON c.object_id = v.object_id 
    LEFT JOIN sys.types t ON c.user_type_id = t.user_type_id 
    JOIN sys.sql_dependencies d ON d.object_id = v.object_id 
     AND c.column_id = d.referenced_minor_id 
    JOIN sys.columns tablecols ON d.referenced_major_id = tablecols.object_id 
     AND tablecols.column_id = d.referenced_minor_id 
     AND tablecols.column_id = c.column_id 
WHERE v.name ='myView' 

Это дает:

 
--------------------------- 
|ALIAS  |TYPE |REALNAME | 
--------------------------- 
|firstName |nchar|firstName | 
|middleName|nchar|middleName| 
|surName |nchar|code  | 
|surName |nchar|lastName | 
--------------------------- 

но третья запись неправильна - это происходит с любым представлением, созданным с использованием предложения «JOIN», потому что есть два столбца с одинаковым «column_id», но в другой таблице s.

+0

AFAIK, регулярный синтаксис для псевдонима столбца используется 'как': выбери Columna, как columnB от t – abatishchev

+2

Настоящее имя для представления может быть даже не столбцом, так что нет никакого способа сделать это. Каким будет название столбца в этом представлении? Создать представление a как select 1 b –

+0

Пока параметр ['VIEW_METADATA' (http://msdn.microsoft.com/en-us/library/ms187956.aspx) не задан при создании представления, SQL Server вернется в DB-библиотеку, ODBC и OLE DB API-интерфейсы метаданных режима просмотра, включая информацию о базовой таблице, к которой относятся столбцы в наборе результатов. Никогда не смотрел на этот аспект сам. –

ответ

12

Учитывая эту точку зрения:

CREATE VIEW viewTest 
AS 
SELECT 
    books.id, 
    books.author, 
    Books.title AS Name 
FROM 
    Books 

То, что я вижу, что вы можете получить столбцы, используемые и таблицы, используемые, делая это:

SELECT * 
FROM INFORMATION_SCHEMA.VIEW_COLUMN_USAGE AS UsedColumns 
WHERE UsedColumns.VIEW_NAME='viewTest' 

SELECT * 
FROM INFORMATION_SCHEMA.VIEW_TABLE_USAGE AS UsedTables 
WHERE UsedTables.VIEW_NAME='viewTest' 

Это для SQL сервера 2005+. Смотрите ссылки here

Редактировать

Дайте ту же точку зрения. Попробуйте этот запрос:

SELECT 
    c.name AS columnName, 
    columnTypes.name as dataType, 
    aliases.name as alias 
FROM 
sys.views v 
JOIN sys.sql_dependencies d 
    ON d.object_id = v.object_id 
JOIN .sys.objects t 
    ON t.object_id = d.referenced_major_id 
JOIN sys.columns c 
    ON c.object_id = d.referenced_major_id 
JOIN sys.types AS columnTypes 
    ON c.user_type_id=columnTypes.user_type_id 
    AND c.column_id = d.referenced_minor_id 
JOIN sys.columns AS aliases 
    on c.column_id=aliases.column_id 
    AND aliases.object_id = object_id('viewTest') 
WHERE 
    v.name = 'viewTest'; 

Он возвращает это для меня:

columnName dataType alias 

id   int  id 
author  varchar author 
title  varchar Name 

Это также тестируется в SQL 2005+

+0

Это интересно, но я ничего не вижу в представлении INFORMATION_SCHEMA.VIEW_COLUMN_USAGE, который можно использовать в соединении для сопоставления с именем псевдонима. В моем примере столбцы возвращаются в другом порядке. Для INFORMATION_SCHEMA.COLUMNS есть «ORDINAL POSITION». Нет такой удачи для INFORMATION_SCHEMA.VIEW_COLUMN_USAGE. –

+0

Обновлен ответ .. Посмотрите: P – Arion

+0

Спасибо, это по существу то, что я могу с собой сделать, используя sp_helptext, чтобы «перепроектировать» виды INFORMATION_SCHEMA, но ваш запрос страдает от той же проблемы, что и моя, - это не сработает, если представление создается из JOIN. Например, он отображает поля «lastName» и «code» в псевдоним «surName» в моем примере. Я уточню вопрос, чтобы отразить это. –

5

Я думаю, вы не можете.

Выбрать запрос скрывает фактический источник данных, с которым он был выполнен. Потому что вы можете запросить что угодно, т. Е. Просматривать, таблицы, даже связанные удаленные серверы.

+0

@Segphault: Почему вы меняете свой ответ без комментариев? Вы не согласны? Хорошо. Но это не повод для downvote, imo. – abatishchev

+0

Имеет смысл. Одно использование вида - это скрытие деталей от посторонних глаз. Должны выставлять тип для его потребления. +1 – Paparazzi

2

не идеальное решение; но можно с высокой степенью точности проанализировать view_definition, особенно если код хорошо организован с последовательным псевдонимом с помощью «as». Кроме того, после псевдонима можно проанализировать запятую ','.

отметить: последнее поле в выбранном пункте не будет запятая, и я не смог исключить элементы используются в качестве комментариев (например, с чересстрочной разверткой в ​​тексте обзора с -)

я написал ниже для таблицы с именем «my_table» и посмотреть, соответственно, называется «» vMy_Table

select alias, t.COLUMN_name 
from 
(
select VC.COLUMN_NAME, 



case when 
ROW_NUMBER() OVER (
partition by C.COLUMN_NAME order by 
CHARINDEX(',',VIEW_DEFINITION,CHARINDEX(C.COLUMN_NAME,VIEW_DEFINITION))- 
CHARINDEX(VC.COLUMN_NAME,VIEW_DEFINITION) 

) = 1 

then 1 
else 0 end 
as lenDiff 



,C.COLUMN_NAME as alias 

,CHARINDEX(',',VIEW_DEFINITION,CHARINDEX(C.COLUMN_NAME,VIEW_DEFINITION)) diff1 
, CHARINDEX(VC.COLUMN_NAME,VIEW_DEFINITION) diff2 

from INFORMATION_SCHEMA.VIEW_COLUMN_USAGE VC 
inner join INFORMATION_SCHEMA.VIEWS V on V.TABLE_NAME = 'v'+VC.TABLE_Name 
inner join information_schema.COLUMNS C on C.TABLE_NAME = 'v'+VC.TABLE_Name 
where VC.TABLE_NAME = 'My_Table' 
and CHARINDEX(',',VIEW_DEFINITION,CHARINDEX(C.COLUMN_NAME,VIEW_DEFINITION))- 
CHARINDEX(VC.COLUMN_NAME,VIEW_DEFINITION) >0 
) 
t 

where lenDiff = 1 

Надеется, что это помогает, и я с нетерпением ждет ваших отзывы

Смежные вопросы