How do i execute a stored procedure in wcf module c# - c#

I am creating a wcf module that i would like to execute a stored procedure and return the results. This is what i have so far
public static class Provder
{
private const string CommandSchema_FullName = "Table3";
public static IEnumerable<ProviderModel> Get(Func<ProviderModel> )
{
var query = new StringBuilder();
query.AppendFormat("SELECT * FROM {0}", CommandSchema_FullName);
if (criteria != null)
return ExecuteQuery(query.ToString()).Where(criteria).ToArray();
return ExecuteQuery(query.ToString());
//i can read from a table like above,im not sure how to add in a new stored procedure that i would like to call
}
private static IEnumerable<ProviderModel> ExecuteQuery(string query)
{
var result = new List<ProviderModel>();
using (var sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["netTiersConnectionString"].ToString()))
{
sqlConnection.Open();
var reader = new SqlCommand(query, sqlConnection).ExecuteReader();
while (reader.Read())
{
result.Add(new ProviderModel
{
});
}
sqlConnection.Close();
}
return result;
}
private static bool ExecuteCommand(string command)
{
var result = false;
using (var sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["netTiersConnectionString"].ToString()))
{
sqlConnection.Open();
try
{
var recordsAffected = new SqlCommand(command, sqlConnection).ExecuteNonQuery();
result = true;
}
catch (SqlException)
{
result = false;
}
finally
{
sqlConnection.Close();
}
}
return result;
}
}
public class ProviderModel
{
}
This is the stored procedure i want to call in the above methods
CREATE PROCEDURE GetListCodes
AS
BEGIN
select concat(p.CourseName,s.LeagueTitle,' ',p.Abbreviation) As Result,p.ProgramCode
FROM Table1 p inner join Table2 s on p.Code=s.Code
END
GO
I am not sure how to call the sp GetListCodes in the above wcf model. I dont have any parameters to pass,i would just like to execute the stored procedure and get the results.

What you need to exceute a store procedure, on the command is a simple line
cmd.CommandType = CommandType.StoredProcedure;
In your case, you would have to replace the line
var recordsAffected = new SqlCommand(command,
sqlConnection).ExecuteNonQuery();
with
var cmd= new SqlCommand(command, sqlConnection);
cmd.CommandType = CommandType.StoredProcedure;
var recordsAffected = cmd.ExecuteNonQuery();
There is a nice little tutorial you can find at https://csharp-station.com/Tutorial/AdoDotNet/Lesson07
And Miscrosoft also has an article located at https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/executing-a-command

Related

Select for login and update at the same time

Is it possible to use SQL command for login and update at the same time? I mean when the Login is done, I want to change logat in 1. Do I have to create a new if with OpenConnection()?
public bool IsLogin(string user, string pass) {
string query = $"SELECT * from utiliz WHERE username='{user}' AND password='{GetSha1(pass)}'";
string query_update = $"UPDATE utiliz SET logat='{1}' WHERE username='{user}'";
try
{
if (OpenConnection())
{
MySqlCommand cmd = new MySqlCommand(query, conn);
MySqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
reader.Close();
conn.Close();
return true;
}
else
{
reader.Close();
conn.Close();
return false;
}
}
else {
conn.Close();
return false;
}
}
catch (Exception ex) {
conn.Close();
return false;
}
}
EDITED
Guys, I have edited my code, following parameters procedure. Is it good what I did?
if (String.IsNullOrEmpty(textBox_pass_login.Text) && String.IsNullOrEmpty(textBox_usr_login.Text) || String.IsNullOrEmpty(textBox_usr_login.Text) || String.IsNullOrEmpty(textBox_pass_login.Text))
{
System.Windows.Forms.MessageBox.Show("Both fields (username,password) are required");
}
else
{
string user = textBox_usr_login.Text;
string password = textBox_pass_login.Text;
string encryptedpass = GetSha1(password);
try
{
using (var connection = conn)
{
string query = "SELECT * from utiliz WHERE username=#user AND password=#password";
using (var command = new MySqlCommand(query, conn))
{
command.Parameters.AddWithValue("#user", user);
command.Parameters.AddWithValue("#password", encryptedpass);
MySqlDataAdapter sda = new MySqlDataAdapter(command);
DataTable dt = new DataTable();
sda.Fill(dt);
conn.Open();
int i = command.ExecuteNonQuery();
conn.Close();
if (dt.Rows.Count > 0)
{
this.Hide();
var form2 = new Form1();
form2.Closed += (s, args) => this.Close();
form2.Show();
}
else
{
System.Windows.Forms.MessageBox.Show("Wrong credentials");
textBox_usr_login.Clear();
textBox_pass_login.Clear();
}
}
}
}
catch
{
System.Windows.Forms.MessageBox.Show("Wrong credentials");
textBox_usr_login.Clear();
textBox_pass_login.Clear();
}
}
There are some important points here. You must use Parameterized queries to improve the performence of your query on the database layer and avoid some problems such as sql injection. You also could use transactions to keep data integrity.
Check the sample bellow with comments (I didn't test this code, may not work properly on your environment):
public bool IsLogin(string user, string pass)
{
// prepare the queries with parameters with '#' and parameter name
const string query = "SELECT count(username) from utiliz WHERE username = #username AND password = #password";
const string query_update = "UPDATE utiliz SET logat = #logat WHERE username = #username";
// prepare the encrypted password
string encryptedPass = GetSha1(pass);
// use a result variable to use as the function result
bool result = false;
try
{
if (OpenConnection())
{
// start a transaction from the connection object
using (MySqlTransaction tran = conn.BeginTransaction())
{
try
{
int userFound = 0;
// prepare the MySqlCommand to use the query, connection and transaction.
using (MySqlCommand userCommand = new MySqlCommand(query, conn, tran))
{
userCommand.Parameters.AddWithValue("#username", user);
userCommand.Parameters.AddWithValue("#password", encryptedPass);
userFound = (int) userCommand.ExecuteScalar();
}
if (userFound > 0)
{
// prepare the MySqlCommand to use the query, connection and transaction to update data
using (MySqlCommand logatCommand = new MySqlCommand(query_update, conn, tran))
{
logatCommand.Parameters.AddWithValue("#logat", DateTime.Now);
logatCommand.Parameters.AddWithValue("#username", user);
logatCommand.ExecuteNonQuery();
}
}
// commit the transaction
tran.Commit();
result = true;
}
catch (Exception ex)
{
// perform some log with ex object.
tran.Rollback();
}
finally
{
conn.Close();
}
}
}
}
catch (Exception e)
{
// perform some log...
return false;
}
return result;
}
As recommended (and demonstrated) by Felipe Oriani, you should use parameterized queries.
Let me pinpoint, however, that you can do this with a single update query. The trick is to filter the update query on both user name and password:
UPDATE utiliz SET logat = #logat WHERE username = #username AND password = #password
You want to run the query with method ExecuteNonQuery, which returns the number of rows affected.
If credentials are valid, the where cause selects the relevant record and the update happens, returning 1 as the count of records affected. Else, no record is updated, and the method returns 0.

PL/SQL How to get SP's OUT parameter

I have a DAL function that needs to call a stored procedure and get the dataset, along with a couple of OUT parameters. I can get the resulting dataset but not sure how to get the parameters.
Normally, the parameters are available through cmd.Parameters["ParamName"].Value but I am using another API to make the DB connection and return the resulting dataset, not sure how to get the OUT parameters in addition to dataset.
Here is what i have, so far:
Public static int getSomething(string inParam, out DataTable dtOut, out string outParam1, out string outParam2)
{
OracleDbCntext dbContext = new OracleDbContext();
DataSet dsOut = new DataSet()
DataTable dtOut = new dataTable();
....
try
{
List<OracleParameter> spParams = new List<OracleParameter>();
spParams.Add(new OracleParameter("INPARAM", OracleDbType.Varchar2, receptacleID, ParameterDirection.Input));
spParams.Add(new OracleParameter("OUTARAM1", OracleDbType.TimeStamp, null, ParameterDirection.Output));
spParams.Add(new OracleParameter("OUTARAM2", OracleDbType.TimeStamp, null, ParameterDirection.Output));
spParams.Add(new OracleParameter("CUR_OUT", OracleDbType.RefCursor, ParameterDirection.Output));
try
{
dbContext.Open();
dbContext.ExecuteStoredProcedure("SOME_PKG.USP_SOMESP", spParams, ref dsOutcome);
}
catch (Exception oConnException)
{
}
if (dsOut != null)
{
if (dsOut.Tables[0].Rows.Count > 0)
{
dtOut = dsOut.Tables[0];
//outParam1 = ????
//outParam2 = ????
}
}
}
}
namespace Something.Model.DataAccess
{
public class OracleDbContext
{
public OracleConnection DbConnection { get; private set; }
public OracleDbContext()
{
string ConnectionString = ConfigurationManager.ConnectionStrings["DefaultConnectionString"].ConnectionString;
DbConnection = new OracleConnection(ConnectionString);
}
public void Open()
{
if (DbConnection.State != ConnectionState.Open)
{
DbConnection.Close();
DbConnection.Open();
}
}
public void Close()
{
if (DbConnection.State == ConnectionState.Open || DbConnection.State == ConnectionState.Broken)
{
DbConnection.Close();
DbConnection.Dispose();
}
}
public void ExecuteStoredProcedure(string spName, List<OracleParameter> spParams, ref DataSet dataset)
{
OracleDataAdapter da = null;
OracleTransaction oraTransaction = null;
using (OracleCommand command = new OracleCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddRange(spParams.ToArray<OracleParameter>());
command.Connection = DbConnection;
command.CommandText = spName;
try
{
oraTransaction = DbConnection.BeginTransaction();
da = new OracleDataAdapter(command);
da.Fill(dataset);
oraTransaction.Commit();
}
catch (Exception e)
{
oraTransaction.Rollback();
}
finally
{
if (oraTransaction != null)
oraTransaction.Dispose();
if (DbConnection != null)
{
this.Close();
}
}
}
}
Stored Procedure in SOME_PKG:
PROCEDURE USP_SOMESP
(
INPARAM VARCHAR2,
OUTPARAM1 OUT TIMESTAMP,
OUTPARAM2 OUT TIMESTAMP,
CUR_OUT OUT GETDATACURSOR
)
....
LVSQUERY:='SELECT FIELD1, '''|| V_EVENTCODE ||''' AS EVENTCODE, ...
WHERE SOMETHING= '''|| V_LOC1||''' ';
OPEN CUR_OUT FOR LVSQUERY;
EXCEPTION WHEN OTHERS THEN
...;
END USP_SOMESP;
As you have a layer in the middle you might need to change your code a little bit.
Change this
spParams.Add(new OracleParameter("OUTARAM1", OracleDbType.TimeStamp, null, ParameterDirection.Output));
with
var outParam1 = new OracleParameter("OUTARAM1", OracleDbType.TimeStamp, null, ParameterDirection.Output);
spParams.Add(outParam1);
And then use the Value property:
outParam1.Value;
According to the documentation:
For output parameters the value is:
Set on completion of the OracleCommand (true for return value parameters also).
Set to the data from the database, to the data type specified in OracleDbType or DbType.

Convert dataset into integer

look i have this code:
private void obtengoUltimoComienzoColocado()
{
ManejoUsuarios lAdm = new ManejoUsuarios();
lblTodoOK.Text = lAdm.LevantoUltimoIDBarco().ToString();
}
public int LevantoUltimoIDBarco()
{
ConexionBD lP = new ConexionBD();
try
{
string lQuery = "Select Max(idBarco) as UltimoID From Comienzos;";
Convert.ToInt32(lP.ObtenerRegistro(lQuery));
return 1;
}
catch (Exception ex)
{
return 0;
}
}
public DataSet ObtenerRegistro(string SqlQuery)
{
DataSet lResult;
SqlConnection lSqlConnection = new SqlConnection("Data Source=SEBA-PC\\sqlexpress;Initial Catalog=Batalla_Naval;Integrated Security=True");
SqlCommand lSqlCommand = null;
try
{
lSqlCommand = new SqlCommand();
lSqlCommand.CommandText = SqlQuery;
lSqlCommand.CommandType = CommandType.Text;
SqlDataAdapter lAdapter = new SqlDataAdapter(lSqlCommand);
lResult = new DataSet();
lSqlConnection.Open();
lSqlCommand.Connection = lSqlConnection;
lAdapter.Fill(lResult);
}
catch (Exception)
{
throw;
}
finally
{
lSqlConnection.Close();
}
return lResult;
}
As you can see i use three functions to go to the database and get the max ID from the table Comienzos, but when i want to convert the data set to int32 the function LevantoUltimoIDBarco returns me 0,
You have to select the first value from the dataset, you can not convert a complete dataset to integer:
Convert.ToInt32(lP.ObtenerRegistro(lQuery).Tables[0].Rows[0][0]);
or simpler (since the query returns an integer in the dataset):
(Int32)(lP.ObtenerRegistro(lQuery).Tables[0].Rows[0][0]);
And then you have to return or save the result instead of just returning 1.
My friend you should use ExecuteScalar to return a single value, and not an adapter and fill a dataset.
SqlConnection lSqlConnection = new SqlConnection("Data Source=SEBA-PC\\sqlexpress;Initial Catalog=Batalla_Naval;Integrated Security=True");
SqlCommand lSqlCommand = null;
try
{
lSqlCommand = new SqlCommand();
lSqlCommand.CommandText = SqlQuery;
lSqlCommand.CommandType = CommandType.Text;
var result = lSqlCommand.ExecuteScalar();
int MyID = Convert.ToInt32(result);
}
catch(ex)
{
// DO SOMETHING
}
Looking at how you retrieve your data, then the correct code to read that integer (MAX()) is the following
string lQuery = "Select Max(idBarco) as UltimoID From Comienzos;";
DataSet ds = lP.ObtenerRegistro(lQuery);
return Convert.ToInt32(ds.Tables[0].Rows[0][0] == DBNull.Value ? 0 : ds.Tables[0].Rows[0][0]);
However, if your table has no record the MAX(idBarco) will return DBNull as result

How to get the primary key of a table in sql server 2008

I have the following code which should be able to get the primary key in a table
public List<string> GetPrimaryKeysForTable(string tableName)
{
List<String> retVal = new List<string>();
SqlCommand command = connector.GetCommand("sp_pkeys");
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Parameters.AddWithValue("#table_name", typeof(SqlChars)).Value = tableName;
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
retVal.Add(reader[3].ToString());
}
return retVal;
}
I have a table called Users in my database. When I pass Users in as my parameter, the reader returns no results. Any idea why this might be failing to return my primary keys?
Try this instead:
command.Parameters.Add("#table_name", SqlDbType.NVarChar).Value = tableName;
It looks like you have an issue with your usage of .AddWithValue() which may be causing your problem. See the fix below:
public List<string> GetPrimaryKeysForTable(string tableName)
{
List<string> retVal = new List<string>();
SqlCommand command = connector.GetCommand("sp_pkeys");
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Parameters.AddWithValue("#table_name", tableName);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
retVal.Add(reader[3].ToString());
}
return retVal;
}
In your example you are attempting to add the #table_name as a Type rather than a string.
Any chance it needs to be qualified with the schema? Something like:
command.Parameters.AddWithValue("#table_name", typeof(SqlChars)).Value = "dbo." + tableName;
or:
command.Parameters.AddWithValue("#schema", "dbo");
Or is there some parm you need to add to tell it the database inside the server?
You can simply use as below, would you please try it out:
command.Parameters.AddWithValue("#table_name", ("dbo." + tableName));
The stored procedure 'sp_pkeys' takes three parameters:
command.Parameters.Add("#table_name", SqlDbType.NVarChar).Value = tableName;
command.Parameters.Add("#table_owner", SqlDbType.NVarChar).Value = tableOwner;
command.Parameters.Add("#table_qualifier", SqlDbType.NVarChar).Value = tableQualifier;
It works with just #table_name but could try passing all three to see if it makes a difference.
Question: Does your table have any keys defined?
I have run the slightly modified code below against severa tables in a test DB of my own and it works as expected:
static class Program
{
static void Main(string[] args)
{
var connStr = new SqlConnectionStringBuilder
{
DataSource = "localhost",
InitialCatalog = "RichTest",
IntegratedSecurity = true
};
using (var conn = new SqlConnection(connStr.ToString()))
{
conn.Open();
var parents = GetPrimaryKeysForTable(conn, "People");
Console.WriteLine("Parent Keys:");
foreach (var p in parents)
{
Console.WriteLine(" {0}", p);
}
}
}
static IList<string> GetPrimaryKeysForTable(SqlConnection conn, string tableName)
{
if (conn == null) throw new ArgumentNullException("Value is null", "conn");
if (string.IsNullOrWhiteSpace(tableName)) throw new ArgumentNullException("Value is null or emtpy", "tableName");
List<String> retVal = new List<string>();
using (var command = new SqlCommand
{
Connection = conn,
CommandText = "sp_pkeys",
CommandType = CommandType.StoredProcedure
})
{
command.Parameters.AddWithValue("#table_name", typeof(SqlChars)).Value = tableName;
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
retVal.Add(reader["COLUMN_NAME"].ToString());
}
}
return retVal;
}
}

.net SQL Server stored procs wrapper class structure

I'm looking to write a C# SQL Server wrapper to call some stored procedures. If I was writing a single function I'd do something like the following (which I think is correct/proper):
void RunStoredProc1(object arg1)
{
using(SqlConnection conn = new SqlConnection(connStr)){
try{
SqlCommand cmd = new SqlCommand("storedProc1", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#input1", arg1);
conn.Open();
cmd.ExecuteNonQuery();
} catch (Exception ex){
//handle the exception appropriately.
}
}
}
The problem I'm having is that it seems like a lot of repeated code... every function will have the same using/try(open/execute)/catch code, and it'd be nice to have it all in only one place. Is there a clean way of doing this? How about for queries that I'd want to use a data reader on?
Something like this should do:
void RunStoredProc(string storedProcName, IDictionary<string, object> args)
{
using (SqlConnection conn = new SqlConnection(connStr))
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = storedProcName;
cmd.CommandType = CommandType.StoredProcedure;
foreach (KeyValuePair<string, object> kvp in args)
{
cmd.Parameters.AddWithValue(kvp.Key, kvp.Value);
}
conn.Open();
cmd.ExecuteNonQuery();
}
}
The connection object itself would probably also be better off as a parameter to this helper method, so you could make it static. It might be interesting to write it as an extension method on SqlConnection.
I would keep the exception handling in your RunStoredProc1 method or even more likely: in the methods that call RunStoredProc1, because exception handling will likely differ on a case by case basis.
void RunStoredProc1(object input1)
{
var args = new Dictionary<string, object>()
{
{ "input1", input1 }
};
try
{
RunStoredProc("storedProc1", args);
}
catch (Exception ex)
{
// Handle exception properly
}
}
Just a fun exercise for me, and not necessarily the way you'd want to implement it. I wrote a quick fluent interface for building and executing SqlCommands.
A couple of sample usages:
int i = Sql.UsingConnection("sample")
.GetTextCommandFor("Select Top 1 ActorID From Actor Where FirstName = #fname")
.AddParameters(new {fname = "Bob"})
.OnException(e => Console.WriteLine(e.Message))
.ExecuteScalar<int>();
var q = Sql.UsingConnection("sample")
.GetTextCommandFor("Select * From Actor Where FirstName=#fname and ActorID > #id")
.AddParameters(new {id = 1000, fname = "Bob"});
using(var reader = q.ExecuteReader())
{
while(reader.Read())
{
// do something
}
}
The actual class(es) and Interfaces are below:
public class Sql
{
public static ISqlCommandTypeSelector UsingConnection(string connection)
{
return new SqlBuilder(connection);
}
private class SqlBuilder : ISqlCommandTypeSelector, ISqlParameterManager, ISqlExecutor
{
private string _connection;
private string _sqltext;
private CommandType _commandtype;
private Action<Exception> _exceptionBehavior = DefaultExceptionBehavior;
private IList<SqlParameter> _inParams;
public SqlBuilder(string connection)
{
_connection = ConfigurationManager.ConnectionStrings[connection].ConnectionString;
_inParams = new List<SqlParameter>();
}
public ISqlParameterManager GetTextCommandFor(string text)
{
_sqltext = text;
_commandtype = CommandType.Text;
return this;
}
public ISqlParameterManager GetProcCommandFor(string proc)
{
_sqltext = proc;
_commandtype = CommandType.StoredProcedure;
return this;
}
public ISqlExecutor OnException(Action<Exception> action)
{
_exceptionBehavior = action;
return this;
}
public void ExecuteNonQuery()
{
try
{
using (var connection = new SqlConnection(_connection))
using (var cmd = connection.CreateCommand())
{
ConfigureCommand(cmd);
PopulateParameters(cmd);
connection.Open();
cmd.ExecuteNonQuery();
}
}
catch(Exception ex)
{
_exceptionBehavior(ex);
}
}
public T ExecuteScalar<T>()
{
T result = default(T);
try
{
using (var connection = new SqlConnection(_connection))
using (var cmd = connection.CreateCommand())
{
ConfigureCommand(cmd);
PopulateParameters(cmd);
connection.Open();
result = (T) cmd.ExecuteScalar();
return result;
}
}
catch(InvalidCastException ex)
{
// rethrow?
}
catch(Exception ex)
{
_exceptionBehavior(ex);
}
return result;
}
public IDataReader ExecuteReader()
{
try
{
var connection = new SqlConnection(_connection);
var cmd = connection.CreateCommand();
ConfigureCommand(cmd);
PopulateParameters(cmd);
connection.Open();
var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
return reader;
}
catch(Exception ex)
{
_exceptionBehavior(ex);
}
return null;
}
public ISqlExecutor AddParameters(object #params)
{
var type = #params.GetType();
var props = type.GetProperties();
foreach (var propertyInfo in props)
{
var param = new SqlParameter("#" + propertyInfo.Name, propertyInfo.GetValue(#params, null));
param.Direction = ParameterDirection.Input;
_inParams.Add(param);
}
return this;
}
public ISqlExecutor WithoutParams()
{
return this;
}
private void ConfigureCommand(SqlCommand cmd)
{
cmd.CommandText = _sqltext;
cmd.CommandType = _commandtype;
}
private void PopulateParameters(SqlCommand cmd)
{
cmd.Parameters.AddRange(_inParams.ToArray());
}
private static void DefaultExceptionBehavior(Exception e)
{
// do something
}
}
}
public interface ISqlCommandTypeSelector
{
ISqlParameterManager GetTextCommandFor(string text);
ISqlParameterManager GetProcCommandFor(string proc);
}
public interface ISqlExecutor
{
ISqlExecutor OnException(Action<Exception> action);
void ExecuteNonQuery();
T ExecuteScalar<T>();
IDataReader ExecuteReader();
}
public interface ISqlParameterManager
{
ISqlExecutor AddParameters(object #params);
ISqlExecutor WithoutParams();
}
There is some repeated code that could probably be refactored some more if you really hate repeated code. This is just a fun exercise, and probably not how you want to do your data access however. This also doesn't support out parameters as it is written.
The Microsoft Enterprise Library Data Access Application Block can help to reduce redundant code like that, if you're sticking to pure ADO.NET for your data layer. See http://msdn.microsoft.com/en-us/library/ff664408(v=PandP.50).aspx. There are lots of code samples online and in the download as well, i.e. http://msdn.microsoft.com/en-us/library/ff664702(v=PandP.50).aspx.
I'm a big fan of letting computers do the rote, repetitive work. They're very good at it. I only have to teach them to do it once. So I wrote a code generator that uses a reference database to generate strongly typed access code. The advantage of this technique is that if you change the stored procedure's signatures, all you have to do it re-gen your data access layer. Any breaking changes will cause compile errors.
The code generate I wrote reads an XML file identifying the stored procedures of interest and retrieves their metadata from the specified reference database(s).
The XML file contains flags identifying whether each stored procedure returns
multiple result sets (dataset)
a single result set (datatable)
a single row (datarow)
a single row with a single column (a scalar value)
a DataReader
an XmlReader
or nothing (nonquery)
From that it generates appropriate code, 1 class per stored procedure. The generated code provides access to the stored procedure's return code as well as the returned value for any output parameters.
It also parses the declaration for the stored procedure in the stored procedure's source code to identify any optional arguments (those with default values): the generated code allows those to be omitted in the call to execute the stored procedure.
Invoking the generated code goes like this:
public DataTable GetRiskFactorsForPatient( int patientID )
{
dbo_GetRiskbyPatient sp = new dbo_GetRiskbyPatient( CONNECT_STRING_ID ) ;
int rc = sp.Exec( patientID ) ;
DataTable dt = sp.ResultSet ;
if ( dt == null ) throw new InvalidOperationException( "nothing returned from stored procedure" ) ;
return dt ;
}
Personally, i prefer
void RunStoredProc1(object arg1)
{
try
{
using(SqlConnection conn = new SqlConnection(connStr))
{
using SqlCommand cmd = new SqlCommand("storedProc1", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#input1", arg1);
conn.Open();
cmd.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
//handle the exception appropriately.
}
}
Over the traditional try catch finally that you would need to do to manage your resources.
But overall, I like doing it with separate methods, so that you can custom tailor your catch blocks for the sproc.
Also, You might need more than one parameter down the road, and you would just be making a mess of a fairly straight-forward function

Categories