In JDBC, how do I know when I am at the end of my FETCH? - postgresql

I am following the example here
http://www.postgresql.org/docs/current/interactive/sql-fetch.html
And then looping the following command manually
FETCH FORWARD 5 FROM liahona;
in java. I have the above in an infinite loop and would like to know how I detect I'm at the end of the data set so I can break the loop

You get an empty result set when running FETCH FORWARD and you are at the end of the cursor's total result set. (This is described in slightly different words in the documentation.)

In use JDBC for this kind of SQL - it's for postgres command-line only.
For JDBC, you need something like this:
ResultSet rs = connection.createStatement().executeQuery("select * from mytable");
while(rs.next()) { // next() returns false if there are no more rows
int col1 = rs.getInt(1);
String col2 = rs.getString(2);
}

Related

Scala Slick: cannot get parameters in query

I have just spent hours on this. I'm trying to make a pretty complicated query in PostgreSQL through Slick in Scala, but Slick will NEVER take any of my parameters into account. If I try something as simple as:
def get(location: String) = {
val query = sql"select * from cities_v where name = $location limit 10"
println(query.toString)
}
The output will be:
SQLActionBuilder(Vector(select * from cities_v where name = ? limit 10),<function2>)
If instead, I try the literal insert:
def get(location: String) = {
val query = sql"select * from cities_v where name = #$location limit 10"
println(query.toString)
}
The output will be:
SQLActionBuilder(Vector(select * from cities_v where name = , ville, limit 10),<function2>
Slick will ALWAYS add commas around any literal argument, no matter where it is placed, even if it's the only argument in the query, as in:
sql"#$q"
Now, what I'd like is make more complex queries, with calculations and function calls within Postgres. But I can't get anywhere given that Slick won't let me use any of my variables.
I tried setting all sorts of implicits, some that extend GetResult some that extend StatementParameters, Slick seems to ignore all them and either replaces my arguments with ? or surrounds them with commas, thereby rendering all of my queries invalid. I would like to add that the #$ is not great because it does not provide sanitization. I'd like to stick with Slick because it's asynchronous, but I'm not sure where to go from here.
These are my version numbers, according to build.sbt:
"postgresql" % "postgresql" % "9.1-901-1.jdbc4",
"com.typesafe.slick" % "slick_2.12" % "3.2.3",
What am I doing wrong?
There is nothing wrong with that ? appears in you result statements. It is just parametrized query, and each ? represents placeholder for future value.
Just run you queries against any database and check results.

PL/SQL How to implement conditional select

I have a small problem which I believed I could solve simply, it turns out I'm not able to figure out.
I have following query:
SELECT custom_field
INTO v_start_of_invoice
FROM BILL
WHERE BIMA_TRACKING_ID = v_previous_BIMAtrackingID
AND BSCO_CODE_ID = 'PRPAYMENT'
AND PREP_SEQ_NUM = 0
AND ITEM_CAT_CODE_ID = 1
AND PARTITION_KEY = v_prev_partition
AND SUBPARTITION_KEY = v_prev_subpartition;
What I would like to achieve here is to give to variable v_start_of_invoice the value "0" if one or all the where condition are not met.
In simple word I don't want the script to fail but I want the variable either to be set with some value if all the where conditions are matched, otherwise I want to assign the value 0.
I'm sure there are quite a few ways but I need to check what could be the best way to achieve that.
Many Thks in advance
M.
You seem to have a misunderstanding of what the exception block actually does. First off you cannot avoid the exception. If you use "select into" the query is successful only when exactly 1 row is returned. Otherwise PLSQL will internally raise the NO_DATA_FOUND when the query returns 0 rows, and TOO_MANY_ROWS when it returns more then 1 row. The exception block tells PLSQL what to do when an error is generated. Basically the exception block tells what action to take on specific errors and whether to continue error processing or discard the error. (Check the RAISE and RAISE_APPLICATION_ERROR statements.)
Keep in mind that blocks can be nested. With this in mind and in context of a outer block the solution offered by #are is exactly what you want. The structure becomes:
Begin
.
.
.
begin
place #are's code here.
end ;
-- Continue your code here: The Error has been handled and execution continues as though the exception never happened.
.
.
.
end;
As far as the "NVL(v_start_of_invoice, 0);" it's a function that will return 0 if v_start_of_invoice is NULL and v_start_of_invoice otherwise. Note the value of INTO variables is not it the select generates an error unless you set it in the exception block.
begin
SELECT custom_field
INTO v_start_of_invoice
FROM BILL
WHERE BIMA_TRACKING_ID = v_previous_BIMAtrackingID
AND BSCO_CODE_ID = 'PRPAYMENT'
AND PREP_SEQ_NUM = 0
AND ITEM_CAT_CODE_ID = 1
AND PARTITION_KEY = v_prev_partition
AND SUBPARTITION_KEY = v_prev_subpartition;
exception WHEN NO_DATA_FOUND THEN
v_start_of_invoice := 0;
end;

Can pysnmp return octectstring values only

I am doing a small script to get SNMP traps with PySnmp.
I am able to get the oid = value pairs, but the value is too long with a small information in the end. How can I access the octectstring only which comes in the end of the value. Is there a way other than string manipulations? Please comment.
OID =_BindValue(componentType=NamedTypes(NamedType('value', ObjectSyntax------------------------------------------------(DELETED)-----------------(None, OctetString(b'New Alarm'))))
Is it possible to get the output like the following, as is available from another SNMP client:
.iso.org.dod.internet.private.enterprises.xxxx.1.1.2.2.14: CM_DAS Alarm Traps:
Edit - the codes are :
**for oid, val in varBinds:
print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
target.write(str(val))**
On screen, it shows short, but on file, the val is so long.
Usage of target.write( str(val[0][1][2])) does not work for all (program stops with error), but the 1st oid(time tick) gets it fine.
How can I get the value from tail as the actual value is found there for all oids.
Thanks.
SNMP transfers information in form of a sequence of OID-value pairs called variable-bindings:
variable_bindings = [[oid1, value1], [oid2, value2], ...]
Once you get the variable-bindings sequence from SNMP PDU, to access value1, for example, you might do:
variable_binding1 = variable_bindings[0]
value1 = variable_binding1[1]
To access the tail part of value1 (assuming it's a string) you could simply subscribe it:
tail_of_value1 = value1[-10:]
I guess in your question you operate on a single variable_binding, not a sequence of them.
If you want pysnmp to translate oid-value pair into a human-friendly representation (of MIB object name, MIB object value), you'd have to pass original OID-value pair to the ObjectType class and run it through MIB resolver as explained in the documentation.
Thanks...
the following codes works like somwwhat I was looking for.
if str(oid)=="1.3.6.1.2.1.1.3.0":
target.write(" = str(val[0][1]['timeticks-value']) = " +str(val[0][1]['timeticks-value'])) # time ticks
else:
target.write("= val[0][0]['string-value']= " + str(val[0][0]['string-value']))

How to add the IF THEN ELSE in the BY/BREAK BY keyword of FOR EACH?

here is the sample that i want to ask:
FOR EACH table-name.... NO LOCK BY (IF TRUE THEN sort-this ELSE sort-that + sort-that2).
END.
This would result in an error.
if it is just
FOR EACH .. NO LOCK BY (IF TRUE THEN sort-this ELSE sort-that).
END.
then there is no error. Progress would accept the code
What is need is if condition is true then sort by one field else sort by two or more fields
If you are in a modern enough version of Progress, then you could construct a dynamic query. This will be more efficient in terms of run time as well as getting you round your problem as having IF statements in your query predicate will make index selection hard.
QueryString = "for each table no-lock...".
if true then
QueryString = QueryString + " by sort-this".
else
QueryString = QueryString + " by sort-that by sort-other".
create query QueryHandle.
QueryHandle:add-buffer(buffer table:handle).
QueryHandle:query-prepare(QueryString).
QueryHandle:query-open.
do while QueryHandle:get-next():
/*some stuff*/
end.
QueryHandle:query-close.
delete object QueryHandle.
As per the previous reply, this is not supported.
Typically, you'd have to prepare the result into a temp-table first, using a logical field in the temp-table for the result of your IF THEN ELSE expression.
Unfortunately, this syntax is not supported. As per the documentation, BREAK/BY expects an expression following it but not a statement.

oledb/ado.net: Get the command's text, with all parameters replaced

Is it possible to get the text of an OleDbCommand with all parameters replaced with their values? E.g. in the code below I'm looking for a way to get the query text
SELECT * FROM my_table WHERE c1 = 'hello' and c2 = 'world'
after I finished assigning the parameters.
var query = "SELECT * FROM my_table WHERE c1 = ? and c2 = ?";
var cmd = new OleDbCommand(query, connection);
cmd.Parameters.Add("#p1", OleDbType.WChar).Value = "hello";
cmd.Parameters.Add("#p2", OleDbType.WChar).Value = "world";
No: you have to iterate through the parameters collection yourself, doing a string.Replace() to get the equivalent. It's particularly painful when you have to use the ? syntax rather than the #parametername syntax.
The reason for this is that the full string is never assembled. The parameters and sent to the server and treated as data, and are never included in the string.
All the same, I for one understand your pain. It would have been nice if they included some kind of .ComposeSQL() method you could call for debugging purposes, that perhaps also produces a compiler warning to help avoid use in production.
If you just need to see what query was executed and dont need to work with it programmatically, you can use SQL Profiler.