无法将存储过程结果返回到Excel

时间:2016-06-27 15:05:13

标签: sql-server excel excel-vba stored-procedures vba

我在SQL Server中有一个存储过程,我从Excel调用,每次都会传递一些动态参数。

我知道存储过程与SQL Server中的参数一起使用(已对此进行了广泛测试),但是当我通过Excel调用该过程时,我没有返回任何结果。

我的连接是在Data ==> Connections中设置的并且正在运行 - 它会立即撤回列名称。它从CommandButton运行,vba在下面:

Private Sub CommandButton1_Click()
Dim HOT As String, RM As String, Season As String, SSD As Date, SED As Date

HOT = Sheets("Sheet1").Range("C2").Value
RM = Sheets("Sheet1").Range("C3").Value
Season = Sheets("Sheet1").Range("C4").Value

If Season = "S16" Then
    SSD = "01/05/2016"
    SED = "31/10/2016"
ElseIf Season = "W16" Then
    SSD = "01/11/2016"
    SED = "30/04/2016"
ElseIf Season = "S17" Then
    SSD = "01/05/2017"
    SED = "31/10/2017"
Else
End If

With ActiveWorkbook.Connections("TRRC").OLEDBConnection
    .CommandText = "EXEC RatesCalculation '" & Season & "','" & HOT & "','" & RM & "'"
    ActiveWorkbook.Connections("TRRC").Refresh
End With
End Sub

季节信息与IF语句中的所有内容无关,我在我的存储过程中有一个声明来定义季节的日期。

我在存储过程中也有SET NOCOUNT ON

以下是我的存储过程:

    @Season Char(3), @RM Char(6), @HOT Char(6)

AS

BEGIN


    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    DECLARE @SSD as Datetime
    DECLARE @SED as Datetime

    IF @Season = 'S16'
        SET @SSD = '01/05/2016'
    IF @Season = 'S16'
        SET @SED = '31/10/2016'
    IF @Season = 'W16'
        SET @SSD = '01/11/2016'
    IF @Season = 'W16'
        SET @SED = '30/04/2017'

--gathering room data (rates, dates) (#tblroomrates)
SELECT DISTINCT holhot.hot, prxcontract.ssnver, prxcontract.conid, atchotroom.atcCode, prxconrate.room, prxconrate.dateid, prxcondate.dateStart, prxcondate.dateEnd, prxconrate.type, prxconrate.rate1, prxconrate.rate2
INTO            #tblroomrates
FROM            atchotroom INNER JOIN
                         prxconroom ON atchotroom.room = prxconroom.atchotroom INNER JOIN
                         prxconrate INNER JOIN
                         prxcondate ON prxconrate.ssnver = prxcondate.ssnver AND prxconrate.conId = prxcondate.conId 
                         AND prxconrate.dateId = prxcondate.dateId ON 
                         prxconroom.ssnver = prxconrate.ssnver AND prxconroom.conId = prxconrate.conId 
                         AND prxconroom.room = prxconrate.room INNER JOIN
                         holhot INNER JOIN
                         name ON holhot.hot = name.tosCode INNER JOIN
                         prxcon ON name.code = prxcon.hot INNER JOIN
                         prxcontract ON prxcon.ssnver = prxcontract.ssnver 
                         AND prxcon.conId = prxcontract.conId ON prxconroom.ssnver = prxcontract.ssnver AND 
                         prxconroom.conId = prxcontract.conId AND atchotroom.code = prxcon.hot
WHERE        (holhot.holcode = @HOT) AND (prxcon.ssnver = '') AND 
                         (prxcontract.constart<=@SED) AND (prxcontract.conend>=@SSD)
                         order by datestart asc;

--updating any blank dates to season dates to represent an all season rate(only applies to type 3 and 4)
UPDATE #tblroomrates
SET #tblroomrates.datestart = prxcontract.constart,
    #tblroomrates.dateend = prxcontract.conend
FROM
    #tblroomrates INNER JOIN prxcontract ON #tblroomrates.ssnver = prxcontract.ssnver AND #tblroomrates.conid = prxcontract.conid
WHERE
    #tblroomrates.datestart is null AND #tblroomrates.dateend is null

--selects all type 3 and 4 rates for all season dates (#tblrates_alldates)
SELECT DISTINCT #tblroomrates.ssnver, #tblroomrates.conid, atcCode, room, dateid, dateStart, dateEnd, [type], rate1, rate2
INTO #tblrates_alldates
FROM #tblroomrates INNER JOIN prxcontract ON #tblroomrates.ssnver = prxcontract.ssnver AND #tblroomrates.conid = prxcontract.conid
WHERE #tblroomrates.dateStart = prxcontract.constart AND #tblroomrates.dateEnd = prxcontract.conend
AND #tblroomrates.[type] IN ('3','4')

--rate update
UPDATE #tblroomrates
SET 
    #tblroomrates.rate1 = #tblrates_alldates.rate1,
    #tblroomrates.rate2 = #tblrates_alldates.rate2
FROM
    #tblroomrates INNER JOIN #tblrates_alldates ON #tblroomrates.ssnver = #tblrates_alldates.ssnver AND #tblroomrates.conid = #tblrates_alldates.conid AND #tblroomrates.room = #tblrates_alldates.room
    INNER JOIN prxcontract ON #tblroomrates.ssnver = prxcontract.ssnver AND #tblroomrates.conid = prxcontract.conid
WHERE
    #tblroomrates.dateStart = prxcontract.constart AND #tblroomrates.dateEnd = prxcontract.conend AND #tblroomrates.dateid >'0'

--gathers rates where type is 1 (#tblrates_baserates)
SELECT DISTINCT * 
INTO #tblrates_baserates
FROM #tblroomrates
WHERE [type] = '1'

--update rate 2
UPDATE #tblroomrates
SET 
    #tblroomrates.rate1 = #tblrates_baserates.rate1
FROM 
    #tblroomrates INNER JOIN #tblrates_baserates ON #tblroomrates.ssnver = #tblrates_baserates.ssnver AND #tblroomrates.conid = #tblrates_baserates.conid 
    AND #tblroomrates.dateid = #tblrates_baserates.dateid
WHERE
    #tblroomrates.[type] = '2'

--Calculate the final rate here
SELECT #tblroomrates.hot AS [Accom Code], #tblroomrates.atcCode AS [Room], #tblroomrates.dateStart AS [Rate Start], #tblroomrates.dateEnd AS [Rate End], 
        CASE 
            WHEN #tblroomrates.rate2 <> 0 AND #tblroomrates.[type] = 3 THEN #tblrates_baserates.rate1 + #tblroomrates.rate2
            WHEN #tblroomrates.rate2 <> 0 AND #tblroomrates.[type] = 4 THEN #tblrates_baserates.rate1 - #tblroomrates.rate2 
            WHEN #tblroomrates.rate2 <> 0 AND #tblroomrates.[type] IN (0,1,2) THEN #tblroomrates.rate1
            ELSE 
                CASE
                    WHEN #tblroomrates.rate1 <> 0 AND #tblroomrates.[type] = 3 THEN #tblrates_baserates.rate1 + (#tblrates_baserates.rate1 * (#tblroomrates.rate1/100))
                    WHEN #tblroomrates.rate1 <> 0 AND #tblroomrates.[type] = 4 THEN #tblrates_baserates.rate1 - (#tblrates_baserates.rate1 * (#tblroomrates.rate1/100))
                    ELSE 
                        CASE
                            WHEN #tblroomrates.rate2 = 0 AND #tblroomrates.rate1 = 0 THEN #tblrates_baserates.rate1
                            ELSE #tblroomrates.rate1
                        END
                END
        END AS Calculated_Rates
FROM #tblroomrates LEFT JOIN #tblrates_baserates ON #tblroomrates.ssnver = #tblrates_baserates.ssnver AND 
    #tblroomrates.conid = #tblrates_baserates.conid AND #tblroomrates.dateid = #tblrates_baserates.dateid
WHERE #tblroomrates.dateid > 0
AND #TBLROOMRATES.ATCCODE = @RM

相当大的一块,但需要收集最终计算所需的所有数据

2 个答案:

答案 0 :(得分:0)

确保Excel工作表正在进行身份验证的用户具有对数据库执行EXECUTE的权限。 SELECT是不够的。您不必担心执行SP内发生的任何操作的权限,因为SP使用与对象所有者相同的权限(与Views等不同)。

答案 1 :(得分:0)

根据上面的建议,我将存储过程拆分为2个单独的过程 - 1用于收集所有相关数据,第二个用于进行最终计算。我认为这是拉尔夫建议的,Excel不知道哪个结果集可以撤回并显示。所以问题解决了。然而,结果显示错误的数字,但这对我来说是一个数学问题。