Public Function ExecuteReader(ByVal behavior As Microsoft.ReportingServices.DataProcessing.CommandBehavior) As Microsoft.ReportingServices.DataProcessing.IDataReader Implements Microsoft.ReportingServices.DataProcessing.IDbCommand.ExecuteReader Try 'This function is the heart of our custom implementation. GetEstimatedCostAndRows(Me.CommandText) 'Does the total Cost exceed the Max Cost or Estimated Rows? If m_MaxEstimatedCost > 0 Then If m_SubmittedEstimatedCost > m_MaxEstimatedCost Then Throw New Exception("This query exceeds the Maximum Cost Value") End If End If If m_MaxEstimatedRows > 0 Then If m_SubmittedEstimatedRows > m_MaxEstimatedRows Then Throw New Exception("This query exceeds the Maximum Estimated Row Value") End If End If Return m_innerDBComm.ExecuteReader(behavior) Catch ex As Exception Throw ex End Try End Function …. ‘ Begin Callout A Private Sub GetEstimatedCostAndRows(ByVal sCommandText As String) Try Dim oSQLDR As IDataReader = Nothing m_SubmittedEstimatedRows = 0 m_SubmittedEstimatedCost = 0 'Set Showplan_xml on m_innerDBCommCostEstimate.CommandType = Microsoft.ReportingServices.DataProcessing.CommandType.Text m_innerDBCommCostEstimate.CommandText = "set showplan_xml on" oSQLDR = m_innerDBCommCostEstimate.ExecuteReader(CommandBehavior.SingleResult) oSQLDR.Dispose() 'Build the Query that is going to be executed. We need to account for Parameters - which we ' will do so by declaring them as Variants Dim sCommandTextParams As String = String.Empty If Not m_innerDBComm.Parameters Is Nothing Then For Each oIDParam As IDataParameter In m_innerDBComm.Parameters sCommandTextParams = sCommandTextParams & "DECLARE " & oIDParam.ParameterName & " SQL_VARIANT; " Next End If m_innerDBCommCostEstimate.CommandText = sCommandTextParams & sCommandText Dim sXMLPlan As String = String.Empty oSQLDR = m_innerDBCommCostEstimate.ExecuteReader(CommandBehavior.SingleResult) While oSQLDR.Read sXMLPlan = sXMLPlan & oSQLDR.GetValue(0).ToString End While oSQLDR.Dispose() m_innerDBCommCostEstimate.CommandText = "set showplan_xml off" oSQLDR = m_innerDBCommCostEstimate.ExecuteReader(CommandBehavior.SingleResult) 'Turns XML Showplan off oSQLDR.Dispose() Console.WriteLine(sXMLPlan) 'Parse the XML to get the Estimated Total Cost and Rows for the query Dim strReader As New StringReader(sXMLPlan) Dim xreader As New System.Xml.XmlTextReader(strReader) Dim doc As New XPathDocument(xreader, XmlSpace.Preserve) Dim navigator As System.Xml.XPath.XPathNavigator = doc.CreateNavigator() Dim nsmgr As New XmlNamespaceManager(navigator.NameTable) 'The exact namespace will depend on the showplan's version - we'll just grab it from ' the string representation of the sXMLPlan Dim sNameSpace As String = Me.GetXMLSchemaNamespace(sXMLPlan) nsmgr.AddNamespace("sql", sNameSpace) Dim xpression As XPathExpression = _ navigator.Compile("//sql:Batch/sql:Statements/sql:StmtSimple/@StatementSubTreeCost") xpression.SetContext(nsmgr) Dim iterator As XPathNodeIterator = navigator.Select(xpression) Dim val As String = String.Empty ' sum costs of all query plans in this batch While iterator.MoveNext m_SubmittedEstimatedCost = m_SubmittedEstimatedCost + CType(iterator.Current.Value, Single) End While 'Does the total Cost exceed the Max Cost If m_MaxEstimatedCost > 0 Then If m_SubmittedEstimatedCost > m_MaxEstimatedCost Then Return End If End If ' get estimated row count - StatementEstRows xpression = navigator.Compile("//sql:Batch/sql:Statements/sql:StmtSimple/@StatementEstRows") xpression.SetContext(nsmgr) iterator = navigator.Select(xpression) ' sum costs of all query plans in this batch While iterator.MoveNext m_SubmittedEstimatedRows = m_SubmittedEstimatedRows + CType(iterator.Current.Value, Integer) End While 'Does the estimated row count exceed the Max Row Count If m_MaxEstimatedRows > 0 Then If m_SubmittedEstimatedRows > m_MaxEstimatedRows Then Return End If End If Catch ex As Exception 'Some queries may not return showplan values 'e.g. - http://msdn2.microsoft.com/en-us/library/ms187886.aspx m_SubmittedEstimatedRows = 0 m_SubmittedEstimatedCost = 0 Finally m_innerDBCommCostEstimate.Dispose() End Try End Sub ‘ End Callout A 5