SELECT *中有时会丢失计算列

时间:2013-08-01 15:23:47

标签: sql azure azure-sql-database

在SQL Azure中,我有一个或多或少像这样设置的表,有两个计算列(IsExpiredIsDeadlineExpired),它们只是将不可为空的日期时间列与当前时间进行比较: / p>

CREATE TABLE [dbo].[Stuff]
(
   [StuffId] int NOT NULL IDENTITY(1,1),
   [Guid] uniqueidentifier NOT NULL,
   [ExpirationDate] datetime NOT NULL,
   [DeadlineDate] datetime NOT NULL,
   [UserId] int NOT NULL,
   [IsExpired] AS CAST((CASE WHEN [ExpirationDate] < GETUTCDATE() THEN 1 ELSE 0 END) AS bit),
   [IsDeadlineExpired] AS CAST((CASE WHEN [DeadlineDate] < GETUTCDATE() THEN 1 ELSE 0 END) AS bit),
   CONSTRAINT [PK_StuffId] PRIMARY KEY ([StuffId]),
   CONSTRAINT [UNQ_Guid] UNIQUE([Guid]),
)
GO

我有一个包含多个结果集的存储过程,其中一个结果集:

SELECT * FROM [dbo].[Stuff] WHERE [Guid] = @guid

我最近发现了错误日志,表明有时在使用SqlDataReader读取结果集时,SqlDataReader.GetOrdinal("IsExpired")会因IndexOutOfRangeException失败。我知道前面的列在这些情况下工作正常,因为它们在前面的代码行中读取而没有错误。我也相信程序的结果集是按正确顺序排列的,因为它们不共享列名(否则读取前面的列同样会失败)。

此外:大部分时间一切似乎都很完美。

这可以归因于Azure瞬态故障吗?

2 个答案:

答案 0 :(得分:1)

请参阅此文章:SELECT * AND SQL Azure

其作者强烈建议更换

SELECT *
FROM TableName

SELECT [Column1], [Column2], ... [ColumnN]
FROM TableName

因为 使用SELECT *会导致额外的分页,RFID查找,不需要的表锁定,并阻碍将来尝试创建覆盖索引。总之,它对性能不利

顺便说一句:在这里你有一些有趣的文章:

  1. How to get to SQL Azure Query Performance Data
  2. Query Performance
  3. Getting Started with the Windows Azure Tools for Visual Studio
  4. Getting Started with SQL Azure Development
  5. Improving Your I/O Performance
  6. Analyzing Query Performance just got easier with SQL Azure.
  7. 由于MS SQL Azure框架的上述行为,我怀疑 GetOrdinary(“IsExpired”)导致System.IndexOutOfRangeException

    结论?将 SELECT 语句与已定义的列列表一起使用可提高SQL Azure数据库的性能并避免使用IndexOutOfRange异常。

答案 1 :(得分:0)

查看一些旧日志,得出的结论是,只有在同时部署DACPAC的同时运行查询时才会发生此错误(作为我们对此特定测试环境的自动部署的一部分)。

我假设在DACPAC部署期间架构不一定处于可靠状态。

从那时起,我们添加了一些代码,以便在部署期间将应用程序置于“维护模式”(即使是这些自动化模式)。这似乎缓解了这个问题。