I need to know that i have 3 tables one with sessional marks with primary key sessional id and another table student with student id as primary key and third table Data with student id and sessional id as foreign keys.
Now i need to update marks of each student in grid view so that marks get stored in sessional marks table.
i am using this query
string hourly1;
string hourly2;
string student_id;
for (int i = 0; i < this.dataGridView1.Rows.Count - 1; i++)
{
hourly1 = dataGridView1[1,i].Value.ToString();
hourly2 = dataGridView1[2,i].Value.ToString();
student_id = Convert.ToString(dataGridView1[3, i].Value);
SqlCommand cmd = new SqlCommand("UPDATE SessionalMarks SET " +
"SessionalMarks.Hourly1Marks = '" + hourly1 + "'," + "SessionalMarks.Hourly2Marks = '" + hourly2 + "'from Student,DATA where Student.StudentId=DATA.StudentId AND Student.StudentId='" + student_id + "'", conn);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
but this query is adding same marks in each row in need to update marks which are placed in the grid view
i think there is a problem in where clause can some one help me please.
It's very unclear what your SQL schema looks like, but in your update statement, everything after FROM isn't being used for any purpose. Your WHERE clause doesn't mention SessionalMarks, so each time you loop through your for loop you're updating all rows in that table.
If you post your SQL schema of these three tables, it might help us understand the shape of your data and help you write a better query. The way you've described it, it sounds like the DATA table ought to contain the marks for each student, but you've apparently put that data in the SessionalMarks table instead.
However, your code has some problems besides the one you've mentioned:
You're composing a SQL query by joining strings together, and it looks like those strings might have come from the user. This exposes you to a SQL injection attack, or at least if the user types a ' your program will behave incorrectly.
You're opening and closing the database connection repeatedly, instead of opening it once and closing it when you're finished.
To fix these problems, you probably should (a) use a parameterized SQL query, and (b) open and close the database connection outside of the loop.
This isn't perfect, but it's a start:
// this query needs to be fixed
string query = #"UPDATE SessionalMarks
SET SessionalMarks.Hourly1Marks = #hourly1
,SessionalMarks.Hourly2Marks = #hourly2
FROM Student,DATA
WHERE Student.StudentId = DATA.StudentId
AND Student.StudentId = #studentid";
// Make sure we dispose of the SqlCommand when we're finished with it
using (SqlCommand cmd = new SqlCommand(query, conn))
{
// Create my three parameters, don't need a value yet
// Need to make sure we have the right SqlDbType specified
cmd.Parameters.Add( new SqlParameter("#hourly1", SqlDbType.Decimal) );
cmd.Parameters.Add( new SqlParameter("#hourly2", SqlDbType.Decimal) );
cmd.Parameters.Add( new SqlParameter("#studentid", SqlDbType.Int) );
conn.Open();
try
{
// For each row in our DataGridView
// We could also use foreach(DataGridViewRow row in dataGridView1.Rows)
for (int i = 0; i < this.dataGridView1.Rows.Count - 1; i++)
{
// Fill in our parameters with our values
cmd.Parameters[0].Value = dataGridView1[1,i].Value.ToString();
cmd.Parameters[1].Value = dataGridView1[2,i].Value.ToString();
cmd.Parameters[2].Value = Convert.ToString(dataGridView1[3, i].Value);
cmd.ExecuteNonQuery();
}
}
finally
{
// Close our database connection even if cmd.ExecuteNonQuery() throws
conn.Close();
}
}
Related
please help. in Visual Studio 2017 and SQL localDB - WinForm learns and makes a small application. Form (Textbox), where "name, surname, address, city, phone and email" is written in Czech language containing "ěščřžýáíé" ". Everything is stored in the database (nvarchar) in order. Everything OK.
In Form2 I have another form where Combobox calls a "surname" and it has to fill in the phone and e-mail automatically from the database. If the surname is without the character "ěščřžýáíé", everything will be displayed correctly. If it contains "ěščřžýáíé", only the last name will be displayed, but the phone and email will not be loaded into the TextBox.
The code sample (without ěščřžýáíé) works perfectly:
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\newtest.mdf;Integrated Security=True");
string sql = "select * from test111 WHERE firmadat ='" + prijmeniComboBox.Text + "'; ";
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader myreader;
try
{
con.Open();
myreader = cmd.ExecuteReader();
while (myreader.Read())
{
string rollno = myreader.GetInt32(0).ToString();
string name = myreader.GetString(1);
string telephone = myreader.GetString(3);
string email = myreader.GetString(4);
textBox1.Text = rollno;
telefonTextBox.Text = telephone;
emailTextBox.Text = email;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Thank you for your help.
The problem is probably here:
string sql = "select * from test111 WHERE firmadat ='" + prijmeniComboBox.Text + "'; ";
Here you take your Unicode string and you concatenate it into a SQL string that is not a Unicode string. I would tell you how to get it working as you intended but this is a really really dangerous way to write SQLs. Someone at kids' toy maker VTech wrote SQLs this way and enabled a hacker to download millions of images of children taken by vtech devices. If one of my developers wrote SQL like this they would be subject to disciplinary action, possibly being fired.
I strongly recommend that you use parameterized SQLs; any number of internet resources will show you how, such as http://bobby-tables.com - it will also solve the problem of getting no results when searching using a search term that contains non-ASCII characters
Take a look at http://dapper-tutorial.net ; using dapper will not only take care of the parameterizing for you, but make your database life easier by reducing your code to just a couple of lines, something like:
using(SqlCommand x = new SqlCommand(conn)
{
var p = x.Query(
"select * from test111 WHERE firmadat = #a",
new { a = prijmeniComboBox.Text }
);
firstNameTextBox.Text = p.FirstName; //or what the column is called on db
...
}
You just write your sql, use #namedParameter placeholders and supply an anonymous object with properties named after the placeholders. Dapper does the rest. If you have a Person class in your project you can even get dapper to create it and populate it for you
I try to UPDATE data in my SQL Server database and I get this error:
System.Data.SqlClient.SqlException
Incorrect syntax near 'de'
Unclosed quotation mark after the character string ')'
private void BtEnrMod_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection("Data Source=.\\BD4X4;Initial Catalog=BD4X4;Integrated Security=True");
con.Open();
SqlCommand cmd = new SqlCommand("UPDATE Service SET Type = " + TxBxService.Text + ", Prix = " + TxBxPrix.Text + "WHERE Code = " + LbCodeAff.Text + "')", con);
int i = cmd.ExecuteNonQuery();
if (i != 0)
{
MessageBox.Show("Service Modifié");
}
else
{
MessageBox.Show("Erreur");
}
this.Close();
con.Close();
}
Replace the one liner that declares your command with this code block:
SqlCommand cmd = new SqlCommand("UPDATE Service SET Type = #t, Prix = #p WHERE Code = #c", con);
cmd.Parameters.AddWithValue("#t", TxBxService.Text);
cmd.Parameters.AddWithValue("#p", TxBxPrix.Text);
cmd.Parameters.AddWithValue("#t", LbCodeAff.Text);
Always avoid writing an sql where you string concatenate in a value provided by the user in a text box; it's the number one security horror you can make with sql. Always use parameters to put values in, like you see here. For more info on this SQL injection hacking, see http://bobby-tables.com
If you ever fin yourself in a situation where you think you have to concatenate to make an sql, don't concatenate a value in; concatenate a parameter in and add the value into the parameters collection. Here's a hypothetical example:
var cmd = new SqlCommand("","connstr");
strSql = "SELECT * FROM table WHERE col IN (";
string[] vals = new[]{ "a", "b", "c" };
for(int x = 0; x<vals.Length; x++){
strSql += ("#p"+x+",");
cmd.Parameters.AddWithValue("#p"+x, vals[x]);
}
cmd.CommandText = strSql + ")";
This uses concatenation to make an sql of SELECT * FROM table WHERE col IN (#p0, #p1, #p2) and a nicely populated parameters collection
When you're done grokking that, read the link Larnu posted in the comments. There are good reasons to avoid using AddWithValue in various scenarios but it will always be preferable to concatenation of values. Never ditch the use of parameters "because I read a blog one time about how AddWithValue is bad" - form parameters using the new parameter constructor, or use AddWithValue shortcut, but never concat values
Or better still than all of this, use an ORM like Entity Framework, nHibernate or Dapper and leave most of this boring boilerplate low level SQL drudgery behind. These libraries do most of this wrangling for you; EF and nH even write th sql too, dapper you write it yourself but it takes care of everything else
Using a good ORM is like the difference between writing creating a UI manually line by line of position, font, anchor, event code for every button, label and text box versus using the windows forms designer; a world apart and there's no sense in taking hours to create manually what software can do more comprehensively, faster and safer for you in seconds
I am trying to add the values of a column of a table. My table looks like this:
enter image description here
I want to add the values of months column for a specific id. My code looks like this:
public int MonthSum(int id)
{
SqlConnection connection = new SqlConnection(connectionString);
string query = "select sum(months) from PayTable where ID=#ID group by ID";
SqlCommand command = new SqlCommand(query,connection);
command.Parameters.Clear();
command.Parameters.Add("ID", SqlDbType.Int);
command.Parameters["ID"].Value = id;
connection.Open();
int total = (int)command.ExecuteScalar();
connection.Close();
return total;
}
Why I am getting exception here??
Since you don't provide more information about the exception, it's only guessing, but you may have a problem adding the parameter as "ID" instead of "#ID". I think that SqlCommand expects the name with the #.
Here some Microsoft documentation with an example very similar to what you are doing.
SqlConnection sc = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=D:\6th sem\DNT\tutorials\application\WindowsFormsApplication2\WindowsFormsApplication2\Login.mdf;Integrated Security=True");
sc.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = sc;
//cmd.CommandText = "SELECT count(*) FROM dictionary WHERE word=#Word AND user=#Unique";
cmd.Parameters.AddWithValue("#Word", textBox_word.Text);
cmd.Parameters.AddWithValue("#Unique", frm.textUserName);
cmd.CommandText = "SELECT COUNT(*) FROM dictionary WHERE word=#Word AND user=#Unique";
int z = (int)cmd.ExecuteScalar();
MessageBox.Show(z.ToString());
if (z >= 1)
{
MessageBox.Show("word already entered in your id");
}
else
{
}
My code is always going in else part and output of above query is always 0 !!!
You should probably use Profiler to see what is being passed to your parameters, but I am highly suspicious of this line:
cmd.Parameters.AddWithValue("#Unique", frm.textUserName);
Don't you want to access the .text property of the textUserName object, the way you did with the #Word parameter?
finally found an answer...
it was problem with SQL database coloumn name user which they are not allowing i dont know the reason why but that was it in my case.
so i changed the coloumn name to user1 and it works correctly...
suggestion 1:-
Please store the values of textBox_word.Text and frm.textUserName in another values and then put here.
cmd.Parameters.AddWithValue("#Word", value1);
cmd.Parameters.AddWithValue("#Unique",value2);
If still any issue then
Suggestion 2:-
Please debug the code and check what exactly values are comming for value1 and value2
I am trying to do create a where clause to pass as a parameter to an Oracle command and it's proving to be more difficult than I thought. What I want to do is create a big where query based off user input from our application. That where query is to be the single parameter for the statement and will have multiple AND, OR conditions in it. This code here works however isn't exactly what I require:
string conStr = "User Id=testschema;Password=pass12341;Data Source=orapdex01";
Console.WriteLine("About to connect to Database with Connection String: " + conStr);
OracleConnection con = new OracleConnection(conStr);
con.Open();
Console.WriteLine("Connected to the Database..." + Environment.NewLine + "Press enter to continue");
Console.ReadLine();
// Assume the connection is correct because it works already without the parameterization
String block = "SELECT * FROM TEMP_VIEW WHERE NAME = :1";
// set command to create anonymous PL/SQL block
OracleCommand cmd = new OracleCommand();
cmd.CommandText = block;
cmd.Connection = con;
// since execurting anonymous pl/sql blcok, setting the command type
// as text instead of stored procedure
cmd.CommandType = CommandType.Text;
// Setting Oracle Parameter
// Bind the parameter as OracleDBType.Varchar2
OracleParameter param = cmd.Parameters.Add("whereTxt", OracleDbType.Varchar2);
param.Direction = ParameterDirection.Input;
param.Value = "MY VALUE";
// Get returned values from select statement
OracleDataReader dr = cmd.ExecuteReader();
// Read the identifier for each result and display it
while (dr.Read())
{
Console.WriteLine(dr.GetValue(0));
}
Console.WriteLine("Selected successfully !");
Console.WriteLine("");
Console.WriteLine("***********************************************************");
Console.ReadKey();
If I change the lines below to be the type of result I want then I get an error "ORA-00933: SQL command not properly ended":
String block = "SELECT * FROM TEMP_VIEW :1";
...
...
param.Value = "WHERE NAME = 'MY VALUE' AND ID = 5929";
My question is how do I accomplish adding my big where query dynamically without causing this error?
Sadly there is no easy way to achieve this.
One thing you will need to understand with parameterised SQL in general is that bind parameters can only be used for values, such as strings, numbers or dates. You cannot put bits of SQL in them, such as column names or WHERE clauses.
Once the database has the SQL text, it will attempt to parse it and figure out whether it is valid, and it will do this without taking any look at the bind parameter values. It won't be able to execute the SQL without all of the values.
The SQL string SELECT * FROM TEMP_VIEW :1 can never be valid, as Oracle isn't expecting a value to immediately follow FROM TEMP_VIEW.
You will need to build up your SQL as a string and also build up the list of bind parameters at the same time. If you find that you need to add a condition on the column NAME, you add WHERE NAME = :1 to the SQL string and a parameter with name :1 and the value you wish to add. If you have a second condition to add, you append AND ID = :2 to the SQL string and a parameter with name :2.
Hopefully the following code should explain a little better:
// Initialise SQL string and parameter list.
String sql = "SELECT * FROM DUAL";
var oracleParams = new List<OracleParameter>();
// Build up SQL string and list of parameters.
// (There's only one in this somewhat simplistic example. If you have
// more than one parameter, it might be easier to start the query with
// "SELECT ... FROM some_table WHERE 1=1" and then append
// " AND some_column = :1" or similar. Don't forget to add spaces!)
sql += " WHERE DUMMY = :1";
oracleParams.Add(new OracleParameter(":1", OracleDbType.Varchar2, "X", ParameterDirection.Input));
using (var connection = new OracleConnection() { ConnectionString = "..."})
{
connection.Open();
// Create the command, setting the SQL text and the parameters.
var command = new OracleCommand(sql, connection);
command.Parameters.AddRange(oracleParams.ToArray());
using (OracleDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
// Do stuff with the data read...
}
}
}