在Session变量

时间:2015-12-14 16:21:16

标签: session memory asp-classic ado recordset

这是我在这里提出的问题的后续> Converting an HTML table to JSON to pass to an AJAX call for downloading as a CSV

我有一个报告页面,可以输出多个记录集作为图形和表格,还有按钮,可以下载为CSV文件"我有一个通用函数,它将接受任意数量的记录集(因为存储过程返回多个记录集)并输出一个CSV,这样很好。

问题是我想将存储过程的输出设置为Session(" DATA")变量,然后创建一个" copy"内存中的数据,以便每当"下载"按下按钮我可以查找一个Session(" DATA")变量并输出它(如果存在)。

问题在于,当我将记录集对象设置为指向Session时,它是参考的,这样一旦它遍历了在页面上输出它们的所有记录集,那么Session就会为空(或者在所有记录集的末尾) - 所以它是一个没有数据的对象)

如何创建"副本"记录集而不是指针,以便Session始终具有完整的记录集,例如

Set Session("DATA") = objCon.Execute(strSQL) '* returns multiple recordsets

Set objRS = Session("DATA")

Do While Not objRS.EOF......

'* BUT now when I want to access Session("DATA") it is at the start of all the recordsets and not a spent, EOF of the last recordset due to me looping through objRS

我可以有一个循环遍历记录集并复制的函数但是这看起来像是很多努力和性能而且我认为必须有一种方法来复制会话的记录集,而不会多次循环它

如果我必须创建一个"复制"对象函数然后我想我将不得不但是在ASP CLASSIC中没有更简单的方法来创建对象的副本而不是引用指针?

1 个答案:

答案 0 :(得分:1)

您可以使用GetRows

将整个记录集读入数组
'GetDataSet
'   Returns a table of data based on the supplied SQL statement and connection string.
'Parameters:
'   sqlString (string) - The SQL string to be sent. This can be either a valid SQL string or an Application setting
'                           specified using the '@' prefix (e.g. @GET_USERNAME)
'   connString (string) - The database connection string. Either a valid connection string, an Application setting
'                           (using the '@' prefix, e.g. @CONN_STRING) or an AMC (AppModeConnection string).
'Usage:
'   dataSet = GetDataSet(sqlString, connString)
'Description:
'   This function generates a table of information in a 2 dimensional array.  The first dimension represents the columns
'   and the second the rows.  If an error occurs while the routine is executing the array and the base index (0,0) is set 
'   to C_ERROR, (0,1) to the VBScript error index, and (0,2) to the VBScript error description.
'Notes:
'   Updated this function to take advantage of the AppModeConnection feature.
'Revisions:
'   30/09/2015  1.1     Added facility to allow recovery of Application settings as Query and connection strings using 
'                       '@', (e.g.: ds = GetDataSet("@GET_USER_DETAIL", "@CONN_DATABASE")
'   25/09/2015  1.0     Added AMC support for Classic ASP. The system will test to see if there is a valid connection 
'                       string based on the current application mode and the connection string provided (e.g. if the 
'                       connection string is 'CONN_DATABASE' and the application mode is 'DEV' then the final connection
'                       string will be 'CONN_DATABASE_DEV'. A connection string should be present to cover this.
' < 25/09/2015  0.1     Bug ironed out that prevented closing of the database.
' < 25/09/2015  0.0     Initial version.
function GetDataSet(ByVal sqlString, ByVal connString)
    'Test to see if there's an application connection string first...
    If Left(connString, 1) = "@" Then
        connString = Application(Mid(connString, 2))
    Else
        Dim amc
        amc = AppModeConnection(connString)
        If amc <> "" then connString = amc
    End If
    'Test the SQL string to see if it's stored as an Application setting...
    If Left(sqlString, 1) = "@" Then sqlString = Application(Mid(sqlString, 2))
    'Define the initial output...
    dim rV, rs
    If  (Application("APP_MODE") =  Application("MODE_DEV")  And  Application("DEV_TRAP_ERRORS")) Or _
        (Application("APP_MODE") <> Application("MODE_DEV")) Then On Error Resume Next
        'Define and open the recordset object...
        set rs = Server.CreateObject("ADODB.RecordSet")
        rs.Open sqlString, connString, 0, 1, 1
        'Initialise an empty value for the containing array...
        redim rV(0,0)
        rV(0,0) = C_NO_DATA
        'Deal with any errors...
        if not rs.EOF and not rs.BOF then
            'Store the data...
            rV = rs.GetRows()
            'Tidy up...
            rs.close
            set rs = nothing
            select case err.number
                case 3021   'No data returned
                    'Do nothing as the initial value will still exist (C_NO_DATA)
                case 0      'No error
                    'Do nothing as data has been returned
                case else
                    redim rV(4,0)
                    rV(C_COL_IDENTIFIER,0) = C_ERROR
                    rV(C_COL_ERROR_ID,0) = err.number
                    rV(C_COL_ERROR_MESSAGE,0) = err.description
                    rV(C_COL_SQL,0) = sqlString
                    rV(C_COL_CONNECTION,0) = "Withheld"
            end select
        end if
    on error goto 0
    'Return the array...
    GetDataSet = rV
end function

这是我自己的深度版本,它使用连接字符串等做一些时髦的东西,所以随意使用它,但请注意,你必须设置连接字符串的处理等。在代码中,但是,核心要素 - GetRows,是您需要的。

您不需要设置任何会话变量,只需按照marekful's answer的相同页面处理所有会话变量即可。您可以使用数组使用简单的For...Next循环来完成此操作。

要使用上述函数,只需声明您的SQL并将其调用为......

Dim ds, sql
sql = "EXEC prc_get_report_data "
ds = GetDataSet(sql, "@my_conn")

(注意:阅读有关连接字符串的代码注释)。

从此返回的数组显然是基于二维零,其中x =列,y =行:​​

ds(x, y)

我倾向于定义常量来覆盖列名,将它们与数据库中的等价物相匹配......

Const COL_ID = 0 'Column 0 is the ID field (note zero based)
Const COL_TITLE = 1 'Title field
Const COL_DESCRIPTION = 2 'Description field

......等等。

然后你可以很好地引用它们:

If ds(COL_ID, row) = 14 Then

使用UBound函数获取数组的范围...

Dim row, rows
For rows = 0 To UBound(ds, 2) '2 is the second dimension of the array (note not zero based
    If ds(COL_ID, row) = avalue Then

你明白了。