Ok, So i am trying to write a program for my HP Ipaq211 that I can use at work (I am a server) to take orders, as opposed to using paper. I have gotten pretty far and decided that it would be best to use a database to hold the full menu information. I created a database for drinks to start with 4 Columns {ID, Item, Price, Options} where ID is the primary Key.
I created a few concoctions that allow me to read the data into an object, and then create a list of those said objects, but all of them perform really slow (4 sec ish on the Ipaq). I have taught myself everything I know in terms of programming so bear with me, here is one of my attempts (which works but is slow and i need it to work faster!)
public class _itemObject
{
public _itemObject()
{
ID = 0;
_ioName = "";
_ioPrice = "";
_ioOptions = -1;
}
public _itemObject(int _next, string Tbl_Name)
{
try
{
string conSTR = "Data Source=" + (System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)) +
"\\TestDatabase.sdf;Persist Security Info=True";
SqlCeConnection _connection = new SqlCeConnection(conSTR);
SqlCeCommand _cmd = new SqlCeCommand("select ID from " + Tbl_Name + " where ID ='" + _next.ToString() + "'", _connection);
SqlCeCommand _cmd2 = new SqlCeCommand("select * from " + Tbl_Name + " where ID ='" + _next.ToString() + "'", _connection);
SqlCeCommand _cmd3 = new SqlCeCommand("select price from " + Tbl_Name + " where ID ='" + _next.ToString() + "'", _connection);
SqlCeCommand _cmd4 = new SqlCeCommand("select special from " + Tbl_Name + " where ID ='" + _next.ToString() + "'", _connection);
_connection.Open();
if (_cmd.ExecuteScalar() != null)
{
ID = (Convert.ToInt32(_cmd.ExecuteScalar().ToString()));
_ioName = _cmd2.ExecuteScalar().ToString();
_ioPrice = _cmd3.ExecuteScalar().ToString();
_ioOptions = (Convert.ToInt32(_cmd4.ExecuteScalar().ToString()));
}
else
{
}
_connection.Close();
}
finally
{
}
}
this object is then added to a List<_itemObject> where I load any needed data from.
I know it is ugly but if anyone has any lessons for me I would appreciate it :)
The answer may differ on what is your final goal.
a) why do you need to use 4 sql commands? One command should be OK to get all information. In example:
SELECT * FROM table_name;
will report all data at once within a SqlCeDataReader.ExecuteReader() call that you can iterate to fill a list.
b) if no SQL server will be invoked later (for remote access/sync etc) and if not too much data records, you may consider switching to another data storage (ie xml (slow too) or binary file).
please provide more details if you need more help.
There are also SQLCE examples available here in stackoverflow: Local database, I need some examples and others (use search).
OK, from your comments I see you have some issues getting started?!
At http://www.codeproject.com/Articles/310378/A-Restaurant-and-Waiter-helper-app-in-WPF-and-Wind you will find a complete POS solution. You can change the waiter's code to use a local database.
...maybe adding some simple example later...
Related
the code is below and the error starting from sqlCommand cmd the 13th line of this code
private void button2_Click(object sender, EventArgs e)
{
if (StudenUsn.Text == "" )
{
MessageBox.Show("Enter The Student Number");
} else {
Con.Open();
String query = "update Student_tbl set StdName='" + StudName.Text + "',where FatherName='" + FtName.Text + "',where MotherName='" + MtName.Text + "',where StdAddress='" + Address.Text + "',where Collage ='" + Collage.Text + "'set StdRoom = " + StRmNum.SelectedValue.ToString()+",StdStatus = '"+ StudSt.SelectedItem.ToString() + "' where StdUsn ='"+StudenUsn+ "')";
SqlCommand cmd = new SqlCommand(query, Con);
cmd.ExecuteNonQuery();
MessageBox.Show("Room Successfully Updates");
Con.Close();
FillStudentDGV();
}
}
Your code should look more like:
private void button2_Click(object sender, EventArgs e)
{
if (StudenUsn.Text == "" )
{
MessageBox.Show("Enter The Student Number");
} else {
var query = #"
update Student_tbl
set
StdName=#sn,
FatherName=#fn,
MotherName=#mn,
StdAddress=#sa,
Collage=#c,
StdRoom=#sr,
StdStatus=#ss
where
StdUsn=#su";
using var con = new SqlConnection(YOUR_CONN_STR_HERE);
using var cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue(#sn, StudName.Text);
cmd.Parameters.AddWithValue(#fn, FtName.Text);
cmd.Parameters.AddWithValue(#mn, MtName.Text);
cmd.Parameters.AddWithValue(#sa, Address.Text);
cmd.Parameters.AddWithValue(#c, Collage.Text);
cmd.Parameters.AddWithValue(#sr, StRmNum.SelectedValue);
cmd.Parameters.AddWithValue(#ss, StudSt.SelectedItem);
cmd.Parameters.AddWithValue(#su, StudenUsn);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
MessageBox.Show("Room Successfully Updates");
FillStudentDGV();
}
}
There are good reasons to avoid using AddWithValue if you use SQLServer which you can get into at a later date if you want, but it's convenient for me (who doesn't know the types and widths of your columns) dealing with the current massive elephant in the room which is your SQL is massively vulnerable to a hacking technique known as sql injection (and to a lesser extent it would blow up with an error for any student whose name included an apostrophe) - using AddWithValue might make your query slightly slower, but better that than it be the cause of the next data breach; learn how to write SQLs right, right now
Never ever take data supplied by a user and concatenate it into an SQL string. Doing so essentially, in most cases, gives the user access to your database. So many big companies whose developers should know better, put up expensive firewalls and security and then let anyone in via this back door anyway; sql injection prone systems are one of the leading causes of hacks in the world today
Always use #parameter placeholders in the SQL for user data and add a parameter to the command's parameters collection, containing the data
Now on the topic of your actual error; the pattern for an update is
update table
set col1=#param1, col2=#param2 ...
where (some conditions)
You have one where and one set. If there is some conditional aspect to your set, like you only want to update the student name/address if it is currently null then you can do like:
update table
set
name=case when name is null then #n else name end,
address=case when address is null then #a else address end
where (some conditions)
Or more simply
update table
set
name=coalesce(name, #n)
address=coalesce(address, #a)
where (some conditions)
You can't mix n match and say "where this=that where this2=that2 set this3=that3" - that's a syntax error. Where is for picking the row you want to update and set is for starting a block of commas separated columns and values the row data is to be updated to.
Strive to write your sql nicely formatted inside an #string; it's a programming language all of its own, and will be easier to debug if it's laid out nicely
Can u try with it ?
String query = "update Student_tbl set StdName='" + StudName.Text + "',StdRoom = '" + StRmNum.SelectedValue.ToString()+"',StdStatus = '"+ StudSt.SelectedItem.ToString() + "' where FatherName='" + FtName.Text + "' and MotherName='" + MtName.Text + "' and StdAddress='" + Address.Text + "' and Collage ='" + Collage.Text + "' and StdUsn ='"+StudenUsn+ "'";
I am building an intranet for my school project inside a form application using the .NET framework and the C# language. This function populates a data grid inside a form. However, the code inside the while structure won't run. I have gone step by step with the debugger, and I reckon the read() method of the "dr" object will not go trough my two inner joined tables, but when I press a button that i have set to show me how many books are there registered in the database, it works. I think there is something wrong with my SQL statement, by what I have searched on this site, but I did not manage to resolve the bug. Carti.Nota and Carti.Stoc are columns with the Number type inside a Microsoft Access 2013 Database.
private void PopulateGridBooks()
{
dataGridView1.Rows.Clear();
using (OleDbConnection connect = new OleDbConnection(ConfigurationManager.ConnectionStrings["LibrarieConectare"].ConnectionString))
{
OleDbCommand command = connect.CreateCommand();
command.Parameters.AddWithValue("#titlu", cautaTitlu.Text);
command.CommandText =
" SELECT Carti.IDCarte, Carti.Titlu, Carti.Editie, Carti.An, Carti.ISBN, Carti.Nota, Carti.IDAutor, Carti.Stoc, Edituri.NumeEditura " +
" FROM (Carti INNER JOIN Edituri ON Carti.IDEditura = Edituri.IDEditura) " +
" WHERE Titlu LIKE '%#titlu%'";
try
{
connect.Open();
OleDbDataReader dr = command.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
dataGridView1.Rows.Add(dr["IDCarte"], dr["Titlu"], dr["NumeEditura"], dr["Stoc"]);
}
}
}
catch (Exception ex)
{
MessageBox.Show("Eroare la populare data grid carti: " + ex.Message);
}
}
}
Think I found it - your parameter is wrong, you should not have an # in the AddwithValue.
Use:
//Exclude the # in the below.
command.Parameters.AddWithValue("titlu", cautaTitlu.Text);
maybe move your parameter addition line to after the command text too.
Try this,
command.CommandText =
" SELECT Carti.IDCarte, Carti.Titlu, Carti.Editie, Carti.An, Carti.ISBN, Carti.Nota, Carti.IDAutor, Carti.Stoc, Edituri.NumeEditura " +
" FROM Carti INNER JOIN Edituri ON Carti.IDEditura = Edituri.IDEditura " +
" WHERE Titlu LIKE '%' + #titlu + '%';
I suggest change in where clause as the following:
"WHERE Titlu LIKE '%' + #titlu + '%'"
I have a button which adds products to the invoice, I want it to delete products off the database as well, how can I edit this query so it deletes from the database?
I think my error is because of the way I am converting cmbQuantity.Text, can someone help me with a fix?
SqlCommand inventorycontrol = new SqlCommand("Update Product SET quantityAvailable=quantityAvailabe - '" + Convert.ToInt32(cmbQuantity.Text) + "' WHERE productName='" + cmbProdName.Text + "'", con);
Without the error message, it's hard to guess.
But at first sight, you have a typo here : quantityAvailable=quantityAvailabe - should be quantityAvailable=quantityAvailab**l**e -.
Moreover, you must not quote the integer part, so '" + quantityToRemove + "' becomes " + quantityToRemove + ". But the best is to use parametrization, which will simplify your code. See Why do we always prefer using parameters in SQL statements?
Try to separate access to your UI and building your SQL:
int quantityToRemove = Convert.ToInt32(cmbQuantity.Text);
string productName = cmbProdName.Text;
string sqlUpdate = #"UPDATE Product
SET quantityAvailable = quantityAvailable - #quantityToRemove
WHERE productName= #productName";
SqlCommand inventorycontrol = new SqlCommand(sqlUpdate, con);
inventorycontrol .Parameters.AddWithValue("quantityToRemove", quantityToRemove);
inventorycontrol .Parameters.AddWithValue("productName", productName);
In the question you have not specify the error, but there may be chances of getting error in your code. that i will clarify you.
When it failed to convert the cmbQuantity.Text to int, you need not to pass an integer within double quotes :- Here my suggested answer will help you to handle this error by showing error message if the quantity is invalid.
The query you are using opens a wide range to SQL Injection. I suggest you to use parameterized query to avoid injection, As a whole you can use like the following:
int quantity;
if (int.TryParse(cmbQuantity.Text, out quantity))
{
SqlCommand inventorycontrol = new SqlCommand("Update Product SET quantityAvailable=quantityAvailabe - #Quantity WHERE productName=#prodName", con);
inventorycontrol.Parameters.AddWithValue("#Quantity",quantity);
inventorycontrol.Parameters.AddWithValue("#prodName", cmbProdName.Text);
//Execue command here
}
else
{
// show message invalid quantity
}
I found some threads here in the forum related to this problem but they didn't help me. I just want to update my database with a date value. These come from a Textfile (written there as 2014-10-02 for example). Now I tried this (which was mentioned in the other threads):
String connectionQuery = form1.conString.Text;
SqlConnection connection = new SqlConnection(connectionQuery);
SqlCommand sqlComInsert = new SqlCommand(#"INSERT INTO [" + form1.tableName.Text + "] ([" + form1.CusId.Text + "],["+ form1.date.Text +"],[" + form1.cusName.Text + "]) VALUES('" + cusId[i] + "',convert(date,'" + date[i] + "',104),'" + "','" + cusName[i] + "')", connection);
sqlComInsert.Connection.Open();
sqlComInsert.ExecuteNonQuery();
sqlComInsert.Connection.Close();
Now when I leave the "'" out ("',convert / "',104)) he tells me that the syntax is incorrect near 2013 (the beginning of my date). When I write it like above then I get:
String or binary data would be truncated.
What is this? I tried also to convert the date with:
for (int i = 0; i < typeDelDate.Count; i++)
{
unFormatedDate = date[i];
formatedDate = unFormatedDate.ToString("dd/MM/yyyy");
dateFormat.Add(formatedDate);
}
but I get still the same errors. How can I update my values? the column type is "date".
Use parametrized queries instead of slapping strings together:
var commandText = "insert (column) values (#dt);";
var cmd = new SqlCommand(commandText, connection);
cmd.Parameters.AddWithValue("dt", DateTime.ParseExact(dateString, "yyyy-MM-dd"));
cmd.ExecuteNonQuery();
Do not pass values into queries by adding strings - if possible, you should always use parameters. It saves you a lot of trouble converting to proper values (different for different locales etc.), it's more secure, and it helps performance.
I keep getting an error when I attempt to insert values into a Access database.
The error is syntactic, which leads to the following exception:
OleDbException was unhandled Syntax error in INSERT INTO statement.
private OleDbConnection myCon;
public Form1()
{
InitializeComponent();
myCon = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\File.mdb");
}
private void insertuser_Click(object sender, EventArgs e)
{
OleDbCommand cmd = new OleDbCommand();
myCon.Open();
cmd.Connection = myCon;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO User ([UserID], [Forename], [Surname], " +
"[DateOfBirth], [TargetWeight], [TargetCalories], [Height]) " +
"VALUES ('" + userid.Text.ToString() + "' , '" +
fname.Text.ToString() + "' , '" +
sname.Text.ToString() + "' , '" +
dob.Text.ToString() + "' , '" +
tarweight.Text.ToString() + "' , '" +
tarcal.Text.ToString() + "' , '" +
height.Text.ToString() + "')";
cmd.ExecuteNonQuery();
myCon.Close();
}
Well, you haven't specified what the error is - but your first problem is that you're inserting the data directly into the SQL statement. Don't do that. You're inviting SQL injection attacks.
Use a parameterized SQL statement instead. Once you've done that, if you still have problems, edit this question with the new code and say what the error is. The new code is likely to be clearer already, as there won't be a huge concatenation involved, easily hiding something like a mismatched bracket.
EDIT: As mentioned in comments, Jet/ACE is vulnerable to fewer types of SQL injection attack, as it doesn't permit DML. For this INSERT statement there may actually be no vulnerability - but for a SELECT with a WHERE clause written in a similar way, user input could circumvent some of the protections of the WHERE clause. I would strongly advise you to use parameterized queries as a matter of course:
They mean you don't have to escape user data
They keep the data separate from the code
You'll have less to worry about if you ever move from Jet/ACE (whether moving this particular code, or just you personally starting to work on different databases)
For other data types such as dates, you don't need to do any work to get the data into a form appropriate for the database
(You also don't need all the calls to ToString. Not only would I expect that a property called Text is already a string, but the fact that you're using string concatenation means that string conversions will happen automatically anyway.)
I posted this as a comment to the duplicate question at: Syntax error in INSERT INTO statement in c# OleDb Exception cant spot the error
Put brackets [] around the table name
"User". It's a reserved word in SQL
Server.
"User" is also a reserved word in Access (judging by the provider in your connection string).
But I completely agree with Jon--if you fix your current implementation, you are just opening up a big security hole (against your User table, no less!)
This problem may occur if your database table contains column names that use Microsoft Jet 4.0 reserved words.
Change the column names in your database table so that you do not use Jet 4.0 reserved words.
If TargetWeight, Height, and TargetCalories are floating-point or integer values, they don't need to be surrounded by quotes in the SQL statement.
Also, not directly related to your question, but you should really consider using a parameterized query. Your code is very vulnerable to SQL injection.
public decimal codes(string subs)
{
decimal a = 0;
con_4code();
query = "select SUBJINTN.[SCODE] from SUBJINTN where SUBJINTN.[ABBR] = '" + subs.ToString() + "'";
cmd1 = new OleDbCommand(query, concode);
OleDbDataReader dr = cmd1.ExecuteReader();
here is error in dr it says syntax error ehile in DBMS its working Well
if (dr.Read())
{
a = dr.GetDecimal(0);
MessageBox.Show(a.ToString());
}
return a;
}
After this
cmd.CommandText="INSERT INTO User ([UserID], [Forename], [Surname], [DateOfBirth], [TargetWeight], [TargetCalories], [Height]) Values ('" + userid.Text.ToString() + "' , '" + fname.Text.ToString() + "' , '" + sname.Text.ToString() + "' , '" + dob.Text.ToString() + "' , '" + tarweight.Text.ToString() + "' , '" + tarcal.Text.ToString() + "' , '" + height.Text.ToString() + "')";
check what this contains, maybe [DateOfBirth] has illegal format