DB2 how do I replace a double quote returned by an XML element - db2

I am able to successfully retrieve the value of XML element using the following SQL
*SELECT XMLQUERY('$item/*:ItemSpec/*:AdditionalDescription/*:ABCDescription/text()' PASSING productval.value_xml as "item") AS H_DESCRIPTION FROM USER1.XMETA*
This returns a value that has double quotes (") in it. How do I replace it with a different value in the same select query. I tried something like this but it didn't work
Select REPLACE(XMLQUERY('$item/*:ItemSpec/*:AdditionalDescription/*:ABCDescription/text()' PASSING productval.value_xml as "item"),'"','QUOT') AS H_DESCRIPTION
The error is No authorized routine named "REPLACE" of type "FUNCTION" having compatible arguments was found...SQLCODE=-440,SQLSTATE==-42884.

XMLQUERY returnes an XML type, try casting it to varchar before applying REPLACE on it:
REPLACE(XMLCAST(XMLQUERY('$item/*:ItemSpec/*:Addition ...) AS VARCHAR(...)), '"','QUOT') AS ..

Related

Why single quote escape cannot be used in QuestDB, Error: dangling expression

I'm trying to use Query Variables in Grafana, the panel query source is PostgreSQL for QuestDB.
I have added the variable without any issue, but I'm unable to use the variable in Panel query since the variable values contains the spaces (SENSOR01 ON_OFF), also I'm unable to figure-out how to add single quote escape.
Following are the scenarios I tried:
Scenario1: this indicates due to space in the Variable value, on_off considered as separate word
where sensor_name = $sensor
db query error: pq: unexpected token: on_off
.
.
Scenario2: tried to add single quotes explicitly for the variable value, but there is generic error from source DB (QuestDB)
where sensor_name = concat('''', $sensor, '''')
db query error: pq: dangling expression
When tried Scenario2 approach directly in query of Variable, getting the same error
..
Scenario3: Hard-coded the variable value with space and with single quotes, but this giving me error with first part of the variable, looks like the hard-coded single quotes not passed here!
Error (Scenario3):
Is there any way/workaround to tackle this issue?
Could you just add the quotes directly in the query?
where sensor_name = '$sensor'
I have a similar grafana panel querying a questDB database using a variable and it works for me. This is my query:
select device_type, avg(duration_ms) as avg_duration_ms, avg(speed) as avg_speed, avg(measure1) as avg_m1, avg(measure2) as avg_m2 from ilp_test
WHERE
$__timeFilter(timestamp) and device_type = '$deviceType'
A rather hacky workaround would be to do:
where sensor_name = concat(cast(cast('&' as int) + 1 as char), $sensor, cast(cast('&' as int) + 1 as char))
This should work, but I'm pretty sure there is a better solution. Let me find it and get back to you.
Update. We may support Postgres syntax (which is '' escaping for a single quote char) in one of upcoming versions. For now, you'd have to use the above workaround.

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

Db2 xmlcast specification

Select xmlcast('<case_id>123</case_id><checknumb>2345</checknumb>' as XML)
This query returns
<case_id;gt;123</case_id
<checknumb>2345</checknumb
How to get
<case_id>123</case_id<checknumb>2345</checknumb>
Why its coming like this when casting into xml.
Your code is trying to cast a string literal '<case_id>123</case_id><checknumb>2345</checknumb>' as an XML string, not an XML document. XML strings cannot contain angle brackets inside them, because these symbols have special meaning for XML parsers, so the angle brackets are converted to entities.
If what you really want is to convert your literal '<case_id>123</case_id><checknumb>2345</checknumb>' to an XML document, you need to make it a valid XML document first (by adding the root element) and then use XMLPARSE(DOCUMENT '<root><case_id>123</case_id><checknumb>2345</checknumb></root>') instead.
If you need to produce an XML sequence, then you should use XMLCONCAT scalar function, and not try to cast a string constant to the XML type.
VALUES XMLCONCAT(XMLELEMENT(NAME "case_id", 123), XMLELEMENT(NAME "checknumb", 2345));
If you need to produce an XML document, then you should use the following:
VALUES XMLELEMENT(NAME "doc", XMLCONCAT(XMLELEMENT(NAME "case_id", 123), XMLELEMENT(NAME "checknumb", 2345)));

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;

placeholder for postgresql box type, using DBI/DBD::PG

I am trying to use placeholders to insert geometric type into a postgresql database.
I tried the two codes below :
my $sth = ($dbh)->prepare("INSERT INTO lrad.matable(zone) VALUES (BOX'((?,?),(?,?))');");
$sth->execute(0.5,0.7,0.4,0.6);
which results in DBD::Pg::st execute failed: called with 4 bind variables when 0 are needed
my $sth = ($dbh)->prepare("INSERT INTO lrad.matable(zone) VALUES (((?,?),(?,?)));");
$sth->execute(0.5,0.7,0.4,0.6);
which results in column "zone" is of type box but expression is of type record
HINT: You will need to rewrite or cast the expression.
Any idea of a way to fix it ? or will i be force to build my box without placeholders ?
Use functions rather than casts to build up the box:
INSERT INTO lrad.matable(zone) VALUES (box(point(?,?),point(?,?)))
You could also build up the string "(0.5,0.7),(0.4,0.6)" in perl, and pass that string in to a single ? placeholder:
INSERT INTO lrad.matable(zone) VALUES (?::box)