VBA / SQL Server:查询超时已过期

时间:2015-03-04 09:29:57

标签: sql-server vba timeout

我一直试图将这个问题调试好几个小时。在VBA中执行SQL Server存储过程时,出现以下错误:运行时错误' -2147217871'查询超时已过期。重要的是要记住它已经工作了几个星期,直到两天前没有问题。

我已经尝试在命令级别更改VBA代码中的timeout参数但没有成功。存储过程在大约12秒内在SQL Server中执行得很好。

我的vba代码如下:

Sub perfAttrib()

' Variables
Dim con As New ADODB.Connection
Dim rs As ADODB.Recordset
Dim cmd As ADODB.Command
Dim qryPos, qryAst As String
con.ConnectionTimeout = 0
Application.ScreenUpdating = False

shtPerf.Columns("A:T").ClearContents

' Select date

con.Open "Provider=SQLOLEDB;Data Source=DOM-SRV02;Initial Catalog=dbPam;Integrated Security=SSPI;"

' ===================================== Get positions ==========================================

' Set up the connection
Set rs = New ADODB.Recordset
Set cmd = New ADODB.Command

cmd.ActiveConnection = con
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "dbo.prcPnL"
Dim clientPort As String
Dim portfolioNb As String

cmd.Parameters.Refresh
cmd.Parameters(1).Value = shtPerfAttrib.Range("cPerfAttribCcy").Text
cmd.Parameters(2).Value = shtPerfAttrib.Range("cPerfAttribStartDate").Text
cmd.Parameters(3).Value = shtPerfAttrib.Range("cPerfAttribEndDate").Text

clientPort = shtPerfAttrib.Range("cPerfPortfolio").Text

portfolioNb = VBA.Right(clientPort, 16)

cmd.Parameters(4).Value = portfolioNb

Set rs = cmd.Execute

If rs.EOF And rs.BOF Then
    MsgBox ("The position query did not return any results.")
    Exit Sub
End If

shtPerf.Activate

' Add headers in the sheet
For i = 0 To rs.Fields.Count - 1
    shtPerf.Cells(2, i + 1) = rs.Fields(i).Name
Next

shtPerf.Cells(3, 1).CopyFromRecordset rs

shtPerfAttrib.Activate

Application.OnTime Now + TimeValue("00:00:03"), "refreshPivot"


End Sub

我的程序非常复杂,看起来像这样:

USE [dbPam]
GO
/****** Object:  StoredProcedure [dbo].[prcPnL]    Script Date: 3/4/2015 9:50:50 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[prcPnL] 
    -- Add the parameters for the stored procedure here
    @ccy nvarchar(3),
    @startDate nvarchar(50) ,
    @endDate nvarchar(50),
    @portfolio nvarchar(100) 

--  <@Param1, sysname, @p1> <Datatype_For_Param1, , int> = <Default_Value_For_Param1, , 0>, 
--  <@Param2, sysname, @p2> <Datatype_For_Param2, , int> = <Default_Value_For_Param2, , 0>
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    --SELECT <@Param1, sysname, @p1>, <@Param2, sysname, @p2>


            SELECT subQuery.colCodeClient, @ccy as perfCcy, subQuery.colBankRelNb, subQuery.bankRelCcy,  subQuery.colPortfolioNb, subQuery. portCcy, subQuery.colDepNb, subQuery.depCcy, subQuery.colId, subQuery.colName,subQuery.colTickerBB, subQuery.colISIN, subQuery.colAssetClass, subQuery.instrCcy  , startDate,  endDate, (tblDatPos.colLots ) as [finalLots], posPrev.colMktPrice as [begPrice] , tblDatPos.colMktPrice as [finaltMktPrice], PnL
        FROM 
        (SELECT tblDefBankRel.colCodeClient, tblDefBankRel.colBankRelNb ,tblDefBankRel.colCcy as bankRelCcy, tblDefPortfolio.colPortfolioNb,tblDefPortfolio.colCcy as portCcy,  TabPrev.colDepNb, tblDefDep.colCcy as depCcy, TabPrev.colId, tblDefSecu.colName, tblDefSecu.colTickerBB, tblDefSecu.colISIN, tblDefSecu.colAssetClass, tblDefSecu.colCcy as instrCcy, min(TabPrev.PrevDate) as startDate, max(TabPrev.colDate) as endDate, sum((TabPrev.colMktPrice-dbPam.dbo.tblDatPos.colMktPrice)*tblDatPos.colLots) AS [locPnL] , sum((TabPrev.colMktPrice*currFX.colValue-dbPam.dbo.tblDatPos.colMktPrice*prevFX.colValue)*tblDatPos.colLots) AS [PnL] 
        FROM (SELECT dbPam.dbo.tblDatPos.colDepNb, dbPam.dbo.tblDatPos.colId, dbPam.dbo.tblDatPos.colDate, Max(Tab_1.colDate) AS PrevDate, dbPam.dbo.tblDatPos.colMktPrice 
                FROM dbPam.dbo.tblDatPos 
                INNER JOIN dbPam.dbo.tblDatPos AS Tab_1 ON (dbPam.dbo.tblDatPos.colId = Tab_1.colId) AND (dbPam.dbo.tblDatPos.colDepNb = Tab_1.colDepNb) AND (dbPam.dbo.tblDatPos.colDate > Tab_1.colDate) 
                WHERE dbPam.dbo.tblDatPos.colDate BETWEEN @startDate AND @endDate
                GROUP BY dbPam.dbo.tblDatPos.colId, tblDatPos.colDate, tblDatPos.colDepNb, tblDatPos.colMktPrice)  AS TabPrev 
        INNER JOIN dbPam.dbo.tblDatPos ON (TabPrev.colId = tblDatPos.colId) AND (TabPrev.PrevDate=tblDatPos.colDate) AND (TabPrev.colDepNb=tblDatPos.colDepNb)
        INNER JOIN dbPam.dbo.tblDefDep ON tblDefDep.colDepNb=tblDatPos.colDepNb
        INNER JOIN dbPam.dbo.tblDefPortfolio ON tblDefPortfolio.colPortfolioNb = tblDefDep.colPortfolioNb
        INNER JOIN dbPam.dbo.tblDefBankRel ON tblDefBankRel.colBankRelNb=tblDefPortfolio.colBankRelNb
        INNER JOIN dbProd.dbo.tblDefSecu ON tblDefSecu.colId = tblDatPos.colId
        INNER JOIN dbMktData.dbo.tblDatFX as prevFX ON (prevFX.colCcy1 = tblDefSecu.colCcy ) AND (prevFX.colCcy2 =  @ccy) AND (TabPrev.PrevDate=prevFX.colDate)
        INNER JOIN dbMktData.dbo.tblDatFX as currFX ON (currFX.colCcy1 = tblDefSecu.colCcy ) AND (currFX.colCcy2 =  @ccy) AND (TabPrev.colDate=currFX.colDate)
        WHERE dbPam.dbo.tblDatPos.colType = 'TRAD'  and tblDefPortfolio.colPortfolioNb = @portfolio and prevFX.colType = 'Bbg' and currFX.colType = 'Bbg'
        GROUP BY tblDefBankRel.colCodeClient, tblDefBankRel.colBankRelNb ,tblDefBankRel.colCcy , tblDefPortfolio.colPortfolioNb,tblDefPortfolio.colCcy ,  TabPrev.colDepNb, tblDefDep.colCcy , TabPrev.colId, tblDefSecu.colName, tblDefSecu.colTickerBB, tblDefSecu.colISIN, tblDefSecu.colAssetClass, tblDefSecu.colCcy  ) as subQuery
        INNER JOIN dbPam.dbo.tblDatPos ON tblDatPos.colId = subQuery.colId AND tblDatPos.colDate = subQuery.endDate AND tblDatPos.colDepNb = subQuery.colDepNb
        INNER JOIN dbPam.dbo.tblDatPos AS posPrev ON  posPrev.colId = subQuery.colId AND posPrev.colDate = subQuery.startDate AND posPrev.colDepNb = subQuery.colDepNb
        WHERE tblDatPos.colType = 'TRAD' and posPrev.colType = 'TRAD'
        --ORDER BY colCodeClient desc
        UNION all
        SELECT subQuery.colCodeClient,@ccy as perfCcy, subQuery.colBankRelNb, subQuery.bankRelCcy,  subQuery.colPortfolioNb, subQuery. portCcy, subQuery.colDepNb, subQuery.depCcy, subQuery.colId, subQuery.colName,'', '', 'Other', subQuery.instrCcy  , startDate,  endDate, tblDatPos.colLots as [finalLots], posPrev.colMktPrice as [begPrice] , tblDatPos.colMktPrice as [finaltMktPrice], PnL
        FROM 
        (SELECT tblDefBankRel.colCodeClient, tblDefBankRel.colBankRelNb ,tblDefBankRel.colCcy as bankRelCcy, tblDefPortfolio.colPortfolioNb,tblDefPortfolio.colCcy as portCcy,  TabPrev.colDepNb, tblDefDep.colCcy as depCcy, TabPrev.colId, tblDefOther.colName, '' as colTickerBB, '' as colISIN, 'Other' as colAssetClass, tblDefOther.colCcy as instrCcy, min(TabPrev.PrevDate) as startDate, max(TabPrev.colDate) as endDate, sum((TabPrev.colMktPrice-dbPam.dbo.tblDatPos.colMktPrice)*tblDatPos.colLots) AS [locPnL] , sum((TabPrev.colMktPrice*currFX.colValue-dbPam.dbo.tblDatPos.colMktPrice*prevFX.colValue)*tblDatPos.colLots) AS [PnL] 
        FROM (SELECT dbPam.dbo.tblDatPos.colDepNb, dbPam.dbo.tblDatPos.colId, dbPam.dbo.tblDatPos.colDate, Max(Tab_1.colDate) AS PrevDate, dbPam.dbo.tblDatPos.colMktPrice 
                FROM dbPam.dbo.tblDatPos 
                INNER JOIN dbPam.dbo.tblDatPos AS Tab_1 ON (dbPam.dbo.tblDatPos.colId = Tab_1.colId) AND (dbPam.dbo.tblDatPos.colDepNb = Tab_1.colDepNb) AND (dbPam.dbo.tblDatPos.colDate > Tab_1.colDate) 
                WHERE dbPam.dbo.tblDatPos.colDate BETWEEN @startDate AND @endDate 
                GROUP BY dbPam.dbo.tblDatPos.colId, tblDatPos.colDate, tblDatPos.colDepNb, tblDatPos.colMktPrice)  AS TabPrev 
        INNER JOIN dbPam.dbo.tblDatPos ON (TabPrev.colId = tblDatPos.colId) AND (TabPrev.PrevDate=tblDatPos.colDate) AND (TabPrev.colDepNb=tblDatPos.colDepNb)
        INNER JOIN dbPam.dbo.tblDefDep ON tblDefDep.colDepNb=tblDatPos.colDepNb
        INNER JOIN dbPam.dbo.tblDefPortfolio ON tblDefPortfolio.colPortfolioNb = tblDefDep.colPortfolioNb
        INNER JOIN dbPam.dbo.tblDefBankRel ON tblDefBankRel.colBankRelNb=tblDefPortfolio.colBankRelNb
        INNER JOIN dbProd.dbo.tblDefOther ON tblDefOther.colId = tblDatPos.colId
        INNER JOIN dbMktData.dbo.tblDatFX as prevFX ON (prevFX.colCcy1 = tblDefOther.colCcy ) AND (prevFX.colCcy2 = @ccy) AND (TabPrev.PrevDate=prevFX.colDate)
        INNER JOIN dbMktData.dbo.tblDatFX as currFX ON (currFX.colCcy1 = tblDefOther.colCcy ) AND (currFX.colCcy2 = @ccy) AND (TabPrev.colDate=currFX.colDate)
        WHERE dbPam.dbo.tblDatPos.colType = 'TRAD' and prevFX.colType = 'Bbg' and currFX.colType = 'Bbg' and tblDefPortfolio.colPortfolioNb = @portfolio
        GROUP BY tblDefBankRel.colCodeClient, tblDefBankRel.colBankRelNb ,tblDefBankRel.colCcy , tblDefPortfolio.colPortfolioNb,tblDefPortfolio.colCcy ,  TabPrev.colDepNb, tblDefDep.colCcy , TabPrev.colId, tblDefOther.colName, tblDefOther.colCcy  ) as subQuery
        INNER JOIN dbPam.dbo.tblDatPos ON tblDatPos.colId = subQuery.colId AND tblDatPos.colDate = subQuery.endDate AND tblDatPos.colDepNb = subQuery.colDepNb
        INNER JOIN dbPam.dbo.tblDatPos AS posPrev ON  posPrev.colId = subQuery.colId AND posPrev.colDate = subQuery.startDate AND posPrev.colDepNb = subQuery.colDepNb
        WHERE tblDatPos.colType = 'TRAD' and posPrev.colType = 'TRAD'
        UNION all
        SELECT subQuery.colCodeClient,  @ccy as perfCcy, subQuery.colBankRelNb, subQuery.bankRelCcy,  subQuery.colPortfolioNb, subQuery. portCcy, subQuery.colAccNb,
         subQuery.accCcy, subQuery.accCcy, subQuery.accCcy,'', '','Cash', subQuery.accCcy  , startDate,  endDate, tblDatCash.colAmount as [finalLots], '1' ,'1', PnL
        FROM 
        (
        SELECT tblDefBankRel.colCodeClient, tblDefBankRel.colBankRelNb ,tblDefBankRel.colCcy as bankRelCcy, tblDefPortfolio.colPortfolioNb,tblDefPortfolio.colCcy as portCcy,
          TabPrev.colAccNb, tblDefAccount.colCcy as accCcy, min(TabPrev.PrevDate) as startDate, max(TabPrev.colDate) as endDate, 
          sum(TabPrev.colAmount*(currFX.colValue-prevFX.colValue)) AS [PnL] 
        FROM 
        (SELECT dbPam.dbo.tblDatCash.colAccNb, dbPam.dbo.tblDatCash.colDate, Max(Tab_1.colDate) AS PrevDate, dbPam.dbo.tblDatCash.colAmount 
                FROM dbPam.dbo.tblDatCash 
                INNER JOIN dbPam.dbo.tblDatCash AS Tab_1 ON (dbPam.dbo.tblDatCash.colAccNb = Tab_1.colAccNb) AND (dbPam.dbo.tblDatCash.colDate > Tab_1.colDate) 
                WHERE dbPam.dbo.tblDatCash.colDate BETWEEN @startDate AND @endDate
                GROUP BY dbPam.dbo.tblDatCash.colAccNb, dbPam.dbo.tblDatCash.colDate,  dbPam.dbo.tblDatCash.colAmount )  AS TabPrev 
        INNER JOIN dbPam.dbo.tblDefAccount ON tblDefAccount.colAccNb = TabPrev.colAccNb
        INNER JOIN dbPam.dbo.tblDefPortfolio ON tblDefPortfolio.colPortfolioNb = tblDefAccount.colPortfolioNb
        INNER JOIN dbPam.dbo.tblDefBankRel ON tblDefBankRel.colBankRelNb=tblDefPortfolio.colBankRelNb
        INNER JOIN dbMktData.dbo.tblDatFX as prevFX ON (prevFX.colCcy1 = tblDefAccount.colCcy ) AND (prevFX.colCcy2 =  @ccy) AND (TabPrev.PrevDate=prevFX.colDate)
        INNER JOIN dbMktData.dbo.tblDatFX as currFX ON (currFX.colCcy1 = tblDefAccount.colCcy ) AND (currFX.colCcy2 =  @ccy) AND (TabPrev.colDate=currFX.colDate)
        WHERE    tblDefPortfolio.colPortfolioNb = @portfolio and prevFX.colType = 'Bbg' and currFX.colType = 'Bbg'
        GROUP BY tblDefBankRel.colCodeClient, tblDefBankRel.colBankRelNb ,tblDefBankRel.colCcy , tblDefPortfolio.colPortfolioNb,tblDefPortfolio.colCcy ,
          TabPrev.colAccNb, tblDefAccount.colCcy ) as subQuery
          INNER JOIN dbPam.dbo.tblDatCash ON tblDatCash.colAccNb = subQuery.colAccNb AND tblDatCash.colDate = subQuery.endDate 


END

期待阅读您的建议。

0 个答案:

没有答案