check for valid working days in an SQL function - sql

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

Related

Error "Invalid Instruction" in PL/SQL function using Oracle

here i'm trying to create a sort of a boolean function but when i try to compile it, it says me that my instruction "truth INTEGER;" is not correct. I can't figure out where does the problem come from because every code sample that i've seen on Google is quite similar to mine. Using Oracle is totally new for me so i'm kinda lost if someone is okay to help me...
I tried a lot of things by searching but nothing works so i'm here to ask for some help...
CODE:
CREATE OR REPLACE FUNCTION HISTOTOX.matching_idipl (iDiplNumero INTEGER) RETURN INTEGER
AS
cpt INTEGER;
truth INTEGER;
BEGIN
SELECT count(*) INTO cpt FROM GARNUCHE.INSC_DIPL WHERE IDIPL_NUMERO = iDiplNumero;
IF cpt = 1 THEN
truth := 1;
ELSE
truth := 0;
END IF;
RETURN truth;
END;
What you reported isn't Oracle error. I replicated your code in my 11g and everything works just fine:
SQL> CREATE OR REPLACE FUNCTION matching_idipl (iDiplNumero INTEGER) RETURN INTEGER
2 AS
3 cpt INTEGER;
4 truth INTEGER;
5
6 BEGIN
7 SELECT count(*) INTO cpt FROM INSC_DIPL WHERE IDIPL_NUMERO = iDiplNumero;
8 IF cpt = 1 THEN
9 truth := 1;
10 ELSE
11 truth := 0;
12 END IF;
13 RETURN truth;
14 END;
15 /
Function created.
SQL> select matching_idipl(1) from dual;
MATCHING_IDIPL(1)
-----------------
1
SQL>
So: where exactly did you execute that code? Which error did you get (exact message and error code, please)?

PostgreSQL how to disable plan caching to fix my base62 hashing?

From the documentation i gather, that PostgreSQL somehow employs its own cache and prepares satements ahead...
This is really bad for my base62 hash values. At some point, after 2-3 tries, they start returning the same number:
LOG: base62_id.val 1501145675089
CONTEXT: PL/pgSQL function copy_article(text) line 23 at RAISE
STATEMENT: select to_json("public"."copy_article"($1)) as value
LOG: copied_article_id QQZCFzm | article_count 1
CONTEXT: PL/pgSQL function copy_article(text) line 37 at RAISE
STATEMENT: select to_json("public"."copy_article"($1)) as value
LOG: base62_id.val 1501145675089
CONTEXT: PL/pgSQL function copy_article(text) line 23 at RAISE
STATEMENT: select to_json("public"."copy_article"($1)) as value
LOG: copied_article_id QQZCFzm | article_count 1
CONTEXT: PL/pgSQL function copy_article(text) line 37 at RAISE
STATEMENT: select to_json("public"."copy_article"($1)) as value
LOG: base62_id.val 1501145675089
CONTEXT: PL/pgSQL function copy_article(text) line 23 at RAISE
STATEMENT: select to_json("public"."copy_article"($1)) as value
LOG: copied_article_id QQZCFzm | article_count 1
CONTEXT: PL/pgSQL function copy_article(text) line 37 at RAISE
STATEMENT: select to_json("public"."copy_article"($1)) as value
LOG: base62_id.val 1501145675089
Here is my function:
CREATE OR REPLACE FUNCTION base62_id() RETURNS character varying
LANGUAGE plpgsql IMMUTABLE
AS $$
DECLARE
chars char[];
ret varchar;
val bigint;
BEGIN
chars := ARRAY['0','1','2','3','4','5','6','7','8','9'
,'A','B','C','D','E','F','G','H','I','J','K','L','M'
,'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
,'a','b','c','d','e','f','g','h','i','j','k','l','m'
,'n','o','p','q','r','s','t','u','v','w','x','y','z'];
val := (CEIL(EXTRACT(EPOCH FROM now()) * 1000))::bigint;
RAISE LOG 'base62_id.val %', val;
ret := '';
IF val < 0 THEN
val := val * -1;
END IF;
WHILE val != 0 LOOP
ret := chars[(val % 62)+1] || ret;
val := val / 62;
END LOOP;
RETURN ret;
END;$$;
In theory, this should work...
Any ideas?
Edit: How i use the function:
DECLARE
copied_article_id text := base62_id();
duplication_check int := 1;
copied_article articles;
BEGIN
WHILE duplication_check IS NOT NULL LOOP
SELECT COUNT(*) INTO duplication_check FROM articles WHERE id = copied_article_id;
END LOOP;
INSERT ... INTO ... SELECT ...
FROM
articles
WHERE
id = base_id;
SELECT * INTO copied_article FROM articles WHERE id = copied_article_id LIMIT 1;
Your explanation is pretty bogus. Plan caching has nothing to do with this outcome, the plancache doesn't care about individual function outputs.
There's at least two giant gaping bugs in the function:
You declare it IMMUTABLE but you call now() which is not immutable. IMMUTABLE functions must return the same result for every call with the same inputs. In fact, your function must be declared VOLATILE if it's allowed to return a different value for each call with the same inputs.
now() is STABLE. It actually returns the same value for each call within a transaction. So presumably using it when you want unique values makes no sense at all. I imagine you actually want clock_timestamp().
The latter problem with now() (a.k.a. current_timestamp) being STABLE across a transaction is likely the cause for the results you report.
BTW, the function will also probably be amazingly slow implemented in plpgsql. If you can turn it into a set operation plus string_agg it might be more tolerable, but still slow.

sql stored function gives an error

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

Compilation error in Oracle PL/SQL

I have been staring at this hours trying to figure out why it won't run, and cannot see any syntax error which should stop this from compiling, but I am nonetheless getting the following errors:
Error(6,1): PL/SQL: SQL Statement ignored
Error(22,7): PL/SQL: ORA-00933: SQL command not properly ended
The function I am trying to create is as follows:
create or replace function caps_get_Uoffer_count_BD(ayrc in varchar2
,mcrc in varchar2)
return number
is
app_count number;
begin
select count(*)
from
(select distinct cap.cap_stuc,cap.cap_apfs , cap.cap_seqn from
intuit.srs_cap cap
,intuit.srs_apf apf
,intuit.srs_ioi ioi
where cap.cap_ayrc = ayrc
and cap.cap_mcrc = mcrc
and apf.apf_stuc = cap.cap_stuc
and apf.apf_seqn = cap.cap_apfs
and apf.apf_recd <= to_date('1501'||substr(ayrc,1,4),'DDMMYYYY')
and cap.cap_stuc = ioi.ioi_stuc
and cap.cap_mcrc = ioi.ioi_mcrc
and ioi.ioi_iodc ='PAPERLESS'
and cap.cap_stac like 'A%'
and cap.cap_idrc in ('U','UF','UI','UD','CFU','CFUF','CIUI','CIUF','CIUD','CIU','CFUI','CFUD'))
return(app_count);
end;
Database is Oracle 11g. Can anyone help?
Many thanks in advance

pl-sql how to perfom a simple max(Date) function

hello
i am new to oracle db , how can i simply ask for the max date?
FUNCTION get_max_date_rec(
i_value_date IN vat.value_date%TYPE := app_utilities_q.server_sys_date )
RETURN vat.rec_id%TYPE
IS
v_date vat.value_date%TYPE;
BEGIN
SELECT MAX(v.value_date)--compiler err
INTO v_date
FROM vat v
WHERE v.value_date < i_value_date
RETURN get_rec_by_date(v_date).rec_id;--compiler err
END get_max_date_rec;
EDIT
this is the err created by the compiler
Error(76,7): PL/SQL: SQL Statement ignored
Error(81,7): PL/SQL: ORA-00933: SQL command not properly ended
I want to return rec_id as writen above...
FUNCTION get_max_date_rec(
i_value_date IN vat.value_date%TYPE
default app_utilities_q.server_sys_date -- assuming this is a default
)
RETURN vat.rec_id%TYPE
IS
v_date vat.value_date%TYPE;
BEGIN
SELECT MAX(v.value_date)--compiler err
INTO v_date
FROM vat v
WHERE v.value_date < i_value_date
RETURN v_date;
END get_max_date_rec;
One risk is that if no records in vat exist for a date greater than i_value_date, the code will fail, throwing the NO_DATA_FOUND exception. You should consider how you might wish to handle that condition - or not handle it, if that's the correct thing to do.
the problem was
not adding
;
in the end of select
SELECT MAX(v.value_date)--compiler err
INTO v_date
FROM vat v
WHERE v.value_date < i_value_date ;