I'm working with MS Access and would like to how to update the data correctly..here is the code i use on my button click event with no luck
OleDbCommand cmd = new OleDbCommand("SELECT * FROM ItemTemp WHERE ITEM='" + txtItemname.Text + "'", GetConnection());
OleDbDataReader reader = cmd.ExecuteReader();
//check if this item exist on the table ItemTemp
if (reader.HasRows == true)
{
// item exists, do below action
OleDbCommand cmde = new OleDbCommand("UPDATE ItemTemp SET QUANTITY=QUANTITY + #QUANTITY, PRICE=PRICE + #PRICE WHERE ITEM='" + txtItemname.Text + "'", GetConnection());
cmde.Parameters.AddWithValue("#QUANTITY", txtItemquantity.Value); //numericupdown control
cmde.Parameters.AddWithValue("#PRICE", txtItemprice.Text); //textbox control
cmde.ExecuteNonQuery();
}
data on database BEFORE updating:
ID | ITEM | QUANTITY | PRICE
1 | ITEM1 | 1 | 400
data on database AFTER updating:
ID | ITEM | QUANTITY | PRICE
1 | ITEM1 | 11 | 400400
data on database which i want it to be AFTER updating:
ID | ITEM | QUANTITY | PRICE
1 | ITEM1 | 2 | 800
i do believe my command is correct if not my bad..there's no other than this code on my button click event. any ideas?
First you should be sure that the database fields Quantity and Price are oo numeric type. If they are Text then your query concatenate the string values passed as parameters with the string present in the database column.
Second, when you pass the parameters with AddWithValue the framework infers the datatype for you looking at the datatype of the passed value. In your case you pass a string and and the database engine sees a string that will be concatenated to the existing value. You need to convert before passing to an appropriate datatype
Finally, use allways parametrized query for every thing you pass to the database engine, especially if the value passed comes from an input textbox.
OleDbCommand cmd = new OleDbCommand("SELECT * FROM ItemTemp WHERE ITEM=#item", GetConnection());
cmd.Parameters.AddWithValue("#item", txtItemName.Text);
OleDbDataReader reader = cmd.ExecuteReader();
//check if this item exist on the table ItemTemp
if (reader.HasRows == true)
{
OleDbCommand cmde = new OleDbCommand("UPDATE ItemTemp SET QUANTITY=QUANTITY + #QUANTITY," +
"PRICE=PRICE + #PRICE WHERE ITEM=#item, GetConnection());
cmde.Parameters.AddWithValue("#QUANTITY", Convert.ToInt32(txtItemquantity.Value));
cmde.Parameters.AddWithValue("#PRICE", Convert.ToDecimal(txtItemprice.Text));
cmde.Parameters.AddWithValue("#item", txtItemName.Text);
cmde.ExecuteNonQuery();
}
ok, its seem to be done now. i just change
cmde.Parameters.AddWithValue("#QUANTITY", txtItemquantity.Value); //numericupdown control
cmde.Parameters.AddWithValue("#PRICE", txtItemprice.Text); //textbox control
to this
cmde.Parameters.AddWithValue("#QUANTITY", Convert.ToInt32(txtItemquantity.Value));
cmde.Parameters.AddWithValue("#PRICE", Convert.ToInt32(txtItemprice.Text));
Related
Hello guys i m working with a school assignment which has a simple form and database.
there is students table in database.
Problem:
This program works when i Enter stu_ID as integer which is primary key like 1234,
problem arise when i enter stu_ID as non-integer.(assignment requirement).
Like BSCS-122.it gives following exception
'System.Data.SqlClient.SqlException' {"Invalid column name 'BSCS'."}
I m working with Visual studio 2015
SQL Server 2008 R2 express.
students
stu_Id varchar(50) PK
stu_Name varchar(50)
Stu_Age int
stu_Semester int
stu_City varchar(50)
+------------+-----------------+---------+--------------+-------------+
| stu_Id | stu_Name | Stu_Age | stu_Semester | stu_City |
+------------+-----------------+---------+--------------+-------------+
| BSCS-122 | Danish Kareem | 22 | 5 | Decya |
| MBA-233 | Kamran | 23 | 5 | JPT |
| .. .... | ............... | ..... ..| ....... .....| ...... .....|
+------------+-----------------+---------+--------------+-------------+
The c# code is bellow.
private void btnInsert_Click(object sender, EventArgs e)
{
SqlConnection objSqlConnection = new SqlConnection(#"Data Source=DESKTOP-VESS66M\SQLEXPRESS;Initial Catalog=Persons;Integrated Security=True");
try
{
//
objSqlConnection.Open();
string insertCommand = "INSERT INTO students VALUES (" +stu_ID.Text+ ",'" + stu_Name.Text + "','" + Convert.ToInt32(stu_Age.Text) + "','" + Convert.ToInt32(stu_Semester.Text) + "','" + stu_City.Text + "')";
SqlCommand objSqlCommand = new SqlCommand(insertCommand, objSqlConnection);
objSqlCommand.ExecuteNonQuery();
//
this.studentsTableAdapter.Fill(this.personsDataSet.students);
//
MessageBox.Show("Student " + txtName.Text + " had been added Successfully", "Added Succefull", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception)
{
throw;
}
finally
{
objSqlConnection.Close();
}
}
Short and quick fix is to add single quotes arount stu_ID but that's prone to SQL injection: "'"+stu_ID.Text+"'"
Better way is to add parameters to your query, to prevent SQL injection:
string insertCommand = "INSERT INTO students VALUES (#stuID, #stuName, #stuAge, #stuSemester, #stuCity)";
insertCommand.Parameters.Add(new SqlParameter("stuId", stu_ID.Text));
command.Parameters.Add(new SqlParameter("stuName", stu_Name.Text));
command.Parameters.Add(new SqlParameter("stuAge", Convert.ToInt32(stu_Age.Text)));
command.Parameters.Add(new SqlParameter("stuSemester", Convert.ToInt32(stu_Semester.Text)));
command.Parameters.Add(new SqlParameter("stuCity", stu_City.Text));
Your text field value needs to be surrounded by single quotes like:
"INSERT INTO students VALUES ('" + stu_ID.Text + "')"
However, this is still an extremely bad idea as you're leaving yourself open to SQL Injection. If you aren't going to use a framework (such as Entity Framework) for your data layer, you at least need to use an SQLParameter to inject your values.
I have this query:
string query = "SELECT afspraak_locatie FROM Afspraak WHERE date(datum) = '" + datum +"'";
The final query will look like this:
SELECT afspraak_locatie FROM Afspraak WHERE date(datum) = '2016-06-16'
When i execute the query in my PHPMYADMIN it returns the row. But when i do it in C# it says my MySqldatareader is empty
Here is the code i use for that:
MySqlCommand cmd1 = new MySqlCommand(query1, connection);
cmd1.CommandType = CommandType.Text;
using (MySqlDataReader reader1 = cmd1.ExecuteReader())
{
while (reader1.Read())
{
result1.Add(reader1.GetString(0));
}
reader1.Close();
}
cmd1.Cancel();
When this gets executed it will give a System.NullreferenceException on the while(reader1.read) part. Any solutions?
Schema and data loaded:
create table Afspraak
(
id int auto_increment primary key,
afspraak_locatie varchar(100) not null, -- just an example (we don't know your datatype)
datum datetime not null -- you said it was a datetime in a comment under your question
);
insert Afspraak (afspraak_locatie,datum) values
('Rome','2016-06-14 13:55:55'),
('London','2016-06-15 15:12:12'),
('Cairo','2016-06-16 07:00:33'),
('Boston','2016-06-17 01:30:00');
select * from afspraak;
+----+------------------+---------------------+
| id | afspraak_locatie | datum |
+----+------------------+---------------------+
| 1 | Rome | 2016-06-14 13:55:55 |
| 2 | London | 2016-06-15 15:12:12 |
| 3 | Cairo | 2016-06-16 07:00:33 |
| 4 | Boston | 2016-06-17 01:30:00 |
+----+------------------+---------------------+
GUI Layer:
private void button1_Click(object sender, EventArgs e)
{
myDB.FindThatRow("2016-06-16"); // get data
}
DB Layer:
public void FindThatRow(string theDate)
{ // or all those rows
//
using (MySqlConnection lconn = new MySqlConnection(connString))
{
lconn.Open();
using (MySqlCommand cmd = new MySqlCommand())
{ //
cmd.Connection = lconn;
cmd.CommandText = #"select id,afspraak_locatie FROM Afspraak WHERE date(datum) = #pTheDate";
cmd.Prepare();
cmd.Parameters.AddWithValue("#pTheDate", theDate);
using (MySqlDataReader rs = cmd.ExecuteReader())
{ //
while (rs.Read())
{
int qId = (int)rs.GetInt32("id");
string sViewIt = rs.GetString("afspraak_locatie");
}
}
}
}
}
It found the data:
Use the using blocks as recommended by everyone. Bind your parameters.
The reasons why one should steer toward data bindings, versus string concatenation as seen in your attempt, include losing the functionality of what binding offers as seen in Configuring Parameters and Parameter Data Types and other links near or off that topic. And, it turns querying into the mess seen in PHP with concatenation which steered their modern usage toward parameter data bindings too.
Imagine how difficult and debug-intensive the following query would be without bindings:
Sql Injection Attacks:
Parameter binding protects you from such attacks, unlike your method of concat. See the following question including this answer for stored procedure usage.
I have excel sheet (named as $Sheet1) and sql table(named as Users) with same Formate which is given below
ID | UserName | FirstName | LastName | DateOfBirth |
1 | robert | robert | poinan | 1984 |
2 | joy | joy | rob | 1990 |
I Have read the whole excel sheet data in DataSet (Named as 'ds') now I want to insert the whole DataSet (which is 'ds') in sql table (which is 'Users')
I am using for loop (can also use foreach loop) to insert 'ds' (DataSet) rows one by one into Users (Sql table) table
sqlConn.Open();
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
SqlCommand cmd = new SqlCommand("INSERT INTO [Users] ([ID],[UserName],[FirstName],[LastName],[DateOfBirth]) VALUES(#ID,#UserName,#FirstName,#LastName,#DateOfBirth))", sqlConn);
cmd.Parameters.AddWithValue("#ID", ds.Tables[0].Rows[i][0].ToString());
cmd.Parameters.AddWithValue("#UserName", ds.Tables[0].Rows[i][1].ToString());
cmd.Parameters.AddWithValue("#FirstName", ds.Tables[0].Rows[i][2].ToString());
cmd.Parameters.AddWithValue("#LastName", ds.Tables[0].Rows[i][3].ToString());
cmd.Parameters.AddWithValue("#DateOfBirth", ds.Tables[0].Rows[i][4].ToString());
cmd.ExecuteNonQuery();
}
}
sqlConn.Close();
in this code I am facing a lot of problems one of these is, if there is any error in inserting the row the program stop but the rows that are inserted before are exists in the sql database next time when I try to run this program the data rows are duplicated.
I have millions of records. if I want to check the data row in sql table it takes a lot of time to execute the whole process.
My quetion is. Is there any way to insert the whole 'DataTable (which is in DataSet)' into Users Table at once
Something Like This
INSERT INTO [Users](ID, FirstName,LastName,DateOfBirth)
SELECT ID, FirstName,LastName,DateOfBirth FROM ds.Tables[0]
;
This is the approach given in MSDN(https://msdn.microsoft.com/en-us/library/ex21zs8x(v=vs.110).aspx). Make a DT and pass the DT as parameter to BulkCopy.
DataTable dt = new DataTable();
dt.Columns.Add("FieldName", typeof(System.Decimal));
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to get last inserted id?
I have a table Absences
| Id | Name | Job |
-------------------------
| 1 | James | 1 |
-------------------------
| 2 | Simon | 1 |
-------------------------
Where ID is an identity Primary Key incrementing by 1.
I'm accessing this table from a program in C# and I need to do the following :
Insert Into Absences (Name, Job) Values ('aName', 'aJob')
The problem is I need to get the Id column where i'm inserting at the same time because Nameand Job are not unique so I won't be able to retreive this exact column after.
Is it possible to add a select on the Id column in that query ?
Update
SqlConnection myConnection = new SqlConnection(#"SomeConnection");
myConnection.Open();
SqlCommand myCommand = myConnection.CreateCommand();
myCommand.CommandText = "Insert Into Absences (Name, Job) Values ('aName', 'aJob')";
int currentAbs = (int)myCommand.ExecuteScalar();
I get an error on the ExecuteScalar Line. Object reference is not set to and instance of object.
The SQL statement SCOPE_IDENTITY() will give you the value of the identity column of the newly inserted row from within the same scope.
SqlConnection myConnection = new SqlConnection(#"SomeConnection");
myConnection.Open();
SqlCommand myCommand = myConnection.CreateCommand();
myCommand.CommandText = "Insert Into Absences (Name, Job) Values ('aName', 'aJob'); SELECT SCOPE_IDENTITY();";
int currentAbs = (int)myCommand.ExecuteScalar();
Scope Identity Definition
If you use SqlCommand, then you can use
int lastId = (int)command.ExecuteScalar();
to retrieve the unique id of the inserted record.
Take a look at Microsoft page.
After this query you can select ##identity to get the last inserted id in mssql server.
One way would be to use SELECT ##IDENTITY immediately after you insert your record:
int id;
string query = "Insert Into Absences (Name, Job) Values ('aName', 'aJob')";
using (SqlCommand cmd = new SqlCommand(query, connection)) {
connection.Open();
// execute your INSERT query
cmd.ExecuteNonQuery();
// get the last-inserted ID
cmd.CommandText = "SELECT ##IDENTITY";
id = (int)cmd.ExecuteScalar();
}
I have a query - "SELECT PK1 FROM users";
I also have a datatable named myTable with three fields of type int;
-----------
| myTable |
-----------
| field1 |
| field2 |
| field3 |
-----------
For each row returned from my query, I would like to put the PK1 value into field2 in myTable leaving field1 and field3 null.
Here's some sample code I have tried so far, but it doesn't seem to be working. Instead, the field PK1 is appended to the end of myTable as a new field.
class Program
{
static void Main(string[] args)
{
string SQL = "SELECT PK1 FROM users";
SqlConnection connection = new SqlConnection([my connection string]);
DataTable myTable = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(SQL, connection);
myTable.Columns.Add("field1", typeof(Int32));
myTable.Columns.Add("field2", typeof(Int32));
myTable.Columns.Add("field3", typeof(Int32));
DataTableMapping dataMapping = adapter.TableMappings.Add("myTable", "users");
dataMapping.ColumnMappings.Add("PK1", "field2");
adapter.Fill(myTable);
foreach (DataRow row in myTable.Rows)
{
Console.WriteLine("------------");
foreach (DataColumn column in myTable.Columns)
{
Console.WriteLine(column.ColumnName + " : " + row[column]);
}
}
Console.ReadKey();
}
}
Is there an issue in my code, or is there another way I can map the fields across?
This is a simplified example for the purposes of this question, as such mapping the field names would be ideal rather than inserting the value at a given position.
I think if it is your requirement then there is nothing wrong with this approach.
Change your query to the following, and you don't need the mapping.
string SQL = "SELECT PK1 as field2 FROM users";
it is adding the column because you are telling it to. You should either use the datamappingColumn feature or the table.column.add feature not both, they are redundant, and probably not necessary.
So if you leave the table.column.add()
Here is an example of how you would "bind" the column names to the columns you set in table, you specify the order in which you want them to appear, you can leave them blank by "" double quote or set them to null by using NULL.
this.table.AutoSetDataBoundColumnHeaders = true;
this.table.SetDataBinding(table, null, "PK1", null);