【发布时间】:2016-06-27 15:05:12
【问题描述】:
我在 SQL Server 中有一个从 Excel 调用的存储过程,每次都传递一些动态参数。
我知道存储过程与 SQL Server 中的参数一起使用(已经对此进行了广泛测试),但是当我通过 Excel 调用该过程时,我没有返回任何结果。
我的连接在 Data==>Connections 中设置并且正在工作 - 它会直接拉回列名。它从一个命令按钮运行,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
相当大的块,但需要收集最终计算所需的所有数据
【问题讨论】:
-
您应该在
.CommandText中设置SET NOCOUNT ON;,如下所示:.CommandText = "set nocount on; EXEC RatesCalculation '" & Season & "','" & HOT & "','" & RM & "'" -
@Ralph,没有区别,仍然没有返回任何结果
-
您是否验证了结果
Debug.Print "EXEC RatesCalculation '" & Season & "','" & HOT & "','" & RM & "'"以查看 T-SQL 命令是否正确并尝试在 SSMS 中运行此结果行?如果这仍然验证,则检查 SSMS 中使用的凭据与 Excel 相比。如果您仍然没有发现问题,那么您还需要将 T-SQL 代码添加到上面的帖子中。 -
查看您的 SP 似乎它通常会返回多个结果。然而,Excel 无法检索多个结果集。
Set nocount on;确保 Excel 只接受最后一次返回。在您的情况下,这将是--Calculate the final rate here。因此,如果select为空,则 Excel 将不会显示任何内容。您可能希望(在第一步中)从一个简单的 SP 开始,以验证 Excel 中的各种结果。 -
@Ralph, 'debug.print' 向我展示了要传递给存储过程的预期值
标签: sql-server excel stored-procedures vba