博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
你是否也忘了刷新视图?
阅读量:6906 次
发布时间:2019-06-27

本文共 1649 字,大约阅读时间需要 5 分钟。

目录

 

起因:

         由于工作原因,我隔几天就要执行一批开发人员提供过来的脚本,部分是新需求的开发,部分是修复bug。往往包含有几百个。我用工具批量执行之后,系统继续运行,后来反反复复会有这样那样的错误,其中一个,经过开发人员的检查,是因为视图没刷新。
         对此我纳闷了很久,视图不就是一堆select语句吗?怎么还要刷新?难道表改了不会跟着改?为此,我首先自己做一个实验,发现的确不会马上改过来,至于啥时候才更改,也不清楚,听说从2000的时候,这个问题已经存在,看来我孤陋寡闻了。
 

测试:

 

 步骤一:首先执行下面语句

 
[sql]   
 
 
  1. USE tempdb  
  2. GO  
  3. --创建表  
  4. IF OBJECT_ID('testTB') IS NOT NULL   
  5.     DROP TABLE testTB  
  6. GO  
  7. CREATE TABLE testTB ( id INT, NAME VARCHAR(10) )  
  8. --插入测试数据  
  9. INSERT INTO testTB  
  10. SELECT 1,'a'  
  11. UNION ALL   
  12. SELECT 2,'b'  
  13. UNION ALL   
  14. SELECT 3,'c'  
  15.   
  16. IF OBJECT_ID('V_testTB') IS NOT NULL   
  17. DROP VIEW V_testTB  
  18. GO  
  19. CREATE   VIEW V_testTB  
  20. AS  
  21.     SELECT  *  
  22.     FROM    testTB  
  23. go   
  24.   
  25. SELECT * FROM V_testTB  
 
 
得到结果:
 
 

步骤二:更改表结构

[sql]   
 
 
  1. --添加一列  
  2. ALTER TABLE testTB ADD  age INT  
然后再来执行一下视图:
 
[sql]   
 
 
  1. SELECT * FROM V_testTB  
得到结果:
 
 
反复执行了10次,结果还是没变。
 

步骤三:使用存储过程刷新视图

 
[sql]   
 
 
  1. sp_refreshview V_testTB  
然后再执行查询视图的语句:
 
[sql]   
 
 
  1. SELECT * FROM V_testTB  
眼前一亮,得到结果:
 
 
可以看出,结构已经刷新,证明有效果了。
 

分析:

 
        细心的人应该发现,其实视图里面我用了*号。可以通过实验来证明,如果不用星号,是没问题的。而如果指定了列名,那么在新加一列的时候,管它有没有刷新,都不会有问题,因为你压根就不会用到这列,那么如果是删除呢?现在来试试,建表的代码依旧,把原有的添加列的代码改成删除列,另外*号依旧保留:
 
[sql]   
 
 
  1. --删除一列  
  2. ALTER TABLE testTB DROP   COLUMN  id  
再执行:
 
[sql]   
 
 
  1. SELECT * FROM V_testTB  
会得到以下的错误:
 
 
证明删除是会报错的,不需要刷新,那么估计大家也猜到,就算指定列,也会报错,现在来证实一下:
 
 
这次报错是这个,部分代码我就不写了。
 

总结:

 
根据上面的实验,可以得出:
 1、视图里面尽可能不要出现*号。*号不仅对性能有影响,也不便于结构的更新。
       
 2、无论视图所涉及的表结构有无修改,每次执行脚本后,刷新一下,总是好的。并且我遇到过这样的情景,一个名字是存储过程的名字,但是在使用:
 
[sql]   
 
 
  1. SELECT DISTINCT  
  2.         'EXEC sp_refreshview ''' + name + ''''  
  3. FROM    sys.objects AS so  
  4.         INNER JOIN sys.sql_expression_dependencies AS sed ON so.object_id = sed.referencing_id  
  5. WHERE   so.type = 'V'  
  6.         AND sed.referenced_id = OBJECT_ID('testTB') ;  
下面语句中时竟然能查出来,证明定义的时候有问题,所以这一步也同时可以检查一下会不会存在问题对象。顺带说一句,上面的脚本是把需要刷新的视图拼接出来,然后一次性执行。
 
转载于:http://blog.csdn.net/dba_huangzj/article/details/8426684
你可能感兴趣的文章
迪士尼研究院用深度学习打造语音动画,让VR社交更真实
查看>>
Veeam和Nutanix加速数字化转型,致力企业级业务永续
查看>>
不要在界面上对数据库进行改动
查看>>
[windows]快速从ftp下载最新软件包的批处理脚本
查看>>
Linux 信号signal处理函数
查看>>
c++ 多线程写日志的一个很实用的日志类源码(支持 c++ builder)
查看>>
推荐系统设计
查看>>
Nginx https证书部署
查看>>
java的NIO和AIO
查看>>
Struts.xml中Action的method与路径的三种匹配方法
查看>>
LoadRunner参数化取值与连接数据库
查看>>
hdu 1247 Hat’s Words(字典树)
查看>>
Vshpere client登录VC报错
查看>>
新手学习oracle之迁移数据表空间
查看>>
Hive SQL 监控系统 - Hive Falcon
查看>>
perl安装和安装模块
查看>>
MySQL5.7.16 gtid复制
查看>>
书稿前言
查看>>
java-第十四章-代参的方法(二)-查找会员积分
查看>>
php 之redis
查看>>