I have a task is change the DB2 sql to Postgres sql. It has a problem in XML handle.
I tried to used this sql
SELECT xmlagg( ', <foo>abc</foo>') as YM
FROM TEST_Table"
It's working fine.
But
SELECT xmlagg( concat(', ', TRIM(CATEGORY))) as YM
from TEST_Table
is not working.
Error msg : SQL Error [42883]: ERROR: function xmlagg(text) does not exist
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
My question is how to change the below DB2sql to Postgres sql ?
**SELECT substr( xmlserialize( xmlagg( xmltext( concat( ', ', TRIM(NM_TEXT) ) ) ) as varchar( 1024 ) ), 3, 128 ) as YM
FROM TEST_Table**
Related
I tried doing this with just a normal CTE (no EXECUTE ... FORMAT) and I was able to do it.
I basically have a table that has some 5 columns and some data in each column that I wanted to concatenate and such to manifest/generate some data in a new column.
I can do something like this and it works:
WITH cte AS (SELECT *, case
when var1 = '' then ''
when var2 = '' then ''
else '' end, 'adding_dummy_text_column'
FROM some_other_table sot
WHERE sot.type = 'java')
INSERT INTO my_new_table
SELECT *, 'This is the new column I want to make with some data from my CTE' || c.type
FROM cte c;
So this works as I said. I'll end up getting a new table that has an extra column which a hardcoded, concatenated string This is the new column I want to make with some data from my CTE Java
Of course, whatever is in the c.type column for the corresponding row in the CTE as it loads the SELECT is what gets concatenated to that string.
The problem is, as soon as I start using the EXECUTE...FORMAT to make it cleaner and have more power to concatenate/combined different data pieces from my different columns (I have data kind of scattered around in bad formats and I'm populating a fresh new table), it's as if the FORMAT arguments or the variables cannot detect the CTE table.
This is how I'm doing it
EXECUTE FORMAT ('WITH cte AS (SELECT *, case
when var1 = %L then %L
when var2 = '' '' then '' ''
else '' '' end, ''adding_dummy_text_column''
FROM some_other_table sot
WHERE sot.type = ''java'')
INSERT INTO my_new_table
SELECT *, ''This is the new column I want to make with some data from my CTE %I''
FROM cte c', 'word1', 'word2', c.type
);
OK, so I know I used the empty string '' '' in this example and the %L but i just wanted to show I had no issues with any of that. Its when I try to reference my CTE columns, so you can see I'm trying to do the same concatenation but by leveraging the EXECUTE...FORMAT and using the %I identifiers. So, the first 2 args are just fine, its the c.type that just no matter what column I try, doesn't work. Also, I removed the c alias and didn't get any better luck. It's 100% anytime I reference the columns on the CTE though, as I have removed all that code and it runs just fine without that.
But yeah, is there any work around? I really want to transform some data and now have to do the || for concatenation.
This should do it:
EXECUTE format($f$WITH cte AS (SELECT *, CASE
WHEN var1 = %L THEN %L
WHEN var2 = ' ' THEN ' '
ELSE ' ' END, 'adding_dummy_text_column'
FROM some_other_table sot
WHERE sot.type = 'java')
INSERT INTO my_new_table
SELECT *, format('This is the new column I want to make with some data from my CTE %%I', c.type)
FROM cte c$f$
, 'word1', 'word2');
There are two levels. You need a second format() that's executed by the dynamic SQL string that's been concatenated by the first format().
I simplified with dollar-quoting. See:
Insert text with single quotes in PostgreSQL
The nested % character must be escaped by doubling it up: %%I. See:
What does %% in PL/pgSQL mean?
Generates and executes this SQL statement:
WITH cte AS (SELECT *, CASE
WHEN var1 = 'word1' THEN 'word2'
WHEN var2 = ' ' THEN ' '
ELSE ' ' END, 'adding_dummy_text_column'
FROM some_other_table sot
WHERE sot.type = 'java')
INSERT INTO my_new_table
SELECT *, format('This is the new column I want to make with some data from my CTE %I', c.type)
FROM cte c
Which could be simplified and improved to this equivalent:
INSERT INTO my_new_table(co1, col2, ...) -- provide target column list!
SELECT *
, CASE WHEN var1 = 'word1' THEN 'word2'
WHEN var2 = ' ' THEN ' '
ELSE ' ' END
, 'adding_dummy_text_column'
, format('This is the new column I want to make with some data from my CTE %I', sot.type)
FROM some_other_table sot
WHERE sot.type = 'java'
About the missing target column list:
Cannot create stored procedure to insert data: type mismatch for serial column
You can one command, create and insert into new table!
create table my_new_table as
select *
, CASE WHEN var1 = 'hello' THEN 'word2'
WHEN var2 = ' ' THEN 'var2 is empty'
ELSE ' ' END adding_dummy_text_column
, format(
'This is the new column I want to make with some data from my CTE %I', sot.type)
from some_other_table sot
where sot.type ='java';
In Postgresql, I am trying to pass the result of a query into a function but I am getting
SQL Error [42703]: ERROR: column "pakito" does not exist Position:
176
WITH pakito AS(
select array(select job_id from job)
),
updating_job AS(
select internal_update_job_progress('xavier-tenant', pakito)
)
select * from pakito
Anyone has any idea why it wouldn't work and how to make it work?
Thanks!
You forgot FROM pakito in the second CTE.
I am trying to insert data into a postgres table from a remote database table. I have written the following query for this purpose but I am getting following error.
'[Code: 0, SQL State: 42601] ERROR: syntax error at or near "table"
Position: 13 [Script position: 141 - 146]'
create table clintrial_EP_map.lead_sponsors (row_id SERIAL, lead_sponsors character varying)
insert into table clintrial_ep_map (lead_sponsors)
( select
*
from
dblink('dbname=x user=x host=x password=x port = x',
'
SELECT
distinct bm_dimt_clinical_trial.lead_sponsor
FROM
dwh_prod.bm_dimt_clinical_trial
where dataset_version_id = xx and lead_sponsor_class = ''xx''
'
) as ls (
lead_sponsor character varying
)
)
;
Please see, the following query is giving me desired output.
select
*
from
dblink('dbname=x user=x host=x password=x port = x',
'
SELECT
distinct bm_dimt_clinical_trial.lead_sponsor
FROM
dwh_prod.bm_dimt_clinical_trial
where dataset_version_id = xx and lead_sponsor_class = ''xx''
'
) as ls (
lead_sponsor character varying
)
;
I am not able to find a syntax error near 'table' in my insert query. Any suggestions here will be really helpful.
Thanks
Your query has two issues.
First: Create table is not ending with ; i am hoping that is typo and Second: Your insert statement is referring to schema name instead of schema qualified table name. And also using keyword 'table' in insert statment which is not required. So your correct query will be
create table clintrial_EP_map.lead_sponsors (row_id SERIAL, lead_sponsors character varying);
and
insert into clintrial_EP_map.lead_sponsors (lead_sponsors)
( select * from
dblink('dbname=x user=x host=x password=x port = x',
'SELECT
distinct bm_dimt_clinical_trial.lead_sponsor
FROM
dwh_prod.bm_dimt_clinical_trial
where dataset_version_id = xx and lead_sponsor_class = ''xx''
'
) as ls (lead_sponsor character varying)
);
the array_to_string is returning text (916-555-1212), however postgresql is treating it as set-operation even with explicit ::text casting.
select nullif(
array_to_string(
regexp_matches('9165551212', '(\d{3})?(\d{3})(\d{4})')::text[]
,'-')::text
, '');
ERROR: NULLIF does not support set arguments
yet I can use char_length which expects text and it works
select char_length(
array_to_string(
regexp_matches('9165551212', '(\d{3})?(\d{3})(\d{4})')::text[]
,'-')::text
)
char_length
-------------
12
yet wrap even that in a nullif and same error
select nullif(
char_length(
array_to_string(
regexp_matches('9165551212', '(\d{3})?(\d{3})(\d{4})')::text[]
,'-')::text
)
,12)
ERROR: NULLIF does not support set arguments
I had the same problem and it seems to be related to the regexp_matches function:
select nullif( (regexp_matches( '123', '(2)' ) )[1] , '' )
; -- ERROR: NULLIF does not support set arguments
select nullif( (regexp_matches( '123', '(2)' )::text[])[1]::text, '' )
; -- ERROR: NULLIF does not support set arguments
select nullif( ( select (regexp_matches( '123', '(2)' ) )[1] ), '' )
; -- ok: gives "2"
so just wrapping the result in a sub-select seems to solve it here as well :-/
Weird... It works if you do
select
nullif(
(
select array_to_string(
regexp_matches(
'9165551212',
'(\d{3})?(\d{3})(\d{4})'
)::text[]
, '-' )
)
, '')
I'm trying to insert point geometry values and other data from one table to another table.
-- create tables
create table bh_tmp (bh_id integer, bh_name varchar
, easting decimal, northing decimal, ground_mod decimal);
create table bh (name varchar);
SELECT AddGeometryColumn('bh', 'bh_geom', 27700, 'POINT',3);
-- popualte bh_tmp
insert into bh_tmp values
(1,'C5',542945.0,180846.0,3.947),
(3,'B24',542850.0,180850.0,4.020),
(4,'B26',543020.0,180850.0,4.020);
-- populate bh from bh_tmp
insert into bh(name, bh_geom) SELECT
bh_name,
CONCAT($$ST_GeomFromText('POINT($$, Easting, ' ', Northing, ' '
, Ground_mOD, $$)', 27700)$$);
FROM bh_tmp;
Gives this error:
ERROR: parse error - invalid geometry
SQL state: XX000
Hint: "ST" <-- parse error at position 2 within geometry
I can't see anything wrong with the ST_GeomFromText string that I've specified. But I can populate table bh if I insert rows 'manually', e.g.:
INSERT INTO bh (name, bh_geom)
VALUES ('C5' ST_GeomFromText('POINT(542945.0 180846.0 3.947)', 27700));
What am I doing wrong?
First of all, there is a misplaced semicolon after CONCAT(...);
And you can't concatenate the function name itself into the string:
INSERT INTO bh(name, bh_geom)
SELECT bh_name
, ST_GeomFromText('POINT(' || concat_ws(' ', easting, northing, ground_mod) || ')'
, 27700)
FROM bh_tmp;
Or, since you have values already (not text), you could use ST_MakePoint() and ST_SetSRID():
ST_SetSRID(ST_MakePoint(easting, northing, ground_mod), 27700)
Should be faster.
Npgsql parameterized query output incompatible with PostGIS
You're getting that error because the output of the CONCAT function is text, and your bh_geom column is geometry, so you're trying to insert text into geometry. This will work:
INSERT INTO bh(name, bh_geom) SELECT
bh_name,
ST_GeomFromText('POINT('
|| easting|| ' '
|| Northing
|| ' '
|| Ground_mOD
|| ')', 27700)
FROM bh_tmp;