I am using Mockrunner to mock Sql DB for my unit tests. Following is my query:-
"select * from table where userId in (" + userIds + ")"
Now my userIds is state dependent. I don't need my test cases dependent on the arrangement inside the list - userIds. So I don't need exact match but regex matching. I have already enabled regex matching by below code:-
StatementResultSetHandler statementHandler = connection.getStatementResultSetHandler();
usersResult = statementHandler.createResultSet("users");
statementHandler.setUseRegularExpressions(true);
//How to write this regex query?
statementHandler.prepareResultSet("select * from table where userId in .*", campaignsResult);
But as it is noted, I have no idea about the regex syntax supported by Mockrunner.
Edit: I unable to match queries like "Select * from tables" with "Select * from tab .*". So It has to do something with the way I using regex with Mockrunner
There are some helpful examples available here. For instance:
public void testCorrectSQL() throws Exception {
MockResultSet result = getStatementResultSetHandler().createResultSet();
getStatementResultSetHandler().prepareResultSet("select.*isbn,.*quantity.*", result);
List orderList = new ArrayList();
orderList.add("1234567890");
orderList.add("1111111111");
Bookstore.order(getJDBCMockObjectFactory().getMockConnection(), orderList);
verifySQLStatementExecuted("select.*isbn,.*quantity.*\\(isbn='1234567890'.*or.*isbn='1111111111'\\)");
}
From this, I surmise that it's using standard Java regex syntax. In which case, you probably want:
prepareResultSet("select \\* from table where userId in \\(.*\\)", campaignsResult);
...or perhaps more succinctly (and depending upon exactly how fine-grained your tests need to be):
prepareResultSet("select .* from table where userId in .*", campaignsResult);
The main caveat to be aware of when enabling the regex matching is that any literal special characters that you want in your query (such as *, (, and ) literals) need to be escaped in your regex before it will work properly.
To prevent from SQL injections, OWASP encodes characters received.Below is the code implemented for org.owasp.esapi.codecs.OracleCodec.java class
//Default implementation that should be overridden in specific codecs. Encodes ' to '' Encodes ' to '' (according to doc)
public String encodeCharacter( char[] immune, Character c ) {
if ( c.charValue() == '\'' )
return "\'\'";
return ""+c;
}
How does above help for the prevention of SQL injection?Please explain.
Using the guidelines at OWASP, multiple test cases can be found here.
The snippet of code you're looking at here defends against someone trying to escape out of the query to run their own arbitrary command.
if ( c.charValue() == '\'' )
If the input value is equal to ASCII char value 0x27 (a single quote)
return "\'\'";
Escape the single quote.
Oracle escaping is here.
Lets say your query is "select * from users where id = \'" + request.getParameter("id")
By not escaping single-quotes, an input like this:
request.setParameter("id", "\' OR 1=1;"); would result in returning all the information in that table by changing the final, non-Java formatted query to select * from users where id = '' OR 1=1;
I highly recommend you download the WebGoat program, and follow its lessons. It will teach you how to use SQL injection, and many other basic web attacks. And the ESAPI swingset will help you learn how to mitigate them.
Here explains very well for oracle and others DBMS:
https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
But rule n. 1 to prevent SQL injection is not to use query concatenation but instead prepared statements! With prepared statements there is no need to encode any parameter (set by sql api) and there are also DB performance optimizations.
I am using oracle 10g and hibernate 3.3.2. I have used regular expression in sql before, now for the first time I am using it in HQL.
Query query = getSession().createQuery("From Company company
where company.id!=:companyId and
regexp_like(upper(rtrim(ltrim(company.num))), '^0*514619915$' )");
This is my hql, when i run it without regex_like function it runs as expected. But I am not able to execute it with regex_like expression.
It says..
nested exception is org.hibernate.hql.ast.QuerySyntaxException:
unexpected AST node: ( near line 1, column 66.....
Kindly help, how can I use regex_like in hibernate native query? OR some other alternative to do so.
Actually, you can't compare the result of REGEXP_LIKE to anything except in conditional statements in PL/SQL.
Hibernate seems to not accept a custom function without a returnType, as you always need to compare the output to something, i.e:
REGEXP_LIKE('bananas', 'a', 'i') = 1
As Oracle doesn't allow you to compare this function's result to nothing, I came up with a solution using case condition:
public class Oracle10gExtendedDialect extends Oracle10gDialect {
public Oracle10gExtendedDialect() {
super();
registerFunction(
"regexp_like", new SQLFunctionTemplate(StandardBasicTypes.BOOLEAN,
"(case when (regexp_like(?1, ?2, ?3)) then 1 else 0 end)")
);
}
}
And your HQL should look like this:
REGEXP_LIKE('bananas', 'a', 'i') = 1
It will work :)
You can most definitely use any type of database-specific function you wish with Hibernate HQL (and JPQL as long as Hibernate is the provider). You simply have to tell Hibernate about those functions. In 3.3 the only option for that is to provide a custom Dialect and register the function from the Dialect's constructor. If you take a look at the base Dialect class you will see lots of examples of registering functions. Usually best to extend the exact Dialect you currently use and simply provide your extensions (here, registering the function).
An interesting note is that Oracle does not classify regexp_like as a function. They classify it as a condition/predicate. I think this is mostly because Oracle SQL does not define a BOOLEAN datatype, even though their PL/SQL does and I would bet regexp_like is defined as a PL/SQL function returning BOOLEAN...
Assuming you currently use Oracle10gDialect, you would do:
public class MyOracle10gDialect extends Oracle10gDialect {
public Oracle10gDialect() {
super();
registerFunction(
"regexp_like",
new StandardSQLFunction( "regexp_like", StandardBasicTypes.BOOLEAN )
);
}
}
I cannot remember if the HQL parser likes functions returning booleans however in terms of being a predicate all by itself. You may instead have to convert true/false to something else and check against that return:
public class MyOracle10gDialect extends Oracle10gDialect {
public Oracle10gDialect() {
super();
registerFunction(
"regexp_like",
new StandardSQLFunction( "regexp_like", StandardBasicTypes.INTEGER ) {
#Override
public String render(
Type firstArgumentType,
List arguments,
SessionFactoryImplementor factory) {
return "some_conversion_from_boolean_to_int(" +
super.render( firstArgumentType, arguments, factory ) +
")";
}
}
);
}
}
You can't access specific database functions unless JPAQL/HQL provide a way to do so, and neither provide anything for regular expressions. So you'll need to write a native SQL query to use regexes.
On another, and very important point, a few colleagues (Oracle DBAs) told me to never use regexes in oracle, as they can't be indexed, which ends up in the DB performing a full DB scan. If the table has a few entries, then it's ok, but if it has lots of rows, it might cripple the performance.
For those using Hibernate criterion with sqlRestriction (Hibernate Version 4.2.7)
Criterion someCriterion = Restrictions.sqlRestriction("regexp_like (column_name, ?, 'i')", "(^|\\s)"+searchValue+"($|\\s|.$)", StringType.INSTANCE);
Or another option is to create similar function in oracle which will return numeric value based on operation result. Something like that
CREATE OR REPLACE FUNCTION MY_REGEXP_LIKE(text VARCHAR2, pattern VARCHAR2)
RETURN NUMBER
IS function_result NUMBER;
BEGIN
function_result := CASE WHEN REGEXP_LIKE(text, pattern)
THEN 1
ELSE 0
END;
RETURN(function_result);
END MY_REGEXP_LIKE;
and you will be able to use
MY_REGEXP_LIKE('bananas', 'a') = 1
You can use Specification.
Specification<YourEntity> specification = (root, query, builder) -> builder.equal(builder.selectCase()
.when(builder.function("regexp_like", Boolean.class, root.get("your_field"), builder.literal("^0*514619915$")), 1)
.otherwise(0), 1);
List<YourEntity> yourEntities = yourEntityRepository.findAll(specification);
i found the solution Accessing REGEXP_LIKE function in CriteriaBuilder useful for this. Add the dialect based on your Oracle version.
I'm making a java application for a toy store and using the MS-Access database.
I'm using the operator "LIKE" to search for products in database using the user's keyword.
E.g. in Access:
SELECT * FROM tblToy WHERE toyName LIKE '*puppy*' OR toyBrand LIKE '*puppy*'
this gives me the desired result in access.
But in java when i run this same query it returns null:
String query = "puppy";
sql = "SELECT * FROM tblToy WHERE toyName LIKE '*" + query+"*' "+
"OR toyBrand LIKE '*" + query + "*'";
rs = db.executeQuery(sql);
while(rs.next()){
String name = rs.getString("toyName");
return name;
}
return null;
Can anyone help me on this? I know it must be something simple which I'm missing out now but I just don't know what to do. Would appreciate your guys help.
I think with Java, you need to escape single quotes, so try using \' for all your single quotes, then try % instead of * as someone else mentioned, since % is the wildcard for SQL.
There are two possibilities for wildcards according to where you are running the query, * or %. In this case, you need %
I have problem using REGEX in Mysql
I have oid value in database like this
id -> value
1.3.6.1.4.1 -> Value a
1.3.6.1.4.1.2499.1.1.2.1.1.1.1.1 -> Value b
1.3.6.1.4.1.2499 -> Value c
And my objecttives are
1. To get single oid & value with the specific oid that i put into sql statement
2. If no specific value then it should reverse the oid number by number until it found the newrest value
For example
If i use
[select id from tablename where '1.3.6.1.4.1.2499.1.1.2.1.1.1.1.1' REGEXP oid]
it should return only 1.3.6.1.4.1.2499.1.1.2.1.1.1.1.1 but the above sql will return all result
If i use
[select id from tablename where '1.3.6.1.4.1.24999999.5' REGEXP oid]
it should return 1.3.6.1.4.1 only but it return 1.3.6.1.4.1 and 1.3.6.1.4.1.2499
If i use
select id from tablename where '1.3.6.1.4.1.2499.1.1.2.1.1.1.1.100' REGEXP oid
it should return 1.3.6.1.4.1.2499 only but it return all ids
I am not really familiar with this REGEXP. Can anyone help me to solve this problem.
Thank you
With MySQL, you should use field REGEXP value, like this:
select id from tablename where oid REGEXP '1.3.6.1.4.1.2499.1.1.2.1.1.1.1.1'
. must be escaped with \
And to match an entire row, use ^ and $:
select id from tablename where oid REGEXP '^1\.3\.6\.1\.4\.1\.2499\.1\.1\.2\.1\.1\.1\.1\.1$'
I don't understand why do you use REGEXP when you can select by LIKE, because you don't search by a regular expression.
I don't think regex is the right tool for this job.
Instead, I'd loop over the input string, treating it as a period-delimited list.
Match the list against oid. If zero matches, remove the last list element. Repeat.