PostgreSQL Declared Variable in Function - database

I work with Potgresql and I have written function
CREATE OR REPLACE FUNCTION staging.shape_commit(layer_id integer)
RETURNS integer AS
$BODY$
declare
layer_name text;
begin
layer_name:=(select shape.layer_name from staging.shape where shape.id=layer_id);
delete from layer_name;
return layer_name;
end;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION staging.shape_commit(integer)
OWNER TO test;
layer_name is variable and really it is table name .but script ignore it as variable and uses as string
Cam anybody help me?

Your question isn't quite clear, but I suspect that you actually want to convert the text to a table name. For this, you want dynamic SQL. Instead of:
delete from layer_name;
Try something more like:
execute $x$delete from $x$ || layer_name::regclass;
http://www.postgresql.org/docs/current/static/plpgsql-statements.html

Related

how to change customer.value to "customer"."value" in snowflake. which removes [,],[0-9] in between the string

create or replace procedure sp()
returns VARCHAR
language javascript
as
$$
var A= ('Customers[0].value'.replace(/\[|\]|[0-9]/g,'')).replace(/(\\w+)/g,'""');
return A;
$$;
call sp();
create or replace procedure sp() returns VARCHAR language javascript as
$$
var A = 'Customers[0].value'.replace(/(\w+)\[[0-9]].(\w+)/g,'"$1"."$2"');
return A;
$$;
call sp();
gives:
SP
"Customers"."value"
If you going to do are fair amount of Javascript it help be helpful to read the replace doc's to learn the different match types, then you can hit F12 and use the web browser console to test/debug strings, without having to mash it into a SP and call/run it.

New optional parameter in SQL Server database function [duplicate]

This question already has answers here:
Alter a SQL server function to accept new optional parameter
(3 answers)
Closed 4 years ago.
I have a stored procedure that looks like this:
CREATE FUNCTION [my_schema].[isEligible]
(#product NUMERIC(8))
RETURNS INT
AS
BEGIN
DECLARE #result INT;
/* do eligibility checking, setting #result */
RETURN #result;
END;
This is referenced in several existing queries similar to this:
SELECT *
FROM person
WHERE my_schema.isEligible(?) > -1 -- negative numbers are eligibility error codes
Where ? is the parameter for a given product id.
In one of the several queries that call the function, I need to pass in a new additional parameter, #exception. I want to have the function behave by default like it did before, and only change behavior for the one call that will be passing in a value for #exception, so I have added the new parameter like so:
CREATE FUNCTION [my_schema].[isEligible]
(#product NUMERIC(8),
#exception CHAR(1) = 'N')
RETURNS INT
AS
BEGIN
DECLARE #result INT;
/*
do eligibility checking (conditionally accounting for
#exception being 'Y'), and setting #result
*/
RETURN #result;
END;
But when I deploy the new version of the function and run a query which only passes in #product I'm getting An insufficient number of arguments were supplied for the procedure or function [my_schema].[isEligible]. I thought that adding = 'N' would provide a default value and avoid this issue.
I read here that sometimes this generic sounding error is actually hiding other errors which aren't allowed to bubble up, but I don't know if that's the case, since it's talking about procedures and this is a function. Not sure if there's a difference or if functions don't support optional arguments like procedures.
I'd love to not have to pass in NULL for the new parameter if possible, which would simplify the rollout of the updated version of the function. Is there a way to do call this function both like isEligible(?) and isEligible(?, ?) or do I need the first one to be isEligible(?, NULL) for it to work?
You could call your function as:
SELECT *
FROM person
WHERE my_schema.isEligible(?, default) > -1
and:
SELECT *
FROM person
WHERE my_schema.isEligible(?, value) > -1

postgresql function creation gives syntax error

I am writing a postgresql function but I cannot seem to find where the error is. Postgresql is at version 9.4.
The following is the function:
CREATE FUNCTION custom_function1()
RETURNS trigger
LANGUAGE plpgsql
AS
$$
DECLARE base_val integer;
BEGIN
base_val := (EXTRACT(YEAR FROM now())::integer * 10000000000);
IF (currval('custom_sequence') < base_val) THEN
setval('custom_sequence', base_val);
END IF;
NEW.id := custom_function2();
RETURN NEW;
END;
$$;
My custom_sequence is in the format YYYY0000000000 (ex. 20150000000000).
So what this basically does (should do) is it checks if the base_val (minimum value for current year) is greater then the currval (current custom_sequence value) and updates the custom_sequence value. Then it returns a new value for that sequence generated with the function custom_function2 (which formats it slighly).
When I try to execute this it gives me:
syntax error at or near "setval"
I am pretty new to both postgresql and writing functions so I am probably not seeying an obvious error. If someone could help me it would be highly appreciated, thank you.
The error is related to what's explained in the doc here:
40.5.2 Executing a Command With No Result
[...]
Sometimes it is useful to evaluate an expression or SELECT query but
discard the result, for example when calling a function that has
side-effects but no useful result value. To do this in PL/pgSQL, use
the PERFORM statement:
PERFORM query;
You should write:
PERFORM setval('custom_sequence', base_val);

Function should have input parameters?

Is it mandatory to pass input parameters for all the user defined functions?
We know, Stored procedure has both input and output parameters.
Function has only input parameters.
We can write a stored procedure without using these parameters too..
Is it possible to write the user defined function without input parameter?
Yes you can definitely write User defined function without parameter.
One more thing I want to clarify that function may have input parameter and it has return value. Return value would be scalar or table depend on type of function you are creation.
Why ask if it is possible when you can just type a few lines and see that it is possible ;-)
CREATE FUNCTION dbo.NoParamsUDF()
RETURNS NVARCHAR(50)
AS
BEGIN
RETURN N'It worked!';
END;
GO
CREATE FUNCTION dbo.NoParamsTVF()
RETURNS TABLE
AS RETURN
SELECT dbo.NoParamsUDF() AS [DidItWork?];
GO
SELECT * FROM dbo.NoParamsTVF();
Returns:
DidItWork?
-------------
It worked!
CREATE FUNCTION dbo.NoParamsUDF()
RETURNS VARCHAR(50)
AS
BEGIN
RETURN N'It worked!';
END;
GO
CREATE FUNCTION dbo.NoParamsTVF()
RETURNS TABLE
AS RETURN
SELECT dbo.NoParamsUDF() AS [DidItWork?];
GO
SELECT * FROM dbo.NoParamsTVF();

Postgres integer arrays as parameters?

I understand that in Postgres pure, you can pass an integer array into a function but that this isn't supported in the .NET data provider Npgsql.
I currently have a DbCommand into which I load a call to a stored proc, add in a parameter and execute scalar to get back an Id to populate an object with.
This now needs to take n integers as arguments. These are used to create child records linking the newly created record by it's id to the integer arguments.
Ideally I'd rather not have to make multiple ExecuteNonQuery calls on my DbCommand for each of the integers, so I'm about to build a csv string as a parameter that will be split on the database side.
I normally live in LINQ 2 SQL savouring the Db abstraction, working on this project with manual data access it's all just getting a bit dirty, how do people usually go about passing these kinds of parameters into postgres?
See: http://www.postgresql.org/docs/9.1/static/arrays.html
If your non-native driver still does not allow you to pass arrays, then you can:
pass a string representation of an array (which your stored procedure can then parse into an array -- see string_to_array)
CREATE FUNCTION my_method(TEXT) RETURNS VOID AS $$
DECLARE
ids INT[];
BEGIN
ids = string_to_array($1,',');
...
END $$ LANGUAGE plpgsql;
then
SELECT my_method(:1)
with :1 = '1,2,3,4'
rely on Postgres itself to cast from a string to an array
CREATE FUNCTION my_method(INT[]) RETURNS VOID AS $$
...
END $$ LANGUAGE plpgsql;
then
SELECT my_method('{1,2,3,4}')
choose not to use bind variables and issue an explicit command string with all parameters spelled out instead (make sure to validate or escape all parameters coming from outside to avoid SQL injection attacks.)
CREATE FUNCTION my_method(INT[]) RETURNS VOID AS $$
...
END $$ LANGUAGE plpgsql;
then
SELECT my_method(ARRAY [1,2,3,4])
I realize this is an old question, but it took me several hours to find a good solution and thought I'd pass on what I learned here and save someone else the trouble. Try, for example,
SELECT * FROM some_table WHERE id_column = ANY(#id_list)
where #id_list is bound to an int[] parameter by way of
command.Parameters.Add("#id_list", NpgsqlDbType.Array|NpgsqlDbType.Integer).Value = my_id_list;
where command is a NpgsqlCommand (using C# and Npgsql in Visual Studio).
You can always use a properly formatted string. The trick is the formatting.
command.Parameters.Add("#array_parameter", string.Format("{{{0}}}", string.Join(",", array));
Note that if your array is an array of strings, then you'll need to use array.Select(value => string.Format("\"{0}\", value)) or the equivalent. I use this style for an array of an enumerated type in PostgreSQL, because there's no automatic conversion from the array.
In my case, my enumerated type has some values like 'value1', 'value2', 'value3', and my C# enumeration has matching values. In my case, the final SQL query ends up looking something like (E'{"value1","value2"}'), and this works.
Full Coding Structure
postgresql function
CREATE OR REPLACE FUNCTION admin.usp_itemdisplayid_byitemhead_select(
item_head_list int[])
RETURNS TABLE(item_display_id integer)
LANGUAGE 'sql'
COST 100
VOLATILE
ROWS 1000
AS $BODY$
SELECT vii.item_display_id from admin.view_item_information as vii
where vii.item_head_id = ANY(item_head_list);
$BODY$;
Model
public class CampaignCreator
{
public int item_display_id { get; set; }
public List<int> pitem_head_id { get; set; }
}
.NET CORE function
DynamicParameters _parameter = new DynamicParameters();
_parameter.Add("#item_head_list",obj.pitem_head_id);
string sql = "select * from admin.usp_itemdisplayid_byitemhead_select(#item_head_list)";
response.data = await _connection.QueryAsync<CampaignCreator>(sql, _parameter);

Resources