SUM(Table) not working when using SqlCommand - c#

When I run the code the result will be of 'Type' instead of the SUM of Name.
Tried also do the SUM inside the Reader[("Types")] and it displays SUM(Types). It should display the amount of that particular name
Code inside c#:
public void DisplayName()
{
try
{
string Connection = #"Data Source=local;Initial Catalog=Project;Integrated Security=True";
SqlConnection Connect = new SqlConnection(Connection);
string Name;
Console.WriteLine("\nShowing Name\n");
Console.WriteLine("Enter name type: \n");
country = Console.ReadLine();
ConnectingDatabase.Open();
string Query = "SELECT SUM(Types) FROM PersonName WHERE Name = #Name";
SqlCommand Commands = new SqlCommand(Query, ConnectingDatabase, ConnectingDatabase.BeginTransaction());
Commands.Parameters.Add(new SqlParameter("#Name", country));
SqlDataReader Reader = ParaComm.ExecuteReader();
if (Reader.Read())
{
Console.WriteLine("Your name is " + name + " with sum of {0}\n", Reader[("Types")]);
}
Reader.Close();
ParaComm.Transaction.Commit();
Connect.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

You should use Group By when use aggregeate function in sql. Try this Sql-Command
string Query = "SELECT SUM(Types) FROM main.Stats Group by column_name WHERE
Name = #Name";

As you learned, you can always reference a column by the column number. i.e 0 in this case.
However, the easiest way to deal with this moving forward, and avoid issues with changes to a query that cause column numbers to change, is to provide an alias for the column.
If you add an alias to your query, changing it to
SELECT SUM(Types) as TypeSum FROM PersonName WHERE Name = #Name you should find that you can access the value using Reader["TypeSum"] syntax.

Related

C# how to pass user input to a parameter in where clause

I want to pass an user input to a where clause in a method.
The method has sql query and it uses parameter, but it seems like the parameter is not passed to the query. (I debugged and saw it does not go into the while loop.
My code is below:
Console.WriteLine("Enter your name: ");
string name = Console.ReadLine();
string prm = "\"" + name + "\""; // Doublequote a string
//execute method
CheckCustomer(prm);
private static string CheckCustomer(string cusName)
{
string cust = "null";
try
{
Console.WriteLine("\nChecking custoemr...\n");
// Sql Select Query
string sql = "SELECT * FROM Customer WHERE CustomerName = #CusName";
SqlCommand cmd = new SqlCommand(sql, sqlConnection);
cmd.Parameters.AddWithValue("#CusName", cusName);
SqlDataReader dr;
dr = cmd.ExecuteReader();
string strCusname = "Customer Name Found";
Console.WriteLine("{0}", strCusname.PadRight(25));
Console.WriteLine("==============================");
while (dr.Read())
{
////reading from the datareader
cust = dr["CustomerName"].ToString();
}
dr.Close();
return cust;
}
catch (SqlException ex)
{
// Display error
Console.WriteLine("Error: " + ex.ToString());
return null;
}
}
When I execute CheckCustomer() without the where clause, it works perfect.
However, once I add a parameter, does not go inside while loop; it goes to dr.Close(); directly.
What is wrong with this code?
To check for nulls in SQL server you use "is null" instead of "where field = null"
if you tried the query in sql server management studio u will not get any result
since string cust = "null"; that means ur code checks for customerName = null, but as i stated that this is not the right way to check for null and this query will not return any result, and since there is no result that means dr.Read() will evaluate to false and the while loop won't be executed
You don't need to wrap the string value in quote. You can remove this line, since SqlParameter will handle that for you.
string prm = "\"" + name + "\""; // Doublequote a string
Also, if you want your query to support optional null values (i.e. where NULL implies that you DO NOT want to filter on customer name then you can simpy do:
SELECT * FROM Customer WHERE CustomerName = ISNULL(#CusName, CustomerName)
In your parameter section you can do something like:
cmd.Parameters.AddWithValue("#CusName", string.IsNullOrWhiteSpace(cusName) ? DbNull.Value: cusName);
If you don't want to allow nulls then you can leave the SQL query as-is as a throw a new ArgumentNullException at the top of your query method (i.e. add a guard clause):
if (string.IsNullOrWhiteSpace(CustomerName)) throw new ArgumentNullException(nameof(CustomerName));
Your query appears to be searching for the first customer with matching name. In that case you should probably add a "TOP 1" to avoid needless overhead:
SELECT TOP 1 * FROM Customer WHERE CustomerName = ISNULL(#CusName, CustomerName)
Console.WriteLine("Enter your name: ");
string name = Console.ReadLine();
string prm = "\"" + name + "\""; // Doublequote a string
//execute method
CheckCustomer(prm);
private static string CheckCustomer(string cusName)
{
string cust = "null";
try
{
Console.WriteLine("\nChecking custoemr...\n");
// Sql Select Query
string sql = "SELECT * FROM Customer WHERE CustomerName = #CusName";
SqlCommand cmd = new SqlCommand(sql, sqlConnection);
cmd.Parameters.AddWithValue("#CusName", cusName);
SqlDataReader dr;
dr = cmd.ExecuteReader();
string strCusname = "Customer Name Found";
Console.WriteLine("{0}", strCusname.PadRight(25));
Console.WriteLine("==============================");
while (dr.Read())
{
////reading from the datareader
cust = dr["CustomerName"].ToString();
}
dr.Close();
return cust;
}
catch (SqlException ex)
{
// Display error
Console.WriteLine("Error: " + ex.ToString());
return null;
}
}
try this.

simple update query doesn't work, but when i put it into database itself it does work

When i run my code in the debugger and I hover my mouse over the parameters they do have the right values in them. It just doesn't update my database but when I copy the query and put it into the database it works without a problem.
The parameter values are:
id = 7
omschrijving = douche muntjes
prijs = 0,5
catagorie = faciliteiten
I checked the connection tring by using an insert query and that does add records to my database. And There is an id with the value of 7 in the database.
When I run a insert query or a delete query through my C# code it does work it's just the update statement that doesn't work. If anyone sees the issue please help me.
public static void wijzigprijs(int id, string omschrijving, decimal prijs, string catagorie)
{
try
{
try
{
OleDbConnection verbinding = new OleDbConnection(
#"Provider=Microsoft.ACE.OLEDB.12.0;
Data Source=..\..\..\La_Rustique.accdb;
Persist Security Info=False;");
verbinding.Open();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
OleDbCommand query = new OleDbCommand();
query.CommandText = #"UPDATE prijslijst
SET omschrijving = #omschrijving,
prijs = #prijs,
catagorie = #catagorie
WHERE id = #id";
query.Parameters.Add(new OleDbParameter("#id", OleDbType.Integer));
query.Parameters["#id"].Value = id;
query.Parameters.Add(new OleDbParameter("#omschrijving", OleDbType.VarChar));
query.Parameters["#omschrijving"].Value = omschrijving;
query.Parameters.Add(new OleDbParameter("#prijs", OleDbType.Decimal));
query.Parameters["#prijs"].Value = prijs;
query.Parameters.Add(new OleDbParameter("#catagorie", OleDbType.VarChar));
query.Parameters["#catagorie"].Value = catagorie;
query.Connection = verbinding;
query.ExecuteNonQuery();
MessageBox.Show("succesvol gewijzigd");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
verbinding.Close();
}
}
EDIT UPDATE
Look at this topic. Here he explains how you should use variables with OleDbCommand
Variables with OleDbCommand
This is how you typically will do it when using SQLCommand parameters:
I know this doesnt answer your questions quite, but when i use SQLCommand i use this code whenever i want to update or insert with variables:
string query = #"UPDATE prijslijst
SET omschrijving = #omschrijving,
prijs = #prijs,
catagorie = #catagorie
WHERE id = #id";
SqlCommand cmd = new SqlCommand(query, connDatabase);
cmd.Parameters.Add("#id", SqlDbType.integer).Value = 7;
cmd.ExecuteNonQuery();
connDatabase.Close();
So you should be able to do the samething. Hope this will help you.
I have never seen OleDB queries written in the above syntax.
To state it differently: OleDB simply does not use named parameters, it uses the position only.
Try to change your SQL statement like this:
query.CommandText = #"UPDATE prijslijst
SET omschrijving = ?,
prijs = ?,
catagorie = ?
WHERE id = ?";
and then add the parameters in sequence of above in the code
below that.

Generate SQL query with inserted params

I want to generate an SQL-query string like this one:
INSERT INTO students (id, name) VALUES (?, ?);
How can I avoid possible sql-injections, if some real values are inserted instead of signs ??
string GetQuery() => "INSERT INTO students (id, name) VALUES (7, #name)"
.Replace("#name", "bad value from user");
Is there any function to prepare parameters in C#? Escaping slashes or quotes? Make a note, I don't have any connection with SQL server and don't want to use EntityFramework.
use parametrized SQL Query for detail check this link
and here is the sample code from same link For Entity Framework
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
// Create a query that takes two parameters.
string queryString =
#"SELECT VALUE Contact FROM AdventureWorksEntities.Contacts
AS Contact WHERE Contact.LastName = #ln AND
Contact.FirstName = #fn";
ObjectQuery<Contact> contactQuery =
new ObjectQuery<Contact>(queryString, context);
// Add parameters to the collection.
contactQuery.Parameters.Add(new ObjectParameter("ln", "Adams"));
contactQuery.Parameters.Add(new ObjectParameter("fn", "Frances"));
// Iterate through the collection of Contact items.
foreach (Contact result in contactQuery)
Console.WriteLine("Last Name: {0}; First Name: {1}",
result.LastName, result.FirstName);
}
For ADO.NET use this link
and here is the sample code from the same link
using System;
using System.Data;
using System.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString =
"Data Source=(local);Initial Catalog=Northwind;"
+ "Integrated Security=true";
// Provide the query string with a parameter placeholder.
string queryString =
"SELECT ProductID, UnitPrice, ProductName from dbo.products "
+ "WHERE UnitPrice > #pricePoint "
+ "ORDER BY UnitPrice DESC;";
// Specify the parameter value.
int paramValue = 5;
// Create and open the connection in a using block. This
// ensures that all resources will be closed and disposed
// when the code exits.
using (SqlConnection connection =
new SqlConnection(connectionString))
{
// Create the Command and Parameter objects.
SqlCommand command = new SqlCommand(queryString, connection);
command.Parameters.AddWithValue("#pricePoint", paramValue);
// Open the connection in a try/catch block.
// Create and execute the DataReader, writing the result
// set to the console window.
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine("\t{0}\t{1}\t{2}",
reader[0], reader[1], reader[2]);
}
reader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
}

Auto generate and AutoIncrement ID in C# when trying to add new record to database

I'm using this code to select the maxID from a database table and each time I want to add a new record, the autogenerated ID is not the last one +1.
public formularAddCompanie()
{
InitializeComponent();
try
{
string cs = "Data Source=CODRINMA\\CODRINMA;Initial Catalog=TrafficManager;Integrated Security=True";
string select = "SELECT max(IDCompanie) FROM Companii";
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
SqlCommand cmd2 = new SqlCommand(select, con);
SqlDataReader sda = cmd2.ExecuteReader();
DataTable idmax = new DataTable("idmax");
idmax.Load(sda);
if (idmax.Rows[0][0].ToString().Trim() == "") { txtID.Text = "1"; }
else { txtID.Text = (int.Parse(idmax.Rows[0][0] .ToString() + 1).ToString()); }
}
}
catch (Exception er) { MessageBox.Show(er.Message); }
}
The table from where the selection is made, looks like this:
IDCompany Name Address City RegNo
1 A Street NY 123
Each time I want to add a new record, the autogenerated ID is like this: 11, 111, 1111. It takes the last ID and add another 1 next to it. What am I missing?
Interestingly, note that
string a = "The meaning of life is " + 42;
converts 42 to a string, creating the result
a == "The meaning of life is 42"
Look at this code:
(int.Parse(idmax.Rows[0][0] .ToString() + 1).ToString()); }
You are converting idmax.Rows[0][0] to a string and adding +1 to the end of the string rather than to an integer value. Try
(int.Parse(idmax.Rows[0][0].ToString()) + 1).ToString(); }
Note that idmax.Rows[0][0] should already have an integer in it (as pointed out in the comments). If that's the case, you can simplify to
(idmax.Rows[0][0] + 1).ToString(); }
idmax.Rows[0][0].ToString() + 1 produces string, not int.
You can try
txtID.Text = (Convert.ToInt32(idmax.Rows[0][0]) + 1).ToString();
I just add this because it seems that none cares about the weakness of the code posted by the poster.
First the MAX function is not reliable if you want to find the next autoincrement value that will be assigned to an ID column. Concurrency could wreak havoc with any schema that use MAX. Just suppose that another user has already retrieved the MAX for its own INSERT operation, then depending on the relative speed of the two computers you or the other user will insert a duplicate value for the IDCompany field.
The only correct way to do this common task is to use the IDENTITY property for the column IDCompany and when you need to insert a new record you should write something like this
try
{
string insert = "INSERT INTO Companii (Name,Address,City,RegNo)
VALUES(#name,#address,#city,#regno);
SELECT SCOPE_IDENTITY()";
using (SqlConnection con = new SqlConnection(cs))
using (SqlCommand cmd = new SqlCommand(insert, con))
{
con.Open();
cmd.Parameters.Add("#name", SqlDbType.NVarChar).Value = txtBoxCity.Text;
.... and on for the other parameters ....
int companyID = Convert.ToInt32(cmd.ExecuteScalar());
... work with the just added company if required
}
}
catch (Exception er)
{ MessageBox.Show(er.Message); }
SCOPE_IDENTITY will return the last identity value inserted into an identity column in the same scope and in this context scope means the connection used by your command.
In any case, if the MAX approach is still required then the code could be simplified a lot using a modified query and SqlCommand.ExecuteScalar instead of building an SqlDataReader, filling a datatable, trying to parse the result with ifs
string getMax = #"select COALESCE(MAX(IDCompany), 0) + 1 AS maxPlusOne
from Companii"
using(SqlConnection cnn = new SqlConnection(.....))
using(SqlCommand cmd = new SqlCommand(getMax, cnn))
{
cnn.Open();
int nextCompanyID = Convert.ToInt32(cmd.ExecuteScalar());
}
The COALESCE function checks the result of the MAX function and if it is NULL returns the second parameter (here 0), then just increment by 1 to get the next MAX directly from the database. ExecuteScalar will do the call returning just the maxPlusOne alias field
try this snippet:
Convert Your String into Int. String with + operator will con-cat and with int it will add numbers.
if (idmax.Rows[0][0].ToString().Trim() == "") { txtID.Text = "1"; }
else {
txtID.Text = Convert.ToString(Convert.ToInt32(idmax.Rows[0][0] .ToString())+1); }
Try This one, my id format is USR001.The code will generate auto id based on the last id inside the database. If the last id in the database is USR001, the the code will generate USR002 and put the id to the textbox
con.Open();
string sqlQuery = "SELECT TOP 1 kode_user from USERADM order by kode_user desc";
SqlCommand cmd = new SqlCommand(sqlQuery, con);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
string input = dr["kode_user"].ToString();
string angka = input.Substring(input.Length - Math.Min(3, input.Length));
int number = Convert.ToInt32(angka);
number += 1;
string str = number.ToString("D3");
txtKodeUser.Text = "USR" + str;
}
con.Close();

Inserting values into sqlserver

I have inserted values into sql several times but now i am facing problem with the following code
protected void Button1_Click(object sender, EventArgs e)
{
string connstring = ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString;
con = new SqlConnection(connstring);
string name = txtName.Text;
string user = txtUser.Text;
string password = txtPwd.Text;
string email = txtEmail.Text;
long phone=Convert.ToInt64(txtPhone.Text);
string address = txtAddr.Text;
string city = txtCity.Text;
string gender = RadioButtonList1.SelectedItem.ToString();
string dob = txtDOB.Text;
string qualification = DropDownList1.SelectedItem.ToString();
string skills = CheckBoxList1.SelectedItem.ToString();
string insertstring = " insert into JobRegisteration values ("+name+","+user+","+password+","+email+","+phone+","+address+","+city+","+gender+","+dob+","+qualification+","+skills+")";
cmd = new SqlCommand(insertstring,con);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
When I am inserting values into this through asp.net page, its giving following error.
Exception Details: System.Data.SqlClient.SqlException: Invalid column name 'sbip'.
Invalid column name 'tttt'.
Invalid column name 'ttt'.
The multi-part identifier "tttttt#sss.ss" could not be bound.
Invalid column name 't'.
Invalid column name 'tttt'.
Invalid column name 'Male'.
Invalid column name 'MCA'.
Invalid column name 'C#'.
where tttt, male mca, etc etc are values that are passed from asp page.
thanks!
use parameters like below and also using statements
string connstring = ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString;
// change this select statement based on your exact column names
string insertstring = "insert into JobRegisteration ([Name] ,[User] ,[Password] ,[Email] ,[Phone],[Address] ,[City] ,[Gender] ,[Dob] ,[Qualification] ,[Skills]) values (#name ,#user ,#password ,#email ,#phone,#address ,#city ,#gender ,#dob ,#qualification ,#skills)";
using (var con = new SqlConnection(connstring))
using(var cmd = new SqlCommand(insertstring, con))
{
cmd.Parameters.AddWithValue("#name", txtName.Text);
cmd.Parameters.AddWithValue("#user", txtUser.Text);
// give all the parameters..
con.Open();
cmd.ExecuteNonQuery();
}
You need to wrap your inserted values with ' otherwise the database treat them as column names:
string insertstring = " insert into JobRegisteration values ('"+name+"','"+user+"','"+password+"','"+email+"','"+phone+"','"+address+"','"+city+"','"+gender+"','"+dob+"','"+qualification+"','"+skills+"')";
Also, as other suggested you really should rely on Prepared Statements to avoid such problems (among others).
There are many solution to your problem.
1) Try to fit with this format:
INSERT INTO table_name (column1,column2,column3,...)
VALUES (value1,value2,value3,...);
2) as said haim770, surround your values with '
3) use sql parameters way
4) or look at Linq, that's really simplify way to work with database
You need to add single quote ' in your query:
string insertstring = " insert into JobRegisteration values ('"+name+"','"+user+"','"+password+"','"+email+"','"+phone+"','"+address+"','"+city+"','"+gender+"','"+dob+"','"+qualification+"','"+skills+"')";
use using (pun!), bind variables (a.k.a. parameters), format your query, when query seems dubious put what you want explicitly...
protected void Button1_Click(object sender, EventArgs e) {
string name = txtName.Text;
string user = txtUser.Text;
string password = txtPwd.Text;
string email = txtEmail.Text;
long phone = Convert.ToInt64(txtPhone.Text); // <- what about +77(555)123-456-78?
string address = txtAddr.Text;
string city = txtCity.Text;
string gender = RadioButtonList1.SelectedItem.ToString();
string dob = txtDOB.Text;
string qualification = DropDownList1.SelectedItem.ToString();
string skills = CheckBoxList1.SelectedItem.ToString();
using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString)) {
con.Open();
using(var cmd = con.CreateCommand()) {
cmd.CommandText =
// replace all "field_for_*" for actual fields
#"insert into JobRegisteration(
field_for_name,
field_for_user,
field_for_password,
field_for_email,
field_for_phone,
field_for_address,
field_for_city,
field_for_gender,
field_for_dob,
field_for_qualification,
field_for_skills)
values (
#prm_name,
#prm_user,
#prm_password,
#prm_email,
#prm_phone,
#prm_address,
#prm_city,
#prm_gender,
#prm_dob,
#prm_qualification,
#prm_skills)";
cmd.Parameters.AddWithValue("#prm_name", name);
cmd.Parameters.AddWithValue("#prm_user", user);
cmd.Parameters.AddWithValue("#prm_password", password);
cmd.Parameters.AddWithValue("#prm_email", email);
cmd.Parameters.AddWithValue("#prm_phone", phone);
cmd.Parameters.AddWithValue("#prm_address", address);
cmd.Parameters.AddWithValue("#prm_city", city);
cmd.Parameters.AddWithValue("#prm_gender", gender);
cmd.Parameters.AddWithValue("#prm_dob", dob);
cmd.Parameters.AddWithValue("#prm_qualification", qualification);
cmd.Parameters.AddWithValue("#prm_skills", skills);
cmd.ExecuteNonQuery();
}
}
}

Categories

Resources