我有一个数据库表,其中有两个日期时间可为空的列,我需要使用 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_inizio
和 stc_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/