【发布时间】:2017-01-30 17:02:04
【问题描述】:
当我在 Excel 单元格 D2(例如)ALFKI 中输入 Northwind DB 示例中的客户 ID 时,我有以下代码:
这是我目前可用的 Excel VBA 代码:
Dim con As ADODB.Connection
Dim cmd As ADODB.Command
Dim rs As ADODB.Recordset
Dim WSP1 As Worksheet
Set con = New ADODB.Connection
Set cmd = New ADODB.Command
Set rs = New ADODB.Recordset
Application.DisplayStatusBar = True
Application.StatusBar = "Contacting SQL Server..."
' Remove any values in the cells where we want to put our Stored Procedure's results.
Dim rngRange As Range
Set rngRange = Range(Cells(8, 2), Cells(Rows.Count, 1)).EntireRow
rngRange.ClearContents
' Log into our SQL Server, and run the Stored Procedure
con.Open "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=Northwind;Integrated Security=SSPI;Trusted_Connection=Yes;"
cmd.ActiveConnection = con
' Set up the parameter for our Stored Procedure
' (Parameter types can be adVarChar,adDate,adInteger)
cmd.Parameters.Append cmd.CreateParameter("CustomerID", adVarChar, adParamInput, 10, Range("D2").Text)
Application.StatusBar = "Running stored procedure..."
cmd.CommandText = "SP_GetOrdersForCustomer"
Set rs = cmd.Execute(, , adCmdStoredProc)
' Copy the results to cell B7 on the first Worksheet
Set WSP1 = Worksheets(1)
WSP1.Activate
If rs.EOF = False Then WSP1.Cells(8, 2).CopyFromRecordset rs
rs.Close
Set rs = Nothing
Set cmd = Nothing
con.Close
Set con = Nothing
Application.StatusBar = "Data successfully updated."
存储过程是 SP_GetOrdersForCustomer,即:
CREATE PROCEDURE [dbo].[SP_GetOrdersForCustomer]
@CustomerID nchar(5)
AS
BEGIN
SELECT cst.[CustomerID],
cst.[CompanyName],
cst.[ContactName],
ord.[OrderID],
ord.[EmployeeID],
emp.[FirstName],
emp.[LastName],
ord.[ShippedDate],
prd.[ProductName],
od.[UnitPrice],
od.[Quantity]
FROM [Customers] cst,
[Orders] ord,
[Order Details] od,
[Employees] emp,
[Products] prd
WHERE ord.[CustomerID] = cst.[CustomerID]
AND emp.[EmployeeID] = ord.[EmployeeID]
AND od.[OrderID] = ord.[OrderID]
AND prd.[ProductID] = od.[ProductID]
AND cst.[CustomerID] = @CustomerID
ORDER BY cst.[CustomerID], emp.[EmployeeID], ord.[ShippedDate] DESC
END
我现在需要在 Northwind 中执行存储过程“Sales by Year”,它有两个日期参数 @Beginning_Date 和 @Ending_Date 都是日期时间数据类型。
如果我将日期 1996-07-01 放在单元格 F1 中,将 1996-08-01 放在单元格 F2 中,则调用参数:
' Set up the parameter for our Stored Procedure
' (Parameter types can be adVarChar,adDate,adInteger,etc)
cmd.Parameters.Append cmd.CreateParameter("@Beginning_Date", adDate, adParamInput, 10, Range("F1").Text)
cmd.Parameters.Append cmd.CreateParameter("@Ending_Date", adDate, adParamInput, 10, Range("F2").Text)
它不起作用。
这是带有日期的存储过程:
USE [Northwind]
GO
/****** Object: StoredProcedure [dbo].[Sales by Year] Script Date: 30/01/2017 22:04:57 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[Sales by Year]
@Beginning_Date DateTime, @Ending_Date DateTime AS
SELECT Orders.ShippedDate, Orders.OrderID, "Order Subtotals".Subtotal, DATENAME(yy,ShippedDate) AS Year
FROM Orders INNER JOIN "Order Subtotals" ON Orders.OrderID = "Order Subtotals".OrderID
WHERE Orders.ShippedDate Between @Beginning_Date And @Ending_Date
这是不起作用的 Excel VBA。我尝试修改上面显示的内容,我认为我应该使用 addDBdate 而不是 adDate 但它失败了“错误 3421 应用程序为当前操作使用了错误类型的值”:
Sub Button1_Click()
Dim con As ADODB.Connection
Dim cmd As ADODB.Command
Dim rs As ADODB.Recordset
Dim WSP1 As Worksheet
Set con = New ADODB.Connection
Set cmd = New ADODB.Command
Set rs = New ADODB.Recordset
Application.DisplayStatusBar = True
Application.StatusBar = "Contacting SQL Server..."
' Remove any values in the cells and clear a space where we want to dump and put our Stored Procedure's results.
Dim rngRange As Range
Set rngRange = Range(Cells(8, 2), Cells(Rows.Count, 1)).EntireRow
rngRange.ClearContents
' Log into our SQL Server, and run the Stored Procedure
con.Open "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=Northwind;Integrated Security=SSPI;Trusted_Connection=Yes;"
cmd.ActiveConnection = con
' Set up the parameter for our Stored Procedure
' (Parameter types can be adVarChar,adDate,adInteger,etc)
cmd.Parameters.Append cmd.CreateParameter("@Beginning_Date", adDate, adParamInput, 10, Range("J1").Text)
cmd.Parameters.Append cmd.CreateParameter("@Ending_Date", adDate, adParamInput, 10, Range("J2").Text)
'Show some text at the bottom on the status bar
Application.StatusBar = "Running stored procedure..."
'run the stored procedure name in SQL and drop the prefix dbo. it's not needed
cmd.CommandText = "Sales by Year"
'Execute it
Set rs = cmd.Execute(, , adCmdStoredProc)
' Copy the results to cell B7 on the first Worksheet
Set WSP1 = Worksheets(1)
WSP1.Activate
If rs.EOF = False Then WSP1.Cells(8, 2).CopyFromRecordset rs
'clean terminate
rs.Close
Set rs = Nothing
Set cmd = Nothing
'close off the connection to the SQL database
con.Close
Set con = Nothing
'Did it work ? Then display message at the bottom status bar
Application.StatusBar = "Data successfully updated."
End Sub
【问题讨论】:
-
你能定义“不起作用”吗?您收到错误消息吗?返回的数据是否不是您认为的数据?稍微绕道,你不应该使用 sp_ 前缀(或者甚至更好地不使用前缀)。 sqlperformance.com/2012/10/t-sql-queries/sp_prefix
-
我已经添加了另一个存储过程来显示日期,以及我无法开始工作的 VBA 代码,日期在单元格 J1 和 J2 中,我尝试了 addDBdate 和 adDate 但我两者都出现相同的错误?
标签: sql sql-server excel stored-procedures vba