SQL存储过程是经典ASP导致w3wp exe到mac

时间:2014-02-07 19:08:51

标签: sql iis vbscript asp-classic

我正在使用经典的ASP,vbscript和SQL Server数据库。我正在对几个站点进行更改,而不是在服务器和数据库之间来回进行多次调用,我们在数据库服务器上的存储过程中执行所有处理。在最后一个客户站点上我尝试了这个,当页面加载时,w3wk.exe(IIS工作者)进程将CPU最大化为100%,然后坐下。除了完整的IISReset之外,什么都不释放CPU。在存储的proc调用之前有一个SQL调用。如果我直接在SQL Analyzer中的数据库服务器上运行存储过程,它将在大约4秒后返回。 IIS日志中没有任何内容。在我推出的其他十几个网站上,我还没有看到这种行为。关于我应该检查什么的任何想法?我完全失去了。这是代码:

Set DBObj = Server.CreateObject("ADODB.Connection")
DBObj.Open(Session("SiteDSN")) 

l_sql = "select count(*) l_count " _
  & " from account_list " _
  & " where email in ('B','Y') " _
  & "   and email_address is not null "

set rs = DBObj.execute(l_sql)
'*** That one works

l_total_count = rs("l_count")

l_sql = "exec stored_proc"

if request("filter1") <> "" then
  l_param1 = request("filter1")
  l_sql = l_sql & " '"& l_param1 & "',"
else
  l_sql = l_sql & " '',"
end if


if request("filter3") <> "" then
 l_param3 = request("filter3")
 l_sql = l_sql & " '"& l_param3 & "',"
else
 l_sql = l_sql & " '',"
end if

'*** The l_sql string is "exec stored_proc '','','' on the first load"

set rs = DBObj.execute(l_sql)

3 个答案:

答案 0 :(得分:0)

内存耗尽过多的原因有很多。在经典的ASP中,它总是更清晰地为记录集和连接对象配置额外的参数,例如超时以防止查询永远运行(例如,如果存储过程被无限循环捕获)。完成后,您还应该关闭然后 DESTROY 每个对象。

IIS应该自动执行此操作,但现实表明情况并非总是这样。自己销毁对象可以确保它确实完成。

这是一个典型的示例代码,它打开一个断开连接的Recordset,只读取所有记录,然后关闭并销毁所有对象。

Const adOpenStatic = 3, adUseClient = 3

Set rs = Server.CreateObject("ADODB.RecordSet")
rs.cursorlocation = adUseClient 
Set DBObj = Server.CreateObject("ADODB.Connection")

'Setting Timeouts in Seconds
DBObj.ConnectionTimeout = 1000
DBObj.CommandTimeout = 1000
DBObj.Open Session("SiteDSN")
rs.open l_sql, DBObj, adOpenStatic
If Not rs.EOF Then
  Set rs.ActiveConnection = Nothing
  While Not rs.EOF

  .. processing data ...

    rs.MoveNext
  End While
End If
'Cleaning Up and Releasing Resources    
rs.Close : Set rs = Nothing
DBObj.Close : Set DBObj = Nothing

答案 1 :(得分:-1)

感谢所有建议。我会“提升”答案的用处,因为我在这个网站上没有足够的声誉来这样做。

最终,我使用了一个我知道正在工作的页面版本,删除了特定于站点的自定义,并为不能正常工作的站点添加了特定于站点的代码。我将过滤器检查一起移动,然后构建整个查询。这有点原因。我唯一的解释是它是由一些微妙的小脚本错误引起的 - 一个额外的空间,或一个通过所有语法检查但打破了实际数据库调用的特殊字符。和往常一样,使用脚本语言,有时候重写那些糟糕的东西可以解决问题。

答案 2 :(得分:-1)

以下是可以使用的相同示例函数,应该可以正常工作。该代码在具有5个以上Web服务器和同一站点上数千个并发用户的Web群集上进行了测试。

'---- LockTypeEnum Values ----
Const adLockReadOnly = 1
Const adLockPessimistic = 2
Const adLockOptimistic = 3
Const adLockBatchOptimistic = 4
'---- ExecuteOptionEnum Values ----
Const adAsyncExecute = &H00000010
Const adAsyncFetch = &H00000020
Const adAsyncFetchNonBlocking = &H00000040
Const adExecuteNoRecords = &H00000080
Const adExecuteStream = &H00000400
'---- CursorLocationEnum Values ----
Const adUseServer = 2
Const adUseClient = 3
'---- CursorTypeEnum Values ----
Const adOpenForwardOnly = 0
Const adOpenKeyset = 1
Const adOpenDynamic = 2
Const adOpenStatic = 3
'---- CommandTypeEnum Values ----
Const adCmdUnknown = &H0008
Const adCmdText = &H0001
Const adCmdTable = &H0002
Const adCmdStoredProc = &H0004
Const adCmdFile = &H0100
Const adCmdTableDirect = &H0200

Dim HostileAttemptString(5)
    HostileAttemptString(0) = "EXEC(@"
    HostileAttemptString(1) = "exec(@" 
    HostileAttemptString(2) = "and%201=" 
    HostileAttemptString(3) = "and%20char(" 
    HostileAttemptString(4) = "exec%28@" 
    HostileAttemptString(5) = "EXEC%28@"

Dim gsDSNString
gsDSNString = "SQL CONNECTION STRING"

'********************************************************************
'* Function: ExecSprocWithOutputParam
'* Objective: Executes stored procedure with variable amount of parameters
'   and no recordset. In addition, sproc must return one and only one output parameter
'* Input: strConnString - database connection string
'   varParamArray - Variant containing array of parameters to pass to sproc
'       Must be in exact order that sproc needs them starting from zero (0)
'   strSprocName - name of stored procedure
'* Output: Variant (output parameter value)
'********************************************************************
Function ExecSprocWithOutputParam(ByVal varParamArray, ByVal strSprocName) 'as variant
    Dim objCmd 'as object
    Dim objConn 'as object
    Dim intCounter 'as integer
    Dim intOutputIndex 'as integer

    intOutputIndex = 0
    Set objCmd = Server.CreateObject("ADODB.Command")
    Set objConn = Server.CreateObject("ADODB.Connection")
    objConn.Open gsDSNString

    With objCmd
        Set .ActiveConnection = objConn
        .CommandType = adCmdStoredProc
        .CommandText = strSprocName

        'Get parameter info from database - need to do this to allow output parameter
        .Parameters.Refresh

        'Start parameters at 1 since 0 is return value which we're not using
        For intCounter = 0 To UBound(varParamArray)
            .Parameters(intCounter + 1).Value = varParamArray(intCounter)

            'Add 2 to get output parameter index because array started at zero and parameters started at 1,
            'and this parameter is in addition to the paramater array passed in
            intOutputIndex = intCounter + 2
        Next

        .Execute , , adExecuteNoRecords

        'Return single output parameter
        'ExecSprocWithOutputParam = .Parameters(intOutputIndex).Value
        ExecSprocWithOutputParam = .Parameters(0).Value
        Set .ActiveConnection = Nothing
    End With

    'Clean up
    objConn.Close
    Set objConn = Nothing
    Set objCmd = Nothing
End Function

'********************************************************************
'* Function: ExecSprocWithParams
'* Objective: Executes stored procedure with variable amount of parameters
'   and no recordset.
'* Input:
'       varParamArray - Variant containing array of parameters to pass to sproc
'           Must be in exact order that sproc needs them starting from zero (0)
'       strSprocName - name of stored procedure
'* Output: None
'********************************************************************
Sub ExecSprocWithParams(ByVal varParamArray, ByVal strSprocName) 'as variant
    Dim objCmd 'as object
    Dim objConn 'as object
    Dim intCounter 'as integer
    Dim intOutputIndex 'as integer

    Set objCmd = Server.CreateObject("ADODB.Command")
    Set objConn = Server.CreateObject("ADODB.Connection")

    objConn.Open gsDSNString

    With objCmd
        Set .ActiveConnection = objConn
        .CommandType = adCmdStoredProc
        .CommandText = strSprocName

        'Get parameter info from database - need to do this to allow output parameter
        .Parameters.Refresh

        'Start parameters at 1 since 0 is return value which we're not using
        For intCounter = 0 To UBound(varParamArray)
            .Parameters(intCounter + 1).Value = SQLScrub(varParamArray(intCounter))
        Next

        .Execute , , adExecuteNoRecords

        Set .ActiveConnection = Nothing
    End With

    'Clean up
    objConn.Close
    Set objConn = Nothing
    Set objCmd = Nothing
End Sub

'********************************************************************
'* Function: ExecSprocWithReturnValue
'* Objective: Executes stored procedure with variable amount of parameters
'   and no recordset. Returns return value parameter from sproc.
'* Input: 
'   varParamArray - Variant containing array of parameters to pass to sproc
'       Must be in exact order that sproc needs them starting from zero (0)
'   strSprocName - name of stored procedure
'* Output: int (return value of parameter value)
'********************************************************************
Function ExecSprocWithReturnValue(ByVal varParamArray, ByVal strSprocName) 'as variant
    Dim objCmd 'as object
    Dim objConn 'as object

    Dim intCounter 'as integer
    Dim intOutputIndex 'as integer

    Set objCmd = Server.CreateObject("ADODB.Command")
    Set objConn = Server.CreateObject("ADODB.Connection")

    objConn.Open gsDSNString

    With objCmd
        Set .ActiveConnection = objConn
        .CommandType = adCmdStoredProc
        .CommandText = strSprocName

        'Get parameter info from database - need to do this to allow output parameter
        .Parameters.Refresh

        'Start parameters at 1 since 0 is return value which we're not using
        For intCounter = 0 To UBound(varParamArray)
            .Parameters(intCounter + 1).Value = varParamArray(intCounter)

            'Add 2 to get output parameter index because array started at zero and parameters started at 1,
            'and this parameter is in addition to the paramater array passed in
            'intOutputIndex = intCounter + 2
        Next

        .Execute , , adExecuteNoRecords

        'Return sproc return value
        ExecSprocWithReturnValue = .Parameters("@RETURN_VALUE").Value

        Set .ActiveConnection = Nothing
    End With

    'Clean up
    objConn.Close
    Set objConn = Nothing
    Set objCmd = Nothing
End Function

'********************************************************************
'* Function: ExecSprocGetOutputParam
'* Objective: Executes stored procedure with variable amount of parameters
' and no recordset. In addition, sproc must return one and only one output parameter
'* Input: strConnString - database connection string
' varParamArray - Variant containing array of parameters to pass to sproc
'  Must be in exact order that sproc needs them starting from zero (0)
' strSprocName - name of stored procedure
'* Output: Variant (output parameter value)
'********************************************************************
Function ExecSprocGetOutputParam(ByVal strSprocName, ByVal varParamArray) 'as variant
 Dim objCmd 'as object
 Dim objConn 'as object
 Dim intCounter 'as integer
 Dim intOutputIndex 'as integer

 Set objCmd = Server.CreateObject("ADODB.Command")
 Set objConn = Server.CreateObject("ADODB.Connection")

 objConn.Open gsDSNString

 With objCmd
     Set .ActiveConnection = objConn
     .CommandType = adCmdStoredProc
     .CommandText = strSprocName

  'Get parameter info from database - need to do this to allow output parameter
  .Parameters.Refresh

  'Start parameters at 1 since 0 is return value which we're not using
  For intCounter = 0 To UBound(varParamArray)
   .Parameters(intCounter + 1).Value = varParamArray(intCounter)

   'Add 2 to get output parameter index because array started at zero and parameters started at 1,
   'and this parameter is in addition to the paramater array passed in
   intOutputIndex = intCounter + 2
  Next

  .Execute , , adExecuteNoRecords

  'Return single output parameter
  ExecSprocGetOutputParam = .Parameters(intOutputIndex).Value

  Set .ActiveConnection = Nothing
 End With

 'Clean up
 objConn.Close
 Set objConn = Nothing
 Set objCmd = Nothing
End Function



'********************************************************************
'* Function: RSFromSproc
'* Objective: Returns recordset from call to stored procedure that takes any amount of parameters
'* Input: strConnString - database connection string
'   varParamArray - Variant containing array of parameters to pass to sproc
'       Must be in exact order that sproc needs them starting from zero (0)
'       Leave parameter blank if there are no parameters in sproc
'   strSprocName - name of stored procedure to use
'* Output: ADO Recordset
'********************************************************************
Function RSFromSproc(ByVal varParamArray, ByVal strSprocName) 'as object
    Dim objCmd 'as object
    Dim objConn 'as object
    Dim objRS 'as object

    Set objCmd = Server.CreateObject("ADODB.Command")
    Set objConn = Server.CreateObject("ADODB.Connection")
    Set objRS = Server.CreateObject("ADODB.Recordset")

    objConn.Open gsDSNString

    With objCmd
        Set .ActiveConnection = objConn
        .CommandType = adCmdStoredProc
        .CommandText = strSprocName

        objRS.CursorLocation = adUseClient
        objRS.CursorType = adOpenForwardOnly
        objRS.LockType = adLockReadOnly

        'Not using Set objRS so recordcount/absolute page properties will work.
        .Execute , varParamArray
        objRS.Open objCmd

        Set .ActiveConnection = Nothing
    End With

    Set RSFromSproc = objRS

    'Clean up
    Set objRS = Nothing
    Set objConn = Nothing
    Set objCmd = Nothing
End Function
'----------------- Support Functions -------------------------------
Function SQLScrub(ByVal val)
   Dim str,rtnVal
   rtnVal = val
   rtnVal = Replace(val,"'","''")

   For Each str in HostileAttemptString
    rtnVal = Replace(rtnVal,str,"")
   Next

   SQLScrub = rtnVal 
 End Function