IQuery is not running as expected - c#

i have the Following Method:
ServiceType GetWithValidServices(long ServiceTypeID);
and the following Function:
public ServiceType GetWithValidServices(long ServiceTypeID)
{
IQuery query = CurrentSession.CreateQuery("select dl.ServiceType from Service as dl"
+ "where dl.ServiceType.ID = :id and dl.IsValid = true"
+ "order by dl.HavePriority desc");
query.SetInt64("id", ServiceTypeID);
var dlArt = query.UniqueResult<ServiceType>();
return dlArt;
}
In the following Method i call the the above mentioned function:
public ServiceCollection GetService(long ServiceTypeID)
{
ServiceType d = DomainToWebgridMapper.GetWebgridServiceType(DaoFactory.Instance.ServiceTypeDao.GetWithValidService(ServiceTypeID));
return d.Service;
}
My Problem is that the query is not running correctly. I can see the Services but the filter where dl.IsValid is not running, also he do not order the Types by Priority.
I use the where-clause in few other Methods and there it is working fine.
I don't know what is going wrong here. Maybe someone can help me.
Thanks in advance

I think I see what your problem is; it has to do with how you're concatenating the strings to create the query. Consider this for a moment:
string query = "select dl.ServiceType from Service as dl"
+ "where dl.ServiceType.ID = :id and dl.IsValid = true"
+ "order by dl.HavePriority desc";
Because you're not inserting any spaces or line breaks at the beginnings/ends of your strings, what your query turns into is this:
select dl.ServiceType from Service as dlwhere dl.ServiceType.ID = :id and dl.IsValid = trueorder by dl.HavePriority desc
^^^^^^^ ^^^^^^^^^
See where I've marked the problems? To remedy this, add an extra space to the end of all but the last string you're concatenating to make up the query, or use something like a verbatim string literal instead.
IQuery query = CurrentSession.CreateQuery(
"select dl.ServiceType from Service as dl " +
"where dl.ServiceType.ID = :id and dl.IsValid = true " +
"order by dl.HavePriority desc"
);

Related

C# String Parameters to protect against injection?

Take this code as an example:
IAmazonSimpleDB client = new AmazonSimpleDBClient(Amazon.RegionEndpoint.USEast1);
SelectResponse response = client.Select(new SelectRequest() {
SelectExpression = "SELECT * FROM `foo` where FooID = '" + id + "'" });
I can rewrite it as such:
IAmazonSimpleDB client = new AmazonSimpleDBClient(Amazon.RegionEndpoint.USEast1);
SelectResponse response = client.Select(new SelectRequest() {
SelectExpression = "SELECT * FROM `foo` where FooID = '{0}'", id });
But from my understanding, that still leaves it vulnerable to injection right?
Is there anything else I can do here? We aren't using SQL so I can't do SQL Parameters.
I usually do a check to see if the id is an integer. That way you will get an exception or a Boolean value if it isn't an int. It will work fine unless you are using GUID values.
var isNumeric = int.TryParse("123", out int n); //Will give a bool
Int32.Parse(yourString); //This will give an exception if it is not an possible integer
If it's anything more than that then you could use a Regex expression to look for strange values and remove characters that shouldn't be there such as spaces. Most SQL injection attacks wont work if there's no spaces... I think. Removing all the spaces is pretty easy and I would assume your ID (even if it is complex) won't include spaces.
string s = " "
string t = s.Replace(" ", ""). //It will be hard to do a sql attack if the spaces are removed.
A little off topic but with C# 6.0 you can format string differentlyl; It's a new feature called "string interpolation" (thanks Etienne de Martel).
$"SELECT * FROM `foo` where FooID = '{id}'"

How to use c# variable with sql server query?

I have to use "messageId" and "parrentId" c# variables in sql query, but when I use error raise: "Incorrect syntax near '.2'.".
How can I use "messageId" and "parrentId" in below query?
internal DataTable getAllMessages(string messageId, string parrentId)
{
Query = "SELECT DISTINCT T1.* FROM mail_Reply T2 JOIN mail_Messages T1 ON (T2."
+ messageId + "=T1." + messageId + " OR T2." + parrentId + "=T1."
+ messageId + ")";
return ExecuteDataTable();
}
Thanks in advance.
Don't try and build a query string like that - it opens you up to a vulnerablity known as SQL Injection - and that is something you need to go away and read about right now...
Once you're done with that, read about Command objects - SqlCommand and friends...
Alternatively, consider embracing Entity Framework...
if you column names are like integer values 1,2,3, then try this,
Query = "SELECT DISTINCT T1.* FROM mail_Reply T2 JOIN mail_Messages T1 ON (T2.["
+ messageId + "]=T1.[" + messageId + "] OR T2.[" + parrentId + "]=T1.["
+ messageId + "])";
return ExecuteDataTable();
use string.format or build the query seperatly in a string variable and assign it to Query

Dynamic where clause in parameter

I am currently trying to build up the where clause of an SqlCommand.
something similar to this
myCommand.CommandText = "SELECT * " +
"FROM TABLE1 " +
"#whereClause";
//I build up the where clause with a StringBuilder
myCommand.Parameters.AddWithValue("#whereClause" theClause.ToString());
But it doesn't seem like this is possible. I got the exception :
SqlException Incorrect syntax near '#whereClause'
The reason I want to do something like this is because I want to avoid X call to the database and this way I leave sorting and filtering to the server.
Is there anyway to do something similar to this?
/edit : The where clause would look something like this WHERE (TABLE1.COL1 = 'the value' OR TABLE1.COL1 = 'another value' OR TABLE1.COL1 = 'this value' ... )
/edit Finaly this was due to a stupid typo error... after I changed to not use the parametrize query. I'll upvote those answer who helped my out. I will mark as answer what was to closer to fix my situation even if it didn't fixed my (stupid) bug
It seems you're trying to add the entire WHERE clause as a parameter - that won't work!
So suppose you need to build something like this
SELECT * from TABLE1 WHERE Field1=#Field1Value and Field2=#Field2Value
And assuming
you have a List<WhereField> of fields to include in the WHERE clause
and that all clauses are ANDed together
and WhereField looks something like this
public class WhereField
{
public string FieldName{get;set;}
public object FieldValue{get;set;}
public string ComparisonOperator{get;set;}
}
then you have something like this:
var whereClause = new StringBuilder();
foreach (var field in WhereFields)
{
whereClause.Append(field.FieldName)
.Append(field.ComparisonOperator)
.Append("#")
.Append(field.FieldName).Append("Value")
.Append (" AND ");
//add the parameter as well:
myCommand.Parameters.AddWithValue("",field.FieldName+"Value");
}
//cleanly close the where clause
whereClause.Append("1=1");
And now you can execute
myCommand.CommandText = "SELECT * " +
"FROM TABLE1 WHERE " + whereClause.ToString();
You can't use a clause (where) with parameters, you are only allowed to use parameters with command.Parameters.
To build a dynamic Where clause, you have to build your query based on conditions and string concatenation and then add the parameters accordingly.
Something like:
sb.Append("SELECT * FROM TABLE1 ");
if (someCondition)
{
sb.Append("WHERE XColumn = #XColumn");
myCommand.Parameters.AddWithValue("#XColumn", "SomeValue");
}
else
{
sb.Append("WHERE YColumn = #YColumn");
myCommand.Parameters.AddWithValue("#YColumn", "SomeOtherValue");
}
myCommand.CommandText = sb.ToString();
May be you need
myCommand.CommandText = "SELECT * " +
"FROM TABLE1 WHERE " +
"#whereClause";

What is the correct syntax for my C# query. It needs to reference a variable named "x"

Ok guys I think this is a pretty simple one, I just don't know the answer myself. I have this query which is as follows
var qry ="/tblEACNumbers?$filter = EACNumber eq " + x ;
The x is a string which is constantly chaning but the syntax requires the string which the query is using to filter must be in ' ' so this would work
var qry ="/tblEACNumbers?$filter = EACNumber eq 'Hello' ";
I understand I can change the string to get the first ' in by doing this
var qry ="/tblEACNumbers?$filter = EACNumber eq '" + x ;
But I don't know how to get the final ' after I have declared the + x string.
Any suggestions?
var qry ="/tblEACNumbers?$filter = EACNumber eq '" + x +"'";
or
var qry = String.Format("/tblEACNumbers?$filter = EACNumber eq '{0}'", x);
Well, you already know how to add string to a string, why not use that again?
var qry = "/tblEACNumbers?$filter = EACNumber eq '" + x + "'";
Another option is to use string.Format():
var qry = string.Format("/tblEACNumbers?$filter = EACNumber eq '{0}'", x);
Both of those options are vulnerable to injection attacks, so you should add some escaping, depending on where you send this query. You don't have to worry about this if x comes from a trusted source, though.

Using items from List<string> in SQL query

Ok, I have a list that consists of a bunch of values from a sql query, that part works fine. What I want to do is use the items in that list to tell another query what to look for. So, what it is saying is that, it should return all columns from CMMReports where PartNumber is like %listItem1..2...3%, Any advice?
List<string> ImportedParts = GetImportedPartNumbers();
string query = "SELECT * FROM CMMReports WHERE (RacfId IS NULL OR RacfId = '') AND (FilePath NOT LIKE '%js91162%') AND PartNumber LIKE %" + ImportedParts + "% ORDER BY CreatedOn DESC;";
Not that I condone this as you should be using parameterized queries. However, this should work:
StringBuilder partNumbers = new StringBuilder();
foreach (string queryValue in ImportedParts)
{
string q = "PartNumber LIKE '%" + queryValue + "%'";
if (string.IsNullOrEmpty(partNumbers.ToString())
{
partNumbers.Append(q);
}
else
{
partNumbers.Append(" OR " + q);
}
}
string query = string.Format("SELECT * FROM CMMReports WHERE (RacfId IS NULL OR RacfId = '') " +
"AND (FilePath NOT LIKE '%js91162%') AND ({0}) " +
"ORDER BY CreatedOn DESC;", partNumbers.ToString());
You might look up the IN clouse for SQL that way you get the answer for the parts that SQL Server can find in the database. Using WHERE x = y for all the items means that if one item can't be found the whole query returns nothing.
I would consider doing this in a stored procedure and passing in your list as an Xml parameter.
See the following article for more info on using Xml parameters in a stored proc:
Passing lists to SQL Server 2005 with XML Parameters - By Jon Galloway
Form there you can easily use your list data inside your stored proc using the Xml syntax and treat it almost as another table of data.
Untested, but you should get the idea:
List<string> ImportedParts = GetImportedPartNumbers();
SqlCommand cmd = myConnection.CreateCommand();
cmd.CommandText = "SELECT * FROM CMMReports WHERE (RacfId IS NULL OR RacfId = '') AND (FilePath NOT LIKE '%js91162%') AND (";
int i = 0;
foreach (string part in ImportedParts) {
cmd.AddParameterWithValue("#param" + i.ToString(), "%" + part + "%");
if (i != 0) cmd.CommandText += " OR"
cmd.CommandText += " PartNumber LIKE #param" + i.ToString();
i++;
}
cmd.CommandText += ") ORDER BY CreatedOn DESC;";
This solution uses a parameterized query instead of just appending strings in the SQL, which is considered a potential security risk.

Categories

Resources