how do I remove trailing blanks in a select on a char(32)?
db2 "create table test (col1 char(32))"
db2 "insert into test values ('one')"
I tried
db2 "select cast(trim(t ' ' from col1 ) as varchar(32)) from test"
db2 "select trim(t ' ' from cast(col1 as varchar(32)) from test"
db2 "select cast(trim(t ' ' from cast(col1 as varchar(32))) as varchar(32)) from test"
... but I always have trailing blanks
Try
select trim(cast(col1 as varchar(32))) from test
proof it with
select length(trim(cast(col1 as varchar(32))) ) from test
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';
The first SQL statement results in an "ERROR: syntax error at or near \ "
This refers to s3_uri\gset.
psql> SELECT aws_commons.create_s3_uri(
'test-bucket',
'animals.csv',
'us-east-1'
) AS s3_uri \gset
psql> \echo :s3_uri
(test-bucket,animals.csv,us-east-1)
psql> SELECT aws_commons.create_aws_credentials(
'<my_access_id>',
'<my_secret_key>',
'<session_token>'
) AS credentials \gset
psql> \echo :credentials
(<my_access_id>,<my_secret_key>,<session_token>)
psql> SELECT aws_s3.table_import_from_s3(
'animals',
'',
'(FORMAT CSV, DELIMITER '','', HEADER true)',
:'s3_uri',
:'credentials'
);
when making dump file with pg_dump command this performace is very fine but in dump is only create alter and inserts with syntax
COPY table1 (id, name) FROM stdin;
1 developer's portal
...
.
I want to make with this syntax sql dump where table will updated
for example
update table1 set name ='hello' where id=1
with pg_dump syntax
This script will do, although, for simplicity's sake, it assumes the table's primary key is the first field:
table=table1
psql -Atc "with a as (select attrelid::regclass::text rel, attnum i, quote_ident(attname) col from pg_attribute where attrelid='$table'::regclass)
select 'select format(\$\$update '||rel||' set '||string_agg(col||'=%s', ', ' order by i)||'\$\$, '||string_agg('quote_nullable('||col||')', ',' order by i)||')||\$\$ where '||
(select col||'=\$\$||quote_nullable('||col||')||\$\$;\$\$ from '||rel from a where i = 1) from a where i > 1 group by rel" |\
psql -At
If you're using PostgreSQL 9.5+, then you could use INSERT ... ON CONFLICT UPDATE ... instead:
table=table1
psql -Atc "with a as (select attrelid::regclass::text rel, attnum i, quote_ident(attname) col from pg_attribute where attrelid='$table'::regclass)
select 'select format(\$\$insert into '||rel||'('||string_agg(col, ',' order by i)||
') values ('||string_agg('%s', ',')||
') on conflict ('||(select col from a where i=1)||') do update set '||
string_agg(case when i > 1 then col||'=excluded.'||col end, ', ' order by i)||';\$\$, '||
string_agg('quote_nullable('||col||')', ',' order by i)||') from '||rel from a where i > 0 group by rel" |\
psql -At
We are using postgresql 8/psql version 8.4. I am querying information_schema.columns for the column names and would like to generate a text file/output file so:
UNLOAD ('select
col1,
col2,
col3,
col4,
col5)
to more text here
or
UNLOAD ( 'select col1,col2,col3,col4,col5) to more text here
So, I'm basically looking to output the colname followed by a "," - colname,
Is this possible? Thanks for the help.
This will create a string like that:
SELECT 'UNLOAD ( ''select ' ||
array_to_string(array_agg(column_name::text), ',') ||
' to more text here'
FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = 'whatever'
;
You can use \o to send it to a file, or use COPY (...) TO STDOUT.
I have successfully constructed the output that I have been looking for from using dynamic SQL to create a pivot table with dynamically created column names.
My code is:
IF OBJECT_ID('tempdb..#TempDB') IS NOT NULL
DROP TABLE #TempDB
SELECT CASEID, FORMNAME, NAME, VALUE INTO #TempDB FROM dbo.EFORM WHERE FORMNAME='IncidentReporting'
IF OBJECT_ID('tempdb..#TempDB1') IS NOT NULL
DROP TABLE #TempDB1
SELECT DISTINCT Name INTO #TempDB1 FROM #TempDB
DECLARE #columns varchar(max)
DECLARE #query varchar(max)
SELECT #columns = COALESCE(#columns + ',[' + cast([Name] as varchar(100)) + ']',
'[' + cast([Name] as varchar(100))+ ']')
FROM #TempDB1
SET #query = 'SELECT * FROM #TempDB AS PivotData '
SET #query = #query +
'PIVOT (MAX(VALUE) FOR [NAME] IN (' + #columns + ')) AS p'
EXEC (#query)
This successfully gives me results like:
CASEID FORMNAME Column1 Column2 Column3
501000000621 IncidentReporting Value1 Valuea Valuev
501000000622 IncidentReporting Value2 Valueb Valuew
601000000126 IncidentReporting Value3 Valuec Valuex
601000000127 IncidentReporting Value4 Valued Valuey
601000000128 IncidentReporting Value5 Valuee Valuez
These results, outputed from the #query variable, are in exactly the format that I want a table of these results to be in.
Can anyone tell me how to get the results that are in the #query variable into a standard SQL table?
I have tried doing a statement like this, but I get the message "Incorrect syntax near ' + #columns + '":
SELECT *
INTO #TempDB4
FROM (SELECT * FROM #TempDB AS PivotData
PIVOT (MAX(VALUE) FOR [NAME] IN (' + #columns + ')) AS p)
Many thanks in advance.
In your existing code, add your into to this line:
SET #query = 'SELECT * FROM #TempDB AS PivotData '
so that you get:
SET #query = 'SELECT * INTO #TempDB4 FROM #TempDB AS PivotData '
Or add insert in the same manner.
To get your unsuccessful query to work as you expect, you'd have to turn that into dynamic SQL, much like your successful query, and call it using exec or sp_executesql