sql stored function gives an error - sql

I am trying to create a stored function to take one parameter called budget. The function should return the string 'LOW' for a budget less than or equal to 500000, 'MID' for a budget less than or equal to 850000, 'HIGH' for a budget less than or equal to 1200000, and 'ULTRA' for a budget above 1200000. But I am getting an error that doesn't make much sense to me.
Here is my function:
set term # ;
create procedure f_rating(budget int)
as
begin
if (budget <= 500000) then
return ('LOW');
else if (budget <= 850000) then
return ('MID');
else if (budget <= 1200000) then
return ('HIGH');
else
return ('ULTRA');
end #
I am still new to sql, so this syntax is based on examples online and such. Here is my error:
SQL Message : -804
An error was found in the application program input parameters for the SQL statement.
Engine Code : 335544569
Engine Message :
Dynamic SQL Error
SQL error code = -804
Function unknown
RETURN
Can anyone help me figure out what this means?

The syntax for stored function is
CREATE FUNCTION funcname [ ( [ <in_params> ] ) ]
RETURNS <domain_or_non_array_type> [COLLATE collation]
[DETERMINISTIC]
<module-body>
So you have made two mistakes, you use procedure instead of function and you miss the RETURNS <type> part. Try
create function f_rating(budget int) RETURNS VARCHAR(5)
as
begin
if (budget <= 500000) then
return 'LOW';
else if (budget <= 850000) then
return 'MID';
else if (budget <= 1200000) then
return 'HIGH';
else
return 'ULTRA';
end #

procedure does not return any value, functions do.
Try:
create function f_rating(budget int)
as
instead of
create procedure f_rating(budget int)
as

Related

T-SQL Scalar-valued function Return Null value

I'm trying to create a Scalar-valued user defined function to substitute my original codes. Basically, I intend to calculate the percentage of 2022 "nnooftickets" data out of the 2020 data for each period, there are 13 period in a year. Unfortunately, my user defined function codes do not work and I'm struggling spotting the issue.
The following are the original codes that works fine:
SELECT
setperiod,
SUM(nnooftickets) AS sumnnoofticketsp,
CASE
WHEN setperiod like '2023%' THEN SUM(nnooftickets) *1.00 / LAG(SUM(nnooftickets),13*(2023-2020)) OVER(ORDER BY setperiod) ELSE null
END AS nnoofticketspyoy
FROM rdg.Sales
GROUP BY setperiod
Then I created a scalar function try to replace the case statement, the codes for the scalar function is as follows:
CREATE FUNCTION [rdg].[getyoy]
(
#var BIGINT, #currentyear SMALLINT, #compareyear SMALLINT, #orderbyperiod VARCHAR, #multiplygap SMALLINT
)
RETURNS DECIMAL(18,4)
AS
BEGIN
DECLARE #YOY AS DECIMAL(18,4)
SELECT #YOY = CASE WHEN #orderbyperiod like '2023%' THEN #Var*1.00 / LAG(#Var, #multiplygap*(#currentyear - #compareyear)) OVER (ORDER BY #orderbyperiod) ELSE null END
RETURN #YOY
END
GO
Finally, I call the function using the codes below:
SELECT
setperiod,
SUM(nnooftickets) AS sumnnoofticketsp,
rdg.getyoy(SUM(nnooftickets), 2023, 2020, setperiod, 13) AS ngrosspyoy
FROM rdg.Sales
GROUP BY setperiod
However, after using the scalar function, there's no output figure (i.e. receive all NULL values) for column ngrosspyoy.
Could anyone help please?

check for valid working days in an SQL function

Im trying to simply create a SQL function in DB2 9.1 (yep thats old).
I tried boolean as return value, but the DB Version doesn't support it so i went with integer.
The function will just check if the selected day is not on a weekend.
Error: DB2 SQL Error: SQLCODE=-104, SQLSTATE=42601, SQLERRMC=END-OF-STATEMENT;6
then return 0;<delim_semicolon>, DRIVER=4.7.85
SQLState: 42601
ErrorCode: -104
what am i doing wrong?
create function checkIfValidWorkingday(variable_date date)
returns int
begin atomic
if dayofweek_iso(variable_date) = 6
then return 0;
else if dayofweek_iso(variable_date) = 7
then return 0;
else return 1;
end if;
end
end
Try:
create function checkIfValidWorkingday(variable_date date)
returns int
language SQL
specific checkIfValidWorkingday
deterministic no external action
return case when dayofweek_iso(variable_date) between 6 and 7 then 0 else 1 end

UDF on DB2 11.0

I was asked to build a user defined function on our Mainframe environment that checks for a search string in a longer string. The only catch is that if we search for example for 'AA' in 'ABCAADAA' the only valid result is the last AA because the first AA actually split in CA and AD.
CREATE FUNCTION F#CRE#WK (WK CHAR(02), WKATTR CHAR(10))
RETURNS INTEGER
LANGUAGE SQL
READS SQL DATA
BEGIN
DECLARE INDEX INTEGER DEFAULT 1;
WHILE (INDEX < 9) DO
SET INDEX = LOCATE_IN_STRING(WKATTR, WK, INDEX);
IF (MOD(INDEX, 2) <> 0) THEN
RETURN 1;
END IF;
END WHILE;
RETURN 0;
END;
It is working fine when I implement it using Data Studio but if I put it onto the host directly (we're using Quick32770) I'm getting a bunch of errors which don't make sense at all. I couldn't find any helpful resources(searched the whole IBM page and Google of course).
First error I'm getting is:
SQLCODE = -104, ERROR: ILLEGAL SYMBOL "<END-OF-STATEMENT>". SOME
SYMBOLS THAT MIGHT BE LEGAL ARE: ;
Which refers to the line I'm declaring my index variable. If I remove the semicolon it tells me that the SET is illegal there because it is expecting a semicolon.
I cannot think of anything else I could try(I messed around with the code a lot but errors just kept getting more weird.). I started working in this field while being in college just a couple of weeks ago and nobody here has actual knowledge about this so I was hoping to find some help here.
If there's anything else you need, just let me know!
Thanks in advance.
This might help you:
https://bytes.com/topic/db2/answers/754686-db2-udf-need-eliminate-if-statement
It says the if statement is not allowed on the mainframe in UDF ?
So this user bend it around to a CASE function.
In order to fix this you need to go into the SPUFI settings and change the TERMINATOR option to something else than a semicolon. If I changed it to & my code must look like this:
CREATE FUNCTION F#CRE#WK (WK CHAR(02), WKATTR CHAR(10))
RETURNS INTEGER
LANGUAGE SQL
READS SQL DATA
BEGIN
DECLARE INDEX INTEGER DEFAULT 1;
WHILE (INDEX < 9) DO
SET INDEX = LOCATE_IN_STRING(WKATTR, WK, INDEX);
IF (MOD(INDEX, 2) <> 0) THEN
RETURN 1;
END IF;
END WHILE;
RETURN 0;
END&

ORACLE SQL Method Produces Warning

I'm having trouble getting the following member method to compile (count_single_buses). Would appreciate any advice on what might be wrong syntactically with my code.
CREATE OR REPLACE TYPE BodyModel2_Type AS OBJECT(
ModelID INTEGER,
ModelName VARCHAR2(45),
FloorType VARCHAR2(45),
Manufacturer VARCHAR2(45),
Length NUMBER(8,2),
Width NUMBER(8,2),
NoOfAxles INTEGER,
MEMBER FUNCTION count_single_buses(ModelID INTEGER) RETURN INTEGER);
/
CREATE OR REPLACE TYPE BODY BodyModel2_Type AS
MEMBER FUNCTION count_single_buses(ModelID INTEGER) RETURN INTEGER IS
N INTEGER;
BEGIN
N := (SELECT COUNT(BODYMODELREF) FROM SINGLEDECKBUS_TABLE S
WHERE S.BODYMODELREF = ModelID);
RETURN N;
END count_single_buses;
END;
--EDIT--
Thanks to #Ravi, I managed to solve the issue my correcting my SQL syntax and setting the resultset to a NUMBER, instead of INTEGER.
CREATE OR REPLACE TYPE BODY BodyModel_Type AS
MEMBER FUNCTION count_single_buses(thisModelID INTEGER) RETURN NUMBER IS
NUM NUMBER;
BEGIN
SELECT COUNT(S.BODYMODELREF) INTO NUM FROM SINGLEDECKBUS_TABLE S WHERE S.BODYMODELREF.MODELID = thisModelID;
RETURN NUM;
END count_single_buses;
END;
/
Still not sure why #Ravi's exact code still produced the warning, and thought that resultset when returning a count value could go into an integer. At any rate, the code works now. Thanks all.
Your BodyModel2_Type Type definition looks okay. However, the body definition is syntactically incorrect.
You cannot define a SQL statement directly to a variable, thus making this statement wrong.
N := (SELECT COUNT(BODYMODELREF) FROM SINGLEDECKBUS_TABLE S
WHERE S.BODYMODELREF = ModelID);
You will have to use Select... into statement in order to assign the result set of your SQL query into a variable. So, the right syntax should look like this
SELECT COUNT(BODYMODELREF) FROM SINGLEDECKBUS_TABLE S INTO N
WHERE S.BODYMODELREF = ModelID
AFAIK you don't have END the Type followed by the Type name like this END count_single_buses. It'll produce an error. So, overall your Type body specification should look like this:
CREATE OR REPLACE TYPE BODY BodyModel2_Type AS
MEMBER FUNCTION count_single_buses(ModelID INTEGER) RETURN NUMBER IS
N NUMBER;
BEGIN
SELECT COUNT(BODYMODELREF) FROM SINGLEDECKBUS_TABLE S INTO N
WHERE S.BODYMODELREF = ModelID;
RETURN (N);
END;
END;
/
I'm writing this off without any live environment available right now so please let me know if you come across any error in the above code.
Cheers.

Calling a custom SQL function

This feels like a basic question, but I have tried everything! I'm writing a custom function SQL function to convert integers into dates:
CREATE FUNCTION convert_to_date (#fin INT)
RETURNS DATE
AS
BEGIN
DECLARE #fout DATE
SET #fout = CASE WHEN #fin IN ('','99999999','0','1') THEN NULL
ELSE CONVERT(DATE,CAST(#fin AS CHAR(8)))
END
RETURN #fout
END
SELECT dbo.convert_to_date(DtSurgDischarge) AS DischargeDate
FROM [TR_MASTER.registry].[dbo].[mgh_tumor]
I get the following error message:
Msg 156, Level 15, State 1, Procedure convert_to_date, Line 16
Incorrect syntax near the keyword 'SELECT'.
What am I doing wrong? Feels like it must be obvious. Thanks everyone!
At the very least you need a GO after the END statement of the function, if you're attempting to execute both the function create and the SELECT in one script - assuming you're using SSMS to run the script, that is.
CREATE FUNCTION convert_to_date (#fin INT)
RETURNS DATE
AS
BEGIN
DECLARE #fout DATE
SET #fout = CASE WHEN #fin IN ('','99999999','0','1') THEN NULL
ELSE CONVERT(DATE,CAST(#fin AS CHAR(8)))
END
RETURN #fout
END
GO
SELECT dbo.convert_to_date(DtSurgDischarge) AS DischargeDate
FROM [TR_MASTER.registry].[dbo].[mgh_tumor]