Problem with calling a stored procedure from my c# code - c#

I want to run a sp from my code. the sp name stored in a db. I pass the parameters via a dictionary. this code is one of my wcf service methods that host in a windows service. my code is :
private DataSet RunReport(int id, ParameterDictionary parametersDic)
{
DataSet result = new DataSet();
try
{
DataSet report = GetReportDataset(id);
if (report.Tables[0].Rows.Count > 0)
{
string reportType = GetReportTypeDataset(Convert.ToInt32(report.Tables[0].Rows[0]["ReportTypeID"]));
if (reportType != ReportType.StoredProcedure.ToString())
{
throw new Exception("your report is not a sp report.");
}
using (DbCommand paramCommand = DatabaseManager.Database.GetStoredProcCommand(report.Tables[0].Rows[0]["SQLQuery"].ToString()))
{
foreach (var parameter in parametersDic)
{
DatabaseManager.Database.SetParameterValue(paramCommand, parameter.Key, parameter.Value);
}
result = DatabaseManager.Database.ExecuteDataSet(paramCommand);
result.AcceptChanges();
}
}
}
catch (Exception ex)
{
throw ex;
}
return result;
}
When I run this code the below error is accured:
An SqlParameter with ParameterName 'ID' is not contained by this
SqlParameterCollection.
In addition, when I call this method via win forms every thing is ok.
what is the problem?

I think you may have to add the parameters before setting them:
foreach param ...
{
DatabaseManager.Database.AddInParameter(paramCommand, <name>, <DbType>);
DatabaseManager.Database.SetParameterValue(paramCommand, parameter.Key, parameter.Value);
}

Related

c# How to create a Method on a Method, or Method Chain

I have created a simplified SQL Data class, and a class method for returning a ready to use resultset:
public SQL_Data(string database) {
string ConnectionString = GetConnectionString(database);
cn = new SqlConnection(ConnectionString);
try {
cn.Open();
} catch (Exception e) {
Log.Write(e);
throw;
}
}
public SqlDataReader DBReader(string query) {
try {
using (SqlCommand cmd = new SqlCommand(query, this.cn)) {
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
} catch {
Log.Write("SQL Error with either Connection String:\n" + cn + " \nor Query:\n" + query);
throw;
}
}
(I catch any errors, log them, and then catch the error higher up the chain. Also, I did not include the ConnectionString() code for brevity. It just returns the requested connection string. That's all.)
This all works just fine, and with a single line of code, I'm ready to .Read() rows.
SqlDataReader rs = new SQL_Data("MyDatabase").DBReader(#"SELECT * FROM Employees");
while (rs.Read()) {
// code
}
rs.Close();
I want to expand this and add a .ColumnReader() method that I want to chain to .DBReader() like this:
string empID = new SQL_Data("MyDatabase").DBReader(#"SELECT * FROM Employees).ColumnReader("EmpID");
I attempted this by adding a .ColumnReader() method, but it ends up being a method of SQL_Data() class directly, not a member or extension of .DBReader(). I also tried adding the .ColumnReader() inside the .DBReader() (like a "closure"), but that didn't work either.
Can this be done?
This ended up working for me:
public static class SQLExtentions {
public static dynamic ColumnReader(this SqlDataReader rs, string colName) {
return rs[colName];
}
}
I will have to expand on it a bit to add some error checking, and perhaps return more than just the dynamic value - like return an object with the value and it's SQL data type. But Paul and Bagus' comments got me on the right track.

Reading Null DateTime column from a Table in SqlServer

I am having an issue reading Calls from my Call Table. One of my columns is a DateTime column, and this column I have allowed to be null, if the call has not been closed. When I execute my C# code that is to fetch all calls from the Calls table, I get an error that the data is null, cannot read when no data is present. I thought If I had an If statement that checks if that column is null, that would solve the issue... but that doesn't work.
Here is the code where I am experiencing the problem:
public void GetAllCalls(Connection connectionObject)
{
try
{
if (memoryObject.GetCallCount() != 0)
{
memoryObject.DeleteAllCalls();
}
SqlCommand getCalls = new SqlCommand("sp_getAllCalls", connectionObject.getDatabaseConnection());
getCalls.CommandType = CommandType.StoredProcedure;
dataReader = getCalls.ExecuteReader();
if (dataReader.HasRows)
{
while (dataReader.Read())
{
if (dataReader.GetDateTime(8).Equals(DBNull.Value))
{
Call newCall = new Call(dataReader.GetString(0), dataReader.GetString(1), dataReader.GetString(2),
dataReader.GetString(3), dataReader.GetString(4), dataReader.GetString(5),
dataReader.GetString(6), dataReader.GetDateTime(7), Convert.ToDateTime(null),
dataReader.GetString(9), dataReader.GetString(10), dataReader.GetString(11),
dataReader.GetString(12));
memoryObject.AddCall(newCall);
}
else
{
Call newCall = new Call(dataReader.GetString(0), dataReader.GetString(1), dataReader.GetString(2),
dataReader.GetString(3), dataReader.GetString(4), dataReader.GetString(5),
dataReader.GetString(6), dataReader.GetDateTime(7), dataReader.GetDateTime(8),
dataReader.GetString(9), dataReader.GetString(10), dataReader.GetString(11),
dataReader.GetString(12));
memoryObject.AddCall(newCall);
}
}
dataReader.Close();
}
else
{
dataReader.Close();
functionsObject.displayMessage("No Calls Found", "No calls were found on the system");
}
}
catch (Exception error)
{
logNewError(error, "GetAllCalls", connectionObject);
}
}
The correct way of checking that is using the SqlDataReader.IsDBNull method
if (dataReader.IsDBNull(8))

Insertion query C# sql server

I have an insertion query in this function :
public string Insert_Piece(List<Piece> liste)
{
this.Connect();
using (connexion)
{
using (SqlCommand sqlCmd = new SqlCommand("INSERT INTO Piece (IDPiece, IDSuperlot, Url) VALUES (#idpiece, #idsuperlot, #url)", connexion))
{
foreach (Piece p in liste)
{
sqlCmd.Parameters.AddWithValue("#idpiece", p.Id_piece);
sqlCmd.Parameters.AddWithValue("#idsuperlot", p.Id_super_lot);
sqlCmd.Parameters.AddWithValue("#url", p.Url_piece);
try
{
sqlCmd.ExecuteNonQuery();
}
catch (Exception e) { return e.ToString(); }
}
return "cava";
}
}
}
But always an exception appears:
I don't know what is the problem and how can i fix it . The 3 attributs are string (varchar) and the selection queries works fine without problem.
What is the matter?
How can i fix it?
It looks like the issue is you are trying to insert too long of a string into the varchar column, try making the varchar column larger or changing it to be a text column.

Prepare Statement Issues

I am trying to implement prepared staments in my code as a way of adding parameters to sql commands that are retrieved from a table held in any generic server. I cannot seem to get it right. I get the following error:
ORA-00936: missing expression
ORA-00936: missing expression
Prepare Statement: select VALUE from RWOL_CONFIGURATION where ID = #ItemId
My guess is that it just isn't replacing the value but I dont know what I am missing.
I am trying the following to achieve the desired result. I create my object, get a query string out of our table in the database, add that to the command, add parameters to a list object and then use the final method shown below to tie it all together and run the query:
//This function gets me a config item from the database
private string GetConfigurationItem(string itemId)
{
//new database connection object
OleDataBaseConnection oleDataBaseConnection = new OleDataBaseConnection();
//todo get this query from the sql factory
SqlFactory sqlFactory = new SqlFactory();
//This method gets the query string from the database
string sqlQuery = sqlFactory.GetQueryString("GET_CONFIGURATION_ITEM", m_dialect);
if (!String.IsNullOrEmpty(sqlQuery))
{
//add parameter to list
oleDataBaseConnection.AddStoredProcedureParameter("#ItemId", itemId);
//execute the sql command after adding the parameters to the command
oleDataBaseConnection.OleExecutePrepareStatementWithParametersQuery(sqlQuery);
string returnValue = oleDataBaseConnection.NextRecord() ? oleDataBaseConnection.GetFieldById(0) : "Error";
oleDataBaseConnection.Close();
return returnValue;
}
else
{
return "ERROR";
}
}
//adds the parameters to list objects ready for the next method
public void AddParameter(string parameter, object value)
{
m_parameterName.Add(parameter);
m_parameterValue.Add(value);
} // End of void AddParameter()
/// <summary>
/// Executes a command with the parameters passed to AddParameter(parameterName, parameterValue) and creates a recordset.
/// </summary>
///
/// <param name="commandName">The name of the stored procedure to execute.</param>
public bool OleExecutePrepareStatementWithParametersQuery(string commandName)
{
if (String.IsNullOrEmpty(commandName))
{
return false;
}
try
{
PrepareConnection();
m_oleDatabaseCommand.CommandText = commandName;
m_oleDatabaseCommand.CommandType = CommandType.StoredProcedure;
if (m_storedProcedureParameterName.Count != 0)
{
for (int i = 0; i < m_storedProcedureParameterName.Count; i++)
{
m_oleDatabaseCommand.Parameters.AddWithValue(m_storedProcedureParameterName[i], m_storedProcedureParameterValue[i]);
}
m_storedProcedureParameterName.Clear();
m_storedProcedureParameterValue.Clear();
}
m_hasRecordSet = true;
m_oleDatabaseDataReader = m_oleDatabaseCommand.ExecuteReader();
return true;
}
catch (Exception ex)
{
if (QueueErrors)
{
QueuedErrorsList.AppendLine(ex.Message);
QueuedErrorsList.AppendLine("Prepare Statement: " + storedProcedureName);
QueuedErrorsList.AppendLine();
QueuedErrorCount++;
return false;
}
try
{
Close();
}
catch
{
}
throw new Exception(ex.Message + "\r\n\r\nPrepare Statement: " + storedProcedureName);
}
} // End of void OleExecutePrepareStatementWithParametersQuery()
Sorry if there is a lot of code but it is fairly straightforward and I thought it would help with the problem.
Is there anything obvious that would stop this from working?
The problem is that the OleDB provider does not support named parameters in the query.
This:
select VALUE from RWOL_CONFIGURATION where ID = #ItemId
Should be:
select VALUE from RWOL_CONFIGURATION where ID = ?
See OleDbParameter on MSDN for examples.

Help with Exception Handling in ASP.NET C# Application

yesterday i posted a question regarding the Exception Handling technique, but i did'nt quite get a precise answer, partly because my question must not have been precise.
So i will ask it more precisely.
There is a method in my BLL for authenticating user. If a user is authenticated it returns me the instance of the User class which i store in the session object for further references.
the method looks something like this...
public static UsersEnt LoadUserInfo(string email)
{
SqlDataReader reader = null;
UsersEnt user = null;
using (ConnectionManager cm = new ConnectionManager())
{
SqlParameter[] parameters = new SqlParameter[1];
parameters[0] = new SqlParameter("#Email", email);
try
{
reader = SQLHelper.ExecuteReader(cm.Connection,
"sp_LoadUserInfo", parameters);
}
catch (SqlException ex)
{
//this gives me a error object
}
if (reader.Read())
user = new UsersDF(reader);
}
return user;
}
now my problem is suppose if the SP does not exist, then it will throw me an error or any other SQLException for that matter. Since this method is being called from my aspx.cs page i want to return some meaning full message as to what could have gone wrong so that the user understands that there was some problem and that he/she should retry logging-in again.
but i can't because the method returns an instance of the User class, so how can i return a message instead ??
i hope i made it clear !
thank you.
There are a lot of approaches you could take here, an easy one would be to return null if you can't find an appropriate user object (because of the exception). then in the calling code you just test for null and if it is null display an error message.
for example
User u = LoadUserInfo(email);
if(u == null)
{
ErrorLabel.Text = "Could not log in.";
ErrorLabel.Visible = true;
//.... or some other notification
}
else
{
//... normal load
}
that would be a basic way to go about it.
There are lot of approaches you have but in your method you declared "SqlDataReader reader = null;" some times you will get error at if condition "if (reader.Read())" because you declared as null.
public static UsersEnt LoadUserInfo(string email)
{
SqlDataReader reader = new SqlDataReader();
UsersEnt user = null;
using (ConnectionManager cm = new ConnectionManager())
{
SqlParameter[] parameters = new SqlParameter[1];
parameters[0] = new SqlParameter("#Email", email);
try
{
reader = SQLHelper.ExecuteReader(cm.Connection,
"sp_LoadUserInfo", parameters);
if (reader.Read())
user = new UsersDF(reader);
}
catch (SqlException ex)
{
user.Exception=ex.Message;
}
}
return user;
}
and then
User us = LoadUserInfo(email);
if(us.Exception != null)
{
ErrorLabel.Text = "Could not log in.";
ErrorLabel.Visible = true;
//.... or some other notification
}
else
{
//... normal load
}
i think it will work.

Categories

Resources