while function in postgresql - postgresql

I want to insert records to a table by function.
CREATE OR REPLACE FUNCTION insert_wilda()
RETURNS integer AS
$BODY$
DECLARE
countKab integer;
i integer;
BEGIN
i := 1;
SELECT count(*)+34 into countKab from m_kab
WHILE (i <= countKab)
loop
INSERT INTO "t_historyWilda"("kdHistory","kdProp","kdKab","kdKec","nmWilda","noUrut",bulan,tahun,"isActive")
SELECT 'i',"kdProp","kdKab",'000',"namaKab",'1', EXTRACT(MONTH FROM TIMESTAMP 'now()'), EXTRACT(YEAR FROM TIMESTAMP 'now()'),'1' FROM m_kab
end loop;
RETURN i;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
But I got error like this:
ERROR: syntax error at or near "<="
LINE 10: WHILE (i <= countKab)
^
********** Error **********
ERROR: syntax error at or near "<="

You missed ';' after this line
SELECT count(*)+34 into countKab from m_kab

Related

EXECUTE in postgresql

create table x(y number, z character varying(100))
insert into x values (1,'foo');
insert into x values (2,'bar');
do $$
declare
k character varying(100);
begin
EXECUTE 'SELECT z FROM '
||quote_ident(x)
into k;
RAISE NOTICE '%',k;
end;
$$ language 'plpgsql';
ERROR: column "x" does not exist
LINE 2: ||quote_ident(x)
^
QUERY: SELECT 'SELECT z FROM '
||quote_ident(x)
CONTEXT: PL/pgSQL function inline_code_block line 7 at
EXECUTE
SQL state: 42703
May I know what am I doing wrong here and I'm on 9.5. Even EXECUTE format is also giving me the same error.
do $$
declare
k character varying(100);
begin
EXECUTE 'SELECT z FROM '
||quote_ident('x')
into k;
RAISE NOTICE '%',k;
end;
$$ language 'plpgsql';
quotes around 'x' worked for me. Thanks

Postgresql function dynamic table quote_ident error

I created a dynamic function. I get a part of table name with dynamically. The function is created successfully. But when I execute the function. I get an error. How can I solve this problem? I call the function with
select * from dwgcould.getlatlngcenter(2000653);
CREATE OR REPLACE FUNCTION dwgcould.getlatlngcenter(IN pro_id integer,
OUT lat_center double precision, OUT lng_center double precision)
AS $$
BEGIN
EXECUTE 'SELECT st_x(st_centroid( st_transform(geom,4326))) as lng_center ,st_y(st_centroid( st_transform(geom,4326))) as lat_center
FROM dwgcould.adpes_v1_' || quote_ident(pro_id) || '_line limit 1';
END;
$$ LANGUAGE plpgsql;
The error code is
ERROR: function quote_ident(integer) does not exist
LINE 2: FROM dwgcould.adpes_v1_' || quote_ident(pro_id) || '_line...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
QUERY: SELECT 'SELECT st_x(st_centroid( st_transform(geom,4326))) as lng_center ,st_y(st_centroid( st_transform(geom,4326))) as lat_center
FROM dwgcould.adpes_v1_' || quote_ident(pro_id) || '_line limit 1'
CONTEXT: PL/pgSQL function dwgcould.getlatlngcenter(integer) line 4 at EXECUTE statement
********** Error **********
ERROR: function quote_ident(integer) does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Context: PL/pgSQL function dwgcould.getlatlngcenter(integer) line 4 at EXECUTE statement
Also How can I check whether table exist?
better use format, eg:
CREATE OR REPLACE FUNCTION dwgcould.getlatlngcenter(IN pro_id integer,
OUT lat_center double precision, OUT lng_center double precision)
AS $$
BEGIN
if (select count(1) from pg_tables where tablename = format('adpes_v1_%s_line',pro_id)) < 1 then
raise info '%','NO SUCH TABLE!';
return;
end if;
EXECUTE format('SELECT * FROM dwgcould.adpes_v1_%s_line limit 1',pro_id) into lat_center,lng_center;
return;
END;
$$ LANGUAGE plpgsql;
docs

Creating TEMP TABLE dynamically in Postgresql and selecting the same table in FOR loop. But getting the error near PIPE symbol

do
$xyz$
declare
y text;
i record;
begin
y := to_char(current_timestamp, 'YYYYMMDDHHMMSS');
raise notice '%',y;
execute 'CREATE TEMP TABLE someNewTable'
||y
||' AS select * from ( VALUES(0::int,-99999::numeric), (1::int, 100::numeric)) as t (key, value)';
for i in (select * from someNewTable||y) loop
raise notice '%',i.key;
end loop;
end;
$xyz$ language 'plpgsql'
ERROR: syntax error at or near "||"
LINE 13: for i in (select * from someNewTable||y) loop
Im unable to understand why the error is at the PIPE symbol. Please help me. I have been trying in Oracle db too, but same error. Am I doing anything wrong here?
The query in for ... loop statement also has to be dynamic, so you should use execute twice.
Use the format() function which is very convenient in conjunction with execute:
do $xyz$
declare
y text;
i record;
begin
y := to_char(current_timestamp, 'YYYYMMDDHHMMSS');
raise notice '%', y;
execute format($ex$
create temp table somenewtable%s
as select * from (
values
(0::int, -99999::numeric),
(1::int, 100::numeric)
) as t (key, value)
$ex$, y);
for i in
execute format($ex$
select * from somenewtable%s
$ex$, y)
loop
raise notice '%',i.key;
end loop;
end;
$xyz$ language 'plpgsql';

Syntax error in declaration of PL/pgSQL function

Can anyone help me with this procedure? It's a pretty simple one, just want to insert some data into a table, but pgAdmin is giving me some errors.
This is the procedure code:
CREATE OR REPLACE FUNCTION FILL_INVOICE2(IN_NUM integer)
RETURNS void AS
DECLARE
counter numeric := 0;
BEGIN
IF in_num > 1 THEN
WHILE counter < 10
LOOP
INSERT INTO INVOICE(ID,INVOICE_ID,SUBSCRIBER_ID,AMOUNT,INVOICE_DATE,RECORD_DATE,INVOICE_TYPE,REST_TO_PAY,DESCRIPTION,INVOICE_REFERENCE)
VALUES(counter,counter,counter,100,current_date,current_date,1,100,'Telco services',1111);
counter := counter + 1;
RAISE NOTICE 'The counter is %', counter;
END LOOP;
END IF;
RETURN;
END;
Error is:
ERROR: syntax error at or near "DECLARE counter numeric"
LINE 3: DECLARE
^
********** Error **********
ERROR: syntax error at or near "DECLARE counter numeric"
SQL state: 42601
Character: 75"
This would work:
CREATE OR REPLACE FUNCTION fill_invoice2(in_num integer)
RETURNS void AS
$func$
DECLARE
counter numeric := 0;
BEGIN
IF in_num > 1 THEN
WHILE counter < 10
LOOP
INSERT INTO invoice(ID,INVOICE_ID,SUBSCRIBER_ID,AMOUNT,INVOICE_DATE,RECORD_DATE
,INVOICE_TYPE,REST_TO_PAY,DESCRIPTION,INVOICE_REFERENCE)
VALUES(counter,counter,counter,100,current_date,current_date
,1,100,'Telco services',1111);
counter := counter + 1;
RAISE NOTICE 'The counter is %', counter;
END LOOP;
END IF;
END
$func$ LANGUAGE plpgsql;
Major points
Missing language declaration.
Missing quotes around function body. Preferrably, use dollar-quoting - like #Eelke advised. Details:
Insert text with single quotes in PostgreSQL
But the whole function looks needlessly expensive.
Use a single INSERT based on generate_series() to replace the expensive loop with inserts per row. Optionally, you can wrap it in a function. Example with simple SQL function:
CREATE OR REPLACE FUNCTION fill_invoice2(in_num integer)
RETURNS void AS
$func$
INSERT INTO invoice(ID,INVOICE_ID,SUBSCRIBER_ID,AMOUNT,INVOICE_DATE,RECORD_DATE
,INVOICE_TYPE,REST_TO_PAY,DESCRIPTION,INVOICE_REFERENCE)
SELECT g,g,g,100,current_date,current_date,1,100,'Telco services',1111
FROM generate_series(0,10) g
WHERE $1 > 1;
$func$ LANGUAGE sql;
Does the same as your original.
I would also consider column defaults for some of your columns. For instance:
ALTER TABLE invoice
ALTER COLUMN invoice_date SET DEFAULT current_date
, ALTER COLUMN record_date SET DEFAULT current_date;
Details:
converting mysql scripts to postgresql script
Then just don't mention those column in the INSERT statement and defaults are filled in automatically.
The body should be passed as a string
CREATE OR REPLACE FUNCTION FILL_INVOICE2(IN_NUM integer) RETURNS void AS
$$
DECLARE
counter numeric := 0;
BEGIN
IF in_num > 1 THEN
WHILE counter < 10 LOOP
INSERT INTOI NVOICE(ID,INVOICE_ID,SUBSCRIBER_ID,AMOUNT,INVOICE_DATE,
RECORD_DATE,INVOICE_TYPE,REST_TO_PAY,DESCRIPTION,INVOICE_REFERENCE)
VALUES(counter,counter,counter,100,current_date,current_date,1,100,
'Telco services',1111);
counter := counter + 1;
RAISE NOTICE 'The counter is %', counter;
END LOOP;
END IF;
RETURN;
END;
$$
You can use $$ to mark the beginning en end of a multiline string.

Postgresql syntax error for if statement in a function

I am trying to write a function in postgresql and i am getting a syntax error for the if statement:
CREATE OR REPLACE FUNCTION getallcampuses(IN a character varying, IN b character varying)
RETURNS TABLE(campusid charactervarying, campusname character varying) AS
$BODY$
BEGIN
if $1 = 'PREK' then
SELECT * from "SIS_campus";
ELSE
BEGIN
IF $2 = 'DAll' then
SELECT distinct(district_id) || 'ALL' AS CampusID, ' District' AS CampusName
UNION
SELECT campus_id, name
FROM "SIS_campus"
WHERE district_name IS NOT NULL
order by name;
Elsif $2 = 'All' then
SELECT campus_id, name
FROM "SIS_campus"
WHERE district_name IS NOT NULL
and isnumeric(name) = 0
order by name;
end if;
END
end if;
END
$BODY$
LANGUAGE sql;
Here is the error:
ERROR: syntax error at or near "if"
LINE 5: if $1 = 'PREK' then
^
The function body is PL/PgSQL, but you declared it LANGUAGE sql.
Use LANGUAGE plpgsql if you're writing PL/PgSQL.
(related prior answer)