I am using visual studio 2010 ultimate with SQL Server 2012, When I click save button first time it works fine, but after changing values it shows above mentioned exception. I m failed to solve this problem. please help me.
Thanks
Abdul Muttalib
public int AddStudent(StudentManager studentManager)
{
try
{
sqlCom.Connection = sqlCon;
sqlCon.Open();
sqlCom.CommandType = CommandType.StoredProcedure;
sqlCom.CommandText = "spAddStudent";
sqlCom.Parameters.AddWithValue("#Name", studentManager.Name);
sqlCom.Parameters.AddWithValue("#Father", tudentManager.Father);
sqlCom.Parameters.AddWithValue("#Gender", tudentManager.Gender);
sqlCom.Parameters.AddWithValue("#Religion", studentManager.Religion);
sqlCom.Parameters.AddWithValue("#MotherTongue", studentManager.Tongue);
sqlCom.Parameters.AddWithValue("#BirthDate", studentManager.BrithDate);
sqlCom.Parameters.AddWithValue("#Class", studentManager.StudentClass);
sqlCom.Parameters.AddWithValue("#Section", studentManager.Section);
sqlCom.Parameters.AddWithValue("#Shift", studentManager.Shift);
sqlCom.Parameters.AddWithValue("#RollNo", studentManager.RollNo);
sqlCom.Parameters.AddWithValue("#Fee", studentManager.Fee);
sqlCom.Parameters.AddWithValue("#FatherOccupation", studentManager.FatherOccupation);
sqlCom.Parameters.AddWithValue("#FatherCNIC", studentManager.Cnic);
sqlCom.Parameters.AddWithValue("#AddWithValueressRes", studentManager.AddressRes);
sqlCom.Parameters.AddWithValue("#PhoneRes", studentManager.PhoneRes);
sqlCom.Parameters.AddWithValue("#PhoneOff", studentManager.PhoneOff);
sqlCom.Parameters.AddWithValue("#Mobile", studentManager.Mobile);
sqlCom.Parameters.AddWithValue("#PostalCode", studentManager.PostalCode);
sqlCom.Parameters.AddWithValue("#Email", studentManager.Email);
sqlCom.Parameters.AddWithValue("#OtherInfo", studentManager.OtherInfo);
int i = sqlCom.ExecuteNonQuery();
sqlCon.Close();
return i;
}
catch (Exception ex)
{
throw ex;
}
}
}
}enter image description here
You could resolve this by calling sqlCom.Parameters.Clear() at the start of AddStudent to prevent accumulating redundant parameters whenever the method is called.
Also, using AddWithValue is easy and common, but it can be problematic.
Related
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.
I am going through a YouTube video, to learn ASP.NET. I've gotten it to work for the most part, with a somewhat major caveat: I can't retrieve a value from a hidden field ID. Because of that, I don't have a value to send to a stored procedure to create or update.
The commented out line is the original statement. When I have that then execute
.ExecuteNonQuery, I get the following error:
Procedure or function 'ResourceCreateOrUpdate' expects parameter '#ResourceID', which was not supplied
When I try to display hfResourceID, I have nothing when trying to pass 0, for a create, or the ResourceID value, i.e. 1. That value however, doesn't get there. I know the stored procedure works because I can execute it in SQL Server Management.
I tried moving hfResourceID to a string, then a integer value, but I seem to be having problems creating the if/else: everything is marked as an error. When I hover over the lines, I get the following message, which pretty much leave me clueless:
"Embedded statement cannot be a declaration or labeled statement".
Would I be able to get any pointers on how to clear up my error, please? Thanks.
2017-10-13 # 10:38: code updated
<asp:HiddenField ID="hfResourceID" runat="server" />
protected void btnSave_Click(object sender, EventArgs e)
{
int intResourceID = 0;
bool boolIDHasValue = true;
try
{
intResourceID = Convert.ToInt32(hfResourceID.Value);
}
catch (Exception ex)
{
lblErrorMessage.Text = ex.Message;
boolIDHasValue = false;
}
if (boolIDHasValue)
{
if (sqlconnODRConnection.State == System.Data.ConnectionState.Closed)
sqlconnODRConnection.Open();
SqlCommand sqlcmdCreateOrUpdate = new SqlCommand("ResourceCreateOrUpdate", sqlconnODRConnection);
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#ResourceID", intResourceID);
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#Status", txtStatus.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#FirstName", txtFirstName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#MiddleName", txtMiddleName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#LastName", txtLastName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#NickName", txtNickName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#Gender", txtGender.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#USCitizen", txtUSCitizen.Text.Trim());
sqlcmdCreateOrUpdate.ExecuteNonQuery();
sqlconnODRConnection.Close();
string strResourceID = hfResourceID.Value;
Clear();
if (strResourceID == "")
lblSuccessMessage.Text = "Saved Successfully";
else
lblSuccessMessage.Text = "Updated Successfully";
FillGridView();
}
}
There are a few issues with the code you copied from that video. But here a snippet as to how it should be done. I've added 3 ways to convert from the HiddenField value to an actual int. Which one you use can depend on how you want to handle errors, 0 values etc. Not included in the snippet, but I like to check for IsNullOrEmpty while using Trim(), that gets rid of spaces that might make the value non-convertible if (!string.IsNullOrEmpty(hfResourceID.Value.Trim())).
int intResourceID = 0;
//this will try to convert but you won't see exeptions when failed
Int32.TryParse(hfResourceID.Value, out intResourceID);
//checks if there is a value in the hiddenfield, but throws yellow screen if not convertible
if (!string.IsNullOrEmpty(hfResourceID.Value))
{
intResourceID = Convert.ToInt32(hfResourceID.Value);
}
//catch an error when the value is not convertible, can be wrapped with !string.IsNullOrEmpty(hfResourceID.Value)
try
{
intResourceID = Convert.ToInt32(hfResourceID.Value);
}
catch (Exception ex)
{
//handle the error, can be seen with ex.Message
}
//if the hidden value is still 0 (for whatever reason) you might not want to execute the query
//so the next part will return and stop executing the rest of the code
if (intResourceID == 0)
{
return;
}
//update the database, using 'using' will ensure proper closure of the connection and disposing of any objects
using (SqlConnection connection = new SqlConnection("myConnectionString"))
using (SqlCommand command = new SqlCommand("ResourceCreateOrUpdate", connection))
{
//set the command type and add the parameters
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#ResourceID", SqlDbType.Int).Value = intResourceID;
try
{
//open the database connection and execute the command
connection.Open();
command.ExecuteNonQuery();
}
catch (Exception ex)
{
//there was an error opening the database connection or with the command, can be viewed with ex.Message
}
}
Your error regarding the embedded statement is because you a declaring
if (strResourceID == "")
int intResourceID = 0;
else
int intResourceID = (Convert.ToInt32(hfResourceID.Value));
When decalring a variable directly after an If or else then you need your curly brackets. So...
if (strResourceID == "")
{
int intResourceID = 0;
}
else
{
int intResourceID = (Convert.ToInt32(hfResourceID.Value));
}
As for your other issues I would need to see your client side code.
Take a look on ASP code, specifically the way you are setting hidden field value. I guess it is properly marked as runat=server but maybe some problem is going on in your asp.net code, try to debug client code by using: console.log function and see the output in your console browser.
So i have this project that needs to print data from the database.
I do this with a simple foreach loop:
public void LoadDatabase()
{
_connection.Open();
_dataAdapter.Fill(_dataTable);
try
{
foreach (DataRow row in _dataTable.Rows)
{
Program.AnimalInfo.Info_ID_ListBox.Items.Add(row["Animal_ID"].ToString());
}
}
catch (Exception ex)
{
MessageBox.Show("Failed to LoadDatabase()" + ex.Message);
}
_connection.Close();
}
The problem is that it will loop anywhere from 2 times to 6 times meaning that it prints everything at least twice.
So at the moment my database contains Animal_Id's id:1 and id:2.
Now i get in my listbox (1, 2, 1, 2) or more depending on the amount of loops. I have no idea why this is happening and how to fix this. So all help would be highly appreciated
ps: if more code or information is needed please let me know.
pss: this is for a windows mobile 6.5 device with .net 3.5 build in Visual studio 2008. also im useing sqlite (not the newest version)
EDIT: After some testing it looks like my other 2 foreach loops in this project have the same problem.
Edit: So with al you guy's help i was able to fix it.
public void GetData()
{
try
{
SQLiteConnection Connection = new SQLiteConnection(#"Data Source = \Program Files\Mobile\Resources\Database\PPP_DB");
Connection.Open();
SQLiteCommand Command = new SQLiteCommand(Query, Connection);
Command.ExecuteNonQuery();
Data_Adapter = new SQLiteDataAdapter("SELECT * FROM Animal_Info", Connection);
Data_Set.Reset();
Data_Adapter.Fill(Data_Set);
Data_Table = Data_Set.Tables[0];
Program.AnimalInfo.Info_ID_ListBox.Items.Clear();
foreach (DataRow row in Data_Table.Rows)
{
if (row.RowState != DataRowState.Deleted)
{
Program.AnimalInfo.Info_ID_ListBox.Items.Add(row["Animal_ID"].ToString());
}
}
Connection.Close();
Program.AnimalInfo.Refresh();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
So it seems that it messed up with the DataTable somewhere, and that made it loop multiple times. ps: i tried to set all items with stuff like Databound, but didn't really work out for me, thats the reason im still doing it this way.
Add the following two lines at the top of your function.
Program.AnimalInfo.Info_ID_ListBox.Items.Clear();
_dataTable.Clear();
This will ensure that you do not double up any row data.
Assuming that there is no unique constraint on "Animal_ID" field in the database (you din't answer to my comment), check for items duplication:
if (!Program.AnimalInfo.Info_ID_ListBox.Items.Contains(row["Animal_ID"].ToString())
Program.AnimalInfo.Info_ID_ListBox.Items.Add(row["Animal_ID"].ToString());
Well first, LoadDatabase() should return a DataTable (or DataSet), this make sthe LoadDatabase() function useful for other data requests, Also you should never need to use a 'for loop' to add items to a ListBox. you can bind the ListBox directly to the source.... something like this should do it
listBox1.DataSource = _dataTable;
listBox1.ValueMember = "Animal_ID";
listBox1.DisplayMember = "Animal_ID";
There are some examples using SqlDataReader and SqlDataAdapter here http://gsidev.somee.com/#2&2AD97ECBE2AE41D08191F6E4C773D8A9&cs
Unique contraints are not needed here. But the listbox.Items collection might have have to be cleared.
Possibly you are (or the system, depends on where the code is, for example in a paint event handler) calling the 'LoadDatabase()' function twice!
Just place a break point in the _dataAdapter.fill() and press F11 to let the app run over this and then right click the _dataTable to inspect it's contents.
Although you can explictely set the datasource of the ListBox, that is not needed and may lead to other side effects you are currently not aware of. It is OK to start with simple code before letting the system do unknwon stuff in the background.
Try that:
public void LoadDatabase()
{
_connection.Open();
_dataAdapter.Fill(_dataTable);
Program.AnimalInfo.Info_ID_ListBox.Items.Clear();
try
{
foreach (DataRow row in _dataTable.Rows)
{
Program.AnimalInfo.Info_ID_ListBox.Items.Add(row["Animal_ID"].ToString());
}
}
catch (Exception ex)
{
MessageBox.Show("Failed to LoadDatabase()" + ex.Message);
}
_connection.Close();
}
So in C#, I have an ODBCDataReader that returns that it has rows, but when I try to access the data it returns an object not set to a reference of an object error. I tested the sql directly on the db and it does return a row without any nulls
OdbcDataReader results;
try
{
// Initialize & open odbc connection
using (OdbcConnection conn = new OdbcConnection(connectionString.ToString()))
{
conn.Open();
// Initialiaze odbc command object
using (OdbcCommand comm = new OdbcCommand(query.ToString(), conn))
{
results = comm.ExecuteReader();
}
}
}
catch
{
//detailed error messaging here (which does not get hit)
}
temp = results;
if (temp.HasRows == false)
{
//error messaging here does not get hit.
}
while (temp.Read())
{
try
{
//I attempted to access the data by creating an object array:
object [] objarray = new object[temp.FieldCount)
temp.GetValues(objarray); //this causes error
}
catch{ // error is caught here "object not set to a reference of an object" }
for (i = 0; i < temp.FieldCount; i++)
{
try
{
//I also attempted other ways to access the data including:
temp[i].ToString(); // this causes error
temp.GetInt32(i).ToString(); // this causes error
temp.GetName(i); //this causes error
}
catch
{
// error is caught here "object not set to a reference of an object"
}
}
}
You are using it outside the using blocks. Move the part where you use [results] inside the using blocks (immediately after the ExecuteReader() call) and you should be in a much better place.
I ran into this same issue. The problem in my case was that I was not binding my parameters correctly. I was binding using #:
SELECT * FROM MyTable WHERE MyField = #MyField
For some reason, this is valid in MySQL and doesn't produce an error, but will not return data. The solution was to bind using ?:
SELECT * FROM MyTable WHERE MyField = ?
Then in C# bind the parameters:
cmd.Parameters.AddWithValue("#MyField", myFieldValue);
Old question, but it's the first result on Google and unanswered. Hope it's helpful.
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.