-
Notifications
You must be signed in to change notification settings - Fork 12
/
SqlCommand.cls
310 lines (203 loc) · 12.2 KB
/
SqlCommand.cls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "SqlCommand"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Private converter As New AdoValueConverter
Private connString As String
Private resultFactory As New SqlResult
Option Explicit
Public Property Get ConnectionString() As String
ConnectionString = connString
End Property
Public Property Let ConnectionString(ByVal value As String)
connString = value
End Property
Public Property Get ParameterFactory() As AdoValueConverter
Attribute ParameterFactory.VB_Description = "Gets an object that can create ADODB Parameters and configure how ADODB Parameters are created."
Set ParameterFactory = converter
End Property
Public Function Execute(connection As ADODB.connection, ByVal sql As String, ParamArray parameterValues()) As ADODB.Recordset
Attribute Execute.VB_Description = "Returns a connected ADODB.Recordset that contains the results of the specified parameterized query."
'Returns a connected ADODB.Recordset that contains the results of the specified parameterized query.
Dim parameters() As Variant
parameters = parameterValues
Set Execute = ExecuteInternal(connection, sql, parameters)
End Function
Public Function ExecuteNonQuery(connection As ADODB.connection, ByVal sql As String, ParamArray parameterValues()) As Boolean
Attribute ExecuteNonQuery.VB_Description = "Returns a Boolean that indicates whether the specified parameterized SQL command (update, delete, etc.) executed without throwing an error."
'Returns a Boolean that indicates whether the specified parameterized SQL command (update, delete, etc.) executed without throwing an error.
Dim parameters() As Variant
parameters = parameterValues
ExecuteNonQuery = ExecuteNonQueryInternal(connection, sql, parameters)
End Function
Public Function ExecuteStoredProc(connection As ADODB.connection, ByVal spName As String, ParamArray parameterValues()) As ADODB.Recordset
Attribute ExecuteStoredProc.VB_Description = "Executes the specified parameterized stored procedure, passing specified parameter values."
'Executes the specified parameterized stored procedure, passing specified parameter values.
Dim parameters() As Variant
parameters = parameterValues
Set ExecuteStoredProc = ExecuteStoredProcInternal(connection, spName, parameters)
End Function
Public Function ExecuteWithParameters(connection As ADODB.connection, ByVal spName As String, parameters As List) As ADODB.Recordset
Attribute ExecuteWithParameters.VB_Description = "Executes specified parameterized stored procedure by passing the specified preconfigured parameters. Use this method over ExecuteStoredProcedure for more complex parameter scenarios, such as running a stored procedure with output parameters."
'Executes specified parameterized stored procedure by passing the specified preconfigured parameters.
'Use this method over ExecuteStoredProcedure for more complex parameter scenarios, such as running a stored procedure with output parameters.
'parameters is expected to be a List containing ADODB.Parameter objects: parameters.ToString = "List<Parameter>"
If Not parameters.IsTypeSafe(New ADODB.parameter) Or parameters.ToString = "List<Variant>" Then Err.Raise vbObjectError + 2, "SqlCommand.ExecuteWithParameters", "Wrong list type. Argument 'parameters' must be a List<Parameter>."
Dim emptyArray() As Variant
Dim cmd As New ADODB.Command
Set cmd = CreateCommand(connection, adCmdStoredProc, spName, emptyArray)
Dim param As ADODB.parameter
For Each param In parameters
cmd.parameters.Append param
Next
Set ExecuteWithParameters = cmd.Execute
End Function
Public Function SelectSingleValue(connection As ADODB.connection, ByVal sql As String, ParamArray parameterValues()) As Variant
Attribute SelectSingleValue.VB_Description = "Returns the value of the first field of the first record of the results of the specified parameterized SQL query."
'Returns the value of the first field of the first record of the results of the specified parameterized SQL query.
Dim parameters() As Variant
parameters = parameterValues
SelectSingleValue = SelectSingleValueInternal(connection, sql, parameters)
End Function
Public Function QuickExecute(ByVal sql As String, ParamArray parameterValues()) As SqlResult
Attribute QuickExecute.VB_Description = "Returns an object representing the result of the specified parameterized SQL statement. Field values for each row can then be accessed by field name or by field index."
'Returns an object representing the result of the specified parameterized SQL statement. Field values for each row can then be accessed by field name or by field index.
Dim parameters() As Variant
parameters = parameterValues
Set QuickExecute = QuickExecuteInternal(sql, parameters)
End Function
Public Function QuickExecuteNonQuery(ByVal sql As String, ParamArray parameterValues()) As Boolean
Attribute QuickExecuteNonQuery.VB_Description = "Opens a connection and returns a Boolean that indicates whether the specified parameterized SQL command (update, delete, etc.) executed without throwing an error, then closes the connection."
'Opens a connection and returns a Boolean that indicates whether the specified parameterized SQL command (update, delete, etc.) executed without throwing an error,
'then closes the connection.
Dim parameters() As Variant
parameters = parameterValues
Dim connection As New ADODB.connection
connection.ConnectionString = connString
connection.Open
QuickExecuteNonQuery = ExecuteNonQueryInternal(connection, sql, parameters)
connection.Close
Set connection = Nothing
End Function
Public Function QuickExecuteStoredProc(ByVal spName As String, ParamArray parameterValues()) As SqlResult
Attribute QuickExecuteStoredProc.VB_Description = "Executes the specified parameterized stored procedure, passing specified parameter values."
'Executes the specified parameterized stored procedure, passing specified parameter values.
Dim parameters() As Variant
parameters = parameterValues
Dim connection As New ADODB.connection
connection.ConnectionString = connString
connection.Open
Dim rs As ADODB.Recordset
Set rs = ExecuteStoredProcInternal(connection, spName, parameters)
Set QuickExecuteStoredProc = resultFactory.Create(rs)
rs.Close
Set rs = Nothing
connection.Close
Set connection = Nothing
End Function
Public Function QuickExecuteWithParameters(ByVal spName As String, parameters As List) As SqlResult
'Executes specified parameterized stored procedure by passing the specified preconfigured parameters.
'Use this method over ExecuteStoredProcedure for more complex parameter scenarios, such as running a stored procedure with output parameters.
Dim connection As New ADODB.connection
connection.ConnectionString = connString
connection.Open
Dim rs As ADODB.Recordset
Set rs = ExecuteWithParameters(connection, spName, parameters)
Set QuickExecuteWithParameters = resultFactory.Create(rs)
rs.Close
Set rs = Nothing
connection.Close
Set connection = Nothing
End Function
Public Function QuickSelectFirstRow(ByVal sql As String, ParamArray parameterValues()) As SqlResultRow
Attribute QuickSelectFirstRow.VB_Description = "Opens a connection and returns an object representing the first record of the results of the specified parameterized SQL query, then closes the connection."
'Opens a connection and returns an object representing the first record of the results of the specified parameterized SQL query, then closes the connection.
Dim parameters() As Variant
parameters = parameterValues
Dim result As SqlResult
Set result = QuickExecuteInternal(sql, parameters)
Set QuickSelectFirstRow = result.First
End Function
Public Function QuickSelectSingleValue(ByVal sql As String, ParamArray parameterValues()) As Variant
Attribute QuickSelectSingleValue.VB_Description = "Opens a connection and returns the value of the first field of the first record of the results of the specified parameterized SQL query, then closes the connection."
'Opens a connection and returns the value of the first field of the first record of the results of the specified parameterized SQL query, then closes the connection.
Dim parameters() As Variant
parameters = parameterValues
Dim connection As New ADODB.connection
connection.ConnectionString = connString
connection.Open
Set QuickSelectSingleValue = SelectSingleValueInternal(connection, sql, parameters)
connection.Close
Set connection = Nothing
End Function
Private Function CreateCommand(connection As ADODB.connection, ByVal cmdType As ADODB.CommandTypeEnum, ByVal sql As String, parameterValues() As Variant) As ADODB.Command
Dim cmd As New ADODB.Command
cmd.ActiveConnection = connection
cmd.CommandType = cmdType
cmd.CommandText = sql
Dim i As Integer
Dim value As Variant
For i = LBound(parameterValues) To UBound(parameterValues)
value = parameterValues(i)
If TypeName(value) <> "Variant()" Then cmd.parameters.Append ToSqlInputParameter(value)
Next
Set CreateCommand = cmd
End Function
Private Function ToSqlInputParameter(ByVal value As Variant) As ADODB.parameter
If IsObject(value) Then Err.Raise vbObjectError + 911, "SqlCommand.ToSqlInputParameter", "Invalid argument, parameter value cannot be an object."
Dim result As ADODB.parameter
Set result = CallByName(converter, "To" & TypeName(value) & "Parameter", VbMethod, value, ADODB.ParameterDirectionEnum.adParamInput)
Set ToSqlInputParameter = result
End Function
Private Function ExecuteInternal(connection As ADODB.connection, ByVal sql As String, parameterValues()) As ADODB.Recordset
Dim cmd As ADODB.Command
Set cmd = CreateCommand(connection, adCmdText, sql, parameterValues)
Set ExecuteInternal = cmd.Execute
End Function
Private Function ExecuteNonQueryInternal(connection As ADODB.connection, ByVal sql As String, parameterValues()) As Boolean
Dim cmd As ADODB.Command
Set cmd = CreateCommand(connection, adCmdText, sql, parameterValues)
Dim result As Boolean
On Error Resume Next
cmd.Execute
result = (Err.Number = 0)
On Error GoTo 0
ExecuteNonQueryInternal = result
End Function
Private Function ExecuteStoredProcInternal(connection As ADODB.connection, ByVal spName As String, parameterValues()) As ADODB.Recordset
Dim cmd As ADODB.Command
Set cmd = CreateCommand(connection, adCmdStoredProc, spName, parameterValues)
Set ExecuteStoredProcInternal = cmd.Execute
End Function
Private Function SelectSingleValueInternal(connection As ADODB.connection, ByVal sql As String, parameterValues()) As Variant
Dim parameters() As Variant
parameters = parameterValues
Dim cmd As ADODB.Command
Set cmd = CreateCommand(connection, adCmdText, sql, parameters)
Dim rs As ADODB.Recordset
Set rs = cmd.Execute
Dim result As Variant
If Not rs.BOF And Not rs.EOF Then result = rs.fields(0).value
rs.Close
Set rs = Nothing
SelectSingleValueInternal = result
End Function
Private Function QuickExecuteInternal(ByVal sql As String, parameterValues()) As SqlResult
Dim parameters() As Variant
parameters = parameterValues
Dim connection As New ADODB.connection
connection.ConnectionString = connString
connection.Open
Dim rs As ADODB.Recordset
Set rs = ExecuteInternal(connection, sql, parameters)
Set QuickExecuteInternal = resultFactory.Create(rs)
rs.Close
Set rs = Nothing
connection.Close
Set connection = Nothing
End Function