我正在使用经典的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)
答案 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