Shortening data access code... would this work? - c#

I am querying for data, if the data does not exist, I insert it. if it does, I do something else:
SqlCommand checkHead = new SqlCommand("SELECT * FROM TABLE WHERE ORDER_NO = '" + orderNo + "';", connection);
SqlDataReader checkHeadReader = checkHead.ExecuteReader(CommandBehavior.SingleRow);
if (!checkHeadReader.HasRows)
{
checkHeadReader.Close();
addHead.ExecuteNonQuery();
}
But I wonder if there's a shorter way to code this? would the code below work?
SqlCommand checkHead = new SqlCommand("SELECT * FROM TABLE WHERE ORDER_NO = ' + orderNo + "';", connection);
if(checkHead.ExecuteReader(CommandBehavior.SingleRow).HasRows)
addHead.ExecuteNonQuery();
else //this order already exists
Server.Transfer(#"~/Views/Error.aspx");

ExecuteScalar is great for this, E.g.
using (SqlCommand cmdCheck = new SqlCommand("Select Count(*) From Table Where Order_No = '" + orderNo + "'", connection))
{
int nExists = (int)cmdCheck.ExecuteScalar();
if (nExists==0) addHead.ExecuteNonQuery();
}

Related

Check if value input in textbox exists in database and insert if not

How to check if the text I input in textbox already exists in database and if so update only the data or anything solution you recommend and if not the data will automatically insert into database? Here is my code:
cn.Open();
cm = new MySqlCommand("SELECT * FROM tblcustomer WHERE fullname LIKE '" + txtCustomer.Text + "'", cn);
dr = cm.ExecuteReader();
dr.Read();
if (dr.HasRows)
{
cm = new MySqlCommand("UPDATE tblcustomer SET fullname = '" + txtCustomer.Text + "' WHERE id LIKE '" + lblCustomerId.Text + "'", cn);
cm.ExecuteNonQuery();
}
else
{
cm = new MySqlCommand("INSERT INTO tblcustomer(fullname) VALUES ('" + txtCustomer.Text + "')", cn);
cm.ExecuteNonQuery();
}
dr.Close();
cn.Close();
Change your SQL to this:
"INSERT INTO tblcustomer fullname VALUES" + txtCustomer.Text + "
ON DUPLICATE KEY UPDATE fullname= " + txtCustomer.Text
Pseudo, didn't validate this, but it is sort of the right idea, of what you want. And does it in a single connection attempt to the DB.
You can find a guide here:
https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html

Populate multiple text boxes with SqlDataReader

I am trying to populate 11 textboxes, using my database information.
private void button5_Click(object sender, EventArgs e)
{
SqlConnection CN = new SqlConnection();
CN.ConnectionString = cons;
try
{
CN.Open();
SqlCommand cmd = new SqlCommand("SELECT FROM Lista1 WHERE DescripcionNombre = "
' + comboBox1.text + '
"",
CN)
;
SqlDataReader myReader = cmd.ExecuteReader();
}
catch
{
MessageBox.Show("You failed!");
}
}
It always fails, not even able to get that right....
The error is in this line of code
SqlCommand cmd = new SqlCommand("SELECT FROM Lista1 WHERE DescripcionNombre = "' + comboBox1.text + '"", CN);
It should be either like this
SqlCommand cmd = new SqlCommand("SELECT * FROM Lista1 WHERE DescripcionNombre = '" + comboBox1.text + """, CN);
Or
SqlCommand cmd = new SqlCommand("SELECT Column1_name, column2_name FROM Lista1 WHERE DescripcionNombre = '" + comboBox1.text + "'", CN);
As you have not selected any columns it didn't work as you expected.
And in the side note pass paramater value instead of passing the value straight from the field values. so that you can avoid SQL Injection
SqlCommand cmd = new SqlCommand("SELECT Column1_name, column2_name FROM Lista1 WHERE DescripcionNombre = #DescripcionNombre", CN);
cmd.Parameters.AddWithValue("#DescripcionNombre", comboBox1.text);
The first order of business would be to write this line properly:
SqlCommand cmd = new SqlCommand("SELECT FROM Lista1 WHERE DescripcionNombre = "' + comboBox1.text + '"", CN);
That's not valid SQL or C#. You need to specify which columns to retrieve from the table. If want all columns then use a wildcard. The next order of business is to learn how to concatenate strings. If you want single quotes to be part of the string literal then they have to be inside the double quotes.
SqlCommand cmd = new SqlCommand("SELECT * FROM Lista1 WHERE DescripcionNombre = '" + comboBox1.text + "'", CN);
That's quite elementary stuff. You should spend some time reading a tutorial or two.
Once that's done, you then need to actually read the data from the data reader. This can help with that. Note the use of parameters rather than string concatenation in those examples? You can learn more about that here.
SqlCommand cmd = new SqlCommand("SELECT FROM Lista1 WHERE DescripcionNombre = "' + comboBox1.text + '"", CN);
You are not selecting any columns or expressions in your SELECT
Your single and double quotes are backwards in the concatenation
You should get in the habit of using parameters instead of concatenating SQL (for several reasons, not the least of which is SQL Injection vulnerability)
A valid statement would be:
SqlCommand cmd = new SqlCommand("SELECT * FROM Lista1 WHERE DescripcionNombre = '"
+ comboBox1.text
+ "'", CN);
You forget to mention column name which you need to fetch in query
Always use parameterized queries How does SQLParameter prevent SQL Injection
SqlCommand cmd = new SqlCommand("SELECT * FROM Lista1 WHERE DescripcionNombre=#DescripcionNombre, CN);
cmd.Parameters.AddWithValue("#DescripcionNombre", comboBox1.text);
But your query should be like this
SqlCommand cmd = new SqlCommand("SELECT * FROM Lista1 WHERE DescripcionNombre = '" + comboBox1.text + "'", CN);

Get Data from Database Where UserID is equal to value from asp:label

Hello and Thanks for reading.
I have a form where users can Insert data into my database and at the same time, The users unique ID is store in the same table.
Here is the Code where I store the Unique in a label:
MembershipUser user = Membership.GetUser();
string id = user.ProviderUserKey.ToString();
lblID.Text = id.ToString();
This is how my Database looks like / ID, Name, Email, Subject, Message, UserID /
Here is my Insert to Database Code:
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString);
conn.Open();
string Name = txtName.Text;
string Email = txtEmail.Text;
string Subject = ddlSubject.SelectedValue;
string Message = txtMessage.Text;
string UniqueID = lblID.Text;
string query = "INSERT INTO Ticket(Name, Email, Subject, Message, UserID)" + "Values('" + Name + "', '" + Email + "', '" + Subject + "', '" + Message + "', '" + UniqueID + "')";
using (SqlCommand com = new SqlCommand(query, conn))
{
com.ExecuteNonQuery();
}
What I'm having problems with is to Get data from the database where UserID = lblID.text.
as you can see in the code below I'm having a problem finding out what to write to load the data, where UserID = lblID.text.
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString);
conn.Open();
using (var GetName = new SqlCommand("SELECT Name FROM Ticket WHERE UserID=''", conn))
using (SqlDataReader dr = GetName.ExecuteReader())
{
if (dr.Read())
{
lblGetData.Text = dr.GetString(dr.GetOrdinal("Name"));
}
}
Thanks alot for your help.
Change this line.
using (var GetName = new SqlCommand("SELECT Name FROM Ticket WHERE UserID=''", conn))
To
using (var GetName = new SqlCommand("SELECT Name FROM Ticket WHERE UserID='" + lblID.Text + "'", conn))
This query is prone to a sql injection attack though .. if you aren't sure of where the value is coming from, you should use a sql parameter to minimize the risk of sql injection.
You need to pass lblID.Text to the SQL query. Use this parameterized query to avoid SQL Injection
using (var GetName = new SqlCommand("SELECT Name FROM Ticket WHERE UserID = #UserID", conn))
{
GetName.Parameters.AddWithValue("#UserID", lblID.Text);
using (SqlDataReader dr = GetName.ExecuteReader())
{
if (dr.Read())
{
lblGetData.Text = dr.GetString(dr.GetOrdinal("Name"));
}
}
}
using (var GetName = new SqlCommand("SELECT Name FROM Ticket WHERE UserID='" + lblID.Text + "'", conn))
Use this answer, I hope it helps.

Getting Data from Access into a text box in C# by clicking a button

I have a table in MS Access that contain: (FoodID, FoodName, Price).
In C# I have three text boxes (txtId, txtName, txtPrice) and a button (btnSearch).
My question is that, In C# I just type FoodID in (txtId) and then click on button Search It'll display FoodName and Price ( from table access) in txtName and txtPrice by itself. I got the source code from you but it error on (OleDbDataReader dr = cmd.ExecuteReader();) its message is "Data type mismatch in criteria expression" .
Please solve this problem for me. This is the whole source code that I got for you.
System.Data.OleDb.OleDbConnection conn = new OleDbConnection();
conn.ConnectionString = "your connection string";
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
cmd.CommandText = "select FoodName, Price from tablename where FoodID = '" + txtId + "' ";
conn.Open();
OleDbDataReader dr = cmd.ExecuteReader();//error this line!
while(dr.Read())
{
txtName.Text = dr["FoodName"].ToString();
txtPrice.Text = dr["Price"].ToString();
}
dr.Close();
conn.Close();
I assume FoodID is int. You should remove single quotes in this case
cmd.CommandText = "select FoodName, Price from tablename where FoodID = " + txtId;
Even better - use parameters:
using (var connection = new OleDbConnection("your connection string"))
using (var command = connection.CreateCommand())
{
command.CommandText = "select FoodName, Price from tablename where FoodID = #FoodID";
command.Parameters.AddWithValue("FoodID", int.Parse(txtId.Text));
connection.Open();
var reader = command.ExecuteReader();
while (reader.Read())
{
txtName.Text = reader["FoodName"].ToString();
txtPrice.Text = reader["Price"].ToString();
}
}
I think the FoodId is of Integer type in the database but over here in the query you have passed as string so convert the string to integer.
cmd.CommandText = "select FoodName, Price from tablename where FoodID = '" + int.Parse(txtId.Text) + "' " ;
There seems to be no problem with this line of code :
OleDbDataReader dr = cmd.ExecuteReader();// correct way
I think the problem is in:
cmd.CommandText = "select FoodName, Price from tablename where FoodID = '" + txtId + "' ";
You need to use the .Text Propertie of the Textbox
cmd.CommandText = "select FoodName, Price from tablename where FoodID = '" + txtId.Text + "' ";

how to improve this code

// conn is read from handydrive
//conn2 read from C:\
this code is for write new record in to DB in C:\ by check exist first.
my problem is too slow for alot of records. and how to improve it to be faster...
SqlCeCommand cmd1 = new SqlCeCommand("Select * from bill_discount ", conn);
SqlCeDataReader dr1 = cmd1.ExecuteReader();
while (dr1.Read() != false)
{
SqlCeCommand cmd4 = new SqlCeCommand("Select * from bill_discount where bill_no='" + dr1.GetInt32(0) + "' AND bill_shopdc='" + dr1.GetString(2) + "' ", conn2);
SqlCeDataReader dr4 = cmd4.ExecuteReader();
if (dr4.Read() == false)
{
SqlCeCommand cmd2 = new SqlCeCommand("INSERT INTO bill_discount (bill_no,bill_value,bill_shopdc) VALUES ('" + dr1.GetInt32(0) + "','" + dr1.GetDouble(1) + "','" + dr1.GetString(2) + "') ", conn2);
// SqlCeDataReader dr2 = cmd2.ExecuteReader();
cmd2.ExecuteNonQuery();
}
}
//-------------------------------------------------------------------
I would take a look at the SqlBulkCopy Class:
Lets you efficiently bulk load a SQL
Server table with data from another
source.
BTW: In your code above, selecting the entire bill_discount table is not really a good idea, especially if the table is large.
[Also, it appears you could perform a single TSQL statement rather than looping through each row and round-tripping to the database.]
This example should be of help: SqlBulkCopy - Copy Table Data Between SQL Servers at High Speeds - ADO.NET 2.0 New Feature
Let's start by make the code more readable. Here's the result:
SqlCeCommand getAllBills = new SqlCeCommand("select * from bill_discount", primaryConnection);
SqlCeDataReader allBillsReader = getAllBills.ExecuteReader();
while (allBillsReader.Read())
{
SqlCeCommand getBill = new SqlCeCommand("select * from bill_discount where bill_no = '" + allBillsReader.GetInt32(0) + "' and bill_shopdc = '" + allBillsReader.GetString(2) + "' ", secondaryConnection);
SqlCeDataReader billReader = getBill.ExecuteReader();
if (!billReader.Read())
{
SqlCeCommand addMissingBill = new SqlCeCommand("insert into bill_discount (bill_no, bill_value, bill_shopdc) values ('" + allBillsReader.GetInt32(0) + "', '" + allBillsReader.GetDouble(1) + "', '" + allBillsReader.GetString(2) + "')", secondaryConnection);
addMissingBill.ExecuteNonQuery();
}
}
Disposable objects must be disposed. Let's do it.
Let's also remove SQL Injections.
Finally, let's optimize the second query: you don't need to select something and executing the reader if you just want to check if the value exists in the database.
using (SqlCeCommand getAllBills = new SqlCeCommand("select bill_no, bill_value, bill_shopdc from [bill_discount]", primaryConnection))
{
using (SqlCeDataReader allBillsReader = getAllBills.ExecuteReader())
{
while (allBillsReader.Read())
{
using (SqlCeCommand getBill = new SqlCeCommand("if exists(select * from [bill_discount] where [bill_no] = #billNumber and bill_shopdc = #billShop) select 1 else select 0", secondaryConnection))
{
getBill.Parameters.AddWithValue("#billNumber", allBillsReader["bill_no"]);
getBill.Parameters.AddWithValue("#billShop", allBillsReader["bill_shopdc"]);
bool billExists = Convert.ToBoolean(getBill.ExecuteScalar());
if (!billExists)
{
using (SqlCeCommand addMissingBill = new SqlCeCommand("insert into [bill_discount] ([bill_no], [bill_value], [bill_shopdc]) values (#billNumber, #billValue, #billShop)", secondaryConnection))
{
addMissingBill.Parameters.AddWithValue("#billNumber", allBillsReader["bill_no"]);
addMissingBill.Parameters.AddWithValue("#billValue", allBillsReader["bill_value"]);
addMissingBill.Parameters.AddWithValue("#billShop", allBillsReader["bill_shopdc"]);
int countAffectedRows = addMissingBill.ExecuteNonQuery();
Debug.Assert(countAffectedRows == 1, "The data was not inserted.");
}
}
}
}
}
}
So here we are.
Now, it's still a low performance solution. To be more effective, you might want to do the same thing in a single SQL query with joins. Since two tables are probably situated on different servers, you may look at linked servers: a feature that enables to execute a single query over several tables from several servers.
I see you are using SqlCe, which has number of limitations when inserting bulk data. The main limitation is the actual SqlCe Engine. You can however bypass this by using direct table inserts:
using (var command = connection.CreateCommand())
{
command.Transaction = transaction;
command.CommandType = CommandType.TableDirect;
command.CommandText = TABLE_NAME_IN_SQL;
using (var rs = command.ExecuteResultSet(ResultSetOptions.Updatable))
{
var rec = rs.CreateRecord();
rec.SetInt32(0, value0); // the index represents the column numbering
rec.SetString(1, value1);
rec.SetInt32(2, value2);
rs.Insert(rec);
}
}

Categories

Resources