在SQL Azure中,我有一个或多或少像这样设置的表,有两个计算列(IsExpired
和IsDeadlineExpired
),它们只是将不可为空的日期时间列与当前时间进行比较: / 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瞬态故障吗?
答案 0 :(得分:1)
请参阅此文章:SELECT * AND SQL Azure。
其作者强烈建议更换
SELECT *
FROM TableName
与
SELECT [Column1], [Column2], ... [ColumnN]
FROM TableName
因为 使用SELECT *会导致额外的分页,RFID查找,不需要的表锁定,并阻碍将来尝试创建覆盖索引。总之,它对性能不利 。
顺便说一句:在这里你有一些有趣的文章:由于MS SQL Azure框架的上述行为,我怀疑 GetOrdinary(“IsExpired”)导致System.IndexOutOfRangeException。
结论?将 SELECT 语句与已定义的列列表一起使用可提高SQL Azure数据库的性能并避免使用IndexOutOfRange异常。
答案 1 :(得分:0)
查看一些旧日志,得出的结论是,只有在同时部署DACPAC的同时运行查询时才会发生此错误(作为我们对此特定测试环境的自动部署的一部分)。
我假设在DACPAC部署期间架构不一定处于可靠状态。
从那时起,我们添加了一些代码,以便在部署期间将应用程序置于“维护模式”(即使是这些自动化模式)。这似乎缓解了这个问题。