我在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
相当大的一块,但需要收集最终计算所需的所有数据
答案 0 :(得分:0)
确保Excel工作表正在进行身份验证的用户具有对数据库执行EXECUTE的权限。 SELECT是不够的。您不必担心执行SP内发生的任何操作的权限,因为SP使用与对象所有者相同的权限(与Views等不同)。
答案 1 :(得分:0)
根据上面的建议,我将存储过程拆分为2个单独的过程 - 1用于收集所有相关数据,第二个用于进行最终计算。我认为这是拉尔夫建议的,Excel不知道哪个结果集可以撤回并显示。所以问题解决了。然而,结果显示错误的数字,但这对我来说是一个数学问题。