如何选择*但没有"列名在每个视图中必须唯一"

Ray*_*Ray 4 t-sql sql-server select view

我需要封装一组表JOIN,我们在供应商的数据库服务器上频繁使用这些表.我们在提取物等的许多地方重用相同的JOIN逻辑.似乎VIEW允许在一个地方定义和维护JOIN.

CREATE VIEW MasterView
AS
SELECT *
FROM entity_1 e1
INNER JOIN entity_2 e2 ON e2.parent_id = entity_1.id
INNER JOIN entity_3 e3 ON e3.parent_id = entity_2.id
/* other joins including business logic */
etc.
Run Code Online (Sandbox Code Playgroud)

问题是供应商定期更改数据库(列添加,名称更改),我希望它自动反映在"MasterView"中.

SELECT*会允许这样,但基础表都有ID列,所以我得到"每个视图中的列名必须是唯一的"错误.

我特别想避免列出表中的列名,因为a)它需要经常维护b)每个表有几百列.

有没有办法实现SELECT*的动态,但有效地排除某些列(即ID列)

谢谢

Ode*_*ded 5

我特别想避免列出表中的列名,因为a)它需要经常维护b)每个表有几百列.

在这种情况下,你无法避免它.您必须指定列名称,对于具有重复名称的列,请使用别名.代码生成可以帮助这些列.

SELECT * 无论如何都是不好的做法 - 如果有人在其中一个表中添加2GB二进制列并填充它,你真的希望它被退回吗?


Ray*_*Ray 0

根据 Madhivanan 的建议,我最终同意了这一点。它类似于 t-clausen.dk 后来建议的(感谢您的努力),尽管我发现 xml 路径样式比游标/等级分区更优雅。

以下在运行时重新创建 MasterView 定义。基础表中的所有列都以表名称为前缀,因此默认情况下我可以在视图中包含两个名称相似的列。仅此一项就解决了我原来的问题,但我还包含了“WHERE column_name NOT IN”子句,以专门排除某些永远不会在 MasterView 中使用的列。

create procedure Utility_RefreshMasterView 
as
begin

    declare @entity_columns varchar(max)
    declare @drop_view_sql varchar(max)
    declare @alter_view_definition_sql varchar(max)

    /* create comma separated string of columns from underlying tables aliased to avoid name collisions */
    select @entity_columns = stuff((
        select ','+table_name+'.['+column_name+'] AS ['+table_name+'_'+column_name+']' 
        from information_schema.columns
        where table_name IN ('entity_1', 'entity_2')
        and column_name not in ('column to exclude 1', 'column to exclude 2')
        for xml path('')), 1, 1, '')


    set @drop_view_sql = 'if exists (select * from sys.views where object_id = object_id(N''[dbo].[MasterView]'')) drop view MasterView'

    set @alter_view_definition_sql = 
    'create view MasterView as select ' + @entity_columns + '
    from entity_1
    inner join entity_2 on entity_2 .id = entity_1.id
    /* other joins follow */'

    exec (@drop_view_sql)
    exec (@alter_view_definition_sql)

end
Run Code Online (Sandbox Code Playgroud)