Postgresql - problem using json function in nested queries - hstore - sql

I have a table orders with a field order_detail of type hstore which saves json data.
Now I want to query on the inner objects of my json data. because The query is somehow complicated I'm trying to tell my problem in easier scenario.
I have tested these 4 subqueries:
Get the original saved json:
select order_detail::json as original
from orders;
This query successfully returns the json formatted data.
Get the inner object 'transaction' inside the order_details:
select order_detail::json as original,
(order_detail -> 'transaction')::json as transaction
from order_details;
This query also works successfully.
Get the id of that transaction:
select order_detail::json as original,
(order_detail -> 'transaction')::json as transaction,
((order_detail -> 'transaction')::json -> 'id')::text as id
from order_details;
The above also works successfully and returns the original json, transaction and id inside the transaction.
Select based on the result of query 3 and get one of the results:
select original
from
(select order_detail::json as original,
(order_detail -> 'transaction')::json as transaction,
((order_detail -> 'transaction')::json -> 'id')::text as id
from order_details) s
where transaction is null and id is null;
This query will raise an exception! The exception says that:
[22P02] ERROR there is a token '=' is invalid**
Why does this exception occurs only in the 4th query? Can anyone help me on this?

Finally I found the problem. When you want have such a field which is json stored in hstore, if you use a simple query you can use something like this:
order_detail -> 'trasaction'
and this will return the transaction part of hashed-stored data in the order_detail field with no problem.
BUT if you want to use such thing in a nested query, you MUST explicitly declare that the field is json. so you must use something like this instead (in all parts of inner query):
order_detail::json -> 'transaction'

Related

SQL Error 'ORA-00904' When Retrieving Data From an XML File Via XMLQuery

I've been trying for days now to retrieve data from an XML file with a SELECT statement in SQL Developer but I constantly get the 'ORA-00904' when trying to execute the statement. So far, these are the steps I've been following:
Create the table and directory where I want the XML data to be stored in:
CREATE TABLE PLAYER OF XMLTYPE; / CREATE DIRECTORY PLDIR AS 'C:\Users\marta\OneDrive\Escritorio\UOC\Sem3\ABD\PR2'; /
Insert into my PLAYER table said data:
INSERT INTO PLAYER VALUES (XMLTYPE(bfilename('PLDIR', 'InfoPlayersWPT.xml'),nls_charset_id('AL32UTF8')))
/
So far so good. The issue appears when I try to execute the SELECT statement
What could it be? I've changed the $Name parameter a million times as well as the Name field but nothing changes. The thing is that in the XML file, these are the fields:
--Update--
I've modified a little bit the structure and this is the new error I get:
enter image description here
I've reached a point where I don't get if there could be a problem with my database connection or if the variable are incorrect.
Any form of help would be much appreciated.
Your table doesn't have a name or id column. Your query is trying to get those, while also transforming the XML to an info node making the id a node rather than an attribute, but you still don't extract the values from that new XML. You don't need to though.
If the document only has one player (which seems unlikely with the outer node 'Players') then you can get the data with an XMLQuery call for each value:
select XMLQuery('/Players/Player/#id' passing p.object_value returning content) as id,
XMLQuery('/Players/Player/Name/text()' passing p.object_value returning content) as name
from player p
ID
NAME
1
Francinsco Navarro Compán
But it's a bit simpler, particularly if you add more data items, to use a single XMLTable instead:
select x.id, x.name
from player p
cross apply XMLTable(
'/Players/Player'
passing p.object_value
columns id number path '#id',
name varchar2(30) path 'Name'
) x
ID
NAME
1
Francinsco Navarro Compán
fiddle
... which would also handle multiple players in each XML document.

How to use json array in WHERE IN clause in Postgres

I have a Postgres query like this
SELECT * FROM my_table WHERE status IN (2,1);
This is part of a big query, but I am facing an issue with the WHERE IN part here. I am using this query inside a function and the input parameters are in JSON format. Now the status values I am getting in in the form of a JSON array and it will be like status=[2,1]. I need to use this array in the WHERE clause in the query and not sure how to do that. Currently, I am using like
SELECT * FROM my_table WHERE status IN (array([2,1]));
But this is giving me an error. The status column is of smallint data type. I know this is simple, but I am very much new to Postgres and could not figure out any method to use the JSON array in WHERE IN clause. Any help will be appreciated.

Why The Query Against HashKey returns no records

I am working on a new sql table. The table has a column [varbinary(8000)], where we are storing hash of a certain text. Now, I am trying to retrieve the same record back by using a where clause against the hashkey, but that yields zero records.
I have added a similar query here: http://sqlfiddle.com/#!18/be996/11
Try without the single quotes, like this
SELECT id, description
FROM ForgeRock
where id = 0x94EE059335E587E501CC4BF90613E0814F00A7B08BC7C648FD865A2AF6A22CC2
and you will get the expected result.

Creating a calculated field table based on data in separate tables

It is straight forward to create a calculated field in a table that uses data IN the table... due to the fact that the expression builder is straight forward to use. However, it appears to me that the expression builder for the calculated field only works with data IN the table;
i.e: expression builder in table MYTABLE works with fields FIELD1.MYTABLE, FIELD2.MYTABLE etc.
Inventory Problem
My problem is that I have two 'count' fields that result from my queries that apply to INPUTQUERY and OUTPUTQUERY (gives me a count of all input data added and a count of all output data added) and now I want to subtract the two to get a stock.
I can't link the table that was created from my query because it wont be able to continually update do the relationship itself, and thus i'm stuck either using the expression builder/SQL.
First question:
Is it possible to have the expression builder reference data from other tables?
i.e expressionbuilder for:
MAINTABLE CALCULATEDFIELD.MAINTABLE = INPUTSUM.INPUTTABLE - OUTPUTSUM.OUTPUTTABLE
(which gives a difference of the two)?
Second question:
if the above isn't possible, can I do this through an SQL code ?
i.e
SELECT(data from INPUTSUM)
FROM(INPUTTABLE)
-
SELECT(data from OUTPUTSUM)
FROM(OUTPUTTABLE)
Try this:
SELECT SUM(T.INPUTSUM) - SUM(T.OUTPUTSUM) AS RESULTSUM
FROM
(
SELECT INPUTSUM, 0 AS OUTPUTSUM
FROM INPUTTABLE
UNION
SELECT 0 AS INPUTSUM, OUTPUTSUM
FROM OUTPUTTABLE
) AS T

Optimize pass parameter to view

I have quite complicated view in mysql, like
select filter.id as filter_id, person.id, person.name
from person, filter
inner join
...
left join
...
where person_match_filter_condition ...
group by filter.filter_id, person.id, person.name
Query filters person which corresponds domain specific conditions.
Typical use of view is:
select * from where filter_id = some_value
Problem is that mysql cannot optimize query. It applies confition by filter_id AFTER get data for all filters - very ineffective.
Idea to get filter_id from other tables is not good for my case.
How can I transform my query to make it more effective?
Wrap the long query in a procedure, and pass the filters to the procedure call as parameters. Then instead of using views you call the procedure, the procedure will build you the entire query and will run optimized query.
Better yet, you can pass parameters to your views in a simple manner by creating a Function to GET your values from Session Variables. See https://www.stackoverflow.com/questions/14511760 for the technique. This is a copy of my create function you may wish to pattern after.
DELIMITER //
CREATE FUNCTION fn_getcase_id()
RETURNS MEDIUMINT(11)
DETERMINISTIC NO SQL
BEGIN
see stackoverflow.com/questions/14511760 and read ALL the info TWICE or MORE. wh 04/13/2017
RETURN #sv_case_id;
END//
DELIMITER ;
You will need to create a similar FN (one for each variable).