How to apply National Character set to dynamic query - c#

I am trying to apply N before variable name for Unicode as mentioned in How to use 'LIKE' statement with unicode strings?
With the following code I am getting following error. What need to be corrected here?
Exception: Invalid column name 'N#input'.
string commandText = #"SELECT AccountType,*
FROM Account
WHERE AccountType LIKE N#input ";
CODE
static void Main(string[] args)
{
string result = DisplayTest("Daily Tax Updates: ----------------- Transactions");
}
private static string DisplayTest(string searchValue)
{
string test = String.Empty;
string connectionString = "Data Source=.;Initial Catalog=LibraryReservationSystem;Integrated Security=True;Connect Timeout=30";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string commandText = #"SELECT AccountType,*
FROM Account
WHERE AccountType LIKE N#input ";
using (SqlCommand command = new SqlCommand(commandText, connection))
{
command.CommandType = System.Data.CommandType.Text;
command.Parameters.AddWithValue("#input", "%" + searchValue + "%");
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
test = reader.GetString(0);
}
}
}
}
}
return test;
}

I see a few issues.
string commandText = #"SELECT AccountType,*
FROM Account
WHERE AccountType LIKE N#input";
should be
string commandText = #"SELECT AccountType,*
FROM Account
WHERE AccountType LIKE #input";
...
command.Parameters.Add("#input",System.Data.SqlDbType.NVarChar,<<size>>);
command.Parameters[0].Value = "%" + searchValue + "%";

I see you're trying to use a nvarchar parameter. I think .net does that by default with .AddWithValue
I'm not sure why do you need the typecast to nvarchar, you should be fine without the 'N' part.
That part you need when you want to specify that a string literal should be treated as nvarchar not as varchar, as in SELECT * from Table where field like N'%VALUE%'
Otherwise, you just declare your variable/parameter as nvarchar

Taken from this stack Stack overflow
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "#CategoryName";
parameter.SqlDbType = SqlDbType.NVarChar;
parameter.Direction = ParameterDirection.Input;
parameter.Value = categoryName;

Try this one -
private static string DisplayTest(string searchValue)
{
string connectionString = "Data Source=.;Initial Catalog=LibraryReservationSystem;Integrated Security=True;Connect Timeout=30";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string commandText = #"SELECT AccountType,* FROM Account WHERE AccountType LIKE #input";
using (SqlCommand command = new SqlCommand(commandText, connection))
{
command.CommandType = System.Data.CommandType.Text;
command.Parameters.Add("#input", SqlDbType.NVarChar);
command.Parameters["#input"].Value = string.Format("%{0}%", searchValue);
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
return reader.GetString(0);
}
}
}
}
}
return String.Empty;
}

Related

Trying to retrieve parameter value from another class library

I have created Member Maintenance Code in which I will retrieve the members ID,Name and all basic things
My code is as follows:
private void Mem_Maintenance_Load(object sender, EventArgs e)
{
try
{
txt_mem_id.Text = Generate_no.gen_no("MEM").ToString();
}
catch(Exception Ex)
{
MessageBox.Show("Error\n\n"+Ex.ToString());
}
}
I have created a ClassLibrary named Library Whose code is as follows
namespace LIBRARY
{
public class Generate_no
{
public static int gen_no(string P_PRM_TYPE)
{ OleDbConnection connection = new OleDbConnection();
connection.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=E:\arekh\MS Access\soc_data.accdb;Persist Security Info=False;";
connection.Open();
int v_last_no = 0;
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
string query = #"select PARM_VALUE from soc_parm_mast where PARM_TYPE = '" + P_PRM_TYPE + "';";
command.CommandText = query;
OleDbDataReader reader = command.ExecuteReader();
reader.Read();
v_last_no = Int32.Parse(reader["PARM_VALUE"].ToString()) + 1;
reader.Close();
command.CommandText = #"update soc_parm_mast set PARM_VALUE = PARM_VALUE+1 where PARM_TYPE = " + P_PRM_TYPE + ";";
command.ExecuteNonQuery();
connection.Close();
return v_last_no;
}
}
}
But during execution an error is coming up
System.FormatException:Input string was not incorrect format at
LIBRARY.Generate_no.gen_no(String P_PRM_TYPE)
command.CommandText = #"update soc_parm_mast set PARM_VALUE = PARM_VALUE+1 where PARM_TYPE = '" + P_PRM_TYPE + "';";
You were missing the single quotation marks in the update statement
The Line v_last_no = Int32.Parse(reader["PARM_VALUE"].ToString()) + 1; causing the specified Error, The Int32.Parse will throw FormatException if the input is not convertible. So i strongly advise you to use Int32.TryParse(). Then the code will be like the following:
public static int gen_no(string P_PRM_TYPE)
{
using (OleDbConnection connection = new OleDbConnection(#"Connection string here"))
{
connection.Open();
int v_last_no = 0;
using (OleDbCommand command = new OleDbCommand())
{
command.Connection = connection;
string query = #"select PARM_VALUE from soc_parm_mast where PARM_TYPE = #P_PRM_TYPE";
command.CommandText = query;
command.Parameters.AddWithValue("#P_PRM_TYPE", P_PRM_TYPE);
OleDbDataReader reader = command.ExecuteReader();
reader.Read();
if (!Int32.TryParse(reader["PARM_VALUE"].ToString(), out v_last_no))
{
// Conversion failed, Show message if needed
// v_last_no will be 0
}
reader.Close();
}
using (OleDbCommand command = new OleDbCommand())
{
command.CommandText = #"update soc_parm_mast set PARM_VALUE = PARM_VALUE+1 where PARM_TYPE =#P_PRM_TYPE";
command.Parameters.AddWithValue("#P_PRM_TYPE", P_PRM_TYPE);
command.ExecuteNonQuery();
}
}
return v_last_no;
}
One more advise for you : beware of SQL Injection while using the Concatenated string as queries. Use parameterized queries instead.

string as name of new class variable

I'm having trouble figuring this out, I want to put the name I send with the method as name of the new class variable I'm trying to make. This is what I have now.
public void GetDier(string naam)
{
string query = "SELECT * FROM [Dieren] WHERE Diersoort = '" + naam + "'";
sqlconn.Open();
SqlCommand cmd = new SqlCommand(query, sqlconn);
SqlDataReader DR = cmd.ExecuteReader();
string diernaam = DR.GetString(1);
int currency = DR.GetInt32(2);
int TPnodig = DR.GetInt32(3);
Dieren naam = new Dieren(diernaam, TPnodig, currency);
}
I want make the string naam, as the new name of the new dier as I'm trying to do in the piece of code above.
Here you have a more secured method to get the data from db:
public Dieren GetDier(string naam)
{
var con = ConfigurationManager.ConnectionStrings["Yourconnection"].ToString();
Dieren naamValue= new Dieren();
using (SqlConnection myConnection = new SqlConnection(con))
{
string oString ="SELECT * FROM [Dieren] WHERE Diersoort = #Diersoort";
SqlCommand oCmd = new SqlCommand(oString, myConnection);
oCmd.Parameters.AddWithValue("#Diersoort", naam);
myConnection.Open();
using (SqlDataReader oReader = oCmd.ExecuteReader())
{
while (oReader.Read())
{
naamValue.naam= oReader["naam"].ToString();
}
myConnection.Close();
}
}
return naamValue;
}
You can't use a variable as name of another variable. And honestly, that doesn't make sense. The name of a variable is only useful to you as a programmer, not for the end result of the code.
Also be aware that your SQL is vulnerable to SQL injection. Always use parameterized queries!

Unable to execute cmd.ExecuteReader()

Here is the code where i'm trying to retrieve user name using emailid.
string query="select name from userdetails where emailid=" + email + ";" ;
connection.Open();
MySqlCommand cmd = new MySqlCommand(query,connection);
MySqlDataReader rd = cmd.ExecuteReader();
while(rd.Read())
{
uname = (string)rd["emailid"];
return uname;
}
parameterized the value to avoid from SQL Injection
string query="select name from userdetails where emailid=#email" ;
MySqlCommand cmd = new MySqlCommand(query,connection);
cmd.Parameters.AddWithValue("#email", email);
Try this code snippet:
string connStr = "connection string here";
string sqlStatement = "select name from userdetails where emailid=#email";
using (MySqlConnection conn = new MySqlConnection(connStr))
{
using(MySqlCommand comm = new MySqlCommand())
{
comm.Connection = conn;
comm.CommandText = sqlStatement;
comm.CommandType = CommandType.Text;
comm.Parameters.AddWithValue("#email", email);
try
{
conn.Open();
MySqlDataReader rd = cmd.ExecuteReader();
// other codes
}
catch(SqlException e)
{
// do something with the exception
// do not hide it
// e.Message.ToString()
}
}
}
For proper coding
use using statement for proper object disposal
use try-catch block to properly handle exception
Put you emailin sigle qoute because it is varchar like this..
string query="select name from userdetails where emailid='" + email + "';" ;
But this may cause SQL Injection...so use this...
string query="select name from userdetails where emailid=#email;" ;
MySqlCommand cmd = new MySqlCommand(query,connection);
cmd.Parameters.AddWithValue("#email",email);
Update your select query like this with adding email in single quote:
string query = "select name from userdetails where emailid='" + email +"';";
or
you can use parametrized query like this :
string query="select name from userdetails where emailid=#email" ;
MySqlCommand cmd = new MySqlCommand(query,connection);
cmd.Parameters.AddWithValue("#email", email);

Connect to SQLite using C#

I got the following error:
Input string was not in a correct format
Can anyone help to me? Here is my input parameters and method:
public void insertSQL(Dictionary<string,object> objects, string dbConnectionString)
{
openConnection(dbConnectionString);
SQLiteCommand command = new SQLiteCommand(sqliteCon);
command.CommandText = "INSERT INTO AppUser VALUES(#name, #surname)", objects, "Data Source=sample.s3db"
command.CommandType = CommandType.Text;
foreach (var param in objects)
{
command.Parameters.Add(new SQLiteParameter(param.Key,SqlDbType.NVarChar){ Value = (String)param.Value} );
Console.WriteLine(command.Parameters.Count);
}
command.ExecuteNonQuery();
closeConnection();
}
You must tell for which columns you are presenting values (other will get their default values)
Something like :
INSERT INTO AppUser (name,surname) VALUES(#name, #surname) ...
Parameters' name in query should be equal to parameters you assign values to:
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
using (SQLiteCommand command = new SQLiteCommand(connection))
{
command.CommandText = "...";
command.Parameters.Add("#name", SqlDbType.NVarChar).Value = name;
command.Parameters.Add("#surname", SqlDbType.NVarChar).Value = value;
connection.Open();
command.ExecuteNonQuery();
}

how to return int value from select query in function?

I need to retrieve Ticket_Id from tbl_Ticket to pass into body section of sending email function..
Is the below code correct?
every times i get Ticket_Id 1..
public int select_TicketId(){
string strConn = System.Configuration.ConfigurationManager.ConnectionStrings["conString"].ConnectionString.ToString();
SqlConnection sqlCon = new SqlConnection(strConn);
string getId = ("select Ticket_Id from tbl_Ticket where Client_EmailAdd='" + objNewTic_BAL.email + "' ");
sqlCon.Open();
SqlCommand cmd1 = new SqlCommand(getId, sqlCon);
int i=cmd1.ExecuteNonQuery();
return i;
}
You are searching for ExecuteScalar which returns the first value.
using System.Configuration;
//
public int select_TicketId()
{
string strConn = ConfigurationManager.ConnectionStrings["conString"].ConnectionString.ToString();
SqlConnection sqlCon = new SqlConnection(strConn);
string getId = ("select TOP 1 Ticket_Id from tbl_Ticket where Client_EmailAdd='" + objNewTic_BAL.email + "' ");
sqlCon.Open();
SqlCommand cmd1 = new SqlCommand(getId, sqlCon);
return Convert.ToInt32(cmd1.ExecuteScalar());
}
Also use CommandProperties to set the where statement for better security, like below:
public int select_TicketId()
{
string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
int result = -1;
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.Text;
command.CommandText = "select TOP 1 Ticket_Id from tbl_Ticket where Client_EmailAdd=#email";
command.Parameters.Add("#email", SqlDbType.Text).Value = objNewTic_BAL.email;
result = Convert.ToInt32(command.ExecuteScalar());
}
return result;
}
You should call int i=(int)cmd1.ExecuteScalar(); method
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalar.aspx
You're calling ExecuteNonQuery. But it's a query. This should have rung some warning bells :)
Try ExecuteScalar instead, and cast the result to int...
return (int) cmd1.ExecuteScalar();
Note that you should use using statements for the command and connection as well, so that both are closed appropriately.
And (I hadn't spotted this before) you should definitely use parameterized SQL instead of including a value directly into your SQL. Otherwise you're open to SQL Injection attacks...
So something like:
private const string FetchTicketIdSql =
"select Ticket_Id from tbl_Ticket where Client_EmailAdd = #Email";
public int FetchTicketId()
{
// No need for ToString call...
string connectionString =
ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand(connection, FetchTicketIdSql))
{
command.Parameters.Add("#Email", SqlDbType.NVarChar).Value =
bjNewTic_BAL.email;
return (int) command.ExecuteScalar();
}
}
}
You should consider what you want to happen if there isn't exactly one result though...
Hiral,
ExecuteNonQuery in
int i=cmd1.ExecuteNonQuery();
will return number of records that satisfy your query. In this case it is 1 (or 0 if there are no emails)
Try using ExecuteReader instead.

Categories