Data Access Layer to execute Stored Procedures

This article explains about executing a single stored procedure or batch of stored procedures from the application layer. As the Data access layer completely decoupled from the Application layer we just need to change the Application layer in case of any change in the underlying database schema.
 
This article explains primarily about calling stored procedures which does not return any result set. This can be extended to handle those stored procedures also.
 

Data access layer

 
This data access layer contains the following key elements.
  • ParamData Structure
  • StoredProcedure class
  • StoredProcedureCollection class
  • Execute class
ParamData structure will contain parameter name, parameter value and data type.
  1. struct ParamData {  
  2.     public string pName, pValue;  
  3.     public SqlDbType pDataType;  
  4.     public ParamData(string pName, SqlDbType pDataType, string pValue) {  
  5.         this.pName = pName;  
  6.         this.pDataType = pDataType;  
  7.         this.pValue = pValue;  
  8.     }  
Stored Procedure class which will have methods to SetParam and Getparam to set and get the parameter list. This will be added to array list which will contain ParamData structures.
  1. public void SetParam(string pName, SqlDbType pDataType, string pValue) {  
  2.     ParamData pData = new ParamData(pName, pDataType, pValue);  
  3.     // adding to array list sParams.  
  4.     sParams.Add(pData);  
Similarly to get the parameter list GetParams method was defined which will return array list of ParamData structures.
  1. public ArrayList GetParams() {  
  2.     if (!(sParams == null)) {  
  3.         return sParams;  
  4.     } else {  
  5.         return null;  
  6.     }  
StoredProcedureCollection class contains the collection of stored procedure classes. This class has ADD and Remove methods to add the StroredProcedure class and remove it when it is not needed.
  1. public void add(StoredProcedure value) {  
  2.     List.Add(value);  
  3. }  
  4. public void Remove(int index) {  
  5.     if (index > Count - 1 || index < 0) {  
  6.         Console.WriteLine("No data to remove");  
  7.     } else {  
  8.         List.RemoveAt(index);  
  9.     }  
This will also have an ITEM method to get the StoredProcedure from the List.
  1. public StoredProcedure Item(int Index) {  
  2.     return (StoredProcedure) List[Index];  
Execute class has a static method ExecuteSps to execute the stored procedures from the collection.
  1. public static bool ExecuteSps(StoredProcedureCollection spCollection, SqlConnection Connection) {  
  2.     try {  
  3.         foreach(StoredProcedure spData in spCollection) {  
  4.             SqlCommand cmd = new SqlCommand();  
  5.             int i = 0;  
  6.             if (Connection.State != ConnectionState.Open)  
  7.                 Connection.Open();  
  8.             cmd.Connection = Connection;  
  9.             cmd.CommandType = CommandType.StoredProcedure;  
  10.             cmd.CommandText = spData.ProcName;  
  11.             IEnumerator myEnumerator = spData.GetParams().GetEnumerator();  
  12.             while (myEnumerator.MoveNext()) {  
  13.                 ParamData pData = (ParamData) myEnumerator.Current;  
  14.                 cmd.Parameters.Add(pData.pName, pData.pDataType);  
  15.                 cmd.Parameters[i].Value = pData.pValue;  
  16.                 i = i + 1;  
  17.             }  
  18.             cmd.ExecuteNonQuery();  
  19.         }  
  20.         return true;  
  21.     } catch (Exception exc) {  
  22.         return false;  
  23.     }  
Please find the code snippet in <<DataAccessLayer.ZIP>> file.
 

Application Layer

 
In the application layer, we have to add the reference of DataAccessLayer.dll. After adding this reference we can call the data access layer functions as per our need. The advantage here is we can dynamically add/remove the parameters as and whenever there is change stored procedure definition.
  1. private void button1_Click(object sender, System.EventArgs e) {  
  2.     SqlConnection connection = new SqlConnection();  
  3.     //change this connect string as per your environment  
  4.     string connectString = "Persist Security Info=False;Integrated Security=SSPI;database=DB1;server=Server2;Connect Timeout=60";  
  5.     connection.ConnectionString = connectString;  
  6.     if (connection.State != ConnectionState.Open)  
  7.         connection.Open();  
  8.     DataAccessLayer.StoredProcedureCollection spCollection = new DataAccessLayer.StoredProcedureCollection();  
  9.     DataAccessLayer.StoredProcedure spData = new DataAccessLayer.StoredProcedure();  
  10.     spData.ProcName = txtSpName.Text;  
  11.     spData.SetParam(txtParam1.Text, SqlDbType.VarChar, txtParamValue1.Text);  
  12.     spData.SetParam(txtParam2.Text, SqlDbType.VarChar, txtParamValue2.Text);  
  13.     spCollection.add(spData);  
  14.     if (DataAccessLayer.Execute.ExecuteSps(spCollection, connection))  
  15.         MessageBox.Show("Successfully executed");  
  16.   
  17.     catch (Exception exc) {  
  18.         return false;  
  19.     }  
Please find the code snippet for using the data access layer from the <<CallingAPP.zip>> file.