13

假设我有一个视图,其中一些列名是别名,例如本例中的“surName”:

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'

产量:

----------------
|别名 |类型 |
 ----------------
|名字 |nchar|
|中间名|nchar|
|姓氏 |nchar|
 ----------------

但是,我也想知道实际的列名。理想情况下:

--------------------------
|别名 |类型 |真实姓名 |
 --------------------------
|名字 |nchar|名字 |
|中间名|nchar|中间名|
|姓氏|nchar|姓氏|
 --------------------------

如何根据别名确定真正的列名是什么? 必须有某种方法可以使用 sys 表和/或 INFORMATION_SCHEMA 视图来检索此信息。


编辑: 我可以接近这种可憎的东西,这类似于 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'

这产生:

--------------------------
|别名 |类型 |真实姓名 |
 --------------------------
|名字 |nchar|名字 |
|中间名|nchar|中间名|
|surName |nchar|代码 |
|姓氏|nchar|姓氏|
 --------------------------

但是第三条记录是错误的——任何使用“JOIN”子句创建的视图都会发生这种情况,因为有两列具有相同的“column_id”,但在不同的表中。

4

4 回答 4

11

鉴于这种观点:

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 server 2005+。请参阅此处的参考

编辑

给出同样的看法。试试这个查询:

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+ 中进行了测试

于 2012-04-07T12:26:53.723 回答
5

我认为你不能。

选择查询隐藏了对其执行的实际数据源。因为您可以查询任何内容,即视图、表,甚至链接的远程服务器。

于 2012-04-06T19:12:23.937 回答
5

花了几个小时试图找到这个问题的答案,并反复遇到不起作用的解决方案和似乎最终放弃的海报,我最终偶然发现了一个似乎有效的答案:

https://social.msdn.microsoft.com/Forums/windowsserver/en-US/afa2ed2b-62de-4a5e-ae70-942e75f887a1/find-out-original-columns-name-when-used-in-a-view- with-alias?forum=transactsql

我相信,下面的 SQL 将返回您正在寻找的内容,它确实在做我需要的事情,并且看起来也表现良好。

SELECT  name
    , source_database
    , source_schema
    , source_table
    , source_column
    , system_type_name
    , is_identity_column
FROM    sys.dm_exec_describe_first_result_set (N'SELECT * from ViewName', null, 1) 

有关该函数的文档sys.dm_exec_describe_first_result_set可以在此处找到,它在 SQL Server 2012 及更高版本中可用:

https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-exec-describe-first-result-set-transact-sql

完全归功于链接上的海报,我自己没有解决这个问题,但我想在这里发布它,以防它对其他搜索此信息的人有用,因为我发现这个线程比我链接到的那个更容易.

于 2018-04-13T14:05:22.587 回答
2

不是完美的解决方案;但是,可以高度准确地解析 view_definition,特别是如果代码组织良好且具有一致的别名 'as'。此外,可以在别名后解析逗号“,”。

注意:select 子句中的最后一个字段没有逗号,我无法排除用作注释的项目(例如在视图文本中交错使用--)

我为名为“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 

希望这会有所帮助,我期待您的反馈

于 2014-10-01T04:13:21.567 回答