how to print variable in postgres function - plpgsql

How to print bwtid or use for to execute query
create or replace function dashboard.rspCreateAndInsertUpdateBranchWiseTurnOverTable(
AccountGroupIdCol NUMERIC(10,0),
SourceBranchIdCol NUMERIC(10,0),
DestinationBranchIdCol NUMERIC(10,0),
WayBillTypeIdCol NUMERIC(1,0),
TotalLRCol NUMERIC(20,0),
TotalBookingAmountCol NUMERIC(20,2),
TotalDeliveryAmountCol NUMERIC(20,2),
GrandTotalAmountCol NUMERIC(20,2),
TotalQuantityCol NUMERIC(20,0),
TotalActualWeightCol NUMERIC(20,3),
TotalChargedWeightCol NUMERIC(20,3),
BookingMonthCol NUMERIC(2,0),
BookingYearCol NUMERIC(4,0),
schemaName TEXT,
TableNameCol TEXT
) returns numeric as
$$
DECLARE
nameid TEXT; -- unique id for tables concat(Year,Month21077, 21089,2,2018,8)
tablename TEXT; -- table name
indexname TEXT; -- index name
indexname1 TEXT; -- index name
sequencename TEXT;
createtablescr TEXT;
indexscr TEXT; -- index on booking date column
indexscr1 TEXT; -- index on booking date column
inserttablescr TEXT;
sequencescr TEXT;
selecttablescr TEXT;
bwtid integer;
begin
tablename = schemaName || '.' || TableNameCol;
indexname = TableNameCol || '_SourceBranchId_idx';
indexname1 = TableNameCol || '_DestinationBranchId_idx';
sequencename = TableNameCol || '_BranchWiseTurnOverId_seq';
sequencescr = 'CREATE SEQUENCE IF NOT EXISTS ' || sequencename || ' `enter code here`INCREMENT 1 START 1 CACHE 1';
createtablescr = 'CREATE TABLE IF NOT EXISTS ' || tablename || ' (
BranchWiseTurnOverId SERIAL PRIMARY KEY,
AccountGroupId NUMERIC(10,0) not null,
SourceBranchId NUMERIC(10,0) not null,
DestinationBranchId NUMERIC(10,0) not null,
WayBillTypeId NUMERIC(1,0) not null,
TotalLR NUMERIC(20,0) not null,
TotalBookingAmount NUMERIC(20,2) not null,
TotalDeliveryAmount NUMERIC(20,2) not null,
GrandTotalAmount NUMERIC(20,2) not null,
TotalQuantity NUMERIC(20,0) not null,
TotalActualWeight NUMERIC(20,3) not null,
TotalChargedWeight NUMERIC(20,3) not null,
BookingMonth NUMERIC(2,0) not null,
BookingYear NUMERIC(4,0) not null
);';
indexscr = 'CREATE INDEX IF NOT EXISTS ' || indexname || ' ON ' || tablename || ' (SourceBranchId);';
indexscr1 = 'CREATE INDEX IF NOT EXISTS ' || indexname1 || ' ON ' || tablename || ' (DestinationBranchId);';
selecttablescr = 'select branchwiseturnoverid INTO bwtid from '|| tablename || ' where AccountGroupId='|| AccountGroupIdCol ||' and SourceBranchId='|| SourceBranchIdCol ||' and DestinationBranchId='|| DestinationBranchIdCol ||' and WayBillTypeId='||WayBillTypeIdCol ||';';
inserttablescr = 'INSERT INTO ' || tablename || '(AccountGroupId, SourceBranchId, DestinationBranchId, WayBillTypeId, TotalLR, TotalBookingAmount,
TotalDeliveryAmount, GrandTotalAmount, TotalQuantity, TotalActualWeight, TotalChargedWeight, BookingMonth, BookingYear)
VALUES (' || AccountGroupIdCol || ',' || SourceBranchIdCol || ',' || DestinationBranchIdCol || ',' || WayBillTypeIdCol || ',' || TotalLRCol
|| ',' || TotalBookingAmountCol || ',' || TotalDeliveryAmountCol || ',' || GrandTotalAmountCol || ',' || TotalQuantityCol || ',' || TotalActualWeightCol
|| ',' || TotalChargedWeightCol || ',' || BookingMonthCol || ',' || BookingYearCol || ');';
EXECUTE sequencescr;
EXECUTE createtablescr;
EXECUTE indexscr;
EXECUTE indexscr1;
EXECUTE inserttablescr;
EXECUTE selecttablescr;
RAISE NOTICE USING MESSAGE = bwtid;
end;
$$
language 'plpgsql';
select dashboard.rspCreateAndInsertUpdateBranchWiseTurnOverTable(270,19168,19168,4,1,1000,1000,1000,5,50,50,6,2019,'dashboard','branchwiseturnover_2019_6');

To answer the direct question "How to print btwid", use the following syntax:
RAISE NOTICE '%', bwtid;

Related

Hello my fellow members, I'm new to postgresql. I want to drop table partition base on max date of field reg_dt in function as below

CREATE OR REPLACE FUNCTION cbsadm.create_part_tbl_cpvmm(cpvmm_custi_m text)
RETURNS void
LANGUAGE plpgsql
AS $function$
DECLARE
BEGIN
PERFORM pg_terminate_backend(pid) FROM pg_stat_activity WHERE pid IN
(SELECT pid FROM pg_catalog.pg_locks pl WHERE pl.relation in
(SELECT oid FROM pg_catalog.pg_class pc WHERE pc.relname = 'cpvmm_custi_m' AND pc.relowner in
(SELECT usesysid FROM pg_catalog.pg_user WHERE usename = 'cbsadm')));
EXECUTE 'CREATE TABLE ' || cpvmm_custi_m || '_' || to_char(now()+'1day','YYYYMMDD') || ' PARTITION OF ' || cpvmm_custi_m || ' FOR VALUES FROM (''' || to_char(now()+'1day','YYYYMMDD') ||''') TO (''' || to_char(now()+'2day','YYYYMMDD') || ''')
tablespace tbs_cbs;';
EXECUTE 'ALTER TABLE '|| cpvmm_custi_m || '_' || to_char(now()+'1day','YYYYMMDD') || ' ADD CONSTRAINT ' || cpvmm_custi_m || '_' || to_char(now()+'1day','YYYYMMDD') || '_un' || ' UNIQUE (reg_dt, card_no, card_sttl_acno);';
EXECUTE 'CREATE UNIQUE INDEX ix_'|| cpvmm_custi_m || '_' || to_char(now()+'1day','YYYYMMDD') || ' ON ' || cpvmm_custi_m || '_' || to_char(now()+'1day','YYYYMMDD') || ' (reg_dt, reg_seqno, cstno) tablespace tbs_cbs;';
EXECUTE 'ANALYZE '|| cpvmm_custi_m || '_' || to_char(now()+'1day','YYYYMMDD') ||';';
--execute 'DROP TABLE cpvmm_custi_m_' || to_char(now()+'-10day','YYYYMMDD')||' ;';
execute 'DROP TABLE cpvmm_custi_m_' || SELECT max(reg_dt) FROM cpvmm_custi_m +'-10day','YYYYMMDD')||' ;';
END;
$function$
;

DB2 dinamic search

I need to create search (like '%-99' or like '%NON%')---there for all tables in SYS in DB2 in all columns --below code
---please for help--this is test code---but I have DB2 Database Error: ERROR [42703] [IBM][DB2/LINUXX8664] SQL0206N "WHERE" is not valid in the context where it is used.
DECLARE GLOBAL TEMPORARY TABLE SESSION.TEMP_DINAMIC_TEST_SEARCH
(
TABSET VARCHAR(128)
, TABSCHEMA VARCHAR(128)
, TABNAME VARCHAR(128)
, COLUMN_NAME VARCHAR(128)
, ROW_COUNT BIGINT
)
ON COMMIT PRESERVE ROWS NOT LOGGED
;
BEGIN
FOR C AS CUR CURSOR WITH HOLD FOR
SELECT 'INSERT INTO SESSION.TEMP_DINAMIC_TEST_SEARCH SELECT '''
||''' ,''' || TABLE_SCHEM || ''',''' || TABLE_NAME || ''',''' || COLUMN_NAME || ''', COUNT( DISTINCT(' || COLUMN_NAME || ')) FROM '
|| '"' || TABLE_SCHEM || '"."' || TABLE_NAME|| '"' ||WHERE|| '"' || COLUMN_NAME || '"' || LIKE || '"' ||'%-99'|| '"' || AS S
FROM SYSIBM.SQLCOLUMNS
WHERE TABLE_SCHEM = 'DWD' AND TABLE_NAME LIKE 'T_X_%'
WITH UR
DO
EXECUTE IMMEDIATE C.S;
COMMIT;
END FOR;
END
Wrong expression is used.
Try this:
SELECT
'INSERT INTO SESSION.TEMP_DINAMIC_TEST_SEARCH SELECT '''
|| ''' ,''' || TABLE_SCHEM || ''',''' || TABLE_NAME || ''',''' || COLUMN_NAME || ''', COUNT( DISTINCT(' || COLUMN_NAME || ')) FROM '
|| '"' || TABLE_SCHEM || '"."' || TABLE_NAME|| '" WHERE "' || COLUMN_NAME || '" LIKE ''%-99''' AS S
FROM SYSIBM.SQLCOLUMNS
WHERE TABLE_SCHEM = 'DWD' AND TABLE_NAME LIKE 'T_X_%'
/*
AND
(
TYPE_NAME LIKE '%CHAR'
OR TYPE_NAME LIKE '%GRAPHIC'
OR TYPE_NAME LIKE '%CLOB'
)
*/
WITH UR
BTW,
It's worth to generate the INSERT SELECT statements for string columns only as shown in the commented out lines.
Try not to use tables in the SYSIBM schema in Db2 for LUW - they are not documented and their content may be changed with some new release / fixpack without any notice. Use SYSCAT views instead - the SYSCAT.COLUMNS view in your case.

Postgresql - Generating where not Exists condition dynamically for re-runnable insert script

I need to generate Insert script in postgres for all the tables in a database such that it can be run again without throwing any error.
The problem is, Only few tables have primary key while the rest have Unique index on different columns.
This is why I am not able to list out the columns on which unique index has been created.
The reason behind this is that the schema is automatically created through Magnolia.
Can anyone help me write the query which produces Insert statement including 'Where not Exists (Select 1 from table where column = value)' condition based on Primary Key/Unique columns?
You can use on conflict:
insert into t ( . . . )
values ( . . . )
on conflict do nothing;
This function returns Insert script for data and works well with tables on which primary constraint is not available.
I have modified the code that I found on another thread by adding the condition to it.
CREATE OR REPLACE FUNCTION public.generate_inserts(varSchema text, varTable text) RETURNS TABLE(resultado text) AS $$
DECLARE CODE TEXT;
BEGIN
CODE :=
(
SELECT
'SELECT ''INSERT INTO '
|| table_schema || '.'
|| table_name ||' ('
|| replace(replace(array_agg(column_name::text)::text,'{',''),'}','') || ') SELECT ''||'
|| replace(replace(replace(array_agg( 'quote_nullable(' || column_name::text || ')')::text,'{',''),'}',''),',',' || '','' || ')
|| ' || '' Where Not Exists (Select 1 From ' || table_name ||' Where 1 = 1 '
|| ''''
|| replace(replace(replace(replace(array_agg(' || '' and (' || column_name::text || ' = '' || quote_nullable(' || column_name::text || '),' || ' || '' or ' || column_name::text || ' is null)''')::text,'{',''),'}',''),'"',''),',','')
|| '|| '');'''
|| ' FROM ' || table_schema || '.' || table_name || ';'
FROM information_schema.columns c
WHERE table_schema = varSchema
AND table_name = varTable
GROUP BY table_schema, table_name);
RETURN QUERY
EXECUTE CODE;
END;
$$ LANGUAGE plpgsql;

postgresql insert dynamic query result into table in cursor

i have the following function, that generates dynamic query and at the end i want to insert result of dynamic query into table, but the error i get is `
ERROR: query has no destination for result data
HINT: If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT: PL/pgSQL function report_get_result(integer) line 46 at SQL statement
SQL statement "SELECT report_get_result(20150131)"
PL/pgSQL function inline_code_block line 2 at PERFORM
********** Error **********'
body of the function is:
CREATE OR REPLACE FUNCTION report_get_result (
datekey integer
) returns setof logic_result_rcd
AS
$body$
DECLARE
LogicID integer;
SheetName text;
Row_ID text;
Column_ID text;
FromTable text;
Operation text;
Amount text;
CriteriaType_1 text;
Function_1 text;
Criteria_1 text;
CriteriaType_2 text;
Function_2 text;
Criteria_2 text;
CriteriaType_3 text;
Function_3 text;
Criteria_3 text;
sql text;
INC Integer;
begin
DROP TABLE IF EXISTS loans;
create temp table loans as
select * from loan.vfact_state_principal where "DateKey" = datekey;
DECLARE cursor_logic REFCURSOR;
BEGIN
OPEN cursor_logic for execute ('SELECT "LogicID" FROM logic_table_rcd');
LOOP
FETCH cursor_logic INTO INC;
if not found then exit;
end if;
BEGIN
SELECT LogicID = "LogicID"
,SheetName = "SheetName"
,Row_ID = "Row_ID"::text
,Column_ID = "Column_ID"::text
,FromTable = "FromTable"
,Operation = "Operation"
,Amount = "Amount"
,CriteriaType_1 = CASE WHEN "CriteriaType_1" <> '' THEN ('WHERE
' || "CriteriaType_1") ELSE '' END
,Function_1 = CASE WHEN "Function_1" is null THEN 'Empty' ELSE
"Function_1" END
,Criteria_1 = CASE WHEN "Criteria_1" is null THEN 'Empty' ELSE
"Criteria_1" END
,CriteriaType_2 = CASE WHEN "CriteriaType_2" <> '' THEN ' AND '
|| "CriteriaType_2" ELSE '' END
,Function_2 = CASE WHEN "Function_2" is null THEN 'Empty' ELSE
"Function_2" END
,Criteria_2 = CASE WHEN "Criteria_2" is null THEN 'Empty' ELSE
"Criteria_2" END
,CriteriaType_3 = CASE WHEN "CriteriaType_3" <> '' THEN ' AND '
|| "CriteriaType_3" ELSE '' END
,Function_3 = CASE WHEN "Function_3" is null THEN 'Empty' ELSE
"Function_3" END
,Criteria_3 = CASE WHEN "Criteria_3" is null THEN 'Empty' ELSE
"Criteria_3" END
FROM public.logic_table_rcd WHERE "LogicID" = INC;
sql:= 'INSERT INTO public.logic_result_rcd SELECT ' || INC::text || ', 1, '
|| EntityID::text || ', ' || DateKey::text || ', ' || 'RCD' || ', ' ||
SheetName::text || ', ' || Row_ID::text || ', ' || Column_ID::text || ', '
|| Operation || '(' || Amount || ')' || ' FROM ' || FromTable
|| CriteriaType_1 || ' ' || Function_1 || ' ' || Criteria_1
|| CriteriaType_2 || ' ' || Function_2 || ' ' || Criteria_2
|| CriteriaType_3 || ' ' || Function_3 || ' ' || Criteria_3;
RETURN QUERY EXECUTE sql;
END;
END LOOP;
CLOSE cursor_logic;
END;
END;
$body$
LANGUAGE plpgsql;
assign value with VAR_NAME := ''; construct, here is an example:
t=# create function f(_i int) returns table (a int) as $$
declare sql text;
begin
sql := format('select %s',_i);
return query execute sql;
end;
$$
language plpgsql
;
CREATE FUNCTION
t=# select * From f(3);
a
---
3
(1 row)

postgresql cannot open INSERT query as cursor

i'm trying to generate dynamic query to insert results of dynamic select into table. my code is the following.
CREATE OR REPLACE FUNCTION public.report_get_result(
datekey integer)
RETURNS setof public.logic_result_rcd
LANGUAGE 'plpgsql'
COST 100
VOLATILE
AS $BODY$
DECLARE
LogicID text;
SheetName text;
Row_ID text;
Column_ID text;
FromTable text;
Operation text;
Amount text;
CriteriaType_1 text;
Function_1 text;
Criteria_1 text;
CriteriaType_2 text;
Function_2 text;
Criteria_2 text;
CriteriaType_3 text;
Function_3 text;
Criteria_3 text;
sql text;
INC Integer;
begin
DROP TABLE IF EXISTS loans;
create temp table loans as
select * from loan.vfact_state_principal where "DateKey" = datekey;
DECLARE cursor_logic REFCURSOR;
BEGIN
OPEN cursor_logic for SELECT "LogicID" FROM logic_table_rcd;
LOOP
FETCH cursor_logic INTO INC;
if not found then exit;
end if;
BEGIN
select into LogicID "LogicID" from public.logic_table_rcd WHERE
"LogicID" = 1;
select into SheetName "SheetName" from public.logic_table_rcd WHERE
"LogicID" = 1;
select into Row_ID "Row_ID" from public.logic_table_rcd WHERE "LogicID"
= 1;
select into Column_ID "Column_ID" from public.logic_table_rcd WHERE
"LogicID" = 1;
select into FromTable "FromTable" from public.logic_table_rcd WHERE
"LogicID" = 1;
select into Operation "Operation" from public.logic_table_rcd WHERE
"LogicID" = 1;
select into Amount "Amount" from public.logic_table_rcd WHERE "LogicID"
= 1;
select into CriteriaType_1 CASE WHEN "CriteriaType_1" <> '' OR
"CriteriaType_1" is not null THEN (' WHERE "' || "CriteriaType_1" || '"')
ELSE '' END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Function_1 CASE WHEN "Function_1" is null THEN '' ELSE
"Function_1" END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Criteria_1 CASE WHEN "Criteria_1" is null THEN '' ELSE
"Criteria_1" END from public.logic_table_rcd WHERE "LogicID" = 1;
select into CriteriaType_2 CASE WHEN "CriteriaType_2" <> '' OR
"CriteriaType_2" is not null THEN ' AND "' || "CriteriaType_2" || '"' ELSE
'' END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Function_2 CASE WHEN "Function_2" is null THEN '' ELSE
"Function_2" END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Criteria_2 CASE WHEN "Criteria_2" is null THEN '' ELSE
"Criteria_2" END from public.logic_table_rcd WHERE "LogicID" = 1;
select into CriteriaType_3 CASE WHEN "CriteriaType_3" <> '' or
"CriteriaType_3" is not null THEN ' AND "' || "CriteriaType_3" || '"' ELSE
'' END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Function_3 CASE WHEN "Function_3" is null THEN '' ELSE
"Function_3" END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Criteria_3 CASE WHEN "Criteria_3" is null THEN '' ELSE
"Criteria_3" END from public.logic_table_rcd WHERE "LogicID" = 1;
sql:= 'INSERT INTO public.logic_result_rc SELECT ' || INC::text || ', 1, '
|| DateKey::text || ', ''' || 'RCD' || ''', ''' || SheetName::text || ''', '
|| Row_ID::text || ', '
|| Column_ID::text || ', ' || Operation || '("' || Amount || '")' || ' FROM
' || FromTable
|| CriteriaType_1 || ' ' || Function_1 || ' ' || Criteria_1
|| CriteriaType_2 || ' ' || Function_2 || ' ' || Criteria_2
|| CriteriaType_3 || ' ' || Function_3 || ' ' || Criteria_3;
RETURN QUERY EXECUTE sql;
END;
END LOOP;
CLOSE cursor_logic;
END;
END;
$BODY$;
ALTER FUNCTION public.report_get_result(integer)
OWNER TO postgres;
But after execution I get the next error:
cannot open INSERT query as cursor
All variables are assigned correctly. may be insert must be somewhere else outside cursor? does INSERT INTO .... FETCH ALL statement exist?
INSERT by default doesn't return any rows, so there is nothing to fetch. You can fix this by appending your sql string with RETURNING *, with should return contents inserted into public.logic_result_rc.
So it would like this: RETURN QUERY EXECUTE concat(sql, ' RETURNING *');
Basic syntax is:
INSERT INTO table_name ( column_name [, ...] )
VALUES ( ) | query
RETURNING * --or list of columns, same syntax like for SELECT