using System;
2
3 using System.Data;
4
5 using System.Xml;
6
7 using System.Data.SqlClient;
8
9 using System.Collections;
10
11 namespace DRPHelper.Chu
12 {
13
14 /// <summary>
15
16 /// SqlServer数据访问帮助类
17
18 /// </summary>
19
20 public sealed class SqlHelper
21 {
22
23 public static SqlConnection connection =
new SqlConnection(
"SERVER=1.1.1.1,21433;DATABASE=Test;PWD=1;UID=sa;");
24 #region 私有构造函数和方法
25
26 private SqlHelper()
27 {
28
29 }
30
31 /// <summary>
32
33 /// 将SqlParameter参数数组(参数值)分配给SqlCommand命令.
34
35 /// 这个方法将给任何一个参数分配DBNull.Value;
36
37 /// 该操作将阻止默认值的使用.
38
39 /// </summary>
40
41 /// <param>命令名</param>
42
43 /// <param>SqlParameters数组</param>
44
45 private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters)
46 {
47
48 if (command ==
null)
throw new ArgumentNullException(
"command");
49
50 if (commandParameters !=
null)
51 {
52
53 foreach (SqlParameter p
in commandParameters)
54 {
55
56 if (p !=
null)
57 {
58
59 // 检查未分配值的输出参数,将其分配以DBNull.Value.
60
61 if ((p.Direction == ParameterDirection.InputOutput || p.Direction == ParameterDirection.Input) &&
62
63 (p.Value ==
null))
64 {
65
66 p.Value =
DBNull.Value;
67
68 }
69
70 command.Parameters.Add(p);
71
72 }
73
74 }
75
76 }
77
78 }
79
80
81
82 /// <summary>
83
84 /// 将DataRow类型的列值分配到SqlParameter参数数组.
85
86 /// </summary>
87
88 /// <param>要分配值的SqlParameter参数数组</param>
89
90 /// <param>将要分配给存储过程参数的DataRow</param>
91
92 private static void AssignParameterValues(SqlParameter[] commandParameters, DataRow dataRow)
93 {
94
95 if ((commandParameters ==
null) || (dataRow ==
null))
96 {
97
98 return;
99
100 }
101
102 int i =
0;
103
104 // 设置参数值
105
106 foreach (SqlParameter commandParameter
in commandParameters)
107 {
108
109 // 创建参数名称,如果不存在,只抛出一个异常.
110
111 if (commandParameter.ParameterName ==
null ||
112
113 commandParameter.ParameterName.Length <=
1)
114
115 throw new Exception(
116
117 string.Format(
"请提供参数{0}一个有效的名称{1}.", i, commandParameter.ParameterName));
118
119 // 从dataRow的表中获取为参数数组中数组名称的列的索引.
120
121 // 如果存在和参数名称相同的列,则将列值赋给当前名称的参数.
122
123 if (dataRow.Table.Columns.IndexOf(commandParameter.ParameterName.Substring(
1)) != -
1)
124
125 commandParameter.Value = dataRow[commandParameter.ParameterName.Substring(
1)];
126
127 i++
;
128
129 }
130
131 }
132
133
134
135 /// <summary>
136
137 /// 将一个对象数组分配给SqlParameter参数数组.
138
139 /// </summary>
140
141 /// <param>要分配值的SqlParameter参数数组</param>
142
143 /// <param>将要分配给存储过程参数的对象数组</param>
144
145 private static void AssignParameterValues(SqlParameter[] commandParameters,
object[] parameterValues)
146 {
147
148 if ((commandParameters ==
null) || (parameterValues ==
null))
149 {
150
151 return;
152
153 }
154
155 // 确保对象数组个数与参数个数匹配,如果不匹配,抛出一个异常.
156
157 if (commandParameters.Length !=
parameterValues.Length)
158 {
159
160 throw new ArgumentException(
"参数值个数与参数不匹配.");
161
162 }
163
164 // 给参数赋值
165
166 for (
int i =
0, j = commandParameters.Length; i < j; i++
)
167 {
168
169 // If the current array value derives from IDbDataParameter, then assign its Value property
170
171 if (parameterValues[i]
is IDbDataParameter)
172 {
173
174 IDbDataParameter paramInstance =
(IDbDataParameter)parameterValues[i];
175
176 if (paramInstance.Value ==
null)
177 {
178
179 commandParameters[i].Value =
DBNull.Value;
180
181 }
182
183 else
184 {
185
186 commandParameters[i].Value =
paramInstance.Value;
187
188 }
189
190 }
191
192 else if (parameterValues[i] ==
null)
193 {
194
195 commandParameters[i].Value =
DBNull.Value;
196
197 }
198
199 else
200 {
201
202 commandParameters[i].Value =
parameterValues[i];
203
204 }
205
206 }
207
208 }
209
210
211
212 /// <summary>
213
214 /// 预处理用户提供的命令,数据库连接/事务/命令类型/参数
215
216 /// </summary>
217
218 /// <param>要处理的SqlCommand</param>
219
220 /// <param>数据库连接</param>
221
222 /// <param>一个有效的事务或者是null值</param>
223
224 /// <param>命令类型 (存储过程,命令文本, 其它.)</param>
225
226 /// <param>存储过程名或都T-SQL命令文本</param>
227
228 /// <param>和命令相关联的SqlParameter参数数组,如果没有参数为‘null‘</param>
229
230 /// <param><c>true</c> 如果连接是打开的,则为true,其它情况下为false.</param>
231
232 private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType,
string commandText, SqlParameter[] commandParameters,
out bool mustCloseConnection)
233 {
234
235 if (command ==
null)
throw new ArgumentNullException(
"command");
236
237 if (commandText ==
null || commandText.Length ==
0)
throw new ArgumentNullException(
"commandText");
238
239 // If the provided connection is not open, we will open it
240
241 if (connection.State !=
ConnectionState.Open)
242 {
243
244 mustCloseConnection =
true;
245
246 connection.Open();
247
248 }
249
250 else
251 {
252
253 mustCloseConnection =
false;
254
255 }
256
257 // 给命令分配一个数据库连接.
258
259 command.Connection =
connection;
260
261 // 设置命令文本(存储过程名或SQL语句)
262
263 command.CommandText =
commandText;
264
265 // 分配事务
266
267 if (transaction !=
null)
268 {
269
270 if (transaction.Connection ==
null)
throw new ArgumentException(
"The transaction was rollbacked or commited, please provide an open transaction.",
"transaction");
271
272 command.Transaction =
transaction;
273
274 }
275
276 // 设置命令类型.
277
278 command.CommandType =
commandType;
279
280 // 分配命令参数
281
282 if (commandParameters !=
null)
283 {
284
285 AttachParameters(command, commandParameters);
286
287 }
288
289 return;
290
291 }
292
293 #endregion 私有构造函数和方法结束
294
295
296
297 #region ExecuteNonQuery命令
298
299 /// <summary>
300
301 /// 执行指定连接字符串,类型的SqlCommand.
302
303 /// </summary>
304
305 /// <remarks>
306
307 /// 示例:
308
309 /// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders");
310
311 /// </remarks>
312
313 /// <param>一个有效的数据库连接字符串</param>
314
315 /// <param>命令类型 (存储过程,命令文本, 其它.)</param>
316
317 /// <param>存储过程名称或SQL语句</param>
318
319 /// <returns>返回命令影响的行数</returns>
320
321 public static int ExecuteNonQuery(
string connectionString, CommandType commandType,
string commandText)
322 {
323
324 return ExecuteNonQuery(connectionString, commandType, commandText, (SqlParameter[])
null);
325
326 }
327
328
329
330 /// <summary>
331
332 /// 执行指定连接字符串,类型的SqlCommand.如果没有提供参数,不返回结果.
333
334 /// </summary>
335
336 /// <remarks>
337
338 /// 示例:
339
340 /// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
341
342 /// </remarks>
343
344 /// <param>一个有效的数据库连接字符串</param>
345
346 /// <param>命令类型 (存储过程,命令文本, 其它.)</param>
347
348 /// <param>存储过程名称或SQL语句</param>
349
350 /// <param>SqlParameter参数数组</param>
351
352 /// <returns>返回命令影响的行数</returns>
353
354 public static int ExecuteNonQuery(
string connectionString, CommandType commandType,
string commandText,
params SqlParameter[] commandParameters)
355 {
356
357 if (connectionString ==
null || connectionString.Length ==
0)
throw new ArgumentNullException(
"connectionString");
358
359 using (SqlConnection connection =
new SqlConnection(connectionString))
360 {
361
362 connection.Open();
363
364 return ExecuteNonQuery(connection, commandType, commandText, commandParameters);
365
366 }
367
368 }
369
370
371
372 /// <summary>
373
374 /// 执行指定连接字符串的存储过程,将对象数组的值赋给存储过程参数,
375
376 /// 此方法需要在参数缓存方法中探索参数并生成参数.
377
378 /// </summary>
379
380 /// <remarks>
381
382 /// 这个方法没有提供访问输出参数和返回值.
383
384 /// 示例:
385
386 /// int result = ExecuteNonQuery(connString, "PublishOrders", 24, 36);
387
388 /// </remarks>
389
390 /// <param>一个有效的数据库连接字符串/param>
391
392 /// <param>存储过程名称</param>
393
394 /// <param>分配到存储过程输入参数的对象数组</param>
395
396 /// <returns>返回受影响的行数</returns>
397
398 public static int ExecuteNonQuery(
string connectionString,
string spName,
params object[] parameterValues)
399 {
400
401 if (connectionString ==
null || connectionString.Length ==
0)
throw new ArgumentNullException(
"connectionString");
402
403 if (spName ==
null || spName.Length ==
0)
throw new ArgumentNullException(
"spName");
404
405 // 如果存在参数值
406
407 if ((parameterValues !=
null) && (parameterValues.Length >
0))
408 {
409
410 // 从探索存储过程参数(加载到缓存)并分配给存储过程参数数组.
411
412 SqlParameter[] commandParameters =
SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
413
414 // 给存储过程参数赋值
415
416 AssignParameterValues(commandParameters, parameterValues);
417
418 return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName, commandParameters);
419
420 }
421
422 else
423 {
424
425 // 没有参数情况下
426
427 return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName);
428
429 }
430
431 }
432
433
434
435 /// <summary>
436
437 /// 执行指定数据库连接对象的命令
438
439 /// </summary>
440
441 /// <remarks>
442
443 /// 示例:
444
445 /// int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders");
446
447 /// </remarks>
448
449 /// <param>一个有效的数据库连接对象</param>
450
451 /// <param>命令类型(存储过程,命令文本或其它.)</param>
452
453 /// <param>存储过程名称或T-SQL语句</param>
454
455 /// <returns>返回影响的行数</returns>
456
457 public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType,
string commandText)
458 {
459
460 return ExecuteNonQuery(connection, commandType, commandText, (SqlParameter[])
null);
461
462 }
463
464
465
466 /// <summary>
467
468 /// 执行指定数据库连接对象的命令
469
470 /// </summary>
471
472 /// <remarks>
473
474 /// 示例:
475
476 /// int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
477
478 /// </remarks>
479
480 /// <param>一个有效的数据库连接对象</param>
481
482 /// <param>命令类型(存储过程,命令文本或其它.)</param>
483
484 /// <param>T存储过程名称或T-SQL语句</param>
485
486 /// <param>SqlParamter参数数组</param>
487
488 /// <returns>返回影响的行数</returns>
489
490 public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType,
string commandText,
params SqlParameter[] commandParameters)
491 {
492
493 if (connection ==
null)
throw new ArgumentNullException(
"connection");
494
495 // 创建SqlCommand命令,并进行预处理
496
497 SqlCommand cmd =
new SqlCommand();
498
499 bool mustCloseConnection =
false;
500
501 PrepareCommand(cmd, connection, (SqlTransaction)
null, commandType, commandText, commandParameters,
out mustCloseConnection);
502
503
504
505 // Finally, execute the command
506
507 int retval =
cmd.ExecuteNonQuery();
508
509
510
511 // 清除参数,以便再次使用.
512
513 cmd.Parameters.Clear();
514
515 if (mustCloseConnection)
516
517 connection.Close();
518
519 return retval;
520
521 }
522
523
524
525 /// <summary>
526
527 /// 执行指定数据库连接对象的命令,将对象数组的值赋给存储过程参数.
528
529 /// </summary>
530
531 /// <remarks>
532
533 /// 此方法不提供访问存储过程输出参数和返回值
534
535 /// 示例:
536
537 /// int result = ExecuteNonQuery(conn, "PublishOrders", 24, 36);
538
539 /// </remarks>
540
541 /// <param>一个有效的数据库连接对象</param>
542
543 /// <param>存储过程名</param>
544
545 /// <param>分配给存储过程输入参数的对象数组</param>
546
547 /// <returns>返回影响的行数</returns>
548
549 public static int ExecuteNonQuery(SqlConnection connection,
string spName,
params object[] parameterValues)
550 {
551
552 if (connection ==
null)
throw new ArgumentNullException(
"connection");
553
554 if (spName ==
null || spName.Length ==
0)
throw new ArgumentNullException(
"spName");
555
556 // 如果有参数值
557
558 if ((parameterValues !=
null) && (parameterValues.Length >
0))
559 {
560
561 // 从缓存中加载存储过程参数
562
563 SqlParameter[] commandParameters =
SqlHelperParameterCache.GetSpParameterSet(connection, spName);
564
565 // 给存储过程分配参数值