简体   繁体   English

在Classic ASP中将SQL导出到Excel的更快捷方式?

[英]Quicker way to export SQL to Excel in Classic ASP?

A view that takes 1 second in SQL Server Studio for over 13000 rows times out on an ASP page running this code after around 2380 rows. 在大约2380行之后运行此代码的ASP页上,在SQL Server Studio中花费1秒钟超过13000行的视图超时。

Is there a better way to do this? 有一个更好的方法吗? I've been searching for 6 months with no luck. 我一直在寻找6个月没有运气。

Server.ScriptTimeout=200
    dim updateNBK
    updateNBK = UCase(request.QueryString("SelTABLE"))

    dim allstring
    allstring = UCase(Request.QueryString("SelTABLE")) & " " & UCase(Request.QueryString("SelNBK"))


    allstring = LCase(allstring)
    dim checkforinject
    If(InStr(allstring, "'")<>0)then
        checkforinject = true
    Elseif(InStr(allstring, "--")<>0)then
        checkforinject = true
    End If

    If (checkforinject = true) then
        Response.Write("<b>Injection Detected</b><br/> You may not enter the following characters: ' or --")
    Elseif (checkforinject = false) then

    dim strSQL


        if(Request.QueryString("submitbutton") = "Download") then

        strSQL = "select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS  where TABLE_NAME = '" & UCase(request.QueryString("SelTABLE")) & "'"


        On Error Resume Next
        set arn = cnt.execute(strSQL)   

        dim datastr
        dim datahead
        datahead = "<table class='bluetable'><thead><tr><td colspan='30'>" & UCase(request.QueryString("SelTABLE")) & " contents</td></tr></thead>"
        dim columns
        colums = 0
        datastr = datastr & "<tbody class='datasheet'><tr class='selectblue'>"
        if not arn.EOF then
                    arn.movefirst

                    do
                        On Error Resume Next
                        datastr = datastr & "<td>" & arn(0) & "</td>"
                        columns = columns + 1
                        arn.movenext
                    loop until arn.EOF
                end if
        datastr = datastr & "</tr>"

        strSQL = "Select * from " & UCase(request.QueryString("SelTABLE"))

        if(UCase(Request.QueryString("SelNBK")) <> "") then

        strSQL = strSQL & " where SubmitterNBK = '" & UCase(Request.QueryString("SelNBK")) & "'"

        end if

        set arn = cnt.execute("Select TimestampColumnName from FormsInfo where FormOutput='" & UCase(request.QueryString("SelTABLE")) & "'")

        strSQL = strSQL & " ORDER BY " & arn(0) & " desc;"

        Response.Write "Test1"

        On Error Resume Next
        set arn = cnt.execute(strSQL)   
        dim counter
        counter = 0
        if not arn.EOF then
                    arn.movefirst
                    Response.Write "Test2"
                    dim cellnum
                    do
                    datastr = datastr & "<tr>"
                        On Error Resume Next
                        cellnum = 0
                        'datastr = datastr & "<td>" & arn.value.toString() & "</td>"
                        do
                        datastr = datastr & "<td>" & arn(cellnum) & "</td>"
                        cellnum = cellnum + 1
                        loop while cellnum < columns
                        arn.movenext
                        'Response.Write "TestLoop"
                        Response.Write "<br/>Loop ran " & counter & " times." 
                        counter = counter + 1
                    datastr = datastr & "</tr>"
                    loop until arn.EOF
                    Response.Write "<br/>Loop ended." 
        end if


        datahead = "<table class='bluetable'>"

        Response.Clear  

        Response.ContentType = "application/vnd.ms-excel" ' arbitrary 

        Response.AddHeader "Content-Disposition","attachment; filename=" & UCase(request.QueryString("SelTABLE")) & ".xls"

        Set adoStream = CreateObject("ADODB.Connection") 
        adoStream.Open() 
        adoStream.Type = 2

        Response.Write datahead & datastr 
        Response.Flush

        adoStream.Close 
        Set adoStream = Nothing 
        Response.End

I suspect your problem lies in the fact that VBScript is horrible with string concatenation - which it appears you are doing a lot of. 我怀疑你的问题在于VBScript在字符串连接方面很糟糕 - 看起来你做的很多。

Although the .NET StringBuilder class is unavailable to VBScript, there are a couple of useful libraries/code samples available. 虽然.NET StringBuilder类对VBScript不可用,但是有一些有用的库/代码示例可供使用。 One example is here: http://www.eggheadcafe.com/articles/20011227.asp 一个例子是: http//www.eggheadcafe.com/articles/20011227.asp

It may take a little rework of your code, but I bet the performance will drastically improve. 可能需要对代码进行一些修改,但我敢打赌,性能会大幅提升。

Here is an example using the code from the link above. 以下是使用上面链接中的代码的示例。 Note that you will probably want to place the FastString class in an include file so you can reuse it elsewhere. 请注意,您可能希望将FastString类放在包含文件中,以便可以在其他地方重用它。

Dim test : Set test = new FastString
Dim I
For I = 0 To 1000
  test.Append("TESTING")
Next
Response.Write test.Concat

Code from the link above: 上面链接中的代码:

Class FastString
  Dim stringArray, growthRate, numItems
  Private Sub Class_Initialize()
    growthRate = 50: numItems = 0
    ReDim stringArray(growthRate)
  End Sub
  Public Sub Append(ByVal strValue)
    ' next line prevents type mismatch error if strValue is null. Performance hit is negligible.
    strValue=strValue & ""
    If numItems > UBound(stringArray) Then ReDim Preserve stringArray(UBound(stringArray) + growthRate)
    stringArray(numItems) = strValue: numItems = numItems + 1
  End Sub
  Public Sub Reset
    Erase stringArray
    Class_Initialize
  End Sub
  Public Function Concat()
    Redim Preserve stringArray(numItems)
    concat = Join(stringArray, "")
  End Function
End Class

Alternate solution: 替代解决方案:

If you don't mind not having styled cells, you can leverage the "GetRows" functionality of the ADO recordset. 如果您不介意没有样式化单元格,则可以利用ADO记录集的“GetRows”功能。 This little used solution is quite useful in this situation: 在这种情况下,这个小用的解决方案非常有用:

Dim tableRows : tableRows = arn.GetString(,,"</td><td>","</td></tr><tr><td>","&nbsp;")
Response.Write "<table class='bluetable'>" & tableRows & "</table>"

So, then, your output becomes: 那么,您的输出变为:

Set arn = cnt.Execute(strSQL)   
Response.Clear  
Response.ContentType = "application/vnd.ms-excel"
Response.AddHeader "Content-Disposition","attachment; filename=" & UCase(request.QueryString("SelTABLE")) & ".xls"
Dim tableRows : tableRows = arn.GetString(,,"</td><td>","</td></tr><tr><td>","&nbsp;")
Response.Write "<table class='bluetable'>" & tableRows & "</table>"

I suspect the string building it what is making it so slow. 我怀疑构建它的字符串是什么让它变得如此之慢。 VBScript is terrible at this. VBScript在这方面很糟糕。

I used to use a class called clsString to do this kind of work. 我曾经使用一个名为clsString的类来完成这种工作。

I think this is it: http://pcdispatchwiki.com/Intranet/includes/funcsSubsClasses.asp 我想是这样的: http//pcdispatchwiki.com/Intranet/includes/funcsSubsClasses.asp

From memory: 从记忆里:

dim tmpStr : set tmpStr = new clsString
tmpStr.add "Hello"
tmpStr.add vbCRLF
tmpStr.add "World"
dim finalText : finalText = tmpStr.Value

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM