如何使用 VBA 执行插入/更新记录的存储过程?
Posted
技术标签:
【中文标题】如何使用 VBA 执行插入/更新记录的存储过程?【英文标题】:How to execute stored procedure which insert/update records using VBA? 【发布时间】:2021-12-03 01:06:58 【问题描述】:我创建了许多使用存储过程的电子表格。我有一个自定义 VBA 代码,当我尝试从 SQL 获取数据时它工作正常。但是,今天我想执行参数化的存储过程,在数据库表上插入和更新数据。当我运行宏时没有出现错误,但是数据库上没有插入/更新操作。我不知道为什么。我在我的工作簿 (myConn
) 中建立了 SQL 连接,就像我每次需要连接 SQL 时所做的那样,所以它肯定是正确的。这是我的标准 VBA 代码:
Sub SaveData()
Dim myValue As Double
myValue = Sheets("XYZ").Range("valueToSave").Value
With ActiveWorkbook.Connections("myConn").OLEDBConnection
.CommandText = Array( _
"EXEC DB.[dbo].[myProc] '" & myValue & "'")
End With
ActiveWorkbook.Connections("myConn").Refresh
End Sub
我需要将数据插入decimal(6,4)
类型的列(在 SQL 表中)。 myProc
当我通过 SSMS 手动运行它而不是在这里使用 VBA 代码时,它做得很好。 valueToSave
是一个 Excel 范围,它存储一个十进制值(例如:23,56
、11,21
等)。当我运行宏时没有任何反应。当我运行宏并转到“连接属性”>“定义”>“命令文本”时,我可以看到有一个带有参数的过程(EXEC DB.[dbo].[myProc]'11,23')。所以我上面的代码似乎工作但没有执行存储过程。
与数据类型有关吗?老实说,我尝试过使用其他 VBA 类型:String
、Variant
、Integer
,但它不起作用。我还更改了 SQL 表中该列的数据类型(更改为 varchar
、int
等),但它也不起作用。最有趣的是,上面的代码在我从数据库中提取数据时可以正常工作,而在需要插入/更新数据时则无法正常工作。
PS。我想我添加了所有必需的参考:
【问题讨论】:
警告:您的代码很危险;它对 SQL 注入攻击很开放。修复您的代码,并parametrise。 我在存储过程中使用参数。无论如何,代码是在我公司内部使用的。我只是想知道为什么插入/更新在这里不起作用"EXEC DB.[dbo].[myProc] '" & myValue & "'"
是不使用参数...即注入...
“无论如何,代码是在我公司内部使用的” 这就像在说“我只把车停在我的住所和办公室外面,所以不锁车是安全的。 "
存储过程可能有参数,但你提交的SQL代码没有。考虑 Alice 在您的 Excel 单元格中输入如下内容:'; drop database DB; --
。是时候阅读 OleDbCommand Parameters 并将该代码转换为 VBA。
【参考方案1】:
使用 ADODB
Option Explicit
Sub SaveData()
Const PROC_NAME = "DB.dbo.myproc"
Dim wb As Workbook
Dim ado As ADODB.Connection, cmd As ADODB.Command
Dim sCon As String, v As Single
Set wb = ThisWorkbook
v = wb.Sheets("XYZ").Range("valueToSave").Value
' get connection string
sCon = wb.Connections("myConn").OLEDBConnection.Connection
sCon = Replace(sCon, "OLEDB;", "")
' open connection
Set ado = New ADODB.Connection
ado.Open sCon
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = ado
.CommandType = adCmdStoredProc
.CommandText = PROC_NAME
.Parameters.Append .CreateParameter("P1", adDecimal, adParamInput)
With .Parameters(0)
.NumericScale = 2
.Precision = 18
.Value = v
End With
.Execute
End With
ado.Close
MsgBox PROC_NAME & " " & v, vbInformation, "Done"
End Sub
【讨论】:
以上是关于如何使用 VBA 执行插入/更新记录的存储过程?的主要内容,如果未能解决你的问题,请参考以下文章