关于sql:在经典ASP中使用存储过程..执行并获取结果

Using Stored Procedure in Classical ASP .. execute and get results

我整天试图解决这个问题,但它似乎对我不起作用。我想执行一个命令并将结果返回到记录集。

问题是两件事之一:我得到的响应是空的,或者我的代码有问题。我知道该命令应该从数据库中获取几行。我在循环内添加了response.write,但是从不打印它们。

这是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SET conn = Server.CreateObject("ADODB.Connection")
conn.open"PROVIDER=SQLOLEDB;DATA SOURCE=X;DATABASE=Y;UID=Z;PWD=W;"
SET objCommandSec = CreateObject("ADODB.Command")
WITH objCommandSec
    SET .ActiveConnection = Conn
    .CommandType = 4
    .CommandText ="usp_Targets_DataEntry_Display"
    .Parameters.Append .CreateParameter("@userinumber", 200, 1, 10, inumber)
    .Parameters.Append .CreateParameter("@group", 200, 1, 50,"ISM")
    .Parameters.Append .CreateParameter("@groupvalue", 200, 1, 50, ismID)
    .Parameters.Append .CreateParameter("@targettypeparam", 200, 1, 50, targetType)
END WITH
   
SET rs = Server.CreateObject("ADODB.RecordSet")
rs = objCommandSec.Execute

while NOT rs.eof
    response.write (1)
    response.write (rs("1_Q1"))
    rs.MoveNext
wend
response.write (2)

已编辑
修改代码后,按照@Joel Coehoorn的回答,解决方案是:

1
2
SET rs = Server.CreateObject("ADODB.RecordSet")
rs.oppen objCommandSec

而不是...

1
2
SET rs = Server.CreateObject("ADODB.RecordSet")
rs = objCommandSec.Execute


使用asp-classic多年后的技巧

  • 无需创建ADODB.Connection,您可以将连接字符串直接传递给ADODB.Command对象的.ActiveConnection属性。这有两个好处,您无需实例化并打开另一个对象,并且由于上下文与ADODB.Command绑定,因此它将与Set objCommandSec = Nothing一起释放。
  • .Execute返回关闭的记录集的常见原因是未在SQL存储过程中设置SET NOCOUNT ON,因为INSERTUPDATE会生成记录影响计数和关闭的记录集。设置SET NOCOUNT ON将停止这些输出,并且仅返回您期望的记录集。
  • 使用ADODB.Recordset循环浏览数据是多余的,除非您需要前后移动并支持标准功能(例如在屏幕上显示记录集)不需要的一些较少使用的方法。而是尝试使用Array

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    Dim conn_string, ROW, ROWS, ary_data

    conn_string ="PROVIDER=SQLOLEDB;DATA SOURCE=X;DATABASE=Y;UID=Z;PWD=W;"

    SET objCommandSec = CreateObject("ADODB.Command")
    WITH objCommandSec
      .ActiveConnection = conn_string
      .CommandType = 4
      .CommandText ="usp_Targets_DataEntry_Display"
      .Parameters.Append .CreateParameter("@userinumber", 200, 1, 10, inumber)
      .Parameters.Append .CreateParameter("@group", 200, 1, 50,"ISM")
      .Parameters.Append .CreateParameter("@groupvalue", 200, 1, 50, ismID)
      .Parameters.Append .CreateParameter("@targettypeparam", 200, 1, 50, targetType)

      SET rs = .Execute()
      IF NOT rs.EOF THEN ary_data = rs.GetRows()
      CALL rs.Close()
      SET rs = Nothing
    END WITH
    SET objCommandSec = Nothing

    'Command and Recordset no longer needed as ary_data contains our data.
    If IsArray(ary_data) Then
      '
    Iterate through array
      ROWS = UBound(ary_data, 2)
      FOR ROW = 0 TO ROWS
        ' Return our row data
        '
    ROW N COLUMN 2 (INDEX starts FROM 0)
        CALL Response.Write(ary_data(1, ROW) &"")
      NEXT
    ELSE
      ' Nothing returned
      Call Response.Write("No data returned")
    End If

  • 看了几分钟,距离我使用经典的asp已经很长时间了,但是我确实看到了三件事:

  • 调用objCommandSec.Execute之前是否需要Open连接?
  • 您是否可以尝试在循环内写出完全不依赖于记录集的字符串文字……只是您实际上在循环遍历代码,因此请查看记录是否返回记录集。
  • 您是否检查了html源,看是否格式错误的html隐藏了您的结果?我记得这种情况在经典的asp循环中的表中发生过几次,在这种情况下,数据将以某种方式隐藏在两行之间,或者在错误的位置关闭表标记将终止表,而以后的行将不可见。

  • 尽管这可能无法直接回答OP的问题,但可能会帮助其他人寻找解决方案。

    最近,我进行了一项维护工作,该工作需要我修改正在运行的ASP经典代码中的某些内容(我已经很长时间没有写过了)。过程调用的编写方式与OP的编写方式相同,而这与我过去的操作方式不同。

    这是我过去使用的语法,我认为它比这里提供的其他解决方案更简洁。

    以下代码显示如何读取输出参数,如何将参数传递给存储过程,将空值传递给参数,读取记录计数以及在RecordSet中进行迭代。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    dim conn, cmd, rs

    SET conn = Server.CreateObject("ADODB.Connection")
    conn.Open"Driver={SQL Server};Server=servername;Uid=username;Pwd=password;Database=dbname;"

    SET cmd = Server.CreateObject("ADODB.Command")
    cmd.ActiveConnection = conn
    cmd.CommandType = adCmdStoredProc
    cmd.CommandText ="procedurename"
    cmd.Parameters.Refresh
    cmd.Parameters("@nullparam") = NULL
    cmd.Parameters("@strparam") ="1"
    cmd.Parameters("@numparam") = 100

    SET rs = Server.CreateObject ("ADODB.RecordSet")
    rs.CursorLocation = adUseClient ' to read recordcount'

    rs.open cmd, , adOpenStatic, adLockReadOnly

    Response.Write"Return Value:" & cmd.Parameters("@RETURN_VALUE") &"<br />"
    Response.Write"Record count:" & rs.RecordCount &"<br />"
    while NOT rs.EOF
        ' or do whatever you like with data'
        Response.Write rs("colname") &""
        rs.MoveNext
    wend