the error says, "Error converting data type varchar to numeric."
This is my set of codes:
private void btnSearchCustomer_Click(object sender, EventArgs e)
{
//Get Customer Records
DataSet dsCustomer = new DataSet();
dsCustomer = GetRecords("Customers");
frmBasicSearch newSearch = new frmBasicSearch();
newSearch.myDataSet = dsCustomer;
newSearch.ShowDialog();
int myRowPosition = newSearch.myRowPosition;
if (myRowPosition != -1) //will display the value inside the textboxes
{
//concuntinated values
this.txtCustomerNo.Text = dsCustomer.Tables["Customers"].Rows[myRowPosition]["CustomerNo"].ToString();
this.txtCustomerName.Text = dsCustomer.Tables["Customers"].Rows[myRowPosition]["CustomerName"].ToString();
this.txtCustomerAddress.Text = dsCustomer.Tables["Customers"].Rows[myRowPosition]["CustomerAddress"].ToString();
groupProduct(true); //this will activate the buttons from the Product Section
}
cn.Close();
cn.Open();
SqlCommand cmdInsert = new SqlCommand();
cmdInsert.Connection = cn;
cmdInsert.Transaction = trnOrder;
cmdInsert.CommandType = CommandType.Text;
cmdInsert.CommandText =
"INSERT INTO ShoppingCart " +
"(OrderDate, CustomerNo, CustomerName, CustomerAddress, PurchaseOrderNo, AgentNo, AgentName, InvoiceNo, TotalAmount, OrderStatus) " +
"VALUES ('" +
dtpOrderDate.Value.Date.ToString() + "', '" +
txtCustomerNo.Text + "', '" +
txtCustomerName.Text + "', '" +
txtCustomerAddress.Text + "', '" +
DBNull.Value + "', '" +
DBNull.Value + "', '" +
DBNull.Value + "', '" +
DBNull.Value + "', '" +
DBNull.Value + "', '" +
"''Void'); " +
"SELECT TOP 1 ShoppingCartNo FROM ShoppingCart " +
"ORDER BY ShoppingCartNo DESC;";
cmdInsert.ExecuteNonQuery();
cn.Close();
}
the highlighted error part is the
int nShoppingCart = Convert.ToInt16(cmdInsert.ExecuteScalar().ToString());
I cannot seem to know where is the problem? thank you for helping
and here is my data schema,
ShoppingCartNo is in primary key and the is identity is auto incriminated by 1
ExecuteScalar executes a SELECT statement and returns the first column of the firest returned row. For INSERT statements use ExecuteNonQuery. It will return an integer, containing the number of inserted lines, so no conversion is needed, simply write
int nShoppingCart = cmdInsert.ExecuteNonQuery();
The error comes from inserting the string 'NULL' into the numeric column TotalAmount.
"'" + DbNull.Value + "'"
will result in 'NULL' (probably, I didn't check, but it definitely is a string, not a numeric value).
You do not need to insert NULL values into columns that can hold NULL values. Simply do not insert these columns, jjust insert the columns containing data.
After that, execute a query using ExecuteScalar, using the mentioned SCOPE-IDENTITY()
ExecuteScalar is typically used in case where your SQL part is returning some rows. Try using ExecuteNonQuery instead while inserting.
Then use your select part with ExecuteScalar. that should work.
Why -
Right now, you have 2 queries - when your run your 2 queries in Management studio - you'd get 'N rows affected' & your ShoppingCartNo. As per your current code, only the first part is returned (due to ExecuteScalar) which results in type conversion error.
First and foremost: this is not the proper way to retrieve the auto-incremented key. Use SCOPE_IDENTITY() instead, or use OUTPUT clause of INSERT. the way you're doing it is incorrect from multiple points of view:
it returns the wrong ID. Two threads insert, both select the same ID (last).
it returns the wrong ID if the IDENTITY was reset
it can return empty result set if the (only) row is deleted between the INSERT and SELECT.
So why don't just use SCOPE_IDENTITY() instead?
Related
I need to insert data in one table and update id in second table using add button:
private void addButton_Click(object sender, EventArgs e)
{
con.Open();
cmd = new SqlCommand("Insert Into Rent(toolId, customerId, custName, Fee, date, dueDate) Values('" + toolIdComboBx.Text + "', '" + custIdTxtBx.Text + "', '" + custNameTxtBx.Text + "', '" + feeTxtBx.Text + "', '" + dateTimePicker2.Text + "', '" + dateTimePicker1.Text + "')", con);
dr = cmd.ExecuteReader();
if (dr.Read())
{
con.Close();
con.Open();
cmd = new SqlCommand("Update Inventory Set Available = 'No' Where ToolId = = '" + toolIdComboBx.Text + "' ");
cmd.ExecuteNonQuery();
}
con.Close();
DisplayData();
}
I can see a few issues here
Always, always, always use parameterized queries (props to #broots-waymb) and never, ever concatenate user input into a SQL command
Use the using keyword to automatically clean up any object with a Dispose() method, which includes SqlConnection and SqlCommand - this ensures proper cleanup in the presence of exceptions; also it just easier to write correctly
Use ExecuteNonQuery() if you're not expecting a recordset to be returned. As #jdweng pointed out the only query that returns a recordset is a SELECT statement (stored procedures might also). The meaning of Read() is this code is unclear, my guess is that it will always return false
Be careful when your database schema contains one table (Inventory) whose state is dependent on the state of another table (Rent). Consider strategies to avoid this, but if you can't, then you should consider wrapping the update to both tables in a database transaction to make sure the state of your system is consistent
You cannot close a connection if it has a open SqlDataReader.
Why do you read from an INSERT statement? What do you expect?
Also, use parameterized queries.
Update
There is no result value from INSERT, so use ExecuteNonQuery() instead. That way, the connection is available for the next SqlCommand
Thanks guys! I figured it out
con.Open();
using (cmd = new SqlCommand("Insert Into Rent(toolId, customerId, custName,
Fee, date, dueDate) Values('" + toolIdComboBx.Text + "', '" + custIdTxtBx.Text + "', '" +
custNameTxtBx.Text + "', '" + feeTxtBx.Text + "', '" + dateTimePicker2.Text + "', '" +
dateTimePicker1.Text + "')", con))
{
cmd.ExecuteNonQuery();
}
using (cmd = new SqlCommand("Update Inventory Set Available = 'No' Where ToolId = '" + toolIdComboBx.Text + "' ", con))
{
cmd.ExecuteNonQuery();
};
con.Close();
DisplayData();
I'm having problem with regards to update my database when I remove a row/s in my datagrid.
I tried using RowsRemoved event but it returns me an error that there is no value in the row deleted.
So when I try searching I have come to this similar problem, all similar problems I have found so far is by adding or subtracting a certain number (like + 1 or - 1). So I matched the code with my parameters.
private void dataGridSales_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
{
using (SqlConnection conn = new SqlConnection(#"Server=" + ip + "," + port + "; Database=records; User ID=" + sqlid + "; Password=" + sqlpass + ""))
{
conn.Open();
int addqty = Convert.ToInt32(dataGridSales.SelectedRows[0].Cells[1].Value.ToString());
string part = dataGridSales.SelectedRows[0].Cells[5].ToString();
using (SqlCommand cmd = new SqlCommand(#"UPDATE [dbo].[products]
SET Quantity = [Quantity] + '" + addqty + "' WHERE [Part No.] = '" + part + "'", conn))
{
cmd.ExecuteNonQuery();
}
conn.Close();
}
}
The problem is, it did not update my database. I also tried this in my SQL
Quantity = Quantity + '" + addqty + "'
Quantity += '" + addqty + "'
Im using SQL Server 2014
This is the value of the addqty and part at the breakpoint
This are my datagridview columns. ColumnIndex = 5 is where the part value, and RowIndex is the selected row.
EDIT:
I have solve the issue. It was a minor mistake that I wasn't checking the syntax correctly (even there are no errors shown).
string part = dataGridSales.SelectedRows[0].Cells[5].ToString();
Forgot to add .Value
string part = dataGridSales.SelectedRows[0].Cells[5].Value.ToString();
Quantity = Quantity + '" + addqty + "'
You define addqty as an int but use it as a string in the SQL. Remove the single quotes to use the value as a number rather than text.
Quantity = Quantity + " + addqty + "
try to replace dataGridSales.SelectedRows[0].Cells[1].Value.ToString() anddataGridSales.SelectedRows[0].Cells[5].ToString(); by
dataGridSales.SelectedRows[e.RowIndex].Cells[1].Value.ToString();
dataGridSales.SelectedRows[e.RowIndex].Cells[5].ToString();
I have a C# form that have a 6 filters (5 combobox, and 1 textbox) that the user can use to perform a search. The problem is that the user can leave some as blank or to use it all. To have a filtered search I used AND when doing a SELECT query, but the problem is it will return a blank or empty search when some of the filters is/are blank. If I will make each condition a query, I will have around 700 and so query. So I have search the closet, I think, scenario in this link
Ignore empty textboxes while searching in database
using (SqlConnection conn = new SqlConnection(#"Data Source=(local);
Initial Catalog=inventory;
Integrated Security=True"))
{
conn.Open();
string query = "SELECT * FROM [dbo].[product] WHERE IsDeleted = '0'";
using (SqlCommand scmd = new SqlCommand())
{
if (!string.IsNullOrEmpty(cmbItem.Text))
{
query += " AND Item Like #Item";
scmd.Parameters.Add("#Item", SqlDbType.VarChar).Value = "%" + item + "%";
}
}
if (!string.IsNullOrEmpty(cmbBrand.Text))
{
query += " AND Brand Like #Brand";
scmd.Parameters.Add("#Brand", SqlDbType.VarChar).Value = "%" + brand + "%";
}
//...additional query
}
scmd.CommandText = query;
scmd.Connection = conn;
using (SqlDataAdapter sda = new SqlDataAdapter(scmd))
{
dataGridView1.Refresh();
DataTable dt = new DataTable();
sda.Fill(dt);
dataGridView1.DataSource = dt;
}
conn.Close();
}
And when performing the search, it is having an error like this;
'Invalid column name 'IsNull'.'
My original query goes something like this. But this will select nothing if one of the where condition is blank/empty.
SELECT * FROM [dbo].[product] WHERE Item = '" + item + "'
AND Brand = '" + brand + "'
AND Description = '" +desc + "'
AND Manufacturer = '" + manu + "'
AND Car = '" + car + "'
AND Year = '" + year + "'
If I use OR instead of AND. It will select something like this.
OR Statement
OR Statement
Below are the images for an ideal search.
Image for ideal selection
Image for ideal selection
Solved, by changing IsDeleted='0' to 1=1
string query = #"SELECT * FROM[dbo].[product] WHERE 1=1";
you can use store procedure and set parameter to default value
sample:
create proc sptest
#Fname nvarchar(50),
#Lname nvarchar(50),
#NCode nvarchar(12),
#UserType int
as
SELECT DISTINCT PersonID,
FName,
LName,
NationalID,
UserType
FROM Persons
WHERE
(FName LIKE('%' + #Fname + '%') OR (#Fname = ''))
AND (LName LIKE('%' + #Lname + '%') OR (#Lname = ''))
AND ((NCode = #NCode) OR (#NCode = ''))
AND ((UserType = #UserType) OR (#UserType = 0))
when textbox is empty or dropdownlists not is selected, get all record
Your original if/and conditions should work, but what you might be running into is a false resolution of the table COLUMN vs the PARAMETER. Since you have the example of
Item like #Item
if there is no actual parameter Item, SQL is implying to use its own value. For these types of queries, I try to prefix the parameter name to match. Change to
Item like #parmItem
and obviously change your parameter name string to match the "#parmItem" reference. This way there is no ambiguity in what value the SQL engine is looking for.
layout and db
if (!(string.IsNullOrEmpty(b.ToString())))
{
string connection = "server=127.0.0.1; database=accounts;user=root; password='';";
MySqlConnection conn = new MySqlConnection(connection);
conn.Open();
string SQL = "INSERT INTO payment_voucher (voucher_no, paid_to, date, account_cr, account_dr, description, student_emp_id, amount, total ) values ('" + label8.Text.ToString() + "','" + textBox1.Text + "', '" + dateTimePicker1.Value + "','" + a + "','" + b + "', '" + richTextBox1.Text + "', '" + textBox3.Text + "', '" + textBox4.Text + "', '" + label11.Text.ToString() + "');";
MySqlCommand command = new MySqlCommand(SQL, conn);
command.ExecuteNonQuery();
conn.Close();
}
i dont know why it is happening. front end is in C#.
That statement will not insert two rows.
You have a few things to check here:
Check if that code is being called twice
Check if there is other similar code that is also being called
Make sure there are no triggers on the table that do an additional insert
Make sure you don't have some weird Try/Catch/Fail logic that causes that entire thing to be run again
And most importantly:
Run a SQL Profiler trace to see exactly what is being sent to the database
Query the table when you've checked those with a raw SELECT query in Enterprise Manager and make sure there is one row.
That code above would not duplicate rows unless called twice.
I am creating a Windows Forms application and now at certain point I need to make a database connection, I have inserted the values to database easily, but now its not updating my data, I am using following query for this purpose:
MySqlCommand sda = new MySqlCommand(#"Update shedulling.tablelayout1 set date = '"
+ date + "',line = " + line + ",col1 = '" + first_textbox.text + "', col2 = '"
+ sec_textbox.text + "',col3_textbox.text = '" + thi_textbox.text
+ "',col4_textbox.text = '" + four + "' where date = '" + date + "' AND line = '"
+ line.ToString() + "' ", conn);
conn is a connection string which is written fine, and date and line are string and integer values send as an argument to this function.
You have missed single quotes in line part. Change it like this line = '" + line + "'.
Also there is one more notable thing in your code: you are trying to find the record in the table that is not exist yet in where clause where date = '" + date + "' AND line = '" + line.ToString() + "' note in this line date and line are the new values not old values so no rows affected in the update query. You should use old values of date and line in the where clause.
Also you should always use parameterized queries. This kind of string concatenations are open for SQL Injection.
Try debugging the code, there must be INSERT statement executing somewhere in your code.
UPDATE: If "line" is integer variable then you need to convert it into string. You have converted it after WHERE clause but not after SET clause.
You may want to post some more code to get exact answer.