What does this JDBC snippet achieves? - sql

String q = "SELECT attr FROM students foo =? AND bar = ?";
PreparedStatement s= connection.prepareStatement(q);
s.setString(1,"a");
s.setString(2."b");
ResultSet rs = s.executeQuery();
if(rs.next())
{
System.out.println("aba");
}
else
{
System.out.println("zab");
}
I'm not entirely sure, but my interpretation is that it performs query to find "attr" from "students" where foo is something and bar is something. In case of successful results from query it prints out aba, otherwise it will print out zab.
Correct me if i'm wrong.What s.setStrings(1,"a") are for? What exactly question mark stands for?

You are mostly right. If there is at least one row in the students table, with field foo='a' and bar='b', this prints out aba, if no such line exists, it prints out zab
The question marks and the0 .setString(1,"a") statements are closely related. The ? denotes a parameter (placeholder, if that is more convenient to grasp) to the query, and the s.set<datatype>() methods 'fill these in'. The first parameter specifies the parameter to fill in, the second specifies the value.
Recommended reading: Using PreparedStatements

The question mark in the query represents the values to be added later on. They act as placeholders.
So you prepare the query once and then just set the values using, e.g.,
s.setString(1,"a");
This sets the first value (aka the first question mark) to a string value of a. There are respective functions for other types like, for example, setInt() or setLong().

Related

Why do variables need single quotes in `execute` SQL query?

Given name = "Ben", this does not work:
DB.execute("SELECT id FROM departments WHERE name = #{name}")
but this does (added single quotes):
DB.execute("SELECT id FROM departments WHERE name = '#{name}'")
Why? Why doesn't Ruby call the variable in the first example? It's already a string. I don't see why that should make any difference. Isn't that equivalent to passing "'Ben'"? Wouldn't this be equivalent to passing "Ben"?
It's not a Ruby problem, but an SQL syntax issue.
WHERE name = tom
and
WHERE name = 'tom'
are two different things.
In the first case, it is treated as a schema object name (presumably a column name here), in the second case it is a String literal.
You run into the same issue whenever you use one programming language to create a program for another programming language (here Ruby -> SQL) by direct String manipulation.
The correct way is to use bind variables.
WHERE name = ?
That also deals with the problem of name containing special characters.
name = "Little Bobby Tables, see http://xkcd.com/327/"

Regex match SQL values string with multiple rows and same number of columns

I tried to match the sql values string (0),(5),(12),... or (0,11),(122,33),(4,51),... or (0,121,12),(31,4,5),(26,227,38),... and so on with the regular expression
\(\s*\d+\s*(\s*,\s*\d+\s*)*\)(\s*,\s*\(\s*\d+\s*(\s*,\s*\d+\s*)*\))*
and it works. But...
How can I ensure that the regex does not match a values string like (0,12),(1,2,3),(56,7) with different number of columns?
Thanks in advance...
As i mentioned in comment to the question, the best way to check if input string is valid: contains the same count of numbers between brackets, is to use client side programm, but not clear SQL.
Implementation:
List<string> s = new List<string>(){
"(0),(5),(12)", "(0,11),(122,33),(4,51)",
"(0,121,12),(31,4,5),(26,227,38)","(0,12),(1,2,3),(56,7)"};
var qry = s.Select(a=>new
{
orig = a,
newst = a.Split(new string[]{"),(", "(", ")"},
StringSplitOptions.RemoveEmptyEntries)
})
.Select(a=>new
{
orig = a.orig,
isValid = (a.newst
.Sum(b=>b.Split(new char[]{','},
StringSplitOptions.RemoveEmptyEntries).Count()) %
a.newst.Count()) ==0
});
Result:
orig isValid
(0),(5),(12) True
(0,11),(122,33),(4,51) True
(0,121,12),(31,4,5),(26,227,38) True
(0,12),(1,2,3),(56,7) False
Note: The second Select statement gets the modulo of sum of comma instances and the count of items in string array returned by Split function. If the result isn't equal to zero, it means that input string is invalid.
I strongly believe there's a simplest way to achieve that, but - at this moment - i don't know how ;)
:(
Unless you add some more constraints, I don't think you can solve this problem only with regular expressions.
It isn't able to solve all of your string problems, just as it cannot be used to check that the opening and closing of brackets (like "((())()(()(())))") is invalid. That's a more complicated issue.
That's what I learnt in class :P If someone knows a way then that'd be sweet!
I'm sorry, I spent a bit of time looking into how we could turn this string into an array and do more work to it with SQL but built in functionality is lacking and the solution would end up being very hacky.
I'd recommend trying to handle this situation differently as large scale string computation isn't the best way to go if your database is to gradually fill up.
A combination of client and serverside validation can be used to help prevent bad data (like the ones with more numbers) from getting into the database.
If you need to keep those numbers then you could rework your schema to include some metadata which you can use in your queries, like how many numbers there are and whether it all matches nicely. This information can be computed inexpensively from your server and provided to the database.
Good luck!

How to use Get command in Monkey talk?

Does anybody know how to use the Get command in monkey talk?
In monkey talk guide only the command is written but no syntax is present.
Here is an example for you,
var x = app.label("label1").get("x","value")
Above line will get the value of label1 and store it in variable x. You can change the second parameter "value" to ".text" or ".size" depending on your needs
since the question is not marked Answered and For the future reference i am answering this.
‘GET’ ACTION RETRIEVES COMPONENT PROPERTY VALUES
Syntax:
ComponenType MonkeyId Get varName propName
Works like an assignment statement (varName= propName)
The default property is “value”
// Get label value currently displayed
Label lastname Get name
// Enter name into input field
Input query EnterText ${name}
// Get the first table item
Table countries Get country items1
// Enter into input field
Input * EnterText ${country}
you can refer this document here, thanqs
I will try to explain using example. Suppose there is a ListView(Table) and you want to scroll till its last item.
//Define a variable
Vars * Define row
//Store size of list in variable row using Get. Check use of "Get" here
Table * Get row size %thinktime=20000
//Now stored variable can be used as per need. here I am using for scrolling
Table * ScrollToRow ${row} %thinktime=2000
Hope it helps you !!

Codeigniter database query bug - does not return expected results

I tested this query in my database, and it works fine:
select * from variables where value = 'commas-:-)';
I get a result. Now, I stored the value in a variable and use the query class.
$value = 'commas-:-)' <<< this is passed as a parameter
$query = "select * from variables where value = '$value'";
$this->db->query($query);
Now, this query works for every other value except for this one - but what's odd is that if I PRINT out the exact query (print_r of $query) and execute it on the database, it returns the correct result. So I'm left to think that the query class is screwing with my query, which it shouldn't because everything is properly escaped and $value is a string literal.
What is going on?
$sql = "SELECT * FROM variables WHERE value = ?";
$this->db->query($sql, array('commas-:-)'));
More info
$get_data = $this->db->from('variables')
->where('value', $value)
->get();
Hope this will work...!
try to use these things for checking the queries
echo $this->db->last_query();
print_r($this->db->result_array($get_data));
I found the issue - it was the rerouting function that was causing the mishap. More specifically, the segment filtering function within the route folder in the system core.
This is what happened:
I created an anchor with the encoded value (commas:-)) and I configured the route to reroute the uri to a function I had in my controller. Each time I clicked the link, the value gets passed, and (supposedly) rerouted to the function. Which it did, for almost all the values I used. Except this one.
1st assumption: the db query function is escaping the values. But I turned off the escape, as well as checked the query by printing. The value was correct. I then tried other query formats, and still no results. Conclusion: There's nothing wrong with the database query functions.
2nd assumption: the data must be corrupt - although the value is correct (I'm getting commas:-)), it's not returning anything except when I type in the value manually. So I tested this:
I created a seperate value, and set it equals to the one I typed in(the one that works). I then printed the original value(one passed) and the newly created value using VAR_DUMP.
Turns out, the argument value (one that doesn't work) is a string with length 14 whereas my new variable was a string with a length of 10. WTF? Conclusion: Something occured during the rerouting / passing process that changed the variable.
I went back to the config folder, and replace the variable $i in the reroute to the literal string value commas:-). And guess what? It worked perfectly. And just to make sure it wasn't the regex, I wrote my own custom regex and it matched fine, but the value was still being changed. So I decided to get under the hood.
I traced the URI manipulation in the routes class to the _explode_segment() function, which was used to perform the regex and analyse the uri for other variables. It also did this thing ...
_filter_uri($str)
for each part of the uri segment that was matched.
What did it do? It replaces programmable characters like ( and ) with their HTML ENTITY. Now, if you don't know, html entities have long lengths than url encoding. LOL. So what happened was this:
Original segment : commas-%3A-%29 <- very nice!
Filtered segment : commas-%3A-) <- NOOOOOOOOO! (the right paren encoded with &#41.)
urldecode("&#41") = string(4)
urldecode("%29") = string(1)
Fail.
or WIN?!

SQLiteQueryBuilder.buildQuery not using selectArgs?

Alright, I'm trying to query a sqlite database. I was trying to be good and use the query method of SQLiteDatabase and pass in the values in the selectArgs parameter to ensure everything got properly escaped, but it wouldn't work. I never got any rows returned (no errors, either).
I started getting curious about the SQL that this generated so I did some more poking around and found SQLiteQueryBuilder (and apparently Stack Overflow doesn't handle links with parentheses in them well, so I can't link to the anchor for the buildQuery method), which I assume uses the same logic to generate the SQL statement. I did this:
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(BarcodeDb.Barcodes.TABLE_NAME);
String sql = builder.buildQuery(new String[] { BarcodeDb.Barcodes.ID, BarcodeDb.Barcodes.TIMESTAMP, BarcodeDb.Barcodes.TYPE, BarcodeDb.Barcodes.VALUE },
"? = '?' AND ? = '?'",
new String[] { BarcodeDb.Barcodes.VALUE, barcode.getValue(), BarcodeDb.Barcodes.TYPE, barcode.getType()},
null, null, null, null);
Log.d(tag, "Query is: " + sql);
The SQL that gets logged at this point is:
SELECT _id, timestamp, type, value FROM barcodes WHERE (? = '?' AND ? = '?')
However, here's what the documentation for SQLiteQueryBuilder.buildQuery says about the selectAgs parameter:
You may include ?s in selection, which
will be replaced by the values from
selectionArgs, in order that they
appear in the selection.
...but it isn't working. Any ideas?
The doc for SQLiteQueryBuilder.buildQuery also says, "The values will be bound as Strings." This tells me that it is doing the straight-forward thing, which is writing the SQL leaving the ? parameter markers in place, which is what you are seeing, and binding the selectArgs as input parameters.
The ? are replaced by sqlite when it runs the query, not in the SQL string. The first string in the array will go where you see the first ?, and so on, when the query actually executes. I would expect the logged SQL to still have the ? markers.
Probably, your query fails because you are quoting the ?. For example, don't use WHERE ID = '?', just use WHERE ID = ?, and make sure the selectArgs is a string that satisfies the query.
Two things:
The ? substitution will not be done at this point, but only when the query is executed by the SQLiteDatabase.
From what I've seen, ? substitution only works for the right side of comparison clauses. For example, some people have tried to use ? for the table name, which blows up. I haven't seen anyone try using ? for the left side of the comparison clause, so it might work -- I'm just warning you that it might not.