SQLHelper.cs
上传用户:autodoor
上传日期:2022-08-04
资源大小:9973k
文件大小:26k
源码类别:

.net编程

开发平台:

Others

  1. //*********************************************************************
  2. // Microsoft Data Access Application Block for .NET
  3. // http://msdn.microsoft.com/library/en-us/dnbda/html/daab-rm.asp
  4. //
  5. // SQLHelper.cs
  6. //
  7. // This file contains the implementations of the SqlHelper and SqlHelperParameterCache
  8. // classes.
  9. //
  10. // For more information see the Data Access Application Block Implementation Overview. 
  11. // 
  12. //*********************************************************************
  13. // Copyright (C) 2000-2001 Microsoft Corporation
  14. // All rights reserved.
  15. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
  16. // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
  17. // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR
  18. // FITNESS FOR A PARTICULAR PURPOSE.
  19. //*********************************************************************
  20. using System;
  21. using System.Data;
  22. using System.Data.SqlClient;
  23. using System.Collections;
  24. namespace qminoa.DA
  25. {
  26. //*********************************************************************
  27. //
  28. // The SqlHelper class is intended to encapsulate high performance, scalable best practices for 
  29. // common uses of SqlClient.
  30. //
  31. //*********************************************************************
  32. public sealed class SqlHelper
  33. {
  34. //*********************************************************************
  35. //
  36. // Since this class provides only static methods, make the default constructor private to prevent 
  37. // instances from being created with "new SqlHelper()".
  38. //
  39. //*********************************************************************
  40. private SqlHelper() {}
  41. //*********************************************************************
  42. //
  43. // This method is used to attach array of SqlParameters to a SqlCommand.
  44. // 
  45. // This method will assign a value of DbNull to any parameter with a direction of
  46. // InputOutput and a value of null.  
  47. // 
  48. // This behavior will prevent default values from being used, but
  49. // this will be the less common case than an intended pure output parameter (derived as InputOutput)
  50. // where the user provided no input value.
  51. // 
  52. // param name="command" The command to which the parameters will be added
  53. // param name="commandParameters" an array of SqlParameters tho be added to command
  54. //
  55. //*********************************************************************
  56. private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters)
  57. {
  58. foreach (SqlParameter p in commandParameters)
  59. {
  60. //check for derived output value with no value assigned
  61. if ((p.Direction == ParameterDirection.InputOutput) && (p.Value == null))
  62. {
  63. p.Value = DBNull.Value;
  64. }
  65. command.Parameters.Add(p);
  66. }
  67. }
  68. //*********************************************************************
  69. //
  70. // This method assigns an array of values to an array of SqlParameters.
  71. // 
  72. // param name="commandParameters" array of SqlParameters to be assigned values
  73. // param name="parameterValues" array of objects holding the values to be assigned
  74. //
  75. //*********************************************************************
  76. private static void AssignParameterValues(SqlParameter[] commandParameters, object[] parameterValues)
  77. {
  78. if ((commandParameters == null) || (parameterValues == null)) 
  79. {
  80. //do nothing if we get no data
  81. return;
  82. }
  83. // we must have the same number of values as we pave parameters to put them in
  84. if (commandParameters.Length != parameterValues.Length)
  85. {
  86. throw new ArgumentException("Parameter count does not match Parameter Value count.");
  87. }
  88. //iterate through the SqlParameters, assigning the values from the corresponding position in the 
  89. //value array
  90. for (int i = 0, j = commandParameters.Length; i < j; i++)
  91. {
  92. commandParameters[i].Value = parameterValues[i];
  93. }
  94. }
  95. //*********************************************************************
  96. //
  97. // This method opens (if necessary) and assigns a connection, transaction, command type and parameters 
  98. // to the provided command.
  99. // 
  100. // param name="command" the SqlCommand to be prepared
  101. // param name="connection" a valid SqlConnection, on which to execute this command
  102. // param name="transaction" a valid SqlTransaction, or 'null'
  103. // param name="commandType" the CommandType (stored procedure, text, etc.)
  104. // param name="commandText" the stored procedure name or T-SQL command
  105. // param name="commandParameters" an array of SqlParameters to be associated with the command or 'null' if no parameters are required
  106. //
  107. //*********************************************************************
  108. private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters)
  109. {
  110. //if the provided connection is not open, we will open it
  111. if (connection.State != ConnectionState.Open)
  112. {
  113. connection.Open();
  114. }
  115. //associate the connection with the command
  116. command.Connection = connection;
  117. //set the command text (stored procedure name or SQL statement)
  118. command.CommandText = commandText;
  119. //if we were provided a transaction, assign it.
  120. if (transaction != null)
  121. {
  122. command.Transaction = transaction;
  123. }
  124. //set the command type
  125. command.CommandType = commandType;
  126. //attach the command parameters if they are provided
  127. if (commandParameters != null)
  128. {
  129. AttachParameters(command, commandParameters);
  130. }
  131. return;
  132. }
  133. //*********************************************************************
  134. //
  135. // Execute a SqlCommand (that returns no resultset) against the database specified in the connection string 
  136. // using the provided parameters.
  137. //
  138. // e.g.:  
  139. //  int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
  140. //
  141. // param name="connectionString" a valid connection string for a SqlConnection
  142. // param name="commandType" the CommandType (stored procedure, text, etc.)
  143. // param name="commandText" the stored procedure name or T-SQL command
  144. // param name="commandParameters" an array of SqlParamters used to execute the command
  145. // returns an int representing the number of rows affected by the command
  146. //
  147. //*********************************************************************
  148. public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  149. {
  150. //create & open a SqlConnection, and dispose of it after we are done.
  151. using (SqlConnection cn = new SqlConnection(connectionString))
  152. {
  153. cn.Open();
  154. //call the overload that takes a connection in place of the connection string
  155. return ExecuteNonQuery(cn, commandType, commandText, commandParameters);
  156. }
  157. }
  158. //*********************************************************************
  159. //
  160. // Execute a stored procedure via a SqlCommand (that returns no resultset) against the database specified in 
  161. // the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
  162. // stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
  163. // 
  164. // This method provides no access to output parameters or the stored procedure's return value parameter.
  165. // 
  166. // e.g.:  
  167. //  int result = ExecuteNonQuery(connString, "PublishOrders", 24, 36);
  168. //
  169. // param name="connectionString" a valid connection string for a SqlConnection
  170. // param name="spName" the name of the stored prcedure
  171. // param name="parameterValues" an array of objects to be assigned as the input values of the stored procedure
  172. // returns an int representing the number of rows affected by the command
  173. //
  174. //*********************************************************************
  175. public static int ExecuteNonQuery(string connectionString, string spName, params object[] parameterValues)
  176. {
  177. //if we receive parameter values, we need to figure out where they go
  178. if ((parameterValues != null) && (parameterValues.Length > 0)) 
  179. {
  180. //pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
  181. SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
  182. //assign the provided values to these parameters based on parameter order
  183. AssignParameterValues(commandParameters, parameterValues);
  184. //call the overload that takes an array of SqlParameters
  185. return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName, commandParameters);
  186. }
  187. //otherwise we can just call the SP without params
  188. else 
  189. {
  190. return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName);
  191. }
  192. }
  193. //*********************************************************************
  194. //
  195. // Execute a SqlCommand (that returns no resultset) against the specified SqlConnection 
  196. // using the provided parameters.
  197. // 
  198. // e.g.:  
  199. //  int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
  200. // 
  201. // param name="connection" a valid SqlConnection 
  202. // param name="commandType" the CommandType (stored procedure, text, etc.) 
  203. // param name="commandText" the stored procedure name or T-SQL command 
  204. // param name="commandParameters" an array of SqlParamters used to execute the command 
  205. // returns an int representing the number of rows affected by the command
  206. //
  207. //*********************************************************************
  208. public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  209. {
  210. //create a command and prepare it for execution
  211. SqlCommand cmd = new SqlCommand();
  212. PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters);
  213. //finally, execute the command.
  214. int retval = cmd.ExecuteNonQuery();
  215. // detach the SqlParameters from the command object, so they can be used again.
  216. cmd.Parameters.Clear();
  217. return retval;
  218. }
  219. //*********************************************************************
  220. //
  221. // Execute a SqlCommand (that returns a resultset) against the database specified in the connection string 
  222. // using the provided parameters.
  223. // 
  224. // e.g.:  
  225. //  DataSet ds = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
  226. // 
  227. // param name="connectionString" a valid connection string for a SqlConnection 
  228. // param name="commandType" the CommandType (stored procedure, text, etc.) 
  229. // param name="commandText" the stored procedure name or T-SQL command 
  230. // param name="commandParameters" an array of SqlParamters used to execute the command 
  231. // returns a dataset containing the resultset generated by the command
  232. //
  233. //*********************************************************************
  234. public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  235. {
  236. //create & open a SqlConnection, and dispose of it after we are done.
  237. using (SqlConnection cn = new SqlConnection(connectionString))
  238. {
  239. cn.Open();
  240. //call the overload that takes a connection in place of the connection string
  241. return ExecuteDataset(cn, commandType, commandText, commandParameters);
  242. }
  243. }
  244. //*********************************************************************
  245. //
  246. // Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in 
  247. // the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
  248. // stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
  249. // 
  250. // This method provides no access to output parameters or the stored procedure's return value parameter.
  251. // 
  252. // e.g.:  
  253. //  DataSet ds = ExecuteDataset(connString, "GetOrders", 24, 36);
  254. // 
  255. // param name="connectionString" a valid connection string for a SqlConnection
  256. // param name="spName" the name of the stored procedure
  257. // param name="parameterValues" an array of objects to be assigned as the input values of the stored procedure
  258. // returns a dataset containing the resultset generated by the command
  259. //
  260. //*********************************************************************
  261. public static DataSet ExecuteDataset(string connectionString, string spName, params object[] parameterValues)
  262. {
  263. //if we receive parameter values, we need to figure out where they go
  264. if ((parameterValues != null) && (parameterValues.Length > 0)) 
  265. {
  266. //pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
  267. SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
  268. //assign the provided values to these parameters based on parameter order
  269. AssignParameterValues(commandParameters, parameterValues);
  270. //call the overload that takes an array of SqlParameters
  271. return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName, commandParameters);
  272. }
  273. //otherwise we can just call the SP without params
  274. else 
  275. {
  276. return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName);
  277. }
  278. }
  279. //*********************************************************************
  280. //
  281. // Execute a SqlCommand (that returns a resultset) against the specified SqlConnection 
  282. // using the provided parameters.
  283. // 
  284. // e.g.:  
  285. //  DataSet ds = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
  286. //
  287. // param name="connection" a valid SqlConnection
  288. // param name="commandType" the CommandType (stored procedure, text, etc.)
  289. // param name="commandText" the stored procedure name or T-SQL command
  290. // param name="commandParameters" an array of SqlParamters used to execute the command
  291. // returns a dataset containing the resultset generated by the command
  292. //
  293. //*********************************************************************
  294. public static DataSet ExecuteDataset(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  295. {
  296. //create a command and prepare it for execution
  297. SqlCommand cmd = new SqlCommand();
  298. PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters);
  299. //create the DataAdapter & DataSet
  300. SqlDataAdapter da = new SqlDataAdapter(cmd);
  301. DataSet ds = new DataSet();
  302. //fill the DataSet using default values for DataTable names, etc.
  303. da.Fill(ds);
  304. // detach the SqlParameters from the command object, so they can be used again.
  305. cmd.Parameters.Clear();
  306. //return the dataset
  307. return ds;
  308. }
  309. //*********************************************************************
  310. //
  311. // Execute a SqlCommand (that returns a 1x1 resultset) against the database specified in the connection string 
  312. // using the provided parameters.
  313. // 
  314. // e.g.:  
  315. //  int orderCount = (int)ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));
  316. // 
  317. // param name="connectionString" a valid connection string for a SqlConnection 
  318. // param name="commandType" the CommandType (stored procedure, text, etc.) 
  319. // param name="commandText" the stored procedure name or T-SQL command 
  320. // param name="commandParameters" an array of SqlParamters used to execute the command 
  321. // returns an object containing the value in the 1x1 resultset generated by the command
  322. //
  323. //*********************************************************************
  324. public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  325. {
  326. //create & open a SqlConnection, and dispose of it after we are done.
  327. using (SqlConnection cn = new SqlConnection(connectionString))
  328. {
  329. cn.Open();
  330. //call the overload that takes a connection in place of the connection string
  331. return ExecuteScalar(cn, commandType, commandText, commandParameters);
  332. }
  333. }
  334. //*********************************************************************
  335. //
  336. // Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the database specified in 
  337. // the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
  338. // stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
  339. // 
  340. // This method provides no access to output parameters or the stored procedure's return value parameter.
  341. // 
  342. // e.g.:  
  343. //  int orderCount = (int)ExecuteScalar(connString, "GetOrderCount", 24, 36);
  344. // 
  345. // param name="connectionString" a valid connection string for a SqlConnection 
  346. // param name="spName" the name of the stored procedure 
  347. // param name="parameterValues" an array of objects to be assigned as the input values of the stored procedure 
  348. // returns an object containing the value in the 1x1 resultset generated by the command
  349. //
  350. //*********************************************************************
  351. public static object ExecuteScalar(string connectionString, string spName, params object[] parameterValues)
  352. {
  353. //if we receive parameter values, we need to figure out where they go
  354. if ((parameterValues != null) && (parameterValues.Length > 0)) 
  355. {
  356. //pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
  357. SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
  358. //assign the provided values to these parameters based on parameter order
  359. AssignParameterValues(commandParameters, parameterValues);
  360. //call the overload that takes an array of SqlParameters
  361. return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName, commandParameters);
  362. }
  363. //otherwise we can just call the SP without params
  364. else 
  365. {
  366. return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName);
  367. }
  368. }
  369. //*********************************************************************
  370. //
  371. // Execute a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection 
  372. // using the provided parameters.
  373. // 
  374. // e.g.:  
  375. //  int orderCount = (int)ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));
  376. // 
  377. // param name="connection" a valid SqlConnection 
  378. // param name="commandType" the CommandType (stored procedure, text, etc.) 
  379. // param name="commandText" the stored procedure name or T-SQL command 
  380. // param name="commandParameters" an array of SqlParamters used to execute the command 
  381. // returns an object containing the value in the 1x1 resultset generated by the command
  382. //
  383. //*********************************************************************
  384. public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
  385. {
  386. //create a command and prepare it for execution
  387. SqlCommand cmd = new SqlCommand();
  388. PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters);
  389. //execute the command & return the results
  390. object retval = cmd.ExecuteScalar();
  391. // detach the SqlParameters from the command object, so they can be used again.
  392. cmd.Parameters.Clear();
  393. return retval;
  394. }
  395. }
  396. //*********************************************************************
  397. //
  398. // SqlHelperParameterCache provides functions to leverage a static cache of procedure parameters, and the
  399. // ability to discover parameters for stored procedures at run-time.
  400. //
  401. //*********************************************************************
  402. public sealed class SqlHelperParameterCache
  403. {
  404. //*********************************************************************
  405. //
  406. // Since this class provides only static methods, make the default constructor private to prevent 
  407. // instances from being created with "new SqlHelperParameterCache()".
  408. //
  409. //*********************************************************************
  410. private SqlHelperParameterCache() {}
  411. private static Hashtable paramCache = Hashtable.Synchronized(new Hashtable());
  412. //*********************************************************************
  413. //
  414. // resolve at run time the appropriate set of SqlParameters for a stored procedure
  415. // 
  416. // param name="connectionString" a valid connection string for a SqlConnection 
  417. // param name="spName" the name of the stored procedure 
  418. // param name="includeReturnValueParameter" whether or not to include their return value parameter 
  419. //
  420. //*********************************************************************
  421. private static SqlParameter[] DiscoverSpParameterSet(string connectionString, string spName, bool includeReturnValueParameter)
  422. {
  423. using (SqlConnection cn = new SqlConnection(connectionString)) 
  424. using (SqlCommand cmd = new SqlCommand(spName,cn))
  425. {
  426. cn.Open();
  427. cmd.CommandType = CommandType.StoredProcedure;
  428. SqlCommandBuilder.DeriveParameters(cmd);
  429. if (!includeReturnValueParameter) 
  430. {
  431. cmd.Parameters.RemoveAt(0);
  432. }
  433. SqlParameter[] discoveredParameters = new SqlParameter[cmd.Parameters.Count];;
  434. cmd.Parameters.CopyTo(discoveredParameters, 0);
  435. return discoveredParameters;
  436. }
  437. }
  438. private static SqlParameter[] CloneParameters(SqlParameter[] originalParameters)
  439. {
  440. //deep copy of cached SqlParameter array
  441. SqlParameter[] clonedParameters = new SqlParameter[originalParameters.Length];
  442. for (int i = 0, j = originalParameters.Length; i < j; i++)
  443. {
  444. clonedParameters[i] = (SqlParameter)((ICloneable)originalParameters[i]).Clone();
  445. }
  446. return clonedParameters;
  447. }
  448. //*********************************************************************
  449. //
  450. // add parameter array to the cache
  451. //
  452. // param name="connectionString" a valid connection string for a SqlConnection 
  453. // param name="commandText" the stored procedure name or T-SQL command 
  454. // param name="commandParameters" an array of SqlParamters to be cached 
  455. //
  456. //*********************************************************************
  457. public static void CacheParameterSet(string connectionString, string commandText, params SqlParameter[] commandParameters)
  458. {
  459. string hashKey = connectionString + ":" + commandText;
  460. paramCache[hashKey] = commandParameters;
  461. }
  462. //*********************************************************************
  463. //
  464. // Retrieve a parameter array from the cache
  465. // 
  466. // param name="connectionString" a valid connection string for a SqlConnection 
  467. // param name="commandText" the stored procedure name or T-SQL command 
  468. // returns an array of SqlParamters
  469. //
  470. //*********************************************************************
  471. public static SqlParameter[] GetCachedParameterSet(string connectionString, string commandText)
  472. {
  473. string hashKey = connectionString + ":" + commandText;
  474. SqlParameter[] cachedParameters = (SqlParameter[])paramCache[hashKey];
  475. if (cachedParameters == null)
  476. {
  477. return null;
  478. }
  479. else
  480. {
  481. return CloneParameters(cachedParameters);
  482. }
  483. }
  484. //*********************************************************************
  485. //
  486. // Retrieves the set of SqlParameters appropriate for the stored procedure
  487. // 
  488. // This method will query the database for this information, and then store it in a cache for future requests.
  489. // 
  490. // param name="connectionString" a valid connection string for a SqlConnection 
  491. // param name="spName" the name of the stored procedure 
  492. // returns an array of SqlParameters
  493. //
  494. //*********************************************************************
  495. public static SqlParameter[] GetSpParameterSet(string connectionString, string spName)
  496. {
  497. return GetSpParameterSet(connectionString, spName, false);
  498. }
  499. //*********************************************************************
  500. //
  501. // Retrieves the set of SqlParameters appropriate for the stored procedure
  502. // 
  503. // This method will query the database for this information, and then store it in a cache for future requests.
  504. // 
  505. // param name="connectionString" a valid connection string for a SqlConnection 
  506. // param name="spName" the name of the stored procedure 
  507. // param name="includeReturnValueParameter" a bool value indicating whether the return value parameter should be included in the results 
  508. // returns an array of SqlParameters
  509. //
  510. //*********************************************************************
  511. public static SqlParameter[] GetSpParameterSet(string connectionString, string spName, bool includeReturnValueParameter)
  512. {
  513. string hashKey = connectionString + ":" + spName + (includeReturnValueParameter ? ":include ReturnValue Parameter":"");
  514. SqlParameter[] cachedParameters;
  515. cachedParameters = (SqlParameter[])paramCache[hashKey];
  516. if (cachedParameters == null)
  517. {
  518. cachedParameters = (SqlParameter[])(paramCache[hashKey] = DiscoverSpParameterSet(connectionString, spName, includeReturnValueParameter));
  519. }
  520. return CloneParameters(cachedParameters);
  521. }
  522. }
  523. }