how to return something else when nothing is found? - sqlite

My current query:
select timestamp from messagesTable
where partner_jid='" + lastUserJid + "' AND msg='.roll'
order by timestamp DESC LIMIT 1 OFFSET 1;
This works fine... unless the values don't exist in the database.
If values do not exist in database, then it should Select * messagesTable; or do nothing if possible.
Is there a way to add a check for that within the same query? It has to be the same query unfortunately because I need to execute things through adb shell. I've been trying things out with CASE but I do not really understand much about SQL.

You can just append a second query, with a WHERE filter that checks whether the first query did not return anything:
SELECT *
FROM (SELECT timestamp
FROM messagesTable
WHERE partner_jid = ?
AND msg = '.roll'
ORDER BY timestamp DESC
LIMIT 1 OFFSET 1)
UNION ALL
SELECT -1 -- or "timestamp FROM msgTab", or whatever
WHERE NOT EXISTS (SELECT timestamp
FROM messagesTable
WHERE partner_jid = ?
AND msg = '.roll');

Related

Can I use CASE WHEN outside of SELECT in SQLite/Conditional Structure in SQLite?

In SQL Server, I can use IF conditional structure to execute some statements if a condition is true. According to this and this, there seem to be no such structure in SQLite.
I want to check if a table exist, if it does, do nothing, if not, do a lot of things including creating tables, inserting and deleting data from other tables and updating as well:
CASE WHEN ((SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = 'TraitsSwap') = 1) THEN
-- 50 lines of code, including CREATE, DROP, INSERT, DELETE and UPDATE statements, with random() in used
ELSE
-- Do nothing
END
Is there anyway I can achieve this? The code includes usage of random() and it requires consistent result (i.e, only random in the first time). I am sorry if this sounds unreasonable, but this is in context of game modding, so I cannot really change the backend code to run separated transaction code.
I think there may be an alternative if there is a function in SQLite that can execute a string/statement block and return a result. For that, I can transform the query into
SELECT CASE WHEN ((SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = 'TraitsSwap') = 1) THEN
ExecuteCode("Code; RETURN 1;")
ELSE
0
END
I tried
SELECT CASE WHEN ((SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = 'TraitsSwap') = 1) THEN
SELECT 1;
INSERT INTO Foo(Test) VALUES("");
SELECT "A";
ELSE
SELECT 1;
SELECT 2;
SELECT "A";
END
but it's unsuccessful, the error is
near "SELECT": syntax error: SELECT CASE WHEN ((SELECT COUNT(*) FROM
sqlite_master WHERE type = 'table' AND name = 'TraitsSwap') = 1) THEN
SELECT

JDBC - SQLITE Select to variable

I am trying to run a query / select statement and save it in a variable. I know how to get something specific from a specific column but not from counting rows.
This is working as I getting MYID specifically.
ResultSet MYIDrs = stmtCFG.executeQuery( "SELECT rowid, MYID from MYINDEX order by rowid desc limit 1;" );
MYID = MYIDrs.getString("MYID");
Now I am trying to count the rows that works in SQLite client but not in the jdbc as I can't figure out what to request.
this is what I have but is not resulting in what I am expecting.
ResultSet FILE_COUNTrs = stmtCFG.executeQuery( "SELECT count(*) from TABLE where MYID = '"+MYID+"';");
FILE_COUNT = FILE_COUNTrs.getString(?????);
problem or question is: What do I put in the ????? as I already tried everything.
I am expecting to see a number.
I am really sorry I found what I was looking for by assigning a name TOTAL
This is my code and it works...
ResultSet FILE_COUNTrs = stmtCFG.executeQuery( "SELECT count(*) AS TOTAL from TABLE where MYID = '"+MYID+"';");
FILE_COUNT = FILE_COUNTrs.getString("TOTAL");
You use wrong data type. COUNT(*) returns Integer type, Not String.
You can do like this without assigning a label for COUNT(*)
int FILE_COUNT = FILE_COUNTrs.getInt(1); // 1: is the column index of COUNT(*)

Different Data types Order By in SQL

I have one situation where i want to sort table on from time but if the status of the row is suppose abc i want to order by these records by status.
Requirement is all vacant records needs to be display at the bottom and after that in top records i have to display records as per from time asc.
status is varchar , fromtime is decimal
e.g. status- vacant,occupied,current etc.
fromtime- 13.00,14.30,07.30 etc.
select * from tbluser order by case when [status]='vacant' then [status] else fromtime end
i am getting below error
Conversion failed when converting the varchar value 'vacant' to data type int
i have 2 columns one with integer and one with varchar. works with varchar. but not with decimal
but when i use below condition it works
[from time] is varchar-
Case When Status = 'Vacant' Then Status Else [from time] End
use cast in your query as cast(fromtime as varchar)
So your query becomes
select
*
from
tbluser
order by
case
when [status]='vacant' then [status]
else cast(fromtime as varchar) end
Edit 1
Here is a similar post which may help you
Understanding a Sql Server Query - CASE within an ORDER BY clause
SELECT *
FROM tbluser
ORDER BY CASE
WHEN [status]='vacant' then [status]
ELSE CONVERT(VARCHAR(max), fromtime)
END

How to select latest Row from table without using ORDER BY

How can I select latest row from by table without sorting it?
It is because it follow by the ID AUTO INCREMENT...
I'm using c# asp.net to select... I did try using LIMIT 5 but it give me an error page..
rSQL = "select COUNT(*) from chatLog_db where sessionid='" + grpID + "' LIMIT 5";
Is there any better way to solve this matter?
I'd appreciate any help please.
You have an id column which is autoincremented, right? Then you can do it like this..
select * from tablename where id=(select MAX(rid) from tablename)
On MSSQL simply use the top 1 instead of limit
select top(1) * from mytable order by some_column
http://msdn.microsoft.com/en-us/library/ms189463.aspx
if the latest means the max id
select * from chatLog_db
where id = (select max(id) from chatLog_db);
EDIT
select 5 records
select * from chatLog_db
where id > (select max(id) - 5 from chatLog_db);
You can try
SELECT * FROM chatLog_db WHERE sessionid > (SELECT MAX(sessionid) - 1 FROM chatLog_db);
You may also try for
SELECT * FROM chatLog_db WHERE sessionid > (SELECT MAX(sessionid) - 5 FROM chatLog_db);
You may use max as well like
select * from chatLog_db where sessionid = (select max(sessionid) from chatLog_db);
Something like that.
If you are not using order by into your query because you are thinking that it will change the order of your dsplay data then i will tell you that there is one trick as well to sort your data as per your need
you can also sort your data as per your need even if you are using
order by into your query,put the result into DataView and sort it
according to your need because DataView allow us sorting facility as
well.
Latest by using Order By like
select * from tablename order by columnname desc LIMIT 5;
Hope it works for you.

PL/SQL - comma separated list within IN CLAUSE

I am having trouble getting a block of pl/sql code to work. In the top of my procedure I get some data from my oracle apex application on what checkboxes are checked. Because the report that contains the checkboxes is generated dynamically I have to loop through the
APEX_APPLICATION.G_F01
list and generate a comma separated string which looks like this
v_list VARCHAR2(255) := (1,3,5,9,10);
I want to then query on that list later and place the v_list on an IN clause like so
SELECT * FROM users
WHERE user_id IN (v_list);
This of course throws an error. My question is what can I convert the v_list to in order to be able to insert it into a IN clause in a query within a pl/sql procedure?
If users is small and user_id doesn't contain commas, you could use:
SELECT * FROM users WHERE ',' || v_list || ',' LIKE '%,'||user_id||',%'
This query is not optimal though because it can't use indexes on user_id.
I advise you to use a pipelined function that returns a table of NUMBER that you can query directly. For example:
CREATE TYPE tab_number IS TABLE OF NUMBER;
/
CREATE OR REPLACE FUNCTION string_to_table_num(p VARCHAR2)
RETURN tab_number
PIPELINED IS
BEGIN
FOR cc IN (SELECT rtrim(regexp_substr(str, '[^,]*,', 1, level), ',') res
FROM (SELECT p || ',' str FROM dual)
CONNECT BY level <= length(str)
- length(replace(str, ',', ''))) LOOP
PIPE ROW(cc.res);
END LOOP;
END;
/
You would then be able to build queries such as:
SELECT *
FROM users
WHERE user_id IN (SELECT *
FROM TABLE(string_to_table_num('1,2,3,4,5'));
You can use XMLTABLE as follows
SELECT * FROM users
WHERE user_id IN (SELECT to_number(column_value) FROM XMLTABLE(v_list));
I have tried to find a solution for that too but never succeeded. You can build the query as a string and then run EXECUTE IMMEDIATE, see http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/dynamic.htm#i14500.
That said, it just occurred to me that the argument of an IN clause can be a sub-select:
SELECT * FROM users
WHERE user_id IN (SELECT something FROM somewhere)
so, is it possible to expose the checkbox values as a stored function? Then you might be able to do something like
SELECT * FROM users
WHERE user_id IN (SELECT my_package.checkbox_func FROM dual)
Personally, i like this approach:
with t as (select 'a,b,c,d,e' str from dual)
--
select val
from t, xmltable('/root/e/text()'
passing xmltype('<root><e>' || replace(t.str,',','</e><e>')|| '</e></root>')
columns val varchar2(10) path '/'
)
Which can be found among other examples in Thread: Split Comma Delimited String Oracle
If you feel like swamping in even more options, visit the OTN plsql forums.

Resources