New optional parameter in SQL Server database function [duplicate] - sql-server

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

Related

Error SQLCODE=-789, SQLSTATE=429BB using the function ST_Contains

I'm getting the error
The data type for parameter or SQL variable "SHAPE" is not supported in the routine, compound SQL statement, or parameter list of a cursor value constructor.. SQLCODE=-789, SQLSTATE=429BB, DRIVER=4.18.60
When I use the code
CREATE OR REPLACE TRIGGER z
BEFORE INSERT OR UPDATE ON x
REFERENCING NEW AS N
FOR EACH ROW
BEGIN
DECLARE contador INTEGER;
SET contador = (SELECT COUNT(*) FROM y s
WHERE NOT(n.yID = s.yID AND db2gse.ST_Contains(s.shape, n.shape) = 1));
IF contador > 0 THEN
SIGNAL SQLSTATE '20001' SET MESSAGE_TEXT ='invalid relationship';
END IF;
END#
But if take out the function ST_Contains, it's works, I don't have a clue why that happens.
EDIT: Windows 7 64bit Ultimate with DB2 11.1 Server edition with ibm data studio, sorry I forgot about this detail.
Well, the error message does give you a clue: structured types (which ST_Geometry and its children are) are not supported in compound SQL statements, such as your trigger body. You'll need to do this check before you convert data from the exchange format to geometry or store the exchange format in the table along with geometry.
In the latter case you would have, along with the shape ST_Geometry column another one, e.g. shape_wkt varchar(5000) and in the trigger do type conversion on the fly:
...AND db2gse.ST_Contains(
db2gse.ST_Geometry(s.shape_wkt),
db2gse.ST_Geometry(n.shape_wkt)
)
db2gse.ST_Geometry(s.shape_wkt) might be optional, because the value does not need to be instantiated in the trigger, so this might work:
...AND db2gse.ST_Contains(
s.shape,
db2gse.ST_Geometry(n.shape_wkt)
)

Postgres function with jsonb parameters

I have seen a similar post here but my situation is slightly different from anything I've found so far. I am trying to call a postgres function with parameters that I can leverage in the function logic as they pertain to the jsonb query. Here is an example of the query I'm trying to recreate with parameters.
SELECT *
from edit_data
where ( "json_field"#>'{Attributes}' )::jsonb #>
'{"issue_description":"**my description**",
"reporter_email":"**user#generic.com**"}'::jsonb
I can run this query just fine in PGAdmin but all my attempts thus far to run this inside a function with parameters for "my description" and "user#generic.com" values have failed. Here is a simple example of the function I'm trying to create:
CREATE OR REPLACE FUNCTION get_Features(
p1 character varying,
p2 character varying)
RETURNS SETOF edit_metadata AS
$BODY$
SELECT * from edit_metadata where ("geo_json"#>'{Attributes}' )::jsonb #> '{"issue_description":**$p1**, "reporter_email":**$p2**}'::jsonb;
$BODY$
LANGUAGE sql VOLATILE
COST 100
ROWS 1000;
I know that the syntax is incorrect and I've been struggling with this for a day or two. Can anyone help me understand how to best deal with these double quotes around the value and leverage a parameter here?
TIA
You could use function json_build_object:
select json_build_object(
'issue_description', '**my description**',
'reporter_email', '**user#generic.com**');
And you get:
json_build_object
-----------------------------------------------------------------------------------------
{"issue_description" : "**my description**", "reporter_email" : "**user#generic.com**"}
(1 row)
That way there's no way you will input invalid syntax (no hassle with quoting strings) and you can swap the values with parameters.

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();

PostgreSQL Declared Variable in Function

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

Calling a sql server stored procedure with output parameter when using Simple.Data

Using Simple.Data, I would like to get the result from an output parameter in a stored procedure. Let's say I have the following SP (disregard the uselessness of it):
CREATE PROCEDURE [dbo].[TestProc]
#InParam int,
#OutParam int OUTPUT
AS
BEGIN
SELECT #OutParam = #InParam * 10
END
When I call it with Simple.Data, I use the following code.
var db = Database.Open();
int outParam;
var result = db.TestProc(42, out outParam);
Console.WriteLine(outParam); // <-- == 0
Console.WriteLine(result.OutputValues["OutParam"]); // <-- == 420
It feels like outParam should contain the value, and not the OutputValues dictionary. So my question is: Is there a nicer way to get the result from OutParam in this particular case?
Unfortunately, out parameters are not supported by the dynamic binding infrastructure used by Simple.Data, as they are not supported in all CLR languages.
I am open to suggestions for better syntax, though.

Resources