PostgreSQL: how to extract value attribute from XML - postgresql

I am trying to convert the following SQL Server query to Postgresql
select CAST(CAST('<IncludeSettle/><StartTime value="2019-03-26 08:45:48.780"></StartTime>' as XML).value('(//StartTime/#value)[1]', 'datetime') AS varchar(40)) + ''')';
I have tried converting it to below and got back following error.
select unnest(xpath('//StartTime/#value', xmlparse(document '<IncludeSettle/><StartTime value="2019-03-26 08:45:48.780"></StartTime>')))
Error:
ERROR: invalid XML document
DETAIL: line 1: Extra content at the end of the document
<IncludeSettle/><StartTime value="2010-03-26 08:45:48.780"></StartTim
^
SQL state: 2200M
As a hack, I had made the following change to make it work.
select unnest(xpath('//StartTime/#value', xmlparse(document '<tempzz>'||'<IncludeSettle/><StartTime value="2019-03-26 08:45:48.780"></StartTime>'||'</tempzz>')))
Output for Postgresql:
2019-03-26 08:45:48.780
I am looking for a better solution. Any help really appreciated.

You can process that by adding the dummy root as you did. The value is already formatted as an ISO timestamp, so you can simply cast it to a timestamp:
But as there is no direct cast from xml to timestamp you need to cast the result of the xpath() to text first.
with data (input) as (
values ('<IncludeSettle/><StartTime value="2019-03-26 08:45:48.780"></StartTime>')
)
select (xpath('//StartTime/#value', ('<dummy_root>'||input||'</dummy_root>')::xml))[1]::text::timestamp
from data

Related

Postgres, query error: ERROR: operator does not exist: character varying = bigint?

I am trying to run this query:
select *
from my_table
where column_one=${myValue}
I get the following error in Datagrip:
[42883] ERROR: operator does not exist: character varying = bigint Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
Now, I have found this question, and I can fix the error by putting a string like this:
select *
from my_table
where column_one='123'
What I need is a way to pass in the '123' as a parameter. I usually do this ${myValue} and it works, but I am not sure how to keep my variable there as an input so I can run dynamic queries in code and let Postgres understand I want to pass in a string and not a number.
Any suggestions?
Here's a screenshot of how I am putting the parameter value in DataGrip...:
Ok, so, I just tried to put quotes in the data grip parameters input field for myValue #thirumal's answer things work. I didn't know I have to quote the value for it to work.
This is what it looks like:
Type cast ${myValue} using SQL Standard,
cast(${myValue} AS varchar)
or using Postgres Syntax:
${myValue}::varchar

Passing a row type to jsonb_to_recordset syntax errors

I'm trying to work out how to expand a JSONB field with a jsonb_to_recordset and a custom type.
Postgres 11.4.
This is just a test case, but for the minute I'm trying to work out the syntax. I've got a table named data_file_info with a JSONB field named table_stats. The JSONB field always includes a JSON array with the same structure:
[
{"table_name":"Activity","record_count":0,"table_number":214},
{"table_name":"Assembly","record_count":1,"table_number":15},
{"table_name":"AssemblyProds","record_count":0,"table_number":154}
]
The following code works correctly:
from data_file_info,
jsonb_to_recordset(table_stats) as table_stats_splat (
table_name text,
record_count integer,
table_number integer
)
What I would like to do is pass in a custm type definition instead of the long-form column definition list shown above. Here's the matching type:
create type data.table_stats_type as (
table_name text,
record_count integer,
table_number integer)
Some examples I've seen, and the docs say, that you can supply a type name using a null:row_type casting in the first parameter to jsonb_to_recordset. The examples that I've found use in-line JSON, while I'm trying to pull stored JSON. I've made a few attempts, all have failed. Below are two of the trials, with errors. Can someone point me towards the correct syntax?
FAIL:
select table_stats_splat.*
from data_file_info,
jsonb_populate_recordset(null::table_stats_type, data_file_info) as table_stats_splat;
-- ERROR: function jsonb_populate_recordset(table_stats_type, data_file_info) does not exist
-- LINE 4: jsonb_populate_recordset(null::table_stats_type, dat...
^
-- HINT: No function matches the given name and argument types. You might need to add explicit type casts. (Line 4)
FAIL:
select *
from jsonb_populate_recordset(NULL::table_stats_type, (select table_stats from data_file_info)) as table_stats_splat;
-- ERROR: more than one row returned by a subquery used as an expression. (Line 2)
I'm doubtlessly missing something pretty obvious, and am hoping someone can suggest what that is.
Use the column as the second parameter:
select table_stats_splat.*
from data_file_info,
jsonb_populate_recordset(null::table_stats_type, table_stats) as table_stats_splat;

Sum(Field) Where Condition=Value

I'm trying to find how should be the correct syntax for Sum(FIELD) where field Condition=Value
I'm using this code;
if ({VatCodes.VatValue} =12) then Sum({InventoryTransTemp.Price})
The problem is that this syntax works but for all my report fields and either contain this value or not.My syntax in sql server is Select Sum(InventoryTransTemp.Price) where Vatcodes.VatValues=12.
How should i write it for succedd my desired result?

T-SQL Conversion failed when converting the nvarchar value '12-02' to data type int

I'm trying to convert this NVARCHAR value into a periodeId.
The Raw data could be '12-02'.
My solution for this was first to try this
(1000+CONVERT(INT,LEFT(2,T1.PERIOD_NAME)))*100+CONVERT(Int,RIGHT(2,t1.PERIOD_NAME))
But i get the same error message here and could find any quick solution for it.
I also tried to just do a simple
LEFT(2,T1.PERIOD_NAME) to see if it was the formula itself that crashed it, but the same error came up.
If you want '12-02' to be 1202, then use replace() to remove the hyphen before conversion:
select cast(replace(period_name, '-', '') as int)
In SQL Server 2012+, you should use try_convert(), in case there are other unexpected values.
You can try:
SELECT (1000+CONVERT(INT,LEFT(t1.PERIOD_NAME,2)))*100+CONVERT(Int,RIGHT(t1.PERIOD_NAME,2))
The character_expression that LEFT operates on is at first place, whereas the integer expression that specifies how many characters of the character_expression will be returned, comes at second place.

What is wrong with this PostgreSQL statement?

I have the following statement that I need to run on a table which has a geometry column. I am getting a WKT from Oracle using my C# program and then attempting to insert it into PostgreSQL using an npgsql connection.
highways=# INSERT INTO cluster_125m (CELL_GEOM)
VALUES(ST_GeomFromWKT('POLYGON ((80000.0 17280.0, 80125.0 17280.0, 80125.0 17405.0, 80000.0 17405.0, 80000.0 17280.0))'));
I get the following error:
ERROR: function st_geomfromwkt(unknown) does not exist
LINE 1: INSERT INTO cluster_125m (CELL_GEOM) VALUES(ST_GeomFromWKT('...
^
HINT: No function matches the given name and argument types. You might need to
add explicit type casts.
What is the issue here and what can be done about it?
Use function ST_GeomFromText instead of ST_GeomFromWKT.