While running through some older code in our app, I ran into something like this:
queryBuilder.selectRaw("myFirstColumnName");
queryBuilder.where().eq("mySecondColumnName", new SelectArg());
where queryBuilder is a com.j256.ormlite.stmt.QueryBuilder. Now, I have no idea how this maps to SQL, but I'm imagining this:
SELECT myFirstColumnName
WHERE mySecondColumnName = SELECT *
which I've never seen, nevermind used, before. What is the purpose of this? What could this be attempting to do, and what would the result be?
Good answer #novak. Just to add some information:
queryBuilder.where().eq("mySecondColumnName", new SelectArg());
This is a bit of a strange pattern. The typical usage of SelectArg is to create a variable so we can set the value later. For example:
SelectArg arg = new SelectArg();
queryBuilder.where().eq("mySecondColumnName", arg);
...
arg.setValue("column1");
Sometimes we know the value of the argument up front but we still want to use the SQL ? mechanism so we might do:
queryBuilder.where().eq("mySecondColumnName", new SelectArg("column1"));
We do this, for example, when we want to protect ourselves from SQL injection attacks or if we are using values that have SQL special characters (like quotes).
The queryBuilder.where() method returns a com.j256.ormlite.stmt.Where<T,ID>.
The eq() method creates an equals comparison for the where conditional.
The resulting SQL query would be:
SELECT myFirstColumnName WHERE mySecondColumnName = ?
The new SelectArg() would be the value for the ?.
Documentation reference for this:
http://ormlite.com/javadoc/ormlite-core/com/j256/ormlite/stmt/Where.html
Related
I am trying to use a full id of a block in the getmaterial part of the code below. this does not work any way that i try.
I cannot find any documentation supporting this issue of handling an id which contains a 'colon :' .
Snip: (Example the 5758:6 below does not work and the string name neither.)
emerald.setIngredient('L', Material.getMaterial("5758:6"));
Material.getMaterial(406) //this is expecting an integer so i cannot give it two numbers
Material.getMaterial(406:1) //this fails as is expecting int
Assuming that emerald is a ShapedRecipe object (since you're using the setIngredient(char, Material) method), then you can also use the setIngredient(char, MaterialData) method instead. You could construct the MaterialData object you want using the (deprecated...) MaterialData(int, byte) constructor. Your new code would look like:
emerald.setIngredient('L', new MaterialData(5758, 6));
The colon in the "full id of a block" is just separating the "id" and "data" values. I think this will do what you're looking for, but if not, let me know so I can clarify.
I don't think you're supposed to be dealing with that number colon thing. Instead, if you want to get to, say, the BRICK material, use Material.BRICK or Material.valueOf("BRICK"). If you want to find the name of a Material m, use m.name() which returns a String.
Okay, so let me just state this first. I am very new to SQL and I don't know a lot about it. I just recently started using it and I've been trying to learn it and improve. Please explain anything you state, as I may not understand common terms etc.
The SQL code I wrote now works like I intend it to, but the string seems obnoxious and made me think that this can't be quite right.
INSERT INTO reputations(uuid, warn, bandate, reasons, mods)
VALUES ('{0}', '{1}', '{2}', CONCAT(reasons, '{3}'), CONCAT(mods, '{4}'))
ON DUPLICATE KEY UPDATE warn = '{1}',
bandate = '{2}',
reasons=CONCAT(reasons, '{3}'),
mods=CONCAT(mods, '{4}')
In my Java code it looks like this:
As you also probably can see, I have no clue on how to properly format/indent it all for use like this. Any tips would be greatly appreciated.
I should also explain that the {n}'s are just spaces where I replace it with the information I want. For example, I replace all {0} with an UUID.
So, my question is. Is there a better way to do this? Any tips or help would be appreciated. Cheers!
I don't understand this part:
VALUES ('{0}', '{1}', '{2}', CONCAT(reasons, '{3}'), CONCAT(mods, '{4}'))
------------------------------------^
The use of the column name there should be generating an error.
Perhaps this is the statement you want:
INSERT INTO reputations(uuid, warn, bandate, reasons, mods)
VALUES ('{0}', '{1}', '{2}', '{3}', '{4}')
ON DUPLICATE KEY UPDATE warn = VALUES(warn),
bandate = VALUES(bandate),
reasons = CONCAT(reasons, VALUES(reasons)),
mods = CONCAT(mods, VALUES(mods));
In the ON DUPLICATE KEY part, you can use VALUES() to get the new value from a particular column. In addition, I suspect you might really want to have a separator for the last two concatenations:
reasons = CONCAT_WS('; ', reasons, VALUES(reasons)),
mods = CONCAT_WS('; ', mods, VALUES(mods));
The use of CONCAT_WS() has a nice side effect if the values are ever NULL -- it will still leave the remaining values.
This is probably a simple one and more Java related than grails but I'm a bit lost and not sure where to even start looking on this, I've googled about but am not really sure what I'm after, so would appreciate a pointer if possible please!
In the grails app I have a form which I save, all well and good. In the controller I can see the list of params it returns via a simple println and when I want to find a specific value currently I do a params.each and then compare the key to a pre defined string to find the one I want, my question is: -
Can I, and how would I, specifically say "get me the value of the parameter with the key "banana", rather than having to loop through the whole list to find it?
Also is there a way of creating a new set of secondary params, or just another plain old dictionary item (is that the right term?) where I use a regular expression to say "give me all the items whose key match the pattern "XYZ"?
It probably doesn't make much difference speed wise as the params are never that big but it'd be nice to make things more efficient where possible.
Any feedback much appreciated!
For a first question, to get 'banana' parameter you have to use:
params.banana
For second, find all with regexp:
def matched = params.findAll { it.key =~ /XYZ/ }
//or
Pattern p = ~/XYZ/
def matched = params.findAll { p.matcher(it.key).matches() }
There's a params object you can use. Eg with someurl.com?myparam=test you can access it with "params.myparam"
More information over here: http://grails.org/doc/2.2.x/ref/Controllers/params.html
i am using replace method for editing text in mysql database and its working well for
every time i try to replace a string by some other string e.g
REPLACE(Eligibility_Points , '(ii)', 'second point is')";
works well for above case
but does not work well in the following case
REPLACE(Eligibility_Points , '(ii)-(iii)', 'second and third point is')";
how should i fix this problem, thanks for your help
Assuming that this is the MySQL REPLACE string function you are talking about, the only reason I can see why the second example wouldn't work is that (maybe) the Eligibility_Points field (or whatever) doesn't contain the first string at all.
Maybe you could provide more context; e.g. what evidence you have that the replace isn't working.
However #vadchen makes a good point. If you do the replacement in the first example, then it will remove all examples that might trigger a replacement in the second example. Maybe you just need to do the "edits" in the reverse order.
There is no need to escape any of the characters in those fragments, either from the Java or SQL perspective.
String searchSQLFilter(String keyword){
for(String filter:new String[]{"|","&","*","%",";","-","+",",","<",">"}){
keyword=keyword.replaceAll("\\Q"+filter+"\\E", "");
}
keyword=keyword.replaceAll("'","\\\\'");
return keyword;
}
sql query:
select * from table where title like '%"+searchSQLFilter(keyword)+"%'
I want to know,searchSQLFilter method is safe?
btw: I know this is not good,using PreparedStatement is better
Sorry, no, it isn't.
Creating your own escaping function is a bad idea: you won't catch all the cases. Vendor-built escaping functions have been tried and tested by millions of users, and patched where necessary.
Example: did you take character encoding into account?
Not a final answer... a blacklist approach can only be safe at a given point in time. You're missing the complex ones like union. At least ' should be included in the blacklist as well.
As you already mentioned - prepared statements are better!