asp.net - 为什么根据检索顺序从 ADO Recordset 中获取空值而不是正确值? (DB表有NTEXT值)

标签 asp.net sql-server datetime vbscript ado

我有一个数据库表,其中有两个日期时间可为空的列,我需要使用 VBScript 从 ASP 页面读取这些列。

这是我写的代码:

Set cmd = Server.CreateObject("ADODB.Command")
With cmd
    .ActiveConnection = conn
    .CommandType = adCmdText
    .Prepared = True
    .CommandText = "SELECT * FROM storico_corsi WHERE stc_id = 5 "
    Set rs = .Execute
    Response.Write("stc_scadenza = {" & rs("stc_scadenza") & "}, ")
    Response.Write("stc_inizio = {" & rs("stc_inizio") & "} ")
    If IsEmpty(rs("stc_inizio")) Then
        Response.Write("- ERROR!")
    End If
End With

此代码给出以下输出:

stc_scadenza = {19/04/2014}, stc_inizio = {} - ERROR!

如果我将检索顺序交换为

...
    Response.Write("stc_inizio = {" & rs("stc_inizio") & "}, ")
    Response.Write("stc_scadenza = {" & rs("stc_scadenza") & "} ")
...

这是我得到的(正确的)结果:

stc_inizio = {19/02/2014}, stc_scadenza = {19/04/2014} 

为什么从 ADO 记录集中检索元素的顺序发生微小变化会产生完全不同的结果?

请注意,我使用的是意大利语言环境 (dd/mm/yyyy) 以及 stc_iniziostc_scadenza,同时经常使用设置为午夜时间戳,属于 SQL 类型 datetime

<小时/>

更新#1:我通过将代码减少为仅操作两个字段、添加空值检查并完全删除 JSON 内容,使代码更简单、更清晰。下面的一些评论引用了以前的、更复杂的版本。

<小时/>

更新 #2:如果我将 SQL 查询替换为

SELECT stc_inizio, stc_scadenza FROM storico_corsi WHERE stc_id = 5

SELECT stc_scadenza, stc_inizio FROM storico_corsi WHERE stc_id = 5

工作正常!但为什么?这是我正在使用的数据库表:

CREATE TABLE [dbo].[storico_corsi] (
    [stc_id] [bigint] IDENTITY(1,1) NOT NULL,
    [stc_id_ute] [bigint] NOT NULL,
    [stc_utente] [varchar](100) NULL,
    [stc_anagrafica] [ntext] NULL,
    [stc_id_can] [bigint] NULL,
    [stc_canale] [varchar](500) NULL,
    [stc_FE_id] [bigint] NULL,
    [stc_quest_finale] [ntext] NULL,
    [stc_quest_corretto] [ntext] NULL,
    [stc_reg_fad] [ntext] NULL,
    [stc_inizio] [datetime] NULL,
    [stc_scadenza] [datetime] NULL,
    [stc_terminato] [char](1) NULL
        CONSTRAINT [DF_storico_corsi_stc_terminato_1]  DEFAULT ('N'),
    [stc_fine] [datetime] NULL,
    [stc_tempo] [bigint] NULL 
        CONSTRAINT [DF_storico_corsi_stc_tempo]  DEFAULT ((0)),
    [stc_data_in] [datetime] NULL 
        CONSTRAINT [DF_storico_corsi_stc_data_in_1]  DEFAULT (getdate()),
    [stc_progressivo] [int] NULL,
    [stc_anno] [int] NULL,
CONSTRAINT [PK_storico_corsi] PRIMARY KEY CLUSTERED ([stc_id] ASC) 
WITH (
    PAD_INDEX = OFF, 
    STATISTICS_NORECOMPUTE = OFF, 
    IGNORE_DUP_KEY = OFF, 
    ALLOW_ROW_LOCKS = ON, 
    ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) 
ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
<小时/>

更新#3:只要我在查询中包含 3 个 ntext 列中的任何一个,就可以重现该问题。如果我不SELECT它们,就不会发生什么不好的事情。显然,ntext 值打破了记录,但它们也以一种不可预测的方式做到了这一点,具体取决于其他字段的检索顺序。

<小时/>

更新 #4:BLOB/ntext 必须最后使用 ADO 获取。这个说法听起来有点疯狂,但这就是我在这里找到的:http://p2p.wrox.com/sql-server-2000/3211-cant-pull-data-ntext-field-into-recordset.html#post78234这和我的经验是一致的。

最佳答案

鉴于我们进一步调查后您看到的结果,问题似乎源于您使用 SELECT * 隐式选择的 NTEXT 列。 .(但不使用。)

正如您所注意到的,有 occasional hints on the web使用 ADO 时,至少曾经在检索 SELECT 列表末尾之前的大型二进制字段时存在问题。 (当你链接到那篇文章时,我确实从昏暗而遥远的过去有了一个模糊的内存,我以前也看过这个建议。)

我怀疑您可能使用的是旧版本的 ADO,并且此问题可能已在更高版本中得到修复。

鉴于在这种特殊情况下,您实际上并不希望从 NTEXT 列中检索值,您应该简单地将 SELECT 列表限制为您实际使用的值需要,一切都应该正常工作。

请注意,除了快速的临时查询之外,通常认为避免使用 SELECT * 是最佳实践。明确选择您需要的列有几个好处。例如,在这种情况下,即使您的 SELECT 运行良好,您仍然会检索 NTEXT 字段中潜在的大量数据(可能跨域)网络)从您的数据库中仅丢弃它而不使用它...

另请注意,在 KB article 317016, "How To Read and Write BLOBs Using GetChunk and AppendChunk" 中,有一些“通过 ADO 使用 BLOB 的建议”,包括:

  • Select the BLOB columns last. Select individual fields, not "*".

关于asp.net - 为什么根据检索顺序从 ADO Recordset 中获取空值而不是正确值? (DB表有NTEXT值),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32987600/

相关文章:

postgresql - 选择两个时间戳之间的记录

asp.net - 通用 Web.Config 重写以删除查询字符串并添加 url seo slug

asp.net - 如何测试ASP.NET成员身份密码是否满足配置的复杂性要求?

c# - 放置多个显示错误 :There is already an open DataReader associated with this Command which must be closed first 的 sql 命令时

sql-server - 在 SQL UDF 中插入记录并返回 Id?

c# - 升级到 EF 6 现在出现 LINQ 错误

asp.net - 是否可以在 Linux 上为 asp 和 asp.net 设置 Web 服务器?

asp.net Gridview,1 条记录跨越两行

c# - 如何获取刚刚添加到 DataTable 的行的标识?

c# - 托管后日期时间出错