How to approach data warehouse (PostgreSQL) documentation? - postgresql

We do have a small data warehouse in PostgreSQL database and I have to document all the tables.
I thought I can add a comment to every column and table and use pipe "|" separator to add more attributes. Then I can use information schema and array function to get documentation and use any reporting software to create desired output.
select
ordinal_position,
column_name,
data_type,
character_maximum_length,
numeric_precision,
numeric_scale,
is_nullable,
column_default,
(string_to_array(descr.description,'|'))[1] as cs_name,
(string_to_array(descr.description,'|'))[2] as cs_description,
(string_to_array(descr.description,'|'))[3] as en_name,
(string_to_array(descr.description,'|'))[4] as en_description,
(string_to_array(descr.description,'|'))[5] as other
from
information_schema.columns columns
join pg_catalog.pg_class klass on (columns.table_name = klass.relname and klass.relkind = 'r')
left join pg_catalog.pg_description descr on (descr.objoid = klass.oid and descr.objsubid = columns.ordinal_position)
where
columns.table_schema = 'data_warehouse'
order by
columns.ordinal_position;
It is a good idea or is there better approach?

Unless you must include descriptions of the system tables, I wouldn't try to shoehorn your descriptions into pg_catalog.pg_description. Make your own table. That way you get to keep the columns as columns, and not have to use clunky string functions.
Alternatively, consider adding specially formatted comments to your master schema file, along the lines of javadoc. Then write a tool to extract those comments and create a document. That way the comments stay close to the thing they're commenting, and you don't have to mess with the database at all to produce the report. For example:
--* Used for authentication.
create table users
(
--* standard Rails-friendly primary key. Also an example of
--* a long comment placed before the item, rather than on the
--* the same line.
id serial primary key,
name text not null, --* Real name (hopefully)
login text not null, --* Name used for authentication
...
);
Your documentation tool reads the file, looks for the --* comments, figures out what comments go with what things, and produces some kind of report, e.g.:
table users: Used for authentication
id: standard Rails-friendly primary key. Also an example of a
long comment placed before the item, rather than on the same
line.
name: Real name
login: Name used for authentication
You might note that with appropriate comments, the master schema file itself is a pretty good report in its own right, and that perhaps nothing else is needed.

If anyone interested, here is what I've used for initial load for my small documentation project. Documentation is in two tables, one for describing tables and one for describing columns and constraints. I appreciate any feedback.
/* -- Initial Load - Tables */
drop table dw_description_table cascade;
create table dw_description_table (
table_description_key serial primary key,
physical_full_name character varying,
physical_schema_name character varying,
physical_table_name character varying,
Table_Type character varying, -- Fact Dimension ETL Transformation
Logical_Name_CS character varying,
Description_CS character varying,
Logical_Name_EN character varying,
Description_EN character varying,
ToDo character varying,
Table_Load_Type character varying, --Manually TruncateLoad AddNewRows
Known_Exclusions character varying,
Table_Clover_Script character varying
);
insert into dw_description_table (physical_full_name, physical_schema_name, physical_table_name) (
select
table_schema || '.' || table_name as physical_full_name,
table_schema,
table_name
from
information_schema.tables
where
table_name like 'dw%' or table_name like 'etl%'
)
/* -- Initial Load - Columns */
CREATE TABLE dw_description_column (
column_description_key serial,
table_description_key bigint,
physical_full_name text,
physical_schema_name character varying,
physical_table_name character varying,
physical_column_name character varying,
ordinal_position character varying,
column_default character varying,
is_nullable character varying,
data_type character varying,
logical_name_cs character varying,
description_cs character varying,
logical_name_en character varying,
description_en character varying,
derived_rule character varying,
todo character varying,
pk_name character varying,
fk_name character varying,
foreign_table_name character varying,
foreign_column_name character varying,
is_primary_key boolean,
is_foreign_key boolean,
CONSTRAINT dw_description_column_pkey PRIMARY KEY (column_description_key ),
CONSTRAINT fk_dw_description_table_key FOREIGN KEY (table_description_key)
REFERENCES dw_description_table (table_description_key) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);
insert into dw_description_column (
table_description_key ,
physical_full_name ,
physical_schema_name ,
physical_table_name ,
physical_column_name ,
ordinal_position ,
column_default ,
is_nullable ,
data_type ,
logical_name_cs ,
description_cs ,
logical_name_en ,
description_en ,
derived_rule ,
todo ,
pk_name ,
fk_name ,
foreign_table_name ,
foreign_column_name ,
is_primary_key ,
is_foreign_key )
(
with
dw_constraints as (
SELECT
tc.constraint_name,
tc.constraint_schema || '.' || tc.table_name || '.' || kcu.column_name as physical_full_name,
tc.constraint_schema,
tc.table_name,
kcu.column_name,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name,
TC.constraint_type
FROM
information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu ON (tc.constraint_name = kcu.constraint_name and tc.table_name = kcu.table_name)
JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name
WHERE
constraint_type in ('PRIMARY KEY','FOREIGN KEY')
AND tc.constraint_schema = 'bizdata'
and (tc.table_name like 'dw%' or tc.table_name like 'etl%')
group by
tc.constraint_name,
tc.constraint_schema,
tc.table_name,
kcu.column_name,
ccu.table_name ,
ccu.column_name,
TC.constraint_type
)
select
dwdt.table_description_key,
col.table_schema || '.' || col.table_name || '.' || col.column_name as physical_full_name,
col.table_schema as physical_schema_name,
col.table_name as physical_table_name,
col.column_name as physical_column_name,
col.ordinal_position,
col.column_default,
col.is_nullable,
col.data_type,
null as Logical_Name_CS ,
null as Description_CS ,
null as Logical_Name_EN,
null as Description_EN ,
null as Derived_Rule ,
null as ToDo,
dwc1.constraint_name pk_name,
dwc2.constraint_name as fk_name,
dwc2.foreign_table_name,
dwc2.foreign_column_name,
case when dwc1.constraint_name is not null then true else false end as is_primary_key,
case when dwc2.constraint_name is not null then true else false end as foreign_key
from
information_schema.columns col
join dw_description_table dwdt on (col.table_schema || '.' || col.table_name = dwdt.physical_full_name )
left join dw_constraints dwc1 on ((col.table_schema || '.' || col.table_name || '.' || col.column_name) = dwc1.physical_full_name and dwc1.constraint_type = 'PRIMARY KEY')
left join dw_constraints dwc2 on ((col.table_schema || '.' || col.table_name || '.' || col.column_name) = dwc2.physical_full_name and dwc2.constraint_type = 'FOREIGN KEY')
where
col.table_name like 'dw%' or col.table_name like 'etl%'
)

Related

SQL Pivot to PGSQL crosstab-->Data not matching

Have following code in SQL,Please help.Iam Stuck on this pivot.
SELECT #QStr = COALESCE(#QStr,'')+',['+ColtoRow+']' FROM(
SELECT DISTINCT PeriodEndDatDisp ColtoRow
from #Esti
)A GROUP BY ColtoRow order by ColtoRow
SELECT #QStr=STUFF(#QStr,1,1,'')
SELECT #Query = '
SELECT GroupID,GroupName,Mes_Type,ParentProductId,ParentProductName,Meas_Nam,fn_ProperCase(SegmentType) SegmentType,SegMeasType,
CurrencyId,ValType,IsPerSha,Mes_Order,ShowSegData,' +#QStr+ '
FROM (
SELECT GroupID,GroupName,Mes_Type,ParentProductId,ParentProductName,Meas_Nam,SegmentType,SegMeasType,EstValue,CurrencyId,ValType,Mes_Order,
ShowSegData,IsPerSha,
PeriodEndDatDisp ColtoRow
FROM #Esti
) AS Src_Table PIVOT
(
MAX(EstValue) FOR ColtoRow IN (' +#QStr+' )
) AS PivotTable ORDER BY GroupID,Mes_Order,Meas_Nam,SegmentType,SegMeasType,ValType;'
EXECUTE #Query;
the Equivalent code in PGSQL is
SELECT string_agg(DISTINCT PeriodEndDateDisplay,',') ColtoRow
from t$Estimate
--o/p FY-2015,FY-2016,Q1-2015,Q1-2016,Q2-2015,Q2-2016,Q3-2015,Q3-2016,Q4-2015,Q4-2016
SELECT *
FROM crosstab(
'SELECT
GroupID,GroupName,MeasureType,ParentProductId,ParentProductName,
MeasureName,est.fn_ProperCase(SegmentType) SegmentType,SegmentMeasureType, EstValue
,CurrencyId,ValType,MeasureOrder,IsPerShare,ShowSegmentData
FROM est.t$estimate'
, $$ SELECT unnest('{Q2-2016,Q4-2015,Q1-2015,Q3-2016,Q4-2016,FY-2016,Q1-2016,Q3-2015,Q2-2015,FY-2015}'::text[])$$
) AS ct ( groupid integer, groupname character varying(500) , measuretype character varying(100) , parentproductid character varying(100) ,
parentproductname character varying(200), measurename character varying(200) , segmenttype character varying ,
segmentmeasuretype character varying(20), EstValue text, currencyid character varying(3), valtype integer,
measureorder integer, ispershare boolean,FY2016 text,
Q1-2015 text,Q1-2016 text,Q2-2015 text,Q2-2016 text,Q3-2015 text,Q3-2016 text,Q4-2015 text,Q4-2016 text);
Problem encountered:
Only 1 row is populated and the quarter values are all null. In MSSQL its 25 rows
hyphen(-)creating issue in Quater time period value eg:Q4-2015

Concatenating two integer columns works in isolation, but not in a function

Related to my question yesterday which was answered by #a_horse_with_no_name.
The following query works..
SELECT
CAST(FC.Life1monthofbirth AS VARCHAR(2)) || '/' || CAST(FC.Life1yearofbirth AS VARCHAR(4))
FROM
public.factclient FC;
...but when I have essentially the same code in a function...
,CAST(FC.Life1monthofbirth AS VARCHAR(2)) || '/' || CAST(FC.Life1yearofbirth AS VARCHAR(4)) AS Life1DOB
I get this error:
ERROR: operator is not unique: unknown / unknown
LINE 25: ,CAST(FC.Life1monthofbirth AS VARCHAR(2)) || '/' || CAST...
^
HINT: Could not choose a best candidate operator. You might need to add explicit type casts.
I don't understand why the first scenario works, but the second one doesn't. I'm using Postgres version 12 and writing my queries using pgAdmin 4.13
I have added the complete function code below. Apologies if it is not very readable.
CREATE OR REPLACE FUNCTION public.postgres_termpositionrawdata_ver2(
p_provider character varying,
p_date date,
p_correlationid character DEFAULT NULL::bpchar,
p_type character varying DEFAULT NULL::character varying,
p_productexclusionset character varying DEFAULT 'LevelTermPosition'::character varying,
p_ctmoptions character varying DEFAULT 'WOM'::character varying,
p_test character varying DEFAULT 'No'::character varying,
p_testaccountlogon character varying DEFAULT NULL::character varying,
p_averagetopx integer DEFAULT 5,
p_filterquote integer DEFAULT NULL::integer,
p_includeduplicatequotes character varying DEFAULT 'Yes'::character varying,
p_ignoreglobalpermissions character varying DEFAULT 'Yes'::character varying,
p_ignoredefaultproductexclusions character varying DEFAULT 'No'::character varying,
p_ignorelowstartresponseindicator character varying DEFAULT 'No'::character varying,
p_ignorevariableresponseindicator character varying DEFAULT 'No'::character varying)
RETURNS void
LANGUAGE 'plpgsql'
COST 100
VOLATILE
AS $BODY$
--DECLARE CONSTANTS
DECLARE
--DECLARE VARIABLES
v_Status varchar(10) = 'Success';BEGIN
-- assume success
-- SET CorrelationID
IF p_CorrelationId IS NULL THEN p_CorrelationId := public.swf_newid();
END IF;
DROP TABLE IF EXISTS FilteredRequests;
DROP TABLE IF EXISTS FilteredResponses;
DROP TABLE IF EXISTS Ranks;
CREATE TEMP TABLE FilteredRequests AS
SELECT * FROM public.dblink('srv_exchangemart',
'SELECT
FRQ.QuoteID
,DEO.Name AS OrganisationName
,DEO.Postcode AS OrganisationPostcode
,DEO.FRN AS OrganisationFRN
,DDQ.Date AS RequestDate
,DLB.LifeBasis
,DDC.Date AS CommencementDate
,CASE
WHEN FRQ.Term <> 0
THEN CAST (FRQ.Term AS Varchar(5)) || "Years"
WHEN FRQ.TermToAge <> 0
THEN "To Age " || CAST(FRQ.TermToAge AS Varchar(5))
ELSE "Unknown"
END AS PolicyTerm
,DQF.QuotationFor
,LCR.LifeCriticalIllnessRiskRelationship
,TDP.TotalPermanentDisabilityCover
,CB.CommissionBasis
,DCT.CommissionType
,DG1.Gender AS Life1Gender
,CONCAT_WS('|', FC.Life1MonthOfBirth, FC.Life1YearOfBirth) AS Life1DOB
,FC.Life1Age AS Life1Age
,FC.Life1QuarterlyAge
,DS1.Smoker AS Life1Smoker
,DO1.Occupation AS Life1Occupation
,DG2.Gender AS Life2Gender
,CONCAT_WS('|', FC.Life2MonthOfBirth, FC.Life2YearOfBirth) AS Life2DOB
,FC.Life2Age AS Life2Age
,FC.Life2QuarterlyAge
,DS2.Smoker AS Life2Smoker
,DO2.Occupation AS Life2Occupation
,DEP.PanelId
FROM ExchangeMart.dbo.FactRequest FRQ
INNER JOIN ExchangeMart.dbo.dimExchangeOrganisation DEO ON FRQ.ExchangeOrganisationID = DEO.ExchangeOrganisationId
INNER JOIN ExchangeMart.dbo.dimExchangeUser DEU ON FRQ.ExchangeUserId = DEU.ExchangeUserId
INNER JOIN ExchangeMart.dbo.dimLifeBasis DLB ON FRQ.LifeBasisId = DLB.LifeBasisID
INNER JOIN ExchangeMart.dbo.dimTotalPermanentDisabilityCover TDP ON FRQ.TotalPermanentDisabilityCoverId = TDP.TotalPermanentDisabilityCoverID
INNER JOIN ExchangeMart.dbo.dimDate DDQ ON FRQ.QuotationDateID = DDQ.DateID
INNER JOIN ExchangeMart.dbo.dimDate DDC ON FRQ.CommencementDateID = DDC.DateID
INNER JOIN ExchangeMart.dbo.dimExchangePanel DEP ON FRQ.ExchangePanelId = DEP.ExchangePanelId
INNER JOIN ExchangeMart.dbo.dimCommissionBasis CB ON FRQ.CommissionBasisId = CB.CommissionBasisId
INNER JOIN ExchangeMart.dbo.dimCommissionType DCT ON FRQ.CommissionTypeId = DCT.CommissionTypeId
INNER JOIN ExchangeMart.dbo.factClient FC ON FRQ.QuoteID = FC.QuoteID
INNER JOIN ExchangeMart.dbo.dimLifeCriticalIllnessRiskRelationship LCR ON FRQ.LifeCriticalIllnessRiskRelationshipId = LCR.LifeCriticalIllnessRiskRelationshipId
INNER JOIN ExchangeMart.dbo.dimQuotationFor DQF ON FRQ.QuotationForId = DQF.QuotationForId
INNER JOIN ExchangeMart.dbo.dimKeyPerson DKP ON FRQ.KeyPersonId = DKP.KeyPersonId
INNER JOIN ExchangeMart.dbo.dimBenefitBasis DBB ON FRQ.BenefitBasisId = DBB.BenefitBasisId
INNER JOIN ExchangeMart.dbo.dimIntegrator DI ON FRQ.ExchangeIntegratorId = DI.ExchangeIntegratorId
INNER JOIN ExchangeMart.dbo.dimGender DG1 ON FC.Life1GenderID = DG1.GenderID
INNER JOIN ExchangeMart.dbo.dimGender DG2 ON FC.Life2GenderID = DG2.GenderID
INNER JOIN ExchangeMart.dbo.dimSmoker DS1 ON FC.Life1SmokerID = DS1.SmokerID
INNER JOIN ExchangeMart.dbo.dimSmoker DS2 ON FC.Life2SmokerID = DS2.SmokerID
INNER JOIN ExchangeMart.dbo.dimOccupation DO1 ON FC.Life1OccupationId = DO1.OccupationID
INNER JOIN ExchangeMart.dbo.dimOccupation DO2 ON FC.Life2OccupationId = DO2.OccupationID
WHERE DDQ.Date = p_Date
AND FRQ.ProductTypeId IN (53) -- TERM ONLY
AND KeyPerson = "No" -- Not Business
AND DBB.BenefitBasis = "Benefit Led" -- ONLY RETURNS BENEFIT LED QUOTES
AND (DEU.LogonId = p_TestAccountLogon OR (p_TestAccountLogon IS NULL
AND DI.DefaultExclusion = "No"
AND DEO.DefaultExclusion = "No"))
AND ( (p_IncludeDuplicateQuotes = "No" AND FRQ.IsDuplicateQuote = 0)
OR (p_IncludeDuplicateQuotes = "Yes"))
AND (FRQ.QuoteId = p_FilterQuote OR p_FilterQuote IS NULL)
AND ( (p_CTMOptions = "CTM Only" AND DEU.LogonId = "CTM000")
OR (p_CTMOptions = "Exclude CTM" AND DEU.LogonId != "CTM000")
OR (p_CTMOptions = "WOM")
)
')
AS DATA(QuoteID INTEGER, OrganisationName character varying, OrganisationPostcode character varying, OrganisationFRN character varying
, RequestDate date, LifeBasis character varying, CommencementDate date, PolicyTerm character varying, QuotationFor character varying
, LifeCriticalIllnessRiskRelationship character varying, TotalPermanentDisabilityCover character varying, COmmissionBasis character varying
, CommisionType character varying, Life1Gender character varying, Life1DOB character varying, Life1Age INTEGER, Life1QuarterlyAge numeric(12,2)
, Life1Smoker character varying, Life1Occupation character varying, Life2Gender character varying, Life2Age INTEGER
, Life2QuarterlyAge numeric(12,2), Life2Smoker character varying, Life2Occupation character varying);
SELECT * FROM FilteredRequests;
END;
$BODY$;
The error message says you are dividing two items, while your intent is to concatenate them.
It implies that you are running this query using EXECUTE, so the query text is build then run, and the result of the concatenation you wrote is executed, leading to the unexpected division.
You would have to transform the query so that the result of the concatenation - which will be executed - is the desired concatenation. Something like:
EXECUTE 'select fieldA' || '||''/''||' || 'fieldB from myTable';

Order by not working on PostgreSQL function

I am new to PostgreSQl and I have created one function which is mentioned below. What I want that when I am running SELECT query in query tool then it working fine and giving result what I want but when I am executing below function then order by not working. Stageno is a "character varying". How can I fix that ?
-- FUNCTION: public.getauditquestion(integer)
-- DROP FUNCTION public.getauditquestion(integer);
CREATE OR REPLACE FUNCTION public.getauditquestion(
auditid integer)
RETURNS TABLE(audit_ques_id bigint, audit_id integer, activityname character varying, question_id integer, question character varying, answer_type integer, answer_lov integer, answertypename character varying, ok_notok integer, oknotokname character varying, answer_min character varying, answer_max character varying, uom integer, uomname character varying, correct_ans integer, created_by integer, created_date timestamp without time zone, stage character varying, stageno character varying, description character varying, severity character varying, who character varying, how character varying, "when" character varying, "where" character varying)
LANGUAGE 'plpgsql'
COST 100.0
VOLATILE
ROWS 1000.0
AS $function$
BEGIN
Return Query
select am.audit_ques_id, am.audit_id ,ddl3.dd_value AS activityName , am.question_id ,
ddl2.question AS question, am.answer_type, am.answer_lov, ddl4.dd_value AS answerTypeName, am.ok_notok ,
ddl5.dd_value AS okNotOkName, am.answer_min, am.answer_max, am.uom, ddl13.dd_value AS uomname, am.correct_ans,
am.created_by, am.created_date,ddl6.dd_value AS stage, ddl14.dd_value AS stage_no, ddl7.description, ddl8.dd_value AS severity,
ddl9.dd_value AS who , ddl10.dd_value AS how , ddl11.dd_value AS "when" , ddl12.dd_value AS "where"
from audit_ques_detail am left join audit_master ddl1 on ddl1.audit_id=am.audit_id
left join dd_type_details ddl3 on ddl3.dd_id=ddl1.activity_id
left join question_master ddl2 on ddl2.question_id=am.question_id
left join dd_type_details ddl4 on ddl4.dd_id = am.answer_type
left join dd_type_details ddl5 on ddl5.dd_id = am.ok_notok
left join dd_type_details ddl6 on ddl6.dd_id = ddl2.stage
left join question_master ddl7 on ddl7.question_id = am.question_id
left join dd_type_details ddl8 on ddl8.dd_id = ddl2.severity
left join dd_type_details ddl9 on ddl9.dd_id = ddl2.who
left join dd_type_details ddl10 on ddl10.dd_id = ddl2.how
left join dd_type_details ddl11 on ddl11.dd_id = ddl2.when
left join dd_type_details ddl12 on ddl12.dd_id = ddl2.where
left join dd_type_details ddl13 on ddl13.dd_id = am.uom
left join dd_type_details ddl14 on ddl14.dd_id = am.stage_no
where am.audit_id = auditid and am.isActive = 1 ORDER BY cast(ddl14.dd_value AS Integer);
END;
$function$;
ALTER FUNCTION public.getauditquestion(integer)
OWNER TO postgres;

Dynamic RETURN EXECUTE QUERY with ILIKE in Postgresql

The search filter in the function below doesn't seem to work. If I don't provide a search parameter, it works, otherwise I get no recordset back. I'm assuming I am making a mess of the single-quoting and ILIKE, but not sure how to re-write this properly. Suggestions?
CREATE OR REPLACE FUNCTION get_operator_basic_by_operator(
_operator_id UUID DEFAULT NULL,
_search TEXT DEFAULT NULL,
_page_number INTEGER DEFAULT 1,
_page_size INTEGER DEFAULT 10,
_sort_col TEXT DEFAULT 'username',
_sort_dir TEXT DEFAULT 'asc',
_include_deleted BOOLEAN DEFAULT FALSE
)
RETURNS TABLE (
id UUID,
party_id UUID,
party_name TEXT,
username VARCHAR(32),
profile_picture_uri VARCHAR(512),
first_name VARCHAR(64),
last_name VARCHAR(64),
street VARCHAR(128),
specifier VARCHAR(128),
city VARCHAR(64),
state VARCHAR(2),
zipcode VARCHAR(9),
primary_email CITEXT,
primary_phone VARCHAR(10),
secondary_email CITEXT,
secondary_phone VARCHAR(10),
last_login TIMESTAMP WITH TIME ZONE,
created TIMESTAMP WITH TIME ZONE,
deleted TIMESTAMP WITH TIME ZONE
)
AS $$
DECLARE
_offset BIGINT;
BEGIN
IF (_page_number < 1 OR _page_number IS NULL) THEN
RAISE EXCEPTION '_page_number cannot be null or less than 1.';
END IF;
IF (_page_size < 1 OR _page_size IS NULL) THEN
RAISE EXCEPTION '_page_size cannot be null or less than 1.';
END IF;
IF (_sort_dir <> 'asc' AND _sort_dir <> 'desc') THEN
RAISE EXCEPTION '_sort_dir must be "asc" or "desc".';
END IF;
_offset := (_page_size * (_page_number-1));
RETURN QUERY EXECUTE '
SELECT
o.id,
p.id,
p.party_name,
o.username,
o.profile_picture_uri,
o.first_name,
o.last_name,
o.street,
o.specifier,
o.city,
o.state,
o.zipcode,
o.primary_email,
o.primary_phone,
o.secondary_email,
o.secondary_phone,
o.last_login,
o.created,
o.deleted
FROM
operator o
LEFT JOIN
party p ON o.party_id = p.id
WHERE ( -- include all or only those active, based on _include_deleted
$1 OR o.deleted > statement_timestamp()
)
AND o.party_id IN ( -- limit to operators in same party
SELECT oi.party_id FROM operator oi WHERE oi.id = $2
)
AND ( -- use optional search filter
$3 IS NULL
OR
o.username ILIKE ''%$3%''
OR
o.first_name ILIKE ''%$3%''
OR
o.last_name ILIKE ''%$3%''
OR
o.primary_email ILIKE ''%$3%''
)
ORDER BY ' || quote_ident(_sort_col) || ' ' || _sort_dir || '
LIMIT
$4
OFFSET
$5'
USING _include_deleted, _operator_id, _search, _page_size, _offset;
END;
The parameter is inserted as a text with quotes, so you should use it this way:
...
o.username ILIKE concat(''%'', $3, ''%'')
...
Personally I would use format() and dollar-quotes.
Strings handles as is, you should to pass ready to use values:
EXECUTE '... o.username ILIKE $3 ...' using ..., '%' || _search || '%', ...

Update column using dblink

I am using below reference to update 2 columns (customer name, service) at table cust_eq_memory_dy.
loopback at table msrouterlistfinal2 will match address at cust_eq_memory_dy.
Can someone help me on this as I got the syntax error at or near "FROM"?
Update between 2 databases using dblink not working
UPDATE cust_eq_memory_dy B
SET customername = A.customername
WHERE B.ipaddress = A.loopbackip
FROM (
SELECT *
FROM DBLINK ( 'host= 10.X.80.160 user=123 password=123 dbname=postgres',
'select customername, serviceid, loopbackip FROM msrouterlistfinal2 ')
as temp (
customername character varying (100),
serviceid character varying (50),
loopbackip character varying (30) )
)A
if you are using postgres I highly recommend you to use the WITH sentence.
WITH A as ( SELECT * FROM DBLINK ( 'host= 10.X.80.160 user=123 password=123 dbname=postgres', 'select customername, serviceid, loopbackip FROM msrouterlistfinal2 ') as temp ( customername character varying (100), serviceid character varying (50), loopbackip character varying (30) ) )
UPDATE cust_eq_memory_dy B SET customername = (SELECT A.customername FROM A WHERE B.ipaddress = A.loopbackip);
Check this link for more information.
https://www.postgresql.org/docs/8.4/static/queries-with.html