Search a string that contains special character in MS Access - c#

I have problem searching for a long string that contains special character in MS Access. Here is my sample data.
staff_Id | hashValue
1 | 4ENOA2838F09dbfTKXeAdEIKRM91MdsDg0W4pRNChdkGa7iwoVifWH9avZdjrPp1QqLJ0ecNe/X716HlwqfSYA==
Here is my SQL command.
SELECT *
FROM table
WHERE hashValue='4ENOA2838F09dbfTKXeAdEIKRM91MdsDg0W4pRNChdkGa7iwoVifWH9avZdjrPp1QqLJ0ecNe/X716HlwqfSYA==';
I had tried googling for escape characters, however I cannot get this working. Hope that you can help me. Thank you.
P.S. I am developing a C# program that interacts with MS-access
UPDATE
Here is my SQL query in my C# program that execute the search query.
string sqlStatement = "SELECT * FROM table WHERE hashValue = #hashedValue";
using (OleDbConnection connection = new OleDbConnection(connString))
{
using (OleDbCommand command = new OleDbCommand())
{
command.Connection = connection;
command.CommandText = sqlStatement;
command.Parameters.AddWithValue("#hashedValue", hashedValue);
ds = new DataSet(); //have been declared
dbAdapter = new OleDbDataAdapter(); //have been declared
dbAdapter.SelectCommand = command;
dbAdapter.Fill(ds, "table"); //empty dataset here
}
}

in C# try writing the command like this:
string hashValue = #"4ENOA2838F09dbfTKXeAdEIKRM91MdsDg0W4pRNChdkGa7iwoVifWH9avZdjrPp1QqLJ0ecNe/X716HlwqfSYA==";
string sql = string.Format("SELECT * FROM table WHERE hashValue = '{0}'", hashValue);
notis the # mark before the string. this allows you to have string that look like this:
string test = #" \ ";
Console.WriteLine(test); //output: \
In your case you can do it like this:
command.Parameters.AddWithValue("#hashedValue", #hashedValue);
but the #-trick works best if its set when the string is declared.

Why not write a query using wildcard?
SELECT *
FROM table
WHERE hashValue Like "*4ENOA2838F09dbfTKXeAdEIKRM91MdsDg0W4pRNChdkGa7iwoVifWH9avZdjrPp1QqLJ0ecNe/X716HlwqfSYA==*";

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);

ODBC parametrized query with unknown number of values?

I want to select several values from database (ODBC datasource). The table is this simple:
| name | value |
+------+-------+
| abcd | 12345 |
Say I want to select values where name is name1, name2 and name3:
SELECT name, value FROM my_table WHERE name="name1" OR name="name2" OR name="name3"
Now I could generate this command:
public string MakeCommand(List<string> names) {
string command = "SELECT name, value FROM my_table WHERE ";
bool first = true;
foreach(string name in names) {
if(first)
first = false;
else
command+=" OR ";
command+="name=\""+name+"\"";
}
}
I hope it's not necessary to emphasize that this would be very bad way to access the database.
So how can I make this a parametrized ODBC command, as described here?
Well, the simplest solution is probably to concatenate a parameter to the sql for each value in your list, and then add this value as a parameter to the OdbcCommand.
using(var command = new OdbcCommand())
{
string sql = "SELECT name, value FROM my_table WHERE name IN(";
for(int i=0; i < names.Count; i++) {
sql = $"{sql} #{i},";
command.Parameters.Add($"#{i}", OdbcType.VarChar).Value = names[i];
}
command.CommandText = sql.TrimEnd(",") +");";
command.Connection = con;
// fill a data set or execute a data reader here....
}
There is no elegant solution to this problem. You can use the IN clause but, still you need to build the parameters one by one. So instead of returning a string you can return the OdbcCommand prepared with all the parameters required by your list of names. Just need to add the connection and execute (or pass also the connection and prepare everything here)
public OdbcCommand MakeCommand(List<string> names, OdbcConnection con) {
List<OdbcParameter> parameters = new List<OdbcParameter>();
List<string> placeholders = new List<string>();
foreach(string name in names) {
OdbcParameter p = new OdbcParameter("?", OdbcType.NVarChar);
p.Value = name;
parameters.Add(p);
placeholders.Add("?")
}
string command = "SELECT name, value FROM my_table WHERE name IN(";
command = command + string.Join(",", placeholders.ToArray()) + ")";
OdbcCommand cmd = new OdbcCommand();
cmd.CommandText = command;
cmd.Connection = con;
cmd.Parameters.AddRange(parameters.ToArray());
return cmd;
}
If you still have problems, then it could be something linked to the parameters DataType. NVarChar, VarChar, Text, String. Some db could react differently to this type. What database are you testing this code against?

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.

Add parameters in query on c#

In my code behind of aspx page I have problem to passed values on Parameters in sql query.
I use MySql database.
Step 1:
I add in List the output of an query:
while (reader.Read())
{
idcolor = reader["idcolor"].ToString();
colorList.Add(idcolor.ToString());
}
ns = string.Join("','", colorList.ToArray());
In debug the output is:
ns = red','green
Step 2:
I need use the values of string ns on a sql query.
And pass the values of string ns in parameters:
str = null;
str = ns == null ? "" : ns.ToString();
sql = #" SELECT * FROM Experience WHERE Colors IN (?); ";
DataSet dsColors = new DataSet();
using (OdbcConnection cn =
new OdbcConnection(ConfigurationManager.ConnectionStrings["ConnMySQL"].ConnectionString))
{
cn.Open();
using (OdbcCommand cmd = new OdbcCommand(sql, cn))
{
cmd.Parameters.AddWithValue("param1", Server.UrlDecode(str.ToString()));
OdbcDataAdapter adapter = new OdbcDataAdapter(cmd);
adapter.Fill(dsColors);
}
}
return dsColors;
Step 3:
If used in query :
sql = #" SELECT * FROM Experience WHERE Colors IN (?); ";
The output in dataset is empty.
If used in query :
sql = #" SELECT * FROM Experience WHERE Colors IN ( '" + Server.UrlDecode(str.ToString()) + "' ); ";
The output in dataset is right.
Anybody know how can I resolve do this?
Can you suggest?
Can you help me?
Thank you in advance.
you have to use MySql.Data.MySqlClient; to connect to Mysql:
sql = #" SELECT * FROM Experience WHERE Colors IN (#param1,#param2) ";
DataSet dsColors = new DataSet();
using ( MySqlConnection cn =
new MySqlConnection(ConfigurationManager.ConnectionStrings["ConnMySQL"].ConnectionString))
{
cn.Open();
using (MySqlCommand cmd = new MySqlCommand(sql, cn))
{
cmd.Parameters.Add("#param1", colorList[0]/ToString());
cmd.Parameters.Add("#param2",colorList[1].ToString());
MySqlDataAdapter adapter = new MySqlaAdapter(cmd);
adapter.Fill(dsColors);
}
}
if you dont want to add a parameter for each color, you can go with
MySql.Data.MySqlClient.MySqlHelper.EscapeString()
that's not pretty but it's internal used by parameters and you can add a dynamic number of values and you're safe against injection
while (reader.Read())
{
idcolor = reader["idcolor"].ToString();
colorList.Add(MySql.Data.MySqlClient.MySqlHelper.EscapeString(idcolor));
}
ns = string.Join("','", colorList.ToArray());
You need to add a parameter and place holder for each item you want in your in clause. For example
sql = #" SELECT * FROM Experience WHERE Colors IN (?,?,?); ";
Then add the params for each one.
cmd.Parameters.AddWithValue("param1", Server.UrlDecode(str.ToString()));
Example
List<string> colours = new List<string>();
colours.Add("black");
colours.Add("red");
var placeHolders = string.Join(",",(from colour in colours select "?").ToList());
var sql = #String.Format(" SELECT * FROM Experience WHERE Colors IN ({0}); ",placeHolders);
DataSet dsColors = new DataSet();
using (OdbcConnection cn = new OdbcConnection(ConnectionString))
{
cn.Open();
using (OdbcCommand cmd = new OdbcCommand(sql, cn))
{
foreach(var colour in colours)
{
cmd.Parameters.AddWithValue(colour, colour);
}
OdbcDataAdapter adapter = new OdbcDataAdapter(cmd);
adapter.Fill(dsColors);
}
}
You appear close with the context, but try getting the results for one color at a time and just keep changing the VALUE of the parameter. By calling the FILL, it will just keep adding records to the table each time it is called. However, set your FILL to point to a DataTable instead of a DataSet. So it doesn't keep putting TABLES into your data set, but instead uses the one continues to append to it. This would work if you had 1 color or 1000 colors...
... rest of previous code BEFORE the OdbcCommand
... and ensure clean values for your colors as others have noted.
using (OdbcCommand cmd = new OdbcCommand(sql, cn))
{
// Just to add the parameter "place-holder" for your query
cmd.Parameters.AddWithValue("param1", "");
// DataTable ONCE to receive all the colors being queried
DataTable tblAllColors = new DataTable();
// build the adapter ONCE no matter how many colors you will be querying
OdbcDataAdapter adapter = new OdbcDataAdapter(cmd);
// so for this loop, you are just getting the colors one at a time.
foreach( string s in colorList )
{
// next color you are trying to get... just overwrite the
// single parameter with the new color.
adapter.SelectCommand.Parameters[0].Value = s;
adapter.Fill(tblAllColors);
}
// you would otherwise have to build your query dynamically and keep
// adding parameter-placeholders "?" for each color in a comma list
// as you were attempting... which would be a slightly different query.
}
dsColors.Tables.Add( tblAllColors );

Data Type Mismatch error in Criteria expression in Select query C# query

My sample code is as follows, I am getting following error;
Data Type Mismatch error in criteria expression.
Details => ScannerAlarmLimits is my table from .mdb database.
string jointS = dsetChamberS1.Tables[0].Rows[tot][0].ToString();
int select1S = Convert.ToInt32(jointS);
string sqlQuery1S = "SELECT TMin,TMax,HMin,HMax from ScannerAlarmLimits WHERE ScannerID='" +select1S+ "'";
OleDbCommand cmd1S = new OleDbCommand(sqlQuery1S, conn);
OleDbDataAdapter adapter1S = new OleDbDataAdapter(cmd1S);
adapter1S.Fill(dsetTempS, "ScannerAlarmLimits");
I just added single quote in the condition of where clause, now its working.
var query = "SELECT * from checkinout where read <> '1'";
If your ScannerID column is integer, then you should not use single quotes with it. Single quotes are for characters. Like;
WHERE ScannerID = " + select1S;
But as a better way, you should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks. Aka bobby-tables.
And use using statement to dispose your connections, commands and adapters.
string jointS = dsetChamberS1.Tables[0].Rows[tot][0].ToString();
int select1S = Convert.ToInt32(jointS);
using(var conn = new OleDbConnection(conString))
using(var cmd1S = conn.CreateCommand())
{
cmd1S.CommandText = "SELECT TMin,TMax,HMin,HMax from ScannerAlarmLimits WHERE ScannerID = #id";
cmd1S.Parameters.AddWithValue("#id", OleDbType.Integer).Value = select1S;
using(var adapter1S = new OleDbDataAdapter(cmd1S))
{
adapter1S.Fill(dsetTempS, "ScannerAlarmLimits");
}
}

Categories