zoukankan      html  css  js  c++  java
  • 数据库表结构变化引起视图字段类型推断错误

    这几天,客户报告了一个Bug,  经过跟踪,发现是下面linq语句引起的,

    manuLines = CustomerDBContext.Bookkeeping_Netvisor_PurchaseInvoicesLines.Where(Function(pil) pil.PIL_PI_SysID = sysID).ToList()

    它会抛出一个转换异常: unable to cast object of type "System.Int32" to "System.String", 然后在堆栈里追踪到其中一步是 SqlDataReader.get_string()...

    这个程序已经跑了很久,一直没有问题, Bookkeeping_Netvisor_PurchaseInvoicesLines 是一个视图, 我跟踪Runtime执行这句后生成的sql, 把它拿到查询分析器里执行,也没有问题,看了数据类型的匹配,还是没有问题, 百思不得其解! 

    偶然, 我把视图删除了,用一样的语句重建,它又正常工作了, 于是我推断是数据库表结构变化,引起视图的结构推断问题。 我重新把数据库恢复到删除视图并重建前, 并调用 sp_refreshView 'Bookkeeping_Netvisor_PurchaseInvoicesLines' ,发现也能解决问题。  后来终于在微软 MSDN文章中找到正解:

    http://msdn.microsoft.com/zh-cn/library/ms187821.aspx ,

    大致意思是说:在创建视图时,如果没有用 with schemabinding 关键字

    则视图相关联表结构的变化可能导致视图结构推断出错。 解决方案是一个个调用 sp_refreshView '视图名' 刷新相关联视图。

    需要注意的是,如果要在视图上创建索引, 也需要在创建视图时使用with schemabinding 关键字,这个在百度知道里已经有人给出了答案,

    在视图上创建索引是有一定的限制的。如楼主所说,要在视图上创建索引,视图定义的时候要包含WITH SCHEMABINDING选项,另外必须在视图上创建一个唯一聚集索引以后才可以创建非聚集索引。
    写了个例子楼主看一下
    CREATE TABLE dbo.Test(a int,b int)
    GO
    CREATE VIEW vTest WITH SCHEMABINDING
    AS
    SELECT a,b
    FROM dbo.Test
    GO
    CREATE UNIQUE CLUSTERED INDEX IX_vTest_a ON vTest(a)
    --注意,由于是唯一性索引,如果基表Test的a列包含重复值的话索引是不能创建成功的
    GO
    --再创建一个非聚集索引
    CREATE INDEX IX_vTest_b ON vTest(b)

  • 相关阅读:
    表达式执行工具方法
    Mysql表创建外键报错
    JVM打印加载类的详情信息
    Shell脚本查询进程存活信息
    旋转数组的最小数字
    斐波那契数列(水题)
    用两个栈实现队列
    变态跳台阶
    跳台阶
    9*9乘法表(5种输出格式)
  • 原文地址:https://www.cnblogs.com/Hcsdn/p/2916712.html
Copyright © 2011-2022 走看看