Why is third argument necessary in DBUtils.ExecuteMap? - basic4android

Dim m As Map
m = DBUtils.ExecuteMap(SQL, "SELECT Id, [First Name], [Last Name], Birthday FROM students WHERE id = ?", _Array As String(value))
Why is third argument needed in DBUtils.ExecuteMap ? I tried looking in DBUtils code module but didnt understand anything.

The third argument is an array (or list) of values that replace the question marks in the query, which is a parameterized query. This way we do not need to escape the string values and it is also easier to build the query as we don't need to concatenate the query and the variables.
You can pass Null if it is not needed (for example, if the query is constant).

Related

How to pick up data from row and put it into tPostgresqlInput?

I have a requets which giving me an ids. I need to iterate them into another request, so I have a sheme like this: scheme
In tPostgresqlInput I have this code rc.id = upper('18ce317b-bf69-4150-b880-2ab739eab0fe') , but instead of id I need to put smthn like globalMap.get(row4.id). How did I do this?
Apparently this is a syntax issue
Try with :
"select * FROM table LEFT JOIN table on parameter JOIN table on parameter
WHERE 1=1 AND
column = 'content'
AND upper(rc.id) = upper('"+((String)globalMap.get("row4.id")) +"')"
Expressions in tDBInput should always begin and end with double quotes.
Don't forget to cast globalMap.get() with the type of your element (here I put String)
.equals is not a DB function but a java function. I have replaced it with '='
Let me know if it's better

Get results from HQL query with the same order as given list

I'm trying make a query with HQL that will stay with the same order as given list of IDs. I know it's possible with SQL but I can't find any way to do it with HQL (and I cannot do it with native SQL because I got many joins)
Example
fingerIds = [3,1,10,4]
SELECT p FROM People p
JOIN FETCH p.fingers f
WHERE f.id IN :fingerIds
DB: PostgreSQL 10.4
Hibernate: 4.3.11.Final
Eg. Given list of IDs: [3,1,10,4]
Actual result's order: [1,3,4,10]
Expected result's order: [3,1,10,4]
You can obtain the order by adding to your query the keyword FIELD, in your example:
SELECT p FROM People p
JOIN FETCH p.fingers f
WHERE f.id IN :fingerIds
ORDER BY FIELD(f.ID,3,1,10,4)
Ofc you can replace the numbers with your variable :fingerIds
You can find more about that command here.
Returns the index (position) of str in the str1, str2, str3, ... list. Returns 0 if str is not found.

How to get only specific rows on DB, when date range fits SQL condition on a 'tsrange' datatype? [duplicate]

I have this query:
some_id = 1
cursor.execute('
SELECT "Indicator"."indicator"
FROM "Indicator"
WHERE "Indicator"."some_id" = %s;', some_id)
I get the following error:
TypeError: 'int' object does not support indexing
some_id is an int but I'd like to select indicators that have some_id = 1 (or whatever # I decide to put in the variable).
cursor.execute('
SELECT "Indicator"."indicator"
FROM "Indicator"
WHERE "Indicator"."some_id" = %s;', [some_id])
This turns the some_id parameter into a list, which is indexable. Assuming your method works like i think it does, this should work.
The error is happening because somewhere in that method, it is probably trying to iterate over that input, or index directly into it. Possibly like this: some_id[0]
By making it a list (or iterable), you allow it to index into the first element like that.
You could also make it into a tuple by doing this: (some_id,) which has the advantage of being immutable.
You should pass query parameters to execute() as a tuple (an iterable, strictly speaking), (some_id,) instead of some_id:
cursor.execute('
SELECT "Indicator"."indicator"
FROM "Indicator"
WHERE "Indicator"."some_id" = %s;', (some_id,))
Your id needs to be some sort of iterable for mogrify to understand the input, here's the relevant quote from the frequently asked questions documentation:
>>> cur.execute("INSERT INTO foo VALUES (%s)", "bar") # WRONG
>>> cur.execute("INSERT INTO foo VALUES (%s)", ("bar")) # WRONG
>>> cur.execute("INSERT INTO foo VALUES (%s)", ("bar",)) # correct
>>> cur.execute("INSERT INTO foo VALUES (%s)", ["bar"]) # correct
This should work:
some_id = 1
cursor.execute('
SELECT "Indicator"."indicator"
FROM "Indicator"
WHERE "Indicator"."some_id" = %s;', (some_id, ))
Slightly similar error when using Django:
TypeError: 'RelatedManager' object does not support indexing
This doesn't work
mystery_obj[0].id
This works:
mystery_obj.all()[0].id
Basically, the error reads Some type xyz doesn't have an __ iter __ or __next__ or next function, so it's not next(), or itsnot[indexable], or iter(itsnot), in this case the arguments to cursor.execute would need to implement iteration, most commonly a List, Tuple, or less commonly an Array, or some custom iterator implementation.
In this specific case the error happens when the classic string interpolation goes to fill the %s, %d, %b string formatters.
Related:
How to implement __iter__(self) for a container object (Python)
Pass parameter into a list, which is indexable.
cur.execute("select * from tableA where id =%s",[parameter])
I had the same problem and it worked when I used normal formatting.
cursor.execute(f'
SELECT "Indicator"."indicator"
FROM "Indicator"
WHERE "Indicator"."some_id" ={some_id};')
Typecasting some_id to string also works.
cursor.execute(""" SELECT * FROM posts WHERE id = %s """, (str(id), ))

it is possible to concatenate one result set onto another in a single query?

I have a table of Verticals which have names, except one of them is called 'Other'. My task is to return a list of all Verticals, sorted in alpha order, except with 'Other' at the end. I have done it with two queries, like this:
String sqlMost = "SELECT * from core.verticals WHERE name != 'Other' order by name";
String sqlOther = "SELECT * from core.verticals WHERE name = 'Other'";
and then appended the second result in my code. Is there a way to do this in a single query, without modifying the table? I tried using UNION
(select * from core.verticals where name != 'Other' order by name)
UNION (select * from core.verticals where name = 'Other');
but the result was not ordered at all. I don't think the second query is going to hurt my execution time all that much, but I'm kind of curious if nothing else.
UNION ALL is the usual way to request a simple concatenation; without ALL an implicit DISTINCT is applied to the combined results, which often causes a sort. However, UNION ALL isn't required to preserve the order of the individual sub-results as a simple concatenation would; you'd need to ORDER the overall UNION ALL expression to lock down the order.
Another option would be to compute an integer order-override column like CASE WHEN name = 'Other' THEN 2 ELSE 1 END, and ORDER BY that column followed by name, avoiding the UNION entirely.

JPQL: sort queryresult by "best matches" possible?

I have the following question/problem:
I'm using JPQL (JPA 2.0 and eclipselink) and I wanna create a query that gives me the results sorted the following way:
At first the results sorted ascending by the best matches. After that should appear the inferior matches.
My objects are based on a simple class called 'Person' with the attributes:
{String Id,
String forename,
String name}
For example if I'm searching for "Picol" the result should look like:
[{129, Picol, Newman}, {23, Johnny, Picol},{454, Picolori, Newta}, {4774, Picolatus, Larimus}...]
PS: I already thought about using two queries, the first is searching with "equals" and the second with "like", although I'm not quite sure how to connect both queryresults...?
Hope for your help and thanks in advance,
Florian
If, as your question seem to imply, you only have two groups (first group : forename or name equals searched string; second group : forename or name contains searched string), and if all the persons of a given group have the same "match score", then using two queries is indeed a good solution.
First query :
select p from Person p where p.foreName = :param or p.name = :param
Second query :
select p from Person p where (p.foreName like :paramSurroundedWithPercent
or p.name like :paramSurroundedWithPercent)
and p.foreName != :param
and p.name != :param
Execute both queries (each returning a List<Person>), and add all the elements of the second list to the first one (using the addAll() method)