Postgres csv upload stored procedures - postgresql

I have a stored procedure for copying details from csv file to database table.
CREATE FUNCTION gis_portal.copycsv(IN path text) RETURNS void AS $$
COPY gis_portal.temp_excel FROM path WITH DELIMITER ','
$$ LANGUAGE sql VOLATILE LEAKPROOF;
But it is showing error as:
ERROR: syntax error at or near "path" SQL state: 42601 Character: 101
Here path is dynamic. Please help me.

COPY statement doesn't support variables - only statements with plan does it. And SQL language doesn't support dynamic SQL - so you should to use plpgsql language
see Dynamically-generated table-name in PostgreSQL COPY command

Related

Postgresql insert stored procedure error : The query does not have a destination for the returned data

I'm trying to create a stored procedure to insert data in the table brand of my postgresql database. Here the code:
CREATE OR REPLACE PROCEDURE public.insert_item_brand(IN brand text)
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
INSERT INTO public."item_brand" ("item_brand")
VALUES (brand::text)
returning "ID_item_brand";
COMMIT;
END;
$BODY$;
but when I call it I get the error:
ERROR: The query does not have a destination for the returned data
CONTEXT: PL / pgSQL function insert_brand_auto (text) line 3 a SQL statement
SQL status: 42601
I also tried to remove the line "returning..." but not work. any advice?

How do I include output parameters in my Postgres PLpgsql stored procedure?

I am creating a stored procedure which was written in SQL Server before.
It took a couple of output parameters.
I am trying to include the same in postgresSQL stored procedure but I am facing the following issues.
Sample Code:
CREATE procedure poii(
VARIADIC list NUMERIC[]
out res int
)
AS $$
BEGIN
END; $$
LANGUAGE plpgsql;
The output is giving the following error:
ERROR: syntax error at or near "out"
LINE 3: out res int
^
SQL state: 42601
Character: 52
I do not wish to use functions due to some requirements.
Please help me get a way around this.
As the documentation says:
OUT arguments are currently not supported for procedures. Use INOUT instead.
This might be implemented in a later versions.
But you don't need that. If you want code that takes arguments and returns a value, a function is the natura way to express that:
CREATE function poii(VARIADIC list NUMERIC[]) RETURNS int ...

Create procedure fails due to semicolons [duplicate]

I have the following function definition for a PostgreSQL 9.3.4 database:
CREATE OR REPLACE FUNCTION update_modified_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.modified_at = now();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
When I try to execute this in SQuirreL (3.5.3 or 3.6), I get the following error:
Error: ERROR: unterminated dollar-quoted string at or near "$$
BEGIN
NEW.modified_at = now()"
Position: 77
SQLState: 42601
ErrorCode: 0
So far I've learned this can be mitigated by using single quotes to delimit the function body like so:
CREATE OR REPLACE FUNCTION update_modified_timestamp()
RETURNS TRIGGER AS '
BEGIN
NEW.modified_at = now();
RETURN NEW;
END;
' LANGUAGE plpgsql;
Still I would like to know if this can't be solved otherwise - I think it must be possible since Flyway can execute this script and it uses the exact same JDBC driver that is configured in SQuirreL.
Update: #a_horse_with_no_name noted that this error has nothing to do with the JDBC driver, but with how SQuirreL parses the SQL statement and splits it into chunks before sending them to the database. Thus the remaining question is: Can SQuirreL send a query raw/unparsed? I've searched quite a bit couldn't find a way to do that.
You can change the statement separator so the statement is not split on a ;:
Go to: Session → Session Properties → SQL → Statement Separator
Even though you can't change it to an empty string, you can change it for example to //, which allows execution of the statement in the question.

DB2 query ,throwing an error

My DB2 query is throwing an error while executing it in DB2 visualizer
DB2 Query :
CREATE OR REPLACE PROCEDURE EDH.WBS_ENTITY (IN column_names varchar(2000),
IN filter_by varchar(2000), IN LIMIT_VALUE INT, IN OFFSET_VALUE INT)
DYNAMIC RESULT SETS 1
LANGUAGE SQL
BEGIN
DECLARE v_dynamicSql varchar(2000);
END ;
Error
[Code: -104, SQL State: 42601] An unexpected token "END-OF-STATEMENT" was found following "micSql varchar(2000)". Expected tokens may include: "".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.22.29
This is a FAQ.
Ensure that you configure your dbvis with an alternative statement-delimiter(terminator) , and then use that special delimiter at the end of the procedure. Db2 needs to know the difference between the delimiters used inside the sproc, as distinct from the delimiter that ends the 'create procedure' statement.
dbvis also has the #delimiter command to let you specify this. Refer to the dbvis documentation for details.
For IBM data studio, see this link, or refer to its online documentation.

Use function variable in dynamic COPY statement

According to docs of PostgreSQL it is possible to copy data to csv file right from a query without using an intermediate table. I am curious how to do that.
CREATE OR REPLACE FUNCTION m_tbl(my_var integer)
RETURNS void AS
$BODY$
DECLARE
BEGIN
COPY (
select my_var
)
TO 'c:/temp/out.csv';
END;
$$ LANGUAGE plpgsql;
I get an error: no such column 'my_var'.
Yes, it is possible to COPY from any query, whether or not it refers to a table.
However, COPY is a non-plannable statement, a utility statement. It doesn't support query parameters - and query parameters are how PL/PgSQL implements the insertion of variables into statements.
So you can't use PL/PgSQL variables with COPY.
You must instead use dynamic SQL with EXECUTE. See the Pl/PgSQL documentation for examples. There are lots of examples here on Stack Overflow and on https://dba.stackexchange.com/ too.
Something like:
EXECUTE format('
COPY (
select %L
)
TO ''c:/temp/out.csv'';
', my_var);
The same applies if you want the file path to be dynamic - you'd use:
EXECUTE format('
COPY (
select %L
)
TO %L;
', my_var, 'file_name.csv');
It also works for dynamic column names but you would use %I (for identifier, like "my_name") instead of %L for literal like 'my_value'. For details on %I and %L, see the documentation for format.