Query working in mysql but not from c# code - c#

I am having c# code like this:
using (MySqlConnection con = new MySqlConnection(AR.ConnectionString))
{
con.Open();
using (MySqlCommand cmd = new MySqlCommand(#"SELECT PORUDZBINAID, USERID, BRDOKKOM, DATUM,
STATUS, MAGACINID, PPID, INTERNIKOMENTAR, REFERENT_OBRADE, NACIN_PLACANJA, TAG FROM
PORUDZBINA WHERE TAG LIKE '%#MOB%'", con))
{
cmd.Parameters.AddWithValue("#MOB", Mobilni);
MySqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
list.Add(new Porudzbina()
{
PorudzbinaID = Convert.ToInt32(dr[0]),
UserID = Convert.ToInt32(dr[1]),
BrDokKom = Convert.ToInt32(dr[2]),
Datum = Convert.ToDateTime(dr[3]),
Status = (PorudzbinaStatus)Convert.ToInt32(dr[4]),
MagacinID = Convert.ToInt32(dr[5]),
PPID = (dr[6] is DBNull) ? (int?)null : Convert.ToInt32(dr[6]),
InterniKomentar = (dr[7] is DBNull) ? null : dr[7].ToString(),
ReferentObrade = (dr[8] is DBNull) ? (int?)null : Convert.ToInt32(dr[8]),
NacinUplate = (PorudzbinaNacinUplate)Convert.ToInt32(dr[9]),
Tag = JsonConvert.DeserializeObject<Properties>(dr["TAG"].ToString())
});
}
}
I put breakpoint and it passes good paramter to query but doesn't enter while() loop (so i is not reading) and it returns no rows.
When i enter same query in my mysql and replace #MOB with parameter passed there, it does return me one row.
I guess problem is something with passing LIKE through c# but not sure why it does that.

You need to change how you are adding parameters slightly:
In your SQL, no quotes and no % symbols.
using (MySqlCommand cmd = new MySqlCommand(#"SELECT PORUDZBINAID, USERID, BRDOKKOM, DATUM,
STATUS, MAGACINID, PPID, INTERNIKOMENTAR, REFERENT_OBRADE, NACIN_PLACANJA, TAG FROM
PORUDZBINA WHERE TAG LIKE #MOB", con))
{
Then the parameter like this, without quotes.
cmd.Parameters.AddWithValue("#MOB", "%" + Mobilni + "%");
BTW: Ideally you should not use AddWithValue, but rather Add(). See this blog:
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
And this SO post:
MySqlCommand Command.Parameters.Add is obsolete
Instead, it should be like this:
cmd.Parameters.Add("#MOB", SqlDbType.Varchar).Value = "%" + Mobilni + "%";
//you must update to use the correct DBType for your data

Since #MOB is inside single quotes, it's interpreted as a string literal, which isn't what you meant. You can fix this by concatenating the placeholder to the % characters:
using (MySqlCommand cmd = new MySqlCommand(
#"SELECT PORUDZBINAID, USERID, BRDOKKOM, DATUM, STATUS, MAGACINID, PPID, INTERNIKOMENTAR, REFERENT_OBRADE, NACIN_PLACANJA, TAG
FROM PORUDZBINA
WHERE TAG LIKE CONCAT('%', #MOB, '%')", con))

Related

passing columnname with a parameter SQLcommand

I've been googling something I dont really cant understand.
In short my problem is this;
When using this;
String sYear2 = "2020";
string query = #"Select decJan from Stats where intRecnum = (select intRecnum from Stats where intAr = #year)";
var cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#year", sYear2);
The result is returning "111" (which is correct vaule of column decJan the year 2020.
But when trying this;
String sYear2 = "2020";
String sColumn2 = "decJan";
string query = #"Select " + #column + #" from tbFuGraddagar where intRecnum = (select intRecnum from tbfuGraddagar where intAr = #year)";
var cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#year", sYear2);
cmd.Parameters.AddWithValue("#column", sColumn2);
I recieve "decJan" as result.
When googling all I have found that its not possible without dynamic SQL or that is bad design.
But I fail to understand what the diffrence is...all I want is to change the static code with a value similar to #year-parameter. the "interpretation" shouldn't care about the validation of SQL-syntax, it's just a matter och string-manipulation.
Or is it just me beeing a bad C#-coder?
Probably addwithvalue method is not valid for adding dynamic column names in select statements. I think you should use c# 8.0 feature, string interpolation to solve this problem.  You can add column names with string interpolation. Can you try this approach :
String sYear2 = "2020";
string deccan = "decJan";
string query = $(Select {decJan} from Stats where intRecnum = (select intRecnum from Stats where intAr = #year)
query = #query;
var cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#year", sYear2);

C# MySQL adding multiple of the same parameter with a loop

Update: as the original question was essentially answered, I've marked this as complete.
I have a C# project in which I'd like to query a database. The SQL query will SELECT from a table, and in the WHERE clause I want to filter the results from a pre-defined list of values specified in C#.
List<string> productNames = new List<string >() { "A", "B", "C" };
foreach (name in productNames)
{
string query = #"
SELECT *
FROM products
WHERE name IN (#name);";
// Execute query
MySqlCommand cmd = new MySqlCommand(query, dbConn);
cmd.Parameters.AddWithValue("name", name);
MySqlDataReader row = cmd.ExecuteReader();
while (row.Read())
{
// Process result
// ...
}
}
However I'm getting an error:
There is already an open DataReader associated with this Connection
which must be closed first
Is it not possible then to use a for loop to add parameters this way to a SELECT statement?
You need to dispose your object to not get the exception. However you don't need to iterate over values and run a query for every value in the list. Try the following code. It makes a parameter for every value and adds it to command to use in "IN (...)" clause.
Also "using" keywords handles disposing objects.
List<string> productsIds = new List<string>() { "23", "46", "76", "88" };
string query = #"
SELECT *
FROM products
WHERE id IN ({0});";
// Execute query
using (MySqlCommand cmd = new MySqlCommand(query, dbConn))
{
int index = 0;
string sqlWhere = string.Empty;
foreach (string id in productsIds)
{
string parameterName = "#productId" + index++;
sqlWhere += string.IsNullOrWhiteSpace(sqlWhere) ? parameterName : ", " + parameterName;
cmd.Parameters.AddWithValue(parameterName, id);
}
query = string.Format(query, sqlWhere);
cmd.CommandText = query;
using (MySqlDataReader row = cmd.ExecuteReader())
{
while (row.Read())
{
// Process result
// ...
}
}
}
You are doing few things wrong. Let me point out them:
Everything is fine in the first iteration of the loop, when you are in second iteration the First Reader associated with the command remains opened and that result in current error.
You are using Where IN(..) you you can specify the values within IN as comma separated so there is no need to iterate through parameters.
You can use String.Join method to construct this values with a comma separator.
Now take a look into the following code:
List<int> productsIds = new List<int>() { 23, 46, 76, 88 };
string idInParameter = String.Join(",", productsIds);
// Create id as comma separated string
string query = "SELECT * FROM products WHERE id IN (#productId);";
MySqlCommand cmd = new MySqlCommand(query, dbConn);
cmd.Parameters.AddWithValue("#productId", idInParameter);
MySqlDataReader row = cmd.ExecuteReader();
while (row.Read())
{
// Process result
// ...
}
Please note if the id field in the table is not integers then you have to modify the construction of idInParameter as like the following:
idInParameter = String.Join(",", productsIds.Select(x => "'" + x.ToString() + "'").ToArray());
Pass the comma separated productIds string instead of looping. Read more about IN here.
string productIdsCommaSeparated = string.Join(",", productsIds.Select(n => n.ToString()).ToArray())
string query = #"
SELECT *
FROM products
WHERE id IN (#productId);";
// Execute query
MySqlCommand cmd = new MySqlCommand(query, dbConn);
cmd.Parameters.AddWithValue("productId", productIdsCommaSeparated );
MySqlDataReader row = cmd.ExecuteReader();
while (row.Read())
{
// Process result
// ...
}
The error you are getting is because you do not close the MySqlDataReader. You must close it to get rid of error before you call ExecuteReader in next iteration but this is not proper way in this case.
From what I tried and tested seems best solution (especially for text column types) is to create a list of individual parameters and add it as a range the to the query and parameters.
e.g:
List<MySqlParameter> listParams = new List<MySqlParameter>();
for (int i = 0; i < listOfValues.Length; i++)
{
listParams.Add(new MySqlParameter(string.Format("#values{0}", i),
MySqlDbType.VarChar) { Value = listOfValues[i] });
}
string sqlCommand = string.Format("SELECT data FROM table WHERE column IN ({0})",
string.Join(",", listParams.Select(x => x.ParameterName)));
......
using (MySqlCommand command = new MySqlCommand(sqlCommand, connection)
{
............
command.Parameters.AddRange(listParams.ToArray());
............
}

Selecting Items from Database that Matches with the string Based on Entered Characters

I want to select the items that matches with the entered string.It seems the query is selecting all items that contain at-least a matching letter.
I don't want exact match ..i want to select the strings that match the starting..Like if i type 'it' i want to list all strings that starts with 'it'
What im i doing wrong?
using (SqlConnection conn = new SqlConnection(constr))
{
try
{
conn.Open();
SqlDataReader myReader = null;
string commandText = "SELECT itemname,rate,stock FROM mytable WHERE itemname LIKE #id";
SqlCommand command = new SqlCommand(commandText, conn);
string searchParam = String.Format("%{0}%", text_item.Text);
command.Parameters.AddWithValue("#id", searchParam);
using (SqlDataAdapter sda = new SqlDataAdapter(command))
{
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
dataGridView1.DataSource = dt;
}
}
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
}
Don't use LIKE but use =. And change your string be exact string, instead of %text%
string commandText = "SELECT itemname,rate,stock FROM mytable WHERE itemname = #id";
...
string searchParam = text_item.Text;
---------------------- EDITED ------------------------
After the updated question, the answer would be:
string searchParam = string.Format("{0}%", text_item.Text);
The first % is not necessary, because you don't want wildcard there.
Instead of "Like" you should use "=". Like is usually used if you want to search with wildcards.
If you want your query to return results starting with, change your parameter value to
string searchParam = String.Format("{0}%", text_item.Text);
Your code is running fine.
Yes, you can use LIKE operator in the query.
Kindly debug and check what's coming in the "text_item" variable.
Narrow your search.
You can refer the link
to check the syntax for like operator.

How to set NCHAR to null with an update statement (C# sqlcommand)

I'm wondering how to set an nchar column to null with an update statement. I found this: NULL value for int in Update statement
which says you have to cast to set non-int fields to NULL.
So I tried the following:
commandText =
#"UPDATE Brukere
SET Engangskode = CAST(NULL AS NCHAR)
WHERE Navn = #navn AND Mobilnr = #mobilnr";
However, when I execute this it still won't update the column to NULL. Am I casting wrong, or is it something else? Any help would be appreciated :)
Longer code snip if needed: http://pastebin.com/8auKuk6Q
The problem is that you are setting the local variable commandText to the update statement instead of the command.CommandText. Change it to the following
command.CommandText = "UPDATE Brukere SET Engangskode=NULL WHERE Navn=#navn AND Mobilnr=#mobilnr";
And I think it will work with or without the casting.
I would recommend NOT to "re-use" the SqlCommand in your example - create a new, specific command for the UPDATE statement, something like this:
using (SqlConnection con = new SqlConnection(connectionString))
{
con.Open();
string bruker = Request.Cookies["Navn"].Value;
string mobilnr = Request.Cookies["Mobilnr"].Value;
string commandText = "SELECT Engangskode FROM Brukere WHERE Navn=#navn AND Mobilnr=#mobilnr";
bool correctCode = false;
try
{
using (SqlCommand command = new SqlCommand(commandText, con))
{
.....
if (correctCode)
{
// DO NOT "reuse" the previous SqlCommand - create a new, specific one!
string updateQuery = "UPDATE Brukere SET Engangskode = NULL WHERE Navn = #navn AND Mobilnr = #mobilnr;";
using (SqlCommand updateCmd = new SqlCommand(updateQuery, con)
{
updateCmd.Parameters.Add("#navn", SqlDbType.NVarChar, 20).Value = bruker;
updateCmd.Parameters.Add("#mobilnr", SqlDbType.NChar, 10).Value = mobilnr;
updateCmd.ExecuteNonQuery();
Response.Redirect("Kvittering.aspx", false);
}
}
}
}
catch( .... )
{
.......
}
}
No need to cast. Juse set column = null. NO quotes, tho!

how to use dynamic strings separated by comma in sql query?

hello i build a webservice in visual studio 2010. i get some id's which are saved in a string looks like this:
string room_ids="5,11,99,42";
they are separated by comma. i created a foreach loop to split the ids and from the comma and use them in my sql query until the ids are finished. but it doesn't work. i get an error it says:
Error converting data type nvarchar to numeric
here is my code, thanks in advance for your help!
internal static List<RAUM> Raum(string RAUMKLASSE_ID, string STADT_ID, string GEBAEUDE_ID, string REGION_ID)
{
List<RAUM> strasseObject = new List<RAUM>();
string[] allegebaude = GEBAEUDE_ID.Split(new char[] { ',' });
foreach (string gebaudeid in allegebaude)
{
Trace.WriteLine("SIND JETZT DRINNE");
Trace.WriteLine(gebaudeid);
using (SqlConnection con = new SqlConnection(#"Data Source=Localhost\SQLEXPRESS;Initial Catalog=BOOK-IT-V2;Integrated Security=true;"))
using (SqlCommand cmd = new SqlCommand(#"SELECT r.BEZEICHNUNG AS BEZEICHNUNG, r.ID AS ID FROM RAUM r WHERE RAUMKLASSE_ID = ISNULL(#Raumklasse_ID, RAUMKLASSE_ID) AND STADT_ID = ISNULL(#Stadt_ID, STADT_ID) AND GEBAEUDE_ID = ISNULL(#gebaudeid,GEBAEUDE_ID ) AND REGION_ID = ISNULL(#Region_ID, REGION_ID)", con))
{
con.Open();
if (!StringExtensions.IsNullOrWhiteSpace(RAUMKLASSE_ID))
cmd.Parameters.AddWithValue("#Raumklasse_ID", RAUMKLASSE_ID);
else
cmd.Parameters.AddWithValue("#Raumklasse_ID", DBNull.Value);
if (!StringExtensions.IsNullOrWhiteSpace(STADT_ID))
cmd.Parameters.AddWithValue("#Stadt_ID", STADT_ID);
else
cmd.Parameters.AddWithValue("#Stadt_ID", DBNull.Value);
if (!StringExtensions.IsNullOrWhiteSpace(GEBAEUDE_ID))
cmd.Parameters.AddWithValue("#gebaudeid", GEBAEUDE_ID);
else
cmd.Parameters.AddWithValue("#gebaudeid", DBNull.Value);
if (!StringExtensions.IsNullOrWhiteSpace(REGION_ID))
cmd.Parameters.AddWithValue("#Region_ID", REGION_ID);
else
cmd.Parameters.AddWithValue("#Region_ID", DBNull.Value);
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
if (rdr["BEZEICHNUNG"] != DBNull.Value && rdr["ID"] != DBNull.Value)
{
strasseObject.Add(new RAUM()
{
RaumName = rdr["BEZEICHNUNG"].ToString(),
RaumID = rdr["ID"].ToString()
});
}
}
}
}
}
return strasseObject;
}
If you already have the IDs in a comma-separated string (called IDstring) then you can just do something like this:
sqlQuery = "SELECT Columns FROM table WHERE ID IN (" + IDstring + ")";
In your specific case, don't split the original string (GEBAEUDE_ID) but use it as it is:
// Don't use a foreach loop any more
string gebaudeIdSection = " AND GEBAEUDE_ID IN (" + GEBAEUDE_ID + ") ";
if (string.IsNullOrEmpty(GEBAUDE_ID)) { gebaudeIdSection = ""; } // if there are no ids, let's remove that part of the query completely.
using (SqlConnection con = new SqlConnection(#"Data Source=Localhost\SQLEXPRESS;Initial Catalog=BOOK-IT-V2;Integrated Security=true;"))
using (SqlCommand cmd = new SqlCommand(#"SELECT r.BEZEICHNUNG AS BEZEICHNUNG, r.ID AS ID FROM RAUM r WHERE RAUMKLASSE_ID = ISNULL(#Raumklasse_ID, RAUMKLASSE_ID) AND STADT_ID = ISNULL(#Stadt_ID, STADT_ID)" + gebaudeIdSection + " AND REGION_ID = ISNULL(#Region_ID, REGION_ID)", con))
{ // The rest of the code is the same as before...
First of all I think you have to correct:
cmd.Parameters.AddWithValue("#gebaudeid", GEBAEUDE_ID);
with:
cmd.Parameters.AddWithValue("#gebaudeid", gebaudeid);
Then, try to convert the ids into integers ( for example, using Convert.ToInt32(gebaudeid) ) and not to pass them as strings in AddWithValue method.
try this:
if (!StringExtensions.IsNullOrWhiteSpace(gebaudeid))
cmd.Parameters.AddWithValue("#gebaudeid", Convert.ToInt32(gebaudeid));
you should also pass the right parameter to your AddWithValue statement. You are iterating over the list of your ID's, that list being allegebaude. So you have to pass the gebaudeid parameter to your statement, instead of what you're doing now.
You can't implicitly treat a comma separated list of values; instead you'll need to create a table values function to split the list of values into a table structure and then use this structure as you would normally.
Have a look at this question: INSERT INTO TABLE from comma separated varchar-list for a sample function.

Categories