POSTGRESQL PG/PGSQL- Function with params - postgresql

I'm having some issues making a function in Postgresql, I have this function:
CREATE OR REPLACE FUNCTION public.isp_ticket(_cr integer, _grupo character varying(255), _numero integer, _descripcion text, _resumen character varying(255), _fechaaper timestamp with time zone, _fechacierr timestamp with time zone, _tipo smallint, _apellidousuarioafectado character varying(255), _apellidosolicitante character varying(255), _tenant character varying(255), _metodoreportado character varying(100), _prioridad smallint, _sla character varying(255), _categoria character varying(255), _estado character varying(255), _herramienta_id integer, _asignado character varying(255), _nombresolicitante character varying(255), _nombreusuarioafectado character varying(255))
RETURNS void AS $$
BEGIN
CASE
WHEN _asignado = '' AND _close_date = '' AND _sla = ''
THEN INSERT INTO public.website_ticket(cr, grupo, numero, descripcion, resumen, fechaaper, tipo, apellidousuarioafectado, apellidosolicitante, tenant, metodoreportado, prioridad, categoria, estado, herramienta_id, nombresolicitante, nombreusuarioafectado) VALUES (_cr, _grupo, _numero, _descripcion, _resumen, _fechaaper, _tipo, _apellidousuarioafectado, _apellidosolicitante, _tenant, _metodoreportado, _prioridad, _categoria, estado, _herramienta_id, _nombresolicitante, _nombreusuarioafectado);
WHEN _asignado = '' AND _close_date = ''
THEN INSERT INTO public.website_ticket(cr, grupo, numero, descripcion, resumen, fechaaper, tipo, apellidousuarioafectado, apellidosolicitante, tenant, metodoreportado, prioridad, sla, categoria, estado, herramienta_id, nombresolicitante, nombreusuarioafectado) VALUES (_cr, _grupo, _numero, _descripcion, _resumen, _fechaaper, _tipo, _apellidousuarioafectado, _apellidosolicitante, _tenant, _metodoreportado, _prioridad, _sla, _categoria, _estado, _herramienta_id, _nombresolicitante, _nombreusuarioafectado);
WHEN new_close_date = ''
THEN INSERT INTO public.website_ticket(cr, grupo, numero, descripcion, resumen, fechaaper, tipo, apellidousuarioafectado, apellidosolicitante, tenant, metodoreportado, prioridad, sla, categoria, estado, herramienta_id, asignado,nombresolicitante, nombreusuarioafectado)
VALUES (_cr, _grupo, _numero, _descripcion, _resumen, _fechaaper, _tipo, _apellidousuarioafectado, _apellidosolicitante, _tenant, _metodoreportado, _prioridad, _sla, _categoria, _estado, _herramienta_id, _asignado, _nombresolicitante, _nombreusuarioafectado);
ELSE
UPDATE public.website_ticket SET fechacierr = _fechacierr WHERE numero = _numero;
END CASE;
END;
$$ LANGUAGE plpgsql;
and when I try to use the function doing this:
SELECT public.isp_ticket(924266,
'EUS_Zona V Region',
512294,
'Nombre: Gisselle Espinoza Contreras\nCorreo: gespinoza#bancoripley.cl
\nAnexo: 6221\nUbicación: Valparaiso\nPais: Chile\nMotivo: Usuario indica
que su computador se apagó repentinamente. Se pudo entrar a windows después
de un buen rato, pero no puede ingresar a las aplicaciones que se conecten a
red.\n\nDirección: Plaza Victoria 1646 - Piso 1 - Banco',
'Valparaiso // Computador con problemas de conexión.',
'2018-01-23 15:17:51',
'',
1,
'Espinoza Contreras',
'Espinoza Contreras',
'Ripley',
'Telephone',
3,
'',
'Ripley.Hardware.Desktop.Falla',
'Open',
1,
'',
'Gissel Rose Marie',
'Gissel Rose Marie')
I tried to CAST every value, and it didn't work either, always appear the same error:
ERROR: no existe la función public.isp_ticket(integer, character varying, integer, text, character varying, timestamp with time zone, unknown, integer, character varying, character varying, character varying, character varying, integer, unknown, character varying, character varying, integer, unknown, character varying, character varying)
LINE 1: SELECT public.isp_ticket(
^
SQL state: 42883
Character: 8
I need help how can I fix it?
Forwards thanks everyone!!!

Parameter #7, _fechacierr should be timestamp with time zone. You can not pass '', change it to null (and cast it to timestamp with time zone) if you need empty value.
And it's worth to read how PostgreSQL finds specific function to call, especially:
If any input arguments are unknown, check the type categories accepted
at those argument positions by the remaining candidates. At each
position, select the string category if any candidate accepts that
category. (This bias towards string is appropriate since an
unknown-type literal looks like a string.) Otherwise, if all the
remaining candidates accept the same type category, select that
category; otherwise fail because the correct choice cannot be deduced
without more clues. Now discard candidates that do not accept the
selected type category. Furthermore, if any candidate accepts a
preferred type in that category, discard candidates that accept
non-preferred types for that argument. Keep all candidates if none
survive these tests. If only one candidate remains, use it; else
continue to the next step.

Related

Procedure is not executing. Error message is ambiguous

I am trying to execute a stored procedure in postgresql.
create procedure add_future_tickers_intl(
v_ticker_serial numeric,
v_source_id character varying DEFAULT NULL::character varying,
v_ticker_id character varying DEFAULT NULL::character varying,
v_sector_id character varying DEFAULT NULL::character varying,
v_status character,
v_market_md character varying DEFAULT NULL::character varying,
v_source_ticker_id character varying DEFAULT NULL::character varying,
v_instrument_type_id numeric DEFAULT NULL::numeric,
v_currency_id character varying DEFAULT NULL::character varying,
v_country_code character varying DEFAULT NULL::character varying,
v_decimal_places numeric DEFAULT NULL::numeric,
v_decimal_correction_factor numeric DEFAULT NULL::numeric,
v_parent_ticker_id character varying DEFAULT NULL::character varying,
v_parent_source_id character varying DEFAULT NULL::character varying,
v_isin_code character varying DEFAULT NULL::character varying,
v_lot_size numeric DEFAULT NULL::numeric, v_unit character varying DEFAULT NULL::character varying,
v_display_ticker character varying DEFAULT NULL::character varying,
v_last_updated_on timestamp without time zone DEFAULT NULL::timestamp without time zone,
v_comments character varying DEFAULT NULL::character varying,
v_listing_date timestamp without time zone,
v_listing_status numeric DEFAULT NULL::numeric,
v_stock_published_status character varying DEFAULT NULL::character varying,
v_max_stocks numeric DEFAULT NULL::numeric,
v_is_settlement_to numeric DEFAULT NULL::numeric,
v_is_main_stock numeric DEFAULT NULL::numeric,
v_last_updated_time timestamp without time zone DEFAULT NULL::timestamp without time zone,
v_currency_correction_factor numeric,
v_global_sector_id character varying DEFAULT NULL::character varying,
v_dfn_sector character varying DEFAULT NULL::character varying,
v_category character varying DEFAULT NULL::character varying,
v_index_type numeric DEFAULT NULL::numeric,
v_source_source_id character varying DEFAULT NULL::character varying,
v_wkn character varying DEFAULT NULL::character varying,
v_reuter_ssymbol character varying DEFAULT NULL::character varying,
v_bloomberg_symbol character varying DEFAULT NULL::character varying,
v_symbol_status character varying DEFAULT NULL::character varying,
v_eligibility_id numeric DEFAULT NULL::numeric,
v_sharia_compliant numeric DEFAULT NULL::numeric,
v_symbolcode character varying DEFAULT NULL::character varying,
v_exchange_status numeric,
v_assct_ticker_serial numeric DEFAULT NULL::numeric,
v_ticker_assctn_date timestamp without time zone DEFAULT NULL::timestamp without time zone,
v_first_trading timestamp without time zone DEFAULT NULL::timestamp without time zone,
v_idx_main_source_id character varying DEFAULT NULL::character varying,
v_otc numeric DEFAULT NULL::numeric,
v_clearance_duration character varying DEFAULT NULL::character varying,
v_lasttradabledate timestamp without time zone DEFAULT NULL::timestamp without time zone,
v_all_descriptions character varying,
v_maturity_date timestamp without time zone DEFAULT NULL::timestamp without time zone,
v_cusip character varying DEFAULT NULL::character varying,
v_is_desc_updated numeric DEFAULT 1,
v_bbgid character varying DEFAULT NULL::character varying,
v_bbgid_composite character varying DEFAULT NULL::character varying,
v_dec_lot_size numeric DEFAULT NULL::numeric,
v_ticker_classification numeric DEFAULT NULL::numeric,
v_display_decimal_places numeric DEFAULT NULL::numeric,
v_ticksize numeric DEFAULT NULL::numeric,
v_sharesoutstanding numeric DEFAULT NULL::numeric,
v_ticker_class_l1 numeric DEFAULT NULL::numeric,
v_ticker_class_l2 numeric DEFAULT NULL::numeric,
v_ticker_class_l3 numeric DEFAULT NULL::numeric,
v_tick_size_string character varying DEFAULT NULL::character varying,
v_mic_code character varying DEFAULT NULL::character varying,
v_min_size numeric DEFAULT NULL::numeric,
v_max_long_size numeric DEFAULT NULL::numeric,
v_max_short_size numeric DEFAULT NULL::numeric,
v_margin_percentage numeric DEFAULT NULL::numeric,
v_display_symbol character varying DEFAULT NULL::character varying,
v_sedol character varying DEFAULT NULL::character varying,
v_stamp_duty_flag numeric DEFAULT NULL::numeric,
v_margin_initial_cash numeric DEFAULT NULL::numeric,
v_margin_maintenance_cash numeric DEFAULT NULL::numeric
)
language edbspl
as
$$
v_is_manually_modified number(1);
begin
begin -- insert block
add_ticker_intl (
v_ticker_serial,
v_source_id,
v_ticker_id,
v_sector_id,
v_status,
v_market_md,
v_source_ticker_id,
v_instrument_type_id,
v_currency_id,
v_country_code,
v_decimal_places,
v_decimal_correction_factor,
v_parent_ticker_id,
v_parent_source_id,
v_isin_code,
v_lot_size,
v_unit,
v_display_ticker,
v_last_updated_on,
v_comments,
v_listing_date,
v_listing_status,
v_stock_published_status,
v_max_stocks,
v_is_settlement_to,
v_is_main_stock,
v_last_updated_time,
v_currency_correction_factor,
v_global_sector_id,
v_dfn_sector,
v_category,
v_index_type,
v_source_source_id,
v_wkn,
v_reuter_ssymbol,
v_bloomberg_symbol,
v_symbol_status,
v_eligibility_id,
v_sharia_compliant,
v_symbolcode,
v_exchange_status,
v_assct_ticker_serial,
v_ticker_assctn_date,
v_first_trading,
v_idx_main_source_id,
v_otc,
v_clearance_duration,
v_lasttradabledate,
v_all_descriptions,
v_cusip,
v_is_desc_updated,
v_bbgid,
v_bbgid_composite,
v_dec_lot_size,
v_ticker_classification,
v_display_decimal_places,
null,
null,
v_TickSize,
v_SharesOutstanding,
v_ticker_class_L1,
v_ticker_class_L2,
v_ticker_class_L3,
v_tick_size_string,
v_mic_code,
v_min_size,
v_max_long_size,
v_max_short_size,
v_margin_percentage,
v_display_symbol,
v_sedol,
v_stamp_duty_flag
);
insert into future_tickers
(
ticker_serial,
contract_size,
maturity_date,
exp_date,
parent_source_id,
parent_ticker_id,
last_updated_on,
DECIMAL_SUPPORTED_LOT_SIZE,
MARGIN_INITIAL_CASH,
MARGIN_MAINTENANCE_CASH
)
values
(
v_ticker_serial,
v_lot_size,
v_maturity_date,
v_lasttradabledate,
v_parent_source_id,
v_parent_ticker_id,
v_last_updated_on,
v_dec_lot_size,
v_margin_initial_cash,
v_margin_maintenance_cash
);
exception
when dup_val_on_index
then
begin -- insert into block
select is_manually_modified
into v_is_manually_modified
from tickers
where ticker_serial=v_ticker_serial;
exception
when no_data_found
then v_is_manually_modified := null;
end; -- insert into block
if (v_is_manually_modified <> 1 or v_is_manually_modified is null)
then
update future_tickers
set
contract_size = v_lot_size,
maturity_date = v_maturity_date,
exp_date = v_lasttradabledate,
parent_source_id = v_parent_source_id,
parent_ticker_id = v_parent_ticker_id,
last_updated_on = v_last_updated_on,
DECIMAL_SUPPORTED_LOT_SIZE = v_dec_lot_size,
MARGIN_INITIAL_CASH = v_margin_initial_cash,
MARGIN_MAINTENANCE_CASH = v_margin_maintenance_cash
where
ticker_serial = v_ticker_serial;
end if;
end; -- insert block
--commit;
end add_future_tickers_intl
$$;
alter procedure add_future_tickers_intl(numeric, varchar, varchar, varchar, char, varchar, varchar, numeric, varchar, varchar, numeric, numeric, varchar, varchar, varchar, numeric, varchar, varchar, timestamp, varchar, timestamp, numeric, varchar, numeric, numeric, numeric, timestamp, numeric, varchar, varchar, varchar, numeric, varchar, varchar, varchar, varchar, varchar, numeric, numeric, varchar, numeric, numeric, timestamp, timestamp, varchar, numeric, varchar, timestamp, varchar, timestamp, varchar, numeric, varchar, varchar, numeric, numeric, numeric, numeric, numeric, numeric, numeric, numeric, varchar, varchar, numeric, numeric, numeric, numeric, varchar, varchar, numeric, numeric, numeric) owner to office;
When I try to execute the following call,
call pkg_ticker_utils.add_future_tickers_intl(
12768341,
'FCBT',
'TY\M23',
null,
'1',
null,
'F:TY\M23',
68,
'USD',
null,
9,
10000000,
'TY\P',
null,
null,
1000,
'Metric Ton ',
'TYM3',
'2023-02-08 04:42:24.808+00',
null,
null,
null,
null,
null,
null,
null,
'2023-06-21 00:00:00+00',
'0'::numeric,
null,
null,
null,
null,
'674',
null,
null,
'TYM3 CBT',
null,
null,
null,
'TYM3',
0,
null,
null,
null,
null,
null,
null,
'2023-06-21 00:00:00+00',
'EN^XTen-Year US Treasury Note Futures Jun-2023 Composite^XTen-Year US Treasury Note Futures Jun-2023 Composite^X|',
null,
null,
1,
'BBG019PMT181',
null,
'0'::numeric,
null,
3,
'0'::numeric,
null,
null,
null,
null,
null,
null,
'0'::numeric,
null,
null,
'0'::numeric,
'TYM3',
null,
0,
null,
null
);
it is throwing error:
[42883] ERROR: procedure pkg_ticker_utils.add_future_tickers_intl(integer, unknown, unknown, unknown, unknown, unknown, unknown, integer, unknown, unknown, integer, integer, unknown, unknown, unknown, integer, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, integer, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, integer, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, integer, unknown, unknown, integer, unknown, integer, integer, unknown, unknown, unknown, unknown, unknown, unknown, integer, unknown, unknown, integer, unknown, unknown, integer, unknown, unknown) does not exist Hint: No procedure matches the given name and argument types. You might need to add explicit type casts. Position: 6
At the end it says:
Hint: No procedure matches the given name and argument types. You might need to add explicit type casts. Position: 6
I do not understand what it means in the end, by position 6 ?
I have tried to count the parameters and all, and they all match. I do not see any discrepancies.
I have tried to count the parameters, match the types and all and it all checks out. What do I have wrong here?
Good luck with finding someone who is ready to dig through tons of parameters.
My advice: avoid character varying or any other non-preferred type in function arguments. Use preferred types, because they facilitate type resolution:
SELECT typname, typcategory FROM pg_type WHERE typispreferred;
typname │ typcategory
═════════════╪═════════════
bool │ B
text │ S
oid │ N
float8 │ N
inet │ I
timestamptz │ D
interval │ T
varbit │ V
(8 rows)
The exception is probably with the numeric types, as you don't want to use double precision there. There, it is best to use types that can be cast to implicitly, so prefer the right-hand types over the left-hand types in the following list:
SELECT c.castsource::regtype, c.casttarget::regtype
FROM pg_cast AS c
JOIN pg_type AS t1 ON c.castsource = t1.oid
JOIN pg_type AS t2 ON c.casttarget = t2.oid
WHERE t1.typcategory = 'N'
AND t2.typcategory = 'N'
AND c.castcontext = 'i'
AND t2.typname !~~ ALL ('{oid,reg%}');
castsource │ casttarget
════════════╪══════════════════
bigint │ real
bigint │ double precision
bigint │ numeric
smallint │ bigint
smallint │ integer
smallint │ real
smallint │ double precision
smallint │ numeric
integer │ bigint
integer │ real
integer │ double precision
integer │ numeric
real │ double precision
numeric │ real
numeric │ double precision
numeric │ numeric
(16 rows)
Since your main question seems to be the "position 6": that is the position in the SQL statement that is related to the error, so probably the procedure call:
CALL procname(tons_of_parameters);
^
|
here

In a PostgresSQL function, is it possible to check if a column value matches a given parameter value?

In the WHERE clause of a SQL Server stored procedure, I can do this:
WHERE (*column_value* = #some_parameter OR #some_parameter IS NULL)
When I try to do the same thing in a PostgreSQL function, it throws an error. For example:
WHERE(FRQ.QuoteId = p_FilterQuote OR p_FilterQuote IS NULL)
produces the error: ***column "p_FilterQuote" does not exist.
The input parameter p_FilterQuote is declared and initialized at the top of the function like this:
p_filterquote integer DEFAULT NULL::integer
There must be a way to 'use' input parameters in a WHERE clause.
The entire function code is shown below.
-- FUNCTION: public.postgres_termpositionrawdata_ver3(character varying, date, character, character varying, character varying, character varying, character varying, character varying, integer, integer, character varying, character varying, character varying, character varying, character varying)
-- DROP FUNCTION public.postgres_termpositionrawdata_ver3(character varying, date, character, character varying, character varying, character varying, character varying, character varying, integer, integer, character varying, character varying, character varying, character varying, character varying);
CREATE OR REPLACE FUNCTION public.postgres_termpositionrawdata_ver3(
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
,DQF.QuotationFor
,LCR.LifeCriticalIllnessRiskRelationship
,TDP.TotalPermanentDisabilityCover
,CB.CommissionBasis
,DCT.CommissionType
,DG1.Gender AS Life1Gender
FROM FactRequest FRQ
INNER JOIN dimExchangeOrganisation DEO ON FRQ.ExchangeOrganisationID = DEO.ExchangeOrganisationId
INNER JOIN dimExchangeUser DEU ON FRQ.ExchangeUserId = DEU.ExchangeUserId
INNER JOIN dimLifeBasis DLB ON FRQ.LifeBasisId = DLB.LifeBasisID
INNER JOIN dimTotalPermanentDisabilityCover TDP ON FRQ.TotalPermanentDisabilityCoverId = TDP.TotalPermanentDisabilityCoverID
INNER JOIN dimDate DDQ ON FRQ.QuotationDateID = DDQ.DateID
INNER JOIN dimDate DDC ON FRQ.CommencementDateID = DDC.DateID
INNER JOIN dimExchangePanel DEP ON FRQ.ExchangePanelId = DEP.ExchangePanelId
INNER JOIN dimCommissionBasis CB ON FRQ.CommissionBasisId = CB.CommissionBasisId
INNER JOIN dimCommissionType DCT ON FRQ.CommissionTypeId = DCT.CommissionTypeId
INNER JOIN factClient FC ON FRQ.QuoteID = FC.QuoteID
INNER JOIN dimLifeCriticalIllnessRiskRelationship LCR ON FRQ.LifeCriticalIllnessRiskRelationshipId = LCR.LifeCriticalIllnessRiskRelationshipId
INNER JOIN dimQuotationFor DQF ON FRQ.QuotationForId = DQF.QuotationForId
INNER JOIN dimKeyPerson DKP ON FRQ.KeyPersonId = DKP.KeyPersonId
INNER JOIN dimBenefitBasis DBB ON FRQ.BenefitBasisId = DBB.BenefitBasisId
INNER JOIN dimIntegrator DI ON FRQ.ExchangeIntegratorId = DI.ExchangeIntegratorId
INNER JOIN dimGender DG1 ON FC.Life1GenderID = DG1.GenderID
INNER JOIN dimGender DG2 ON FC.Life2GenderID = DG2.GenderID
INNER JOIN dimSmoker DS1 ON FC.Life1SmokerID = DS1.SmokerID
INNER JOIN dimSmoker DS2 ON FC.Life2SmokerID = DS2.SmokerID
INNER JOIN dimOccupation DO1 ON FC.Life1OccupationId = DO1.OccupationID
INNER JOIN dimOccupation DO2 ON FC.Life2OccupationId = DO2.OccupationID
WHERE DDQ.Date = p_date
AND FRQ.ProductTypeId IN (53) -- TERM ONLY
AND DKP.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, QuotationCoverFor character varying,
LifeCIRiskRelationship character varying, TPDOption character varying, CommissionBasis character varying,
CommissionType character varying, Life1Gender character varying);
-- SELECT * FROM FilteredRequests;
END;
$BODY$;
The SQL statement is executed as it is on the remote database, and no parameter substitutions of any kind are performed.
You have to do that yourself:
DECLARE
sql text;
BEGIN
sql := format(
'SELECT ... WHERE(FRQ.QuoteId = %L::integer OR %L::integer IS NULL)',
p_FilterQuote,
p_FilterQuote
);
SELECT * FROM dblink('conn', sql) AS ...;
END;

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';

ERROR: extra data after last expected column - COPY

When I try to import the data with delimiter | I receive the error:
ERROR: extra data after last expected column
I am able to load the data if I remove double quote or single quote from the filed which have issue in the below sample data but my requirement is I need all data without removing any.
This is my copy command:
COPY public.dimingredient FROM '/Users//Downloads/archive1/test.txt'
DELIMITER '|' NULL AS '' CSV HEADER ESCAPE AS '"' ;
My table:
public.dimingredient
(
dr_id integer NOT NULL,
dr_loadtime timestamp(6) without time zone NOT NULL,
dr_start timestamp(6) without time zone NOT NULL,
dr_end timestamp(6) without time zone NOT NULL,
dr_current boolean NOT NULL,
casnumber character varying(100) COLLATE pg_catalog."default" NOT NULL,
ingredientname character varying(300) COLLATE pg_catalog."default" NOT NULL,
matchingstrategy character varying(21) COLLATE pg_catalog."default",
percentofconfidence double precision,
disclosurestatus character varying(42) COLLATE pg_catalog."default",
issand character varying(1) COLLATE pg_catalog."default",
sandmeshsize character varying(20) COLLATE pg_catalog."default",
sandquality character varying(20) COLLATE pg_catalog."default",
isresincoated character varying(1) COLLATE pg_catalog."default",
isartificial character varying(1) COLLATE pg_catalog."default",
CONSTRAINT dimingredient_pkey PRIMARY KEY (dr_id)
)
my data:
5144|2016-07-01 13:34:25.1001891|1900-01-01 00:00:00.0000000|9999-12-31 23:59:59.9999999|True|93834|"9-octadecenamide,n,n-bis(2-hydroxyethyl)-, (9z)"|"NO CAS MATCH FOUND"||Disclosed|||||
5145|2016-07-01 13:34:25.1001891|1900-01-01 00:00:00.0000000|9999-12-31 23:59:59.9999999|True|93834|"9-octadecenamide,n,n-bis-2(hydroxy-ethyl)-,(z)""|"NO CAS MATCH FOUND"||Disclosed|||||
Omitting the empty line in your dample data, I get a different error message with 9.6, to wit:
ERROR: unterminated CSV quoted field
CONTEXT: COPY dimingredient, line 3: "5145|2016-07-01 13:34:25.1001891|1900-01-01 00:00:00.0000000|9999-12-31 23:59:59.9999999|True|93834|..."
Strangely enough, that error message has been there since CSV COPY was introduced in version 8.0, so I wonder how your data are different from the data you show above.
The error message is easily explained: There is an odd number of quotation characters (") in the second line.
Since two doubled quotes in a quoted string are interpreted as a single double quote (" is escaped as ""), the fields in the second line are:
5145
2016-07-01 13:34:25.1001891
1900-01-01 00:00:00.0000000
9999-12-31 23:59:59.9999999
True
93834
9-octadecenamide,n,n-bis-2(hydroxy-ethyl)-,(z)"|NO CAS MATCH FOUND||Disclosed|||||
... and then COPY hits the end of file while parsing a quoted string. Hence the error.
The solution is to use an even number of " characters per field.
If you need a " character in a field, either choose a different QUOTE or quote the field and double the ".

PostgreSQL COPY from CSV with delimiter "|"

please, can anyone help me to solve this problem?
I'd like to create a table in Postgres database with data from CSV file with delimiter "|", while trying to use the command COPY (or Import) I get this error:
ERROR: extra data after last expected column
CONTEXT: COPY twitter, line 2: ""Sono da Via Martignacco
http://t.co/NUC6MP0z|"<a href=""http://foursquare.com"" rel=""nofollow"">f..."
The first 2 lines of CSV:
txt|"source"|"ulang"|"coords"|"tweettime_wtz"|"country"|"id"|"userid"|"in_reply_user_id"|"in_reply_status_id"|"uname"|"ucreationdate"|"utimezone"|"followers_count"|"friends_count"|"x_coords"|"y_coords"
Sono da Via Martignacco http://t.co/NUC6MP0z|"foursquare"|"it"|"0101000020E6100000191CA9E7726F2A4026C1E1269F094740"|"2012-05-13 10:00:45+02"|112|201582743333777411|35445264|""|""|"toffo93"|"2009-04-26 11:00:03"|"Rome"|1044|198|13.21767353|46.07516943
For this data I have created in Postgres a table "Twitter"
CREATE TABLE public.twitter
(
txt character varying(255),
source character varying(255),
ulang character varying(255),
coords geometry(Point,4326),
tweettime_wtz character varying(255),
country integer,
userid integer NOT NULL,
in_reply_user_id character varying(255),
in_reply_status_id character varying(255),
uname character varying(255),
ucreationdate character varying(255),
utimezone character varying(255),
followers_count integer,
friends_count integer,
x_coords numeric,
y_coords numeric,
CONSTRAINT id PRIMARY KEY (userid)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.twitter
OWNER TO postgres;
Any ideas, guys?
The destination table contain 16 column, but your file contain have 17 column.
It seems to be the id field who is missing.
try to set you table as:
CREATE TABLE public.twitter
(
txt character varying(255),
source character varying(255),
ulang character varying(255),
coords geometry(Point,4326),
tweettime_wtz character varying(255),
country integer,
id character varying,
userid integer NOT NULL,
in_reply_user_id character varying(255),
in_reply_status_id character varying(255),
uname character varying(255),
ucreationdate character varying(255),
utimezone character varying(255),
followers_count integer,
friends_count integer,
x_coords numeric,
y_coords numeric,
CONSTRAINT twitter_pk PRIMARY KEY (userid)
)
WITH (
OIDS=FALSE
);
Change the data type of the id field as you need it.
My solution:
So the problem was in my CSV file: it has had invisible signs of quotes. I haven't seen them when I opened CSV in Excel, I saw the lines in this way:
txt|"source"|"ulang"|"coords"|"tweettime_wtz"|"country"|"id"|"userid"|"in_reply_user_id"|"in_reply_status_id"|"uname"|"ucreationdate"|"utimezone"|"followers_count"|"friends_count"|"x_coords"|"y_coords"
Sono da Via Martignacco http://t.co/NUC6MP0z|"foursquare"|"it"|"0101000020E6100000191CA9E7726F2A4026C1E1269F094740"|"2012-05-13 10:00:45+02"|112|201582743333777411|35445264|""|""|"toffo93"|"2009-04-26 11:00:03"|"Rome"|1044|198|13.21767353|46.07516943
But when I opened CSV in notepad I saw it differently:
"txt"|"source"|"ulang"|"coords"|"tweettime_wtz"|"country"|"id"|"userid"|"in_reply_user_id"|"in_reply_status_id"|"uname"|"ucreationdate"|"utimezone"|"followers_count"|"friends_count"|"x_coords"|"y_coords"
"Sono da Via Martignacco http://t.co/NUC6MP0z"|"foursquare"|"it"|"0101000020E6100000191CA9E7726F2A4026C1E1269F094740"|"2012-05-13 10:00:45+02"|112|201582743333777411|35445264|""|""|"toffo93"|"2009-04-26 11:00:03"|"Rome"|1044|198|13.21767353|46.07516943
"
So i should delete all quotes (in Notepad and saving the file as CSV), so that the text became:
txt|source|ulang|coords|tweettime_wtz|country|id|userid|in_reply_user_id|in_reply_status_id|uname|ucreationdate|utimezone|followers_count|friends_count|x_coords|y_coords
Sono da Via Martignacco http://t.co/NUC6MP0z|<a href=http://foursquare.com rel=nofollow>foursquare</a>|it|0101000020E6100000191CA9E7726F2A4026C1E1269F094740|2012-05-13 10:00:45+02|112|201582743333777411|35445264|||toffo93|2009-04-26 11:00:03|Rome|1044|198|13.21767353|46.07516943
Only after this I was able to use Import tool in pgAdmin without any problem!