【问题标题】:SQL Server: does data type change of column (kept column name same) requires recreation of views?SQL Server:列的数据类型更改(保持列名相同)是否需要重新创建视图?
【发布时间】:2017-06-01 08:47:44
【问题描述】:

我将列的数据类型从 nvarchar 更改为 datetime,在 SQL Server 中保持列名相同。是否需要删除并重新创建依赖于该列的视图?

【问题讨论】:

  • ,没有。
  • 不,您不需要更改视图。视图是一个已编译的 t-sql,它从您选择的任何表中获取信息。它会自动改变数据类型
  • 如果您已经对列进行了更改,那么是什么阻止您查询视图并自己测试...?
  • @iamdave 什么都没有,这就是在测试中无论如何都要做的事情,但是我需要查看很多视图并找到正在使用这个特定列的视图以及来自社区的一些信息,关于如何这在后台工作真的会帮助我计划我的测试。谢谢
  • 将 RedGate 的 SQL 搜索安装到 SSMS 中。然后,您可以搜索引用您已更新的表/列的视图。显然,理想情况下,您应该在 进行更改之前完成所有这些检查...

标签: sql-server


【解决方案1】:

当您更改基表列类型时,您应该始终至少刷新视图:

exec sp_refreshview 'yourView'

这就是原因。 当您更改表定义时,不会刷新视图元数据。 现在想象一下,您的用户对基表没有权限,但对视图有 SELECT 权限。如果他们向 sp_help 询问此视图的列,或者如果他们在 OE 中打开 Columns 文件夹,它仍会显示旧类型。然后用户可以进行非法查询,他们会发疯地弄清楚会发生什么。 我给你这个例子来说明会发生什么。

create view dbo.vw_test_types as
select art_code, art_desc
from dbo.test_types;
go

insert into dbo.test_types (art_code, art_desc)
values ('123', 'trekking shoes');
go

alter table dbo.test_types alter column art_code int;
go

exec sp_help 'dbo.vw_test_types'

select art_desc + ' ' + art_code as full_art_desc
from dbo.vw_test_types;

--Msg 245, Level 16, State 1, Line 33
--Conversion failed when converting the varchar value 'trekking shoes ' to data type int.


exec sp_refreshview 'dbo.vw_test_types'
go

exec sp_help 'dbo.vw_test_types'
go 

在这里,您创建了一个仅包含 varchar 列的表。然后基于此表创建一个视图并输入一行。此时您决定将 art_code 类型更改为 int,该命令可以正常工作。 但是查看视图的元数据(exec sp_help 'dbo.vw_test_types'),它仍然只显示 varchar 列。 现在有一个用户无法访问基表,他想显示包括 art_code 在内的整个描述。他打开 SSMS -> OE -> dbo.vw_test_types -> Columns 并看到所有列都是 varchar,所以他只是连接了 art_desc 和 art_code。并得到错误!而且他真的很生气,他只看到 varchar 但错误告诉他 abot int type

甚至更糟。想想用户是否基于该查询构建了一些报告。有一天,所有这些报告都不起作用,它们可以配置为不向用户显示错误,只是无法显示“处理查询时发生错误”

【讨论】:

    【解决方案2】:

    不是作为答案,而是为了进一步的 sepupic 上面的回答(谁打败了我!),请考虑以下几点:

    Begin Transaction
    Create Table dbo.SOTest(col1 Numeric(12,2));
    Go
    Create View dbo.SOTestV As Select col1 From dbo.SOTest
    Go
    Select c.name, t.name
    From sys.columns As c
    Join sys.types As t
    On c.user_type_id = t.user_type_id
    Where c.object_id = Object_Id('dbo.SoTestV')
    Go
    Alter Table dbo.SOTest Alter Column col1 Int
    Go
    Select c.name, t.name
    From sys.columns As c
    Join sys.types As t
    On c.user_type_id = t.user_type_id
    Where c.object_id = Object_Id('dbo.SoTestV')
    Go
    Exec sys.sp_refreshview N'dbo.SOTestV'
    Go
    Select c.name, t.name
    From sys.columns As c
    Join sys.types As t
    On c.user_type_id = t.user_type_id
    Where c.object_id = Object_Id('dbo.SoTestV')
    Go
    Rollback Transaction
    

    结果将是

    col1   numeric
    
    (1 row(s) affected)
    
    col1   numeric
    
    (1 row(s) affected)
    
    col1   int
    

    从而证明视图中的元数据在刷新之前仍然显示之前的数据类型。

    【讨论】:

      猜你喜欢
      • 2017-06-15
      • 1970-01-01
      • 2013-11-10
      • 2014-06-18
      • 2016-02-03
      • 1970-01-01
      • 2012-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多