SQL attribute name in parameterized query - sql

I am using following function for retrieving record on choice. I gave table my column name and value and it shows the result. but the problem is, Its not getting column name as parameter like:
public List<Products> ListAllProducts(string searchOption, string searchValue)
{
db.ClearParameters();
db.AddParameter(db.MakeInParam("#ColumnName", DbType.String, 50, searchOption));
db.AddParameter(db.MakeInParam("#Value", DbType.String, 50, searchValue));
string query = #"SELECT *
FROM [Products]
WHERE #ColumnName LIKE '%'+#Value+'%'";
ds = db.GetDataSet(query);
//Rest of code but above query is not executing
}
but when I use query like this:
string query = #"SELECT *
FROM [Products]
WHERE "+searchOption+" LIKE '%'+#Value+'%'";
It runs fine and give me result. I read this, this and this one specially, but got no idea.
Kindly guide me.

Parameters can be used in place of values inside expressions, and for nothing else: in particular, you cannot use parameters to denote table names, column names, sort order specifiers, or other parts of SQL statement that are not values.
Your non-parametersized query works, because searchOption is copied into your SQL, and becomes part of the query string.
If you need to build a query that changes conditions based on a parameter, you need to change the condition to account for all possible values of #ColumnName, like this
string query = #"SELECT *
FROM [Products]
WHERE (#ColumnName='FirstName' AND FirstName LIKE '%'+#Value+'%')
OR (#ColumnName='LastName' AND LastName LIKE '%'+#Value+'%')
OR (#ColumnName='Location' AND Location LIKE '%'+#Value+'%')";
or fall back on generating your query dynamically. As long as searchOption is not coming from user's input directly, you are safe from SQL injection attacks even though your SQL is generated dynamically.

While Trying, I came across following option and posted in answer ,so other may get benifit of this.
string query = String.Format(
#"SELECT *
FROM [Products]
WHERE {0} LIKE '%'+#Value+'%'", searchOption
);
So the complete function becomes:
public List<Products> ListAllProducts(string searchOption, string searchValue)
{
db.ClearParameters();
db.AddParameter(db.MakeInParam("#Value", DbType.String, 50, searchValue));
string query = String.Format(
#"SELECT *
FROM [Products]
WHERE {0} LIKE '%'+#Value+'%'", searchOption
);
ds = db.GetDataSet(query);
//Rest of code
}

Related

Select Specific Column from a Linked Server Table

I have the following C# code to select a column from a table that is on a linked server:
var query2 = $#"select [FileName] from [AMS_H2H].[H2H].[dbo].[FileReconciliation] where ProductCode = #productCode";
LayZConnection(); //make the db connection
var candidates = _dbConnection.Query<int>(query2, new { productCode = "ACHDH" });
When running it, I get the following error:
"Input string was not in a correct format."
If my query is instead the following, where I select all columns, it works:
var query2 = $#"select * from [AMS_H2H].[H2H].[dbo].[FileReconciliation]
What is the correct format to select just the FileName. Btw, the first query works fine from MSSMS.
You're specifying a type of int in Query<int>, which will cause Dapper to try and map the result of the query to an integer, however your query is returning a filename in select [FileName], which would suggest that it is a string.
Changing the type Query<string> should solve the issue.
More information on Dapper's Query method is available in Dapper's documentation

Cannot run simply query, getting "missing right parenthesis" error

What is wrong with this query?
select author_num from (henry_author where (contains(author_first,'Albert') > 0))
Keeps giving me an error that is is missing a right parenthesis?
SELECT author_num FROM henry_author WHERE author_first LIKE '%Albert%';
or, probably better to account for data inconsistencies:
SELECT author_num FROM henry_author WHERE UPPER(author_first) LIKE '%ALBERT%';
The % is a wildcard matching zero or more characters. So %ALBERT% means anything can be before or after 'ALBERT', which is effectively what your contains() function is doing.
UPPER is just a function which converts the string into upper case characters, which makes it easier to deal with potential data inconsistencies, ie. someone typed in 'albert' instead of 'Albert', etc.
Since you're using JDBC, you might want to structure your query to use PreparedStatement which will allow you to parameterize your query like so:
final String sqlSelectAuthorNum = "SELECT author_num FROM henry_author WHERE UPPER(author_first) LIKE ?";
final PreparedStatement psSelectAuthorNum = conn.prepareStatement(sqlSelectAuthorNum);
// now execute your query someplace in your code.
psSelectAuthorNum.setString(1, "%" + authorName + "%");
final ResultSet rsAuthorNum = psSelectAuthorNum.executeQuery();
if (rsAuthorNum.isBeforeFirst()) {
while (rsAuthorNum.next()) {
int authorNumber = rsAuthorNum.getInt(1);
// etc...
}
}

How can I use SQL Parameters in a CONTAINS clause?

I am looking to do something like:
select * from MyValues
where CONTAINS(MyValues.Value, ' #p0 OR #p1 OR #p2 or #p3 ')
I issue the query through EF's SqlQuery() method like:
query = context.Database.SqlQuery<MyResult>(#"select * from MyValues
where CONTAINS(MyValues.Value, '#p0 OR #p1 OR #p2 OR #p3')",
new SqlParameter("#p0", "Cat"),
new SqlParameter("#p1", "Green"),
new SqlParameter("#p2", "Red"),
new SqlParameter("#p3", "Dog"));
The command goes through fine, no exceptions, but I do not receive any results. When I manually use the strings in place of the parameters, I get the expected results. I've tried various forms and combinations of quotation marks but to no avail.
Are SQL Parameters allowed within a CONTAINS expression?
Thanks!
Because the CONTAINS function uses a single string, I don't believe that you can use parameters as you have them. You can try building up the full string and passing that in as a single parameter however. As long as the string that you build is then passed in as a parameter I believe that you'll avoid any issues with possible SQL injection.
May be you can try this.
query = context.Database.SqlQuery<MyResult>(#"select * from MyValues)
Once you get your list.filter it using below query.
First put all your parameters in a string array.
string[] paramValues= [p1,p2,p3,p4]
var results=query.where(r=> paramValues.Contains(r.Value));
Note:If your resultset is huge.it's not a good idea to return all results to front end and do filter.in most cases you have other conditions to filter.

QueryDSL like operation SimplePath

Similarly to this question I would like to perform an SQL "like" operation using my own user defined type called "AccountNumber".
The QueryDSL Entity class the field which defines the column looks like this:
public final SimplePath<com.myorg.types.AccountNumber> accountNumber;
I have tried the following code to achieve a "like" operation in SQL but get an error when the types are compared before the query is run:
final Path path=QBusinessEvent.businessEvent.accountNumber;
final Expression<AccountNumber> constant = Expressions.constant(AccountNumber.valueOfWithWildcard(pRegion.toString()));
final BooleanExpression booleanOperation = Expressions.booleanOperation(Ops.STARTS_WITH, path, constant);
expressionBuilder.and(booleanOperation);
The error is:
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [7!%%] did not match expected type [com.myorg.types.AccountNumber (n/a)]
Has anyone ever been able to achieve this using QueryDSL/JPA combination?
Did you try using a String constant instead?
Path<?> path = QBusinessEvent.businessEvent.accountNumber;
Expression<String> constant = Expressions.constant(pRegion.toString());
Predicate predicate = Expressions.predicate(Ops.STARTS_WITH, path, constant);
In the end, I was given a tip by my colleague to do the following:
if (pRegion != null) {
expressionBuilder.and(Expressions.booleanTemplate("{0} like concat({1}, '%')", qBusinessEvent.accountNumber, pRegion));
}
This seems to do the trick!
It seems like there is bug/ambiguity. In my case, I need to search by couple fields with different types (String, Number), e.g. SQL looks like:
SELECT * FROM table AS t WHERE t.name = "%some%" OR t.id = "%some%";
My code looks like:
BooleanBuilder where = _getDefaultPredicateBuilder();
BooleanBuilder whereLike = new BooleanBuilder();
for(String likeField: _likeFields){
whereLike = whereLike.or(_pathBuilder.getString(likeField).contains(likeValue));
}
where.and(whereLike);
If first _likeFields is type of String - request works fine, otherwise it throws Exception.

multiple parameter "IN" prepared statement

I was trying to figure out how can I set multiple parameters for the IN clause in my SQL query using PreparedStatement.
For example in this SQL statement, I'll be having indefinite number of ?.
select * from ifs_db where img_hub = ? and country IN (multiple ?)
I've read about this in
PreparedStatement IN clause alternatives?
However I can't figure it out how to apply it to my SQL statement above.
There's not a standard way to handle this.
In SQL Server, you can use a table-valued parameter in a stored procedure and pass the countries in a table and use it in a join.
I've also seen cases where a comma-separated list is passed in and then parsed into a table by a function and then used in a join.
If your countries are standard ISO codes in a delimited list like '#US#UK#DE#NL#', you can use a rather simplistic construct like:
select * from ifs_db where img_hub = ? and ? LIKE '%#' + country + '#%'
Sormula will work for any data type (even custom types). This example uses int's for simplicity.
ArrayList<Integer> partNumbers = new ArrayList<Integer>();
partNumbers.add(999);
partNumbers.add(777);
partNumbers.add(1234);
// set up
Database database = new Database(getConnection());
Table<Inventory> inventoryTable = database.getTable(Inventory.class);
ArrayListSelectOperation<Inventory> operation =
new ArrayListSelectOperation<Inventory>(inventoryTable, "partNumberIn");
// show results
for (Inventory inventory: operation.selectAll(partNumbers))
System.out.println(inventory.getPartNumber());
You could use setArray method as mentioned in the javadoc below:
http://docs.oracle.com/javase/6/docs/api/java/sql/PreparedStatement.html#setArray(int, java.sql.Array)
Code:
PreparedStatement statement = connection.prepareStatement("Select * from test where field in (?)");
Array array = statement.getConnection().createArrayOf("VARCHAR", new Object[]{"AA1", "BB2","CC3"});
statement.setArray(1, array);
ResultSet rs = statement.executeQuery();