运行时错误3001'参数是错误的types或超出可接受的范围…'

我有一个Excel表,并且想要更新由Excel的第12列引用的SQL Server表logging的date值(使用getdate函数)。

我的代码如下,但我看到:

运行时错误3001参数的types错误或超出可接受的范围或彼此冲突。

在SQL表中,MODIFIEDDATE字段是datetimetypes,而MAINREF字段是整数types。

Private Sub CommandButton2_Click() Dim conn2 As New ADODB.Connection Dim rst2 As New ADODB.Recordset Dim j As Integer conn2.ConnectionString = "Provider=SQLOLEDB.1;Password=abc;Persist Security Info=True;User ID=sa;Initial Catalog=logodb;Data Source=A3650;Use Procedure for Prepare=1;Auto" conn2.Open For j = 0 To 1900 If Sayfa1.Cells(j + 4, 12) = "" Then Sayfa1.Cells(j + 4, 13) = "empty" Else rst2.Open "UPDATE T_015 SET MODIFIEDDATE=GETDATE() WHERE MAINREF='" & Sayfa1.Cells(j + 4, 12) & "'", conn, 1, 3 rst2.Close End If Next j End Sub 

我试图改变SQL查询,(CInt(cell.value))

 rst2.Open "UPDATE T_015 SET MODIFIEDDATE=GETDATE() WHERE MAINREF='" & CInt(Sayfa1.Cells(j + 4, 12)) & "'", conn, 1, 3 

但是,它没有工作。

ADODB.Recordset对象不应该用于UPDATE查询。 直接从ADODB.Connection执行SQL语句

 Dim conn2 As New ADODB.Connection conn2.ConnectionString = "Provider=SQLNCLI11;Server=MYSERVER;Database=TMP;UID=sa;password=abc;" conn2.Open conn2.Execute "UPDATE T_015 SET MODIFIEDDATE=GETDATE() WHERE MAINREF=1" 

有几种方法可以满足您的要求,而且您似乎将两者混合在一起。

一种方法是一次更新一个logging,为此,您可以使用Connection对象,更可取的方法是使用Command对象。 我最好说,因为参数化的命令是一个更强大的方式来执行你的SQL。 如果您打算使用SQL,那么您可能应该阅读这些内容。 你会这样做的方式如下:

 Public Sub ParameterisedProcedure() Dim conn As ADODB.Connection Dim cmd As ADODB.Command Dim prm As ADODB.Parameter Dim v As Variant Dim j As Integer 'Read the sheet data v = Sayfa1.Range("L4", "M1904").Value2 'Open the database connection Set conn = New ADODB.Connection conn.ConnectionString = "Provider=SQLOLEDB.1;" & _ "Password=abc;" & _ "Persist Security Info=True;" & _ "User ID=sa;" & _ "Initial Catalog=logodb;" & _ "Data Source=A3650;" & _ "Use Procedure for Prepare=1;" & _ "Auto" conn.Open 'Loop through the values to update records For j = 1 To UBound(v, 1) If IsEmpty(v(j, 1)) Then v(j, 2) = "empty" Else 'Create the parameterised command Set cmd = New ADODB.Command cmd.ActiveConnection = conn cmd.CommandType = adCmdText cmd.CommandText = "UPDATE T_015 " & _ "SET MODIFIEDDATE=? " & _ "WHERE MAINREF=?" prm = cmd.CreateParameter(Type:=adDate, Value:=Now) cmd.Parameters.Append prm prm = cmd.CreateParameter(Type:=adInteger, Value:=v(j, 1)) cmd.Parameters.Append prm cmd.Execute End If Next 'Write the updated values Sayfa1.Range("L4", "M1904").Value = v 'Close the database Set prm = Nothing Set cmd = Nothing conn.Close End Sub 

另一种方法是使用Transactions ,你会确实使用一个Recordset (即类似于你已经完成)。 在这种情况下,我build议这样做是更好的方法,因为一次执行一个命令(如上面的代码)非常慢。 更快的方法是在一个事务中提交所有的更新。 像参数化命令一样,从stream氓stringinput您的SQL命令文本也是安全的。 代码看起来像这样:

 Public Sub TransactionProcedure() Dim conn As ADODB.Connection Dim rs As ADODB.Recordset Dim cmdText As String Dim v As Variant Dim j As Integer 'Read the sheet data v = Sayfa1.Range("L4", "M1904").Value2 'Open the database connection Set conn = New ADODB.Connection conn.ConnectionString = "Provider=SQLOLEDB.1;" & _ "Password=abc;" & _ "Persist Security Info=True;" & _ "User ID=sa;" & _ "Initial Catalog=logodb;" & _ "Data Source=A3650;" & _ "Use Procedure for Prepare=1;" & _ "Auto" conn.Open 'Retrieve the data Set rs = New ADODB.Recordset cmdText = "SELECT * FROM T_015" rs.Open cmdText, conn, adOpenStatic, adLockReadOnly, adCmdText 'Loop through the values to update the recordset On Error GoTo EH conn.BeginTrans For j = 1 To UBound(v, 1) If IsEmpty(v(j, 1)) Then v(j, 2) = "empty" Else 'Find and update the record rs.Find "MAINREF=" & CStr(v(j, 1)) If Not rs.EOF Then rs!ModifiedDate = Now rs.Update End If End If Next conn.CommitTrans 'Write the updated values Sayfa1.Range("L4", "M1904").Value = v 'Close the database rs.Close conn.Close Exit Sub EH: conn.RollbackTrans Sayfa1.Range("L4", "M1904").Value = v rs.Close conn.Close MsgBox Err.Description End Sub