RowFilter with special characters - c#

I have a table named myMainTable and I want to operate a .RowFilter on my DataView. For the moment my code is as such (the value used for the RowFilter is an example value):
var mainDataView = maindataDataSet.Tables["myMainTable"].DefaultView;
mainDataView .RowFilter = "LastName= '" + "Gemma O'Neil" + "'";
var mainDataTable = mainDataView.ToTable();
the problem I have of course is that it thinks (because of the ' in O'Neil) that the value I am looking for ends at "Gemma O".
How can I have it successfully apply the RowFilter for the full value "Gemma O'Neil" ?

For circumstances such as this, you would simply need to escape the ' character; which for RowFilter is simply another ':
string surname = "Gemma O'Neil";
mainDataView .RowFilter = "LastName= '" + surname.Replace("'", "''") + "'";
(or, neater:
string surname = "Gemma O'Neil";
mainDataView.RowFilter =
String.Format("LastName='{0}', surname.Replace("'", "''"));
)
Incidentally, this is a very similar problem to that faced by people trying to avoid SQL Injection attacks. If this is a new development then I'd recommend investigating Entity Framework and LINQ, which will handle this for you automatically.

Related

Creating reusable SQL commands in c# programing

I have following query that works.
string sqlCommandText = "SELECT * FROM Admin_T where AdminID =
'" + textBox.Text + "'";
It is a fix command and I cannot use it with user given Table names and Column names at run time.
What I am actually trying to make is command like
string sqlCommandText = "SELECT * FROM Admin_T where
'" + UserGivenColumnName + "' = '" + conditionTB.Text + "'";
"UserGivenColumnName" can be any column that is part of that specific table.
Trying to create flexibility so that same command can be used under different circumstances.
SqlCommand and none of related classes used by ADO.NET does not support such a functionality as far as I know.
Of course your should never build your sql queries with string concatenation. You should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
But prepared statements only for values, not column names or table names. If you really wanna put your input string to your column name, create a whitelist and use it as a validation before you put it in your query.
http://codeblog.jonskeet.uk/2014/08/08/the-bobbytables-culture/
I think an Object-Relational Mapper (ORM) is perhaps the droid you are looking for. Entity Framework might be a good place to start.
Please also do take the time to understand what SQL injection is, as the other users have also prompted you to.
It is not returning anything as it is just comparing two strings
With the 'UserGivenColumnName' it is a string comparison
And those two strings are not equal
You can do it (column) by just not including the '
But it is still a bad idea
SQLinjection is a very real and very bad thing
string sqlCommandText =
"SELECT * FROM Admin_T where " + UserGivenColumnName + " = '" + conditionTB.Text + "'";
or
string sqlCommandText =
"SELECT * FROM Admin_T where [" + UserGivenColumnName + "] = '" + conditionTB.Text + "'";

no result on select query using Npgsql and c#

I tried to search a lot for tutorials on Npgsql and c#. but I couldn't resolve the below problem.
When I run the program, my programs stop and breaks at execute query. and when I try debug and check the return value from the execute reader is empty.
below is the sample code:
string user=textBox1.Text;
NpgsqlConnection dataconnect = new NpgsqlConnection(
"Server=127.0.0.1;Port=5432;User Id=dbuser;Password=dbpass;Database=dbname;");
string query = "Select USERNAME from helperdata.credentials where USERNAME = "
+ textBox1.Text + " and PASSWORD = " + textBox2.Text;
dataconnect.Open();
NpgsqlCommand command = new NpgsqlCommand(query, dataconnect);
NpgsqlDataReader reader = command.ExecuteReader();
if(reader.Read())
{
MessageBox.Show("Login Successful");
}
else
{
MessageBox.Show("Login failed");
}
reader.Close();
dataconnect.Close();
When I try to run the below query in Pgsql it returns the data.
Select "USERNAME" from helperdata.credentials where "USERNAME" = 'admin'
I am new to Npgsql.
I would also like if someone could provide me some good tutorial sites which provides detail explanation of Npgsql and C#.
Thanks in advance.
I have identified two problems in your code. The first the usage of uppercase letters on PostgreSQL identifiers. PostgreSQL allows identifiers with other than simple lowercase letter, but only if you quote them.
In fact, you can use, for instance:
CREATE TABLE helperdata.credentials (... USERNAME varchar, ...);
But PostgreSQL will convert it to:
CREATE TABLE helperdata.credentials (... username varchar, ...);
So, to make it really left with uppercase, you have to quote it as following:
CREATE TABLE helperdata.credentials (... "USERNAME" varchar, ...);
And that seems to be the way you have created your table, and the problem with that is that always you refers to that table in a query, you'll have to quote it. So the beginning of your query should be:
string query = "Select \"USERNAME\" from helperdata.credentials ... ";
My recommendation, is to modify your column and table names to don't use such identifiers. For this case you can do:
ALTER TABLE helperdata.credentials RENAME COLUMN "USERNAME" TO username;
The second problem, is the lack of string quotation when you concatenated the username from the textbox into the query. So, you should do something as the following (BAD PRACTICE):
string query = "Select \"USERNAME\" from helperdata.credentials where \"USERNAME\" = '"
+ textBox1.Text + "' and \"PASSWORD\" = '" + textBox2.Text + "'";
There is a huge problem with that, you can have SQL injection. You could create a function (or use one from Npgsql, not sure if there is) to escape the string, or, more appropriately, you should use a function that accept parameters in the query using NpgsqlCommand, which you can simple send the parameters or a use a prepared statement.
Check the Npgsql documentation, and find for "Using parameters in a query" and "Using prepared statements" to see examples (there are no anchors in the HTML to link here, so you'll have to search).

Why is SQL statement returning all rows when passing " "?

I am using this SQL statement to get rows:
SELECT firstname, lastname
FROM myTable
WHERE ((lastname LIKE '" + parameter + "%')
parameter gets a value form a textbox. The default value of textbox is " "
My problem is I am getting all the rows when nothing is entered in the textbox. I tried to use
WHERE lastname =
This simply gives me all the records that has " "
What is the correct way of getting data that excludes blanks in the database and also does not give your any record when blank or " " is passed as a parameter
You're using a wilcard, so for a blank search string, you end up with
... WHERE lastname LIKE '%'
which will match everything. If nothing is entered into the search form, you should simply detect that at the script level and NOT run the query, e.g. in php-ish terms:
if (strlen($_GET['keywords']) == 0) {
die("No search terms entered");
}
First, I hope you do some sanitizing to avoid sql injection.
Then you can at your choice :
not run the query if sanitizing parameter including a trim() is empty
have SELECT firstname, lastname FORM myTable WHERE ((lastname LIKE '" + parameter + "%') AND ''<>'" + parameter + "'"
the second one being a bad practice from a performance point, and it would assume you've given up sanitizing (very bad)
Also you should note that, in your sanitizing process, you will have to escape or remove special characters _ and %, see
http://msdn.microsoft.com/en-us/library/ms179859(v=sql.105).aspx
I you do not handle this, a non empty parameter equal to % will lead to a like '%%', which is equivalent to like '%'
SELECT firstname, lastname
FROM myTable
WHERE lastname LIKE '" + parameter + "%'
AND NULLIF(lastname,'') IS NOT NULL
AND '" + parameter + "' <> ''
Quite simply only return records where lastname startswith your 'parameter' and only where 'parameter' is not empty string.
Edit: Added code for the requirement that it never returns record with blank lastname.
Well you could just test for string.IsNullOrEmpty on parameter variable in your code so that you don't even need to make the database call.
In my view its the most efficient thing to do.

LINQ to SQL custom query builder

It was easy to build a custom query like this with ADO.NET:
SqlCommand.CommandText = "SELECT Column" + variable1 + ", Column" + Variable2 + " FROM TABLE";
Is that able to do so in LINQ to SQL?
Thanks
No there is no common way to build a dynamic query.
A method has to have a known, specific return type. That type can be
System.Object but then you have to use a lot of ugly reflection code
to actually get the members. And in this case you'd also have to use a
lot of ugly reflection expression tree code to generate the return
value.
If you're trying to dynamically generate the columns on the UI side -
stop doing that. Define the columns at design time, then simply
show/hide the columns you actually need/want the user to see. Have
your query return all of the columns that might be visible.
Unless you're noticing a serious performance problem selecting all of
the data columns (in which case, you probably have non-covering index
issues at the database level) then you will be far better off with
this approach. It's perfectly fine to generate predicates and sort
orders dynamically but you really don't want to do this with the
output list.
More about this
Yes You can do something like that with Dynamic query with Linq.
This is an example that you can build a custom query with Dynamic query with Linq:
string strWhere = string.Empty;
string strOrderBy = string.Empty;
if (!string.IsNullOrEmpty(txtAddress.Text))
strWhere = "Address.StartsWith(\"" + txtAddress.Text + "\")";
if (!string.IsNullOrEmpty(txtEmpId.Text))
{
if(!string.IsNullOrEmpty(strWhere ))
strWhere = " And ";
strWhere = "Id = " + txtEmpId.Text;
}
if (!string.IsNullOrEmpty(txtDesc.Text))
{
if (!string.IsNullOrEmpty(strWhere))
strWhere = " And ";
strWhere = "Desc.StartsWith(\"" + txtDesc.Text + "\")";
}
if (!string.IsNullOrEmpty(txtName.Text))
{
if (!string.IsNullOrEmpty(strWhere))
strWhere = " And ";
strWhere = "Name.StartsWith(\"" + txtName.Text + "\")";
}
EmployeeDataContext edb = new EmployeeDataContext();
var emp = edb.Employees.Where(strWhere);
grdEmployee.DataSource = emp.ToList();
grdEmployee.DataBind();
For more information you can check this page.

How to solve a syntax error when using this INSERT INTO statement and the .NET OleDb namespace?

I keep getting an error when I attempt to insert values into a Access database.
The error is syntactic, which leads to the following exception:
OleDbException was unhandled Syntax error in INSERT INTO statement.
private OleDbConnection myCon;
public Form1()
{
InitializeComponent();
myCon = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\File.mdb");
}
private void insertuser_Click(object sender, EventArgs e)
{
OleDbCommand cmd = new OleDbCommand();
myCon.Open();
cmd.Connection = myCon;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO User ([UserID], [Forename], [Surname], " +
"[DateOfBirth], [TargetWeight], [TargetCalories], [Height]) " +
"VALUES ('" + userid.Text.ToString() + "' , '" +
fname.Text.ToString() + "' , '" +
sname.Text.ToString() + "' , '" +
dob.Text.ToString() + "' , '" +
tarweight.Text.ToString() + "' , '" +
tarcal.Text.ToString() + "' , '" +
height.Text.ToString() + "')";
cmd.ExecuteNonQuery();
myCon.Close();
}
Well, you haven't specified what the error is - but your first problem is that you're inserting the data directly into the SQL statement. Don't do that. You're inviting SQL injection attacks.
Use a parameterized SQL statement instead. Once you've done that, if you still have problems, edit this question with the new code and say what the error is. The new code is likely to be clearer already, as there won't be a huge concatenation involved, easily hiding something like a mismatched bracket.
EDIT: As mentioned in comments, Jet/ACE is vulnerable to fewer types of SQL injection attack, as it doesn't permit DML. For this INSERT statement there may actually be no vulnerability - but for a SELECT with a WHERE clause written in a similar way, user input could circumvent some of the protections of the WHERE clause. I would strongly advise you to use parameterized queries as a matter of course:
They mean you don't have to escape user data
They keep the data separate from the code
You'll have less to worry about if you ever move from Jet/ACE (whether moving this particular code, or just you personally starting to work on different databases)
For other data types such as dates, you don't need to do any work to get the data into a form appropriate for the database
(You also don't need all the calls to ToString. Not only would I expect that a property called Text is already a string, but the fact that you're using string concatenation means that string conversions will happen automatically anyway.)
I posted this as a comment to the duplicate question at: Syntax error in INSERT INTO statement in c# OleDb Exception cant spot the error
Put brackets [] around the table name
"User". It's a reserved word in SQL
Server.
"User" is also a reserved word in Access (judging by the provider in your connection string).
But I completely agree with Jon--if you fix your current implementation, you are just opening up a big security hole (against your User table, no less!)
This problem may occur if your database table contains column names that use Microsoft Jet 4.0 reserved words.
Change the column names in your database table so that you do not use Jet 4.0 reserved words.
If TargetWeight, Height, and TargetCalories are floating-point or integer values, they don't need to be surrounded by quotes in the SQL statement.
Also, not directly related to your question, but you should really consider using a parameterized query. Your code is very vulnerable to SQL injection.
public decimal codes(string subs)
{
decimal a = 0;
con_4code();
query = "select SUBJINTN.[SCODE] from SUBJINTN where SUBJINTN.[ABBR] = '" + subs.ToString() + "'";
cmd1 = new OleDbCommand(query, concode);
OleDbDataReader dr = cmd1.ExecuteReader();
here is error in dr it says syntax error ehile in DBMS its working Well
if (dr.Read())
{
a = dr.GetDecimal(0);
MessageBox.Show(a.ToString());
}
return a;
}
After this
cmd.CommandText="INSERT INTO User ([UserID], [Forename], [Surname], [DateOfBirth], [TargetWeight], [TargetCalories], [Height]) Values ('" + userid.Text.ToString() + "' , '" + fname.Text.ToString() + "' , '" + sname.Text.ToString() + "' , '" + dob.Text.ToString() + "' , '" + tarweight.Text.ToString() + "' , '" + tarcal.Text.ToString() + "' , '" + height.Text.ToString() + "')";
check what this contains, maybe [DateOfBirth] has illegal format

Categories