【问题标题】:SQL executing twice in IIS10 with ASP ClassicSQL 在 IIS10 中使用 ASP Classic 执行两次
【发布时间】:2017-07-31 03:49:08
【问题描述】:

我在 IIS 10(使用 asp classic 作为 api)和 SQL Server 2016 中有一个新的开发/测试环境。今天,我注意到一些帖子在数据库中增加了一倍的记录。 经过进一步审查,IIS 日志仅显示一个请求,但 SQL Trace 显示 2 个并发 SQL:BatchCompleted 跟踪,每次调用使用不安全的cn.execute "stored_procedure 'param1'" 方法的数据库,但任何使用准备好的语句的数据库调用只有一个 RPC :在跟踪中完成命中并且表现正常。

我们的生产环境具有相同的 SQL 版本,但目前仍在 IIS6 中。几周前,我丢失了具有相同设置的开发 IIS 框,之前没有注意到这一点。我们大约 90% 的 API 已经在生产环境中使用了十多年,但没有发生这种情况,现在也没有发生。

我对 IIS 10 有点陌生,因为我一直在维护 IIS6 环境,所以也许我配置了一些错误,但是除了启用 ASP 经典路径和父路径之外,我没有做太多修改来获得我们的旧版 API 正在运行。

导致双重执行的 ASP 示例:

dim cn
dim dbConnectionString
dim SQL
dim rs

dbConnectionString = "Provider=SQLNCLI11;Server=srvr\instance;Database=DB;Uid=user;Pwd=pass;"
Set cn = Server.CreateObject("ADODB.Connection")
cn.open dbConnectionString
cn.CommandTimeout = 0
SQL = "store_procedure_name 'paramValue'"
RS.Open SQL, cn, adOpenStatic, adLockReadOnly
Response.Write( rs(0) )
rs.Close
set rs = nothing
Response.end

并且使用 ADODB 准备好的语句会导致正常执行。

 Dim cmd
 Set cmd = Server.CreateObject("ADODB.Command")
 With cmd
    .ActiveConnection = cn
    .CommandType = adCmdStoredProc
    .CommandText = "StoredProcedureName"
    .CommandTimeout = 0
End With

我错过了什么让我整天发疯?大多数 API 使用不太安全的字符串方法(我知道 SQL 注入等),因为我们没有分配时间来重构准备好的语句。但是,所有新代码都是用准备好的语句编写的。

更新

SQL Native Client 11 中似乎有些不同。从 SQL 2008 R3 获取版本 10,它不再进行双重调用。 Provider=SQLNCLI10

我想在这一点上,我可以继续使用版本 sqlncli 10,但我很想知道 sqlncli 11 发生了什么......

【问题讨论】:

  • 如果忘记在问题代码片段中创建 rs 对象:set rs = server.CreateObject("ADODB.Recordset")
  • 感谢@JoshMontgomery,我们已将范围缩小到RS.Open 创建第二个电话。使用set RS = cn.Execute(SQL) 不会导致同样的问题

标签: sql-server asp-classic iis-10


【解决方案1】:

因为你不是直接更新记录集对象,所以不要使用

RS.Open SQL, cn, adOpenStatic, adLockReadOnly

而是

设置 RS = cn.Execute( sql )

过去我在使用 RS.Open 时遇到过奇怪的问题,并且仅当我想直接在记录集中修改数据时才使用它们,这对我来说并不常见。

【讨论】:

  • 感谢您的建议。它没有帮助,但这是一个好主意。我确实在我们的新开发代码中使用了set RS = Stmt.Execute()
  • 实际上,我收回了这一点...我创建了第二个站点并在错误的站点上测试了该更改 - 这样就阻止了第二次跟踪的发生...进展!下一个问题是为什么RS.Open 会导致第二次调用 sql 而cn.execute 不会?由于一台测试服务器,我无法更改 60k + 行代码。
  • 我猜这是一个游标相关的问题,试试 RS.Open SQL, cn, 3,, 1,如果这不起作用报告回来,我会看到(或其他人)可以来尝试其他东西
  • 基于生产环境可以正常使用代码,我开始了解生产环境和这个测试环境之间的不同之处。将其缩小到 SQLNCLI 驱动程序,我尝试了 SQL 2008r3 的版本 10,它现在可以正常工作。根据我们的常量库,adOpenStatic 为 3,adLockReadOnly 为 1。我看到将 int 直接放入其中的唯一一件事是它删除了常量包含文件。为了完整起见,我将这些常量输出到响应中,它们仍然分别报告为 3 和 1。
  • 感谢您的帮助...我只是希望我知道为什么 SQLNCLI11 的工作方式与 SQLNCLI10 不同。还没有找到很多文献……每个的痕迹看起来也完全不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-28
  • 2020-08-24
  • 1970-01-01
  • 2014-05-31
  • 1970-01-01
  • 2013-12-19
  • 1970-01-01
相关资源
最近更新 更多