put SELECT COUNT(*) statement result into int variable - c#

I have a SELECT COUNT(*) statement in C#/ASP.NET and I want to store the result as an int to use as an IF condition. However I am getting an error in visual studio:
Error:System.Data.SqlClient.SqlException (0x80131904): The data types text and varchar are incompatible in the equal to operator. at System.Data.SqlClient.SqlConnection.
It tells me its occurring at the int temp line. The columns I'm accessing in the database table are of text type.
conn.Open();
String checkEmail = "select count(*) from Players where PlayerEmail= '" + txtEmailLogIn.Text + "'";
SqlCommand com = new SqlCommand(checkEmail, conn);
int temp = Convert.ToInt32(com.ExecuteScalar().ToString());
conn.Close();
if (temp > 0)
{
}

The problem is in your SQL. You can't use = when comparing TEXT data types, instead you can use LIKE:
String checkEmail = "select count(*) from Players where PlayerEmail LIKE '" + txtEmailLogIn.Text + "'";
Be warned though, that you are opening yourself up to SQL injection attacks when composing SQL strings like this.

DavidG's answer above works. However, if you have the opportunity to change the database schema, you could also fix the error by changing the PlayerEmail column from text to varchar(max). The text data type has been deprecated since at least 2005.

Related

System.IndexOutOfRangeException SQL Server Query in C#

I want to use selected item from my combo box for my SqlDataReader.
Which wrong in my syntax?
string varfunction = cbFunctionClass.SelectedItem.ToString();
con.Open();
SqlCommand sqlFunName = new SqlCommand("SELECT " + varfunction + " FROM sdn_cd_allclass WHERE MIDCLASS_CODE = '" + cbMiddleClass.Text + "'", con);
SqlDataReader sqlFunNameReader = sqlFunName.ExecuteReader();
while (sqlFunNameReader.Read())
{ lbFunctionClassName.Text = sqlFunNameReader[varfunction].ToString(); }
sqlFunNameReader.Close();
con.Close();
I need to use varfunction to select SQL column.
If varfunction contains a single digit, your query would read something like
SELECT 7 FROM sdn_cd_allclass...
for example. This would not select a column named 7 but the literal 7, i.e. an integer with the value of 7. And the column in the result, that holds this integer has no name, especially isn't its name 7.
If you want to select a column named 7 (which probably isn't the best idea BTW) you have to quote it by putting square brackets around it, so that the query becomes
SELECT [7] FROM sdn_cd_allclass...
So try
... "SELECT [" + varfunction + "] FROM sdn_cd_allclass..." ...
And as an aside, like already commented many times, I also recommend you to rework this and use parameterized queries (for the literals, i.e. the value in the WHERE clause of your current query, it won't work with identifiers, i.e. the column name).

Invalid Column Name: "value" - Error Even though it works in another form.

I am stuck at one problem and I just can't solve this.
I get this Error:
Error Message
That's the relevant table
The Code:
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
string query = "UPDATE CAC SET nextMaintainance = #nextMaintainance WHERE department = " + #departmentCB.Text;
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("#nextMaintainance", nextMaintainanceDT.Value);
command.ExecuteNonQuery();
The weird thing I don't understand is that a similar code works just fine without any error in my project:
query = "UPDATE LDV SET received = #received, department = #department WHERE Id =" + #idTxt.Text;
command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("#received", inDT.Value);
command.Parameters.AddWithValue("#department", departmentCb.Text);
command.ExecuteNonQuery();
MessageBox.Show("Lungenautomat wurde aktualisiert");
If relevant, my connection string:
connectionString = ConfigurationManager.ConnectionStrings["SCBA_Manager_0._1.Properties.Settings.SCBAmanagerConnectionString"].ConnectionString;
I really hope you can help me :(
Thank you!
The department column is a text column, so comparing it to a value means the value should be wrapped in quotes.
// This fix is not the recommended approach, see the explanation after this code block
string query = "UPDATE CAC SET nextMaintainance = #nextMaintainance WHERE department = '" + departmentCB.Text + "'";
// ^--------------------------^------ single quote added to wrap the value returned by departmentCB.Text
On the other hand, this error does not occur in your second example, because there you're correctly using the Parameters.AddWithValue() method to add the value for the #department parameter, and because id is a numeric column, so it doesn't require the value wrapped in quotes.
However, while the code shown above does the job, it is not the right way of doing the job. The correct way is to used parameters for all values to be injected into a query. The queries you've shown above are already correctly using parameters for some values (e.g. nextMaintenance in the first query, received and department in the second), but are incorrectly doing string concatenation for other values (e.g. department in the first query, id in the second).
Usage of Parameterized SQL
The benefit of using parameterized SQL is that it automatically takes care of adding quotes, prevents SQL injection, etc.
Therefore, its best to change your first code block to:
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
string query = "UPDATE CAC SET nextMaintainance = #nextMaintainance WHERE department = #department";
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("#department", departmentCb.Text);
command.Parameters.AddWithValue("#nextMaintainance", nextMaintainanceDT.Value);
command.ExecuteNonQuery();
Notice how the string query is a single string without any messy concatenation, and that it contains two parameters #nextMaintenance and #department? And how the values for those parameters are correctly injected using Parameters.AddWithValue() in the following lines?
Your second code block can be similarly improved by using a parameter for the Id column.
query = "UPDATE LDV SET received = #received, department = #department WHERE Id = #Id ";
command.Parameters.AddWithValue("#Id", idTxt.Text);
Further Information
Do read up about SQL injection ( https://technet.microsoft.com/en-us/library/ms161953(v=sql.105).aspx ) to see how using string concatenation like your original code can lead to various security issues, and why parameterized queries are the preferred way of injecting dynamic values into SQL queries.
You can read up more about parameterized queries here: https://msdn.microsoft.com/en-us/library/yy6y35y8(v=vs.110).aspx
In your first example, the WHERE clause evaluates to
WHERE department = Kasseedorf
wheras it should be
WHERE department = 'Kasseedorf'
So the line should be
string query = "UPDATE CAC SET nextMaintainance = #nextMaintainance WHERE department = '" + #departmentCB.Text +"'";
It works in the second example, because id is an integer and doesn't neet quotes.

Using parameters in sql query to determine which column to use

I am trying to pull data from my table based on the button a user clicks, so if they click the 1940's button it will pull all products from that decade but I cant get the query to work. It has to do with the #decade parameter because that is where I am getting the user input from but it doesnt like it when I am trying to choose a column using that parameter
ImageButton decadeBtn = (ImageButton)sender;
var decade = decadeBtn.CommandArgument;
yearHead.InnerText = decade.ToString();
string cmd="";
DataSet ds;
if (typeOfArchive == "On Hand")
{
cmd = #"Select * From ARCHIVE_DECADE_TBL WHERE DECADE_#decade=#decade AND PRODUCT_LINE=#Line AND LOCATION is not null;";
}
else if(typeOfArchive == "All Other"){
cmd = #"Select * From ARCHIVE_DECADE_TBL WHERE DECADE_#decade=#decade AND PRODUCT_LINE=#Line AND LOCATION is null";
}
using (OleDbConnection dbConn = new OleDbConnection(connectionString))
using (OleDbDataAdapter dbCmdDecade = new OleDbDataAdapter(cmd, dbConn))
{
dbConn.Open();
dbCmdDecade.SelectCommand.Parameters.Add("#decade", OleDbType.Integer).Value = decade;
dbCmdDecade.SelectCommand.Parameters.Add("#line", OleDbType.VarChar).Value = productLine;
ds = new DataSet();
dbCmdDecade.Fill(ds, "products");
}
No you can't use a parameter in that way. As a rule, you cannot use a parameter to define a column name or a table name (or concatenating it to form a column name). A parameter could only be used to define a value used in the query. (or with a stored procedure to create an SQL Text inside the sp to be executed but that is another more complex story),
However, assuming that you are not allowing your users to type directly the decade value (Sql Injection vulnerability), then it is pretty simple to create a string with the column name desidered and use it in your query.
Add a method that just concatenate together you decade string with your prefix for the DECADE column
private string GetDecadeColumn(string decade)
{
return "DECADE_" + decade;
}
and in you query
if (typeOfArchive == "On Hand")
{
cmd = #"Select * From ARCHIVE_DECADE_TBL WHERE " +
GetDecadeColumn(decade) +
" AND PRODUCT_LINE=#Line AND LOCATION is not null;";
}
else if(typeOfArchive == "All Other"){
cmd = #"Select * From ARCHIVE_DECADE_TBL WHERE " +
GetDecadeColumn(decade) +
" AND PRODUCT_LINE=#Line AND LOCATION is null";
}
So ARCHIVE_DECADE_TBL has columns that are named something like DECADE_1990 with a value of 1990, DECADE_2000 with a value of 2000, etc?
It really should be designed to just be called "DECADE" with the value being 1990/2000/etc, but if that's not possible, you'll have to build your query dynamically. I don't believe those parameters will work to set the column name. They can set a value to check for, but not the column names.
You'll have to build the query out manually in c#, so something like:
cmd = #"Select * From ARCHIVE_DECADE_TBL WHERE DECADE_" + decade + #" = #decade AND PRODUCT_LINE=#Line AND LOCATION is not null;";
Now, if I misunderstood and your column is actually named DECADE_#decade, then I think you'll just need to change your variable so it's not #decade, so something like #mydecade. The conflict there will confuse it.
Sooooo like...
cmd = #"Select * From ARCHIVE_DECADE_TBL WHERE DECADE_#decade=#mydecade AND PRODUCT_LINE=#Line AND LOCATION is not null;";
And then down below:
dbCmdDecade.SelectCommand.Parameters.Add("#mydecade", OleDbType.Integer).Value = decade;
That probably shouldn't have an # in the column name though. :)

save a decimal value in database c#

I am trying to save a value from text box into sql database. I am having the error as shown on the picture. my code below:
public void datastore()
{
string Blerje, Shitje, Data;
Blerje = usdollar_buy.Text;
Shitje = usdollar_sell.Text;
Data = dateTimePicker.Text;
try
{
string constring = "Data Source=DELL;Initial Catalog=login_register;Integrated Security=True";
/* Declaring Connection Variable */
SqlConnection con = new SqlConnection(constring);
String sql = "INSERT into [login_register].[dbo].[BlerjeShitje] values ('" + Blerje + "','" + Shitje + "','" + Data + "')";
/* Checking Connection is Opend or not If its not open the Opens */
if (con.State != ConnectionState.Open)
con.Open();
SqlCommand cmd = new SqlCommand(sql, con);
/* Executing Stored Procedure */
cmd.ExecuteNonQuery();
con.Close();
MessageBox.Show("Te dhenat u ruajten ne databaze");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
1. You might be having more columns in your table than mentioned values(3) in your query.
so it is always good to specify the column names in your query for which columns you are inserting the values.
Try This:
INSERT INTO [TableName](COL1,COl2,COL3)
Values(Value1,Value2,Value3);
2. As you mentioned your columsn are decimals, you are inserting them as as strings by enclosing the values within single quotes.
You should not enclose the decima values within single quotes.
Suggestion : Your query is open to SQL Injection Attacks.
I Would suggest you to use the Parameterised queries to avoid them.
You are missing the fields in your insert statement.
The database will try to determine the right columns and their order, but if you don't deliver all fields in the appropriate order, your query will fail.
So in short:
Deliver all fields in the correct order;
Or: add the fields you want to fill in the insert.
Sample:
String sql = "INSERT into [login_register].[dbo].[BlerjeShitje] (Blerje, Shitje, Data) values ('" + Blerje + "','" + Shitje + "','" + Data + "')";
change the datatype to (18,6) or so, whichever is suitable for you,
The second part of decimal data type shows how many digits do you require after the 'point'. In your case it's '0', so db is rounding it to nearest integer.
Source: http://msdn.microsoft.com/en-us/library/ms187746.aspx

Using parametrized parameters WITH sqlcommandbuilder [no dataadapter]

I am trying to use a parametrized query which takes 2 column names and a table name and retrieves the data from a sql server DB.
The problem is it is not possible to parametrize the table name so i found a solution using a sqlcommandbuilder.quoteIdentifer(tablename) and this bit works...but apparently they don't play nice together.
I get exception containing a single word which is the column name
If i put the column name by hand it works.
What is wrong here?
public List<ItemsWithDescription> GetItemsFromDB(string name, string desc, string tableName)
{
List<ItemsWithDescription> items = new List<ItemsWithDescription>();
try
{
Status = 1;
SqlCommandBuilder builder = new SqlCommandBuilder();
cmd = new SqlCommand("Select #Name, #Desc from "+ builder.QuoteIdentifier(tableName), conn);
cmd.Parameters.AddWithValue("#Name", name);
cmd.Parameters.AddWithValue("#Desc", desc);
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
items.Add(new ItemsWithDescription(dr[name].ToString(), dr[name].ToString() + " | " + dr[desc].ToString()));
}
}
items.Sort((x, y) => string.Compare(x.Item, y.Item));
}
catch
{
Status = -1;
}
return items;
}
Edit:
This works but I would prefer to know why both can't be used together:
cmd = new SqlCommand("Select" +
builder.QuoteIdentifier(name) + "," +
builder.QuoteIdentifier(desc) + "from " +
builder.QuoteIdentifier(tableName), conn);
You can't parameterize column names. You can't do that in regular SQL actually.
What you need is Dynamic SQL.
If you follow the various newsgroups on Microsoft SQL Server, you
often see people asking why they can't do:
SELECT * FROM #tablename
SELECT #colname FROM tbl
SELECT * FROM tbl WHERE x IN (#list)
For all three examples you can expect someone to answer Use dynamic
SQL and give a quick example on how to do it. Unfortunately, for all
three examples above, dynamic SQL is a poor solution. On the other
hand, there are situations where dynamic SQL is the best or only way
to go.
Also take a look Table-Valued Parameters if you use SQL Server 2008 and above.

Categories

Resources