I'm trying to create a simple function in oracle for my lesson plan and cannot see what I'm doing wrong.
CREATE OR REPLACE FUNCTION ten_pct(num1 IN NUMBER)
RETURN NUMBER
IS
BEGIN
RETURN (num1 * 0.1);
END;
I've tried declaring a variable and setting it equal to the equation and returning it and get the same error.
Error(2,14): PLS-00103: Encountered the symbol "" when expecting one of the following: . # % ; is authid as cluster order using external character deterministic parallel_enable pipelined aggregate result_cache The symbol "" was ignored.
I'm hoping someone sees my mistake.
That code works on my machine
SQL> CREATE OR REPLACE FUNCTION ten_pct(num1 IN NUMBER)
2 RETURN NUMBER
3 IS
4 BEGIN
5 RETURN (num1 * 0.1);
6 END;
7 /
Function created.
Realistically, there is some difference between the code that you posted here and the code that you're actually trying to run.
Related
I am a beginner and using pascal and i am trying this problem that i attach. What should i do next? I am trying to make this program work by showing the "ayam" Function. But i don't know how to code the rest.
function ayam(a, b:integer) :
integer;
var
m: integer;
begin
readln(a) ;
readln(b) ;
readln(m) ;
begin
if (b=0) then
ayam:= 1 else
ayam:= a * ayam(a, b-1) mod m;
end;
writeln(ayam);
end;
The first thing I should say is that when a question is to do with coursework, as is obviously the case here, there is an unwritten convention that we do not write an answer which simply does your programming task for you. So in the following, I have not commented on whether the code inside your ayam function actually correctly implements what is required - that is for you to do.
Secondly, you did not say which Pascal implementation you are using. I have written the code of this answer in Lazarus, the IDE for FreePascal (aka FPC), which is the best of the freeware Pascal implementations currently available.
The first thing to do with your code is to re-format it the way it should be formatted,
using indentation of statements to reflect the structure of the steps you are
trying to code. Basically, your eye should be able to follow the code structure
as easily as possible. This gives something like this:
function ayam(a, b:integer) : integer;
var
m: integer;
begin
readln(a) ;
readln(b) ;
readln(m) ;
begin
if (b=0) then
ayam:= 1
else
ayam:= a * ayam(a, b-1) mod m;
end;
writeln(ayam);
end;
With that change made, it is pretty obvious that there is something wrong with
the logic of your code, because a and b are declared as input variables to
the ayam function but your code actually reads in their values via the
readln statements inside the function. This is what made me think that you think
you have done all that's necessary to write your program. In fact, you have not. What you are missing
is some code which sets up the input parameters a and b (and m, see below) in some way and then
invokes your ayam function to calculate its value and then does something with
the result. At the moment, your code simply defines ayam but takes no steps
to use it. So, to get your ayam function to do anything, you need to write a complete
Pascal program that uses it. Something like this:
program ayamprogram;
{ the following declares some variables for the program to use }
var
varA,
varB,
varM,
varResult : Integer;
{ next, we define the ayam function }
function ayam(a, b, m:integer) : integer;
begin
begin
if (b=0) then
ayam:= 1
else
ayam:= a * ayam(a, b-1, m) mod m;
end;
end;
{ now we write the code of the program, which reads in the values to be
used by ayam, then invokes ("calls") ayam to calculate its value and
assign its value to the varResult variable and then outputs the calculated
result using the writeln statement
}
begin
{ this is the code of the program }
readln(varA);
readln(varB);
readln(varM);
varResult := ayam(varA, varB, varM);
writeln('function ayam evaluates to ', varResult);
readln; { this causes the program to pause so you can see the result of the writeln statement }
end. { end of program }
Note that I have used different variable names for the variables which are supplied to ayam, varA, varB, varM, from the variable names used inside ayam to avoid confusion between them.
Note also that as it is bad practice to read user input inside an executing function, the value to be used for M is read in before ayam is called and is supplied to ayam as a third parameter.
A point you need to consider regarding the expression
ayam:= a * ayam(a, b-1, m) mod m
is whether the mod m should operate on the value of ayam(a, b-1, m) or on the entire expression including the a * as well; if so, parentheses can enforce the evaluation order you need, by writing
ayam:= (a * ayam(a, b-1, m)) mod m
I'm decoding a JWT with Postgresql. The function test is a simplified version of what it actually does. Here it serves to show an error message that I'm getting too.
CREATE TYPE parts AS (header json, payload json, valid boolean);
CREATE OR REPLACE FUNCTION verify(token text, secret text, algorithm text DEFAULT 'HS256')
RETURNS parts AS $$
SELECT
'{"alg": "HS256","typ": "JWT"}'::json AS header,
'{"id": 1, "exp": 1524683318}'::json AS payload,
TRUE AS valid;
$$ LANGUAGE sql;
CREATE OR REPLACE FUNCTION test(token text)
RETURNS parts AS $$
DECLARE
jwt_parts parts;
BEGIN
SELECT verify(test.token, 'secret')
INTO jwt_parts;
RETURN jwt_parts;
END
$$ LANGUAGE plpgsql;
After running SELECT test('xx') this is the error I'm getting (on Postgres v10.1):
ERROR: invalid input syntax for type json
DETAIL: Token "(" is invalid.
CONTEXT: JSON data, line 1: (...
PL/pgSQL function test(text) line 5 at SQL statement
I would like to SELECT ... INTO my custom parts type. I have tried many ways to rephrase, but I suspect this can be done much simpler than what I've tried so far.
PS: The real function test(token text) I'm using is larger and needs the plpgsql language.
PS2: Just to make sure that the currently given answers make sense to people visiting this question. The original version of my question had a test function like this:
CREATE OR REPLACE FUNCTION test(token text)
RETURNS parts AS $$
DECLARE
jwt_parts parts;
BEGIN
SELECT ('{"alg": "HS256","typ": "JWT"}', '{"id": 1, "exp": 1524683318}', TRUE)
INTO jwt_parts;
RETURN jwt_parts;
END
$$ LANGUAGE plpgsql;
The parentheses cause you to select a single column (of type row), where you actually need three columns. For example:
select (1,2,3)
>>
row
--------
(1,2,3)
(1 row)
So omit the parentheses after select:
SELECT ('{"alg": "HS256","typ": "JWT"}', '{"id": 1, "exp": 1524683318}', TRUE)
^^^ ^^^
In reply to your comment, the error in your new query comes from:
SELECT verify('xxx', 'yyy')
INTO jwt_parts;
This again tries to assign a single column to a three-column type. Instead, you can use:
SELECT * FROM verify('xxx', 'yyy')
INTO jwt_parts;
You shouldn't select a tuple but a regular row (remove parenthesis):
SELECT '{"alg": "HS256","typ": "JWT"}', '{"id": 1, "exp": 1524683318}', TRUE
I'm new with PL/SQL I have a assignment where I need to make a function. The assignment is as follows:
> "Create a function 'afdeling_van:'
> - this function accepts a medewerkernummer(employee number) as argument
> - give the afdelingnummer(department number) from the medewerkernummer(employee number) back"
So I need to create a function with a parameter that returns a number. After that I probably need to add some code to make it return a medewerker(employee) number back.
I got pretty stuck with this one as I am really new to PL/SQL. What I do have at the moment is this:
declare
procedure afdeling_van(p_persoon in medewerkers.mnr%type)--table name with column name
is
begin
select med.mnr
from medewerkers med;
where mnr = p_persoon;
end afdeling_van;
begin
afdeling_van(10);
end;
It's not working for me. I have tried different solutions. But as I lack experience and I cannot find the solution or information that I need on the web. I am trying it to ask here
one other thing. I think it's similair to my problem. In the previous assignment I made a procedure instead of a function. The procedure is as follows:
declare
v_medewerker varchar2(50) := ontsla_med();
procedure ontsla_med(p_medewerkers in medewerkers.naam%type)
is
begin
delete from medewerkers
where naam = p_medewerkers;
end ontsla_med;
begin
ontsla_med('');
dbms_output.put_line('Medewerker: ' || v_medewerker || 'verwijdert uit medewerker, inschrijven en uitvoeringen bestand.' );
exception
when no_data_found then
dbms_output.put_line('Medewerker bestaat niet/ is al verwijderd.');
end;
/
this works except for the last dbms_output.put_line. If I remove the output line, then it will work and with the output line, it won't.
I hope my question is not too vague.
Thanks in advance.
You need to create a function instead of a procedure, and you've got a semi-colon in the wrong place. Try something like:
declare
nReturned_value MEDEWERKERS.AFDELINGNUMMER%TYPE;
FUNCTION afdeling_van(p_persoon in medewerkers.mnr%type) --table name with column name
RETURN MEDEWERKERS.AFDELINGNUMMER%TYPE
is
nAFDELINGNUMMER MEDEWERKERS.AFDELINGNUMMER%TYPE;
begin
select med.AFDELINGNUMMER
INTO nAFDELINGNUMMER
from medewerkers med
where mnr = p_persoon;
RETURN nAFDELINGNUMMER ;
end afdeling_van;
begin
nReturned_value := afdeling_van(10);
DBMS_OUTPUT.PUT_LINE('nReturned_value = ' || nReturned_value);
end;
Edit
In your second example, I don't believe that the line v_medewerker varchar2(50) := ontsla_med(); will compile. ontsla_med is a procedure rather than a function, and because procedures don't return anything they can't be used in an assignment statement.
However, v_medewerker is only used in the DBMS_OUTPUT line which you say causes a problem - thus, it may be that the compiler is eliminating the variable because it's not used if the DBMS_OUTPUT line is removed, thus eliminating the problem. Try changing the declaration to v_medwerker varchar2(50) := 'Hello'; and see if that helps.
I want to make a function which will check each character of a string.
For example, lets take a word "pppppoooossssttt", in this case the function will return a warning if same character repeated for more that 2 times. Here 'p' is repeated for 5 times. So the function will return a warning message.
If you're able to install plpython on your setup, this is what I would do. Then you could simply place this test inside a "WHERE" clause of a standard SQL function. It's immutable so it will only be called once, and it always returns True so it won't affect the results of a SQL query. Postgres has had some pretty shaky python implementations but either they or EnterpriseDB cleaned things up in the latest release.
CREATE OR REPLACE FUNCTION two_or_less(v text)
RETURNS BOOLEAN AS $$
#If the string is two characters
#or less, we can quit now.
ct = len(v)
if ct < 3:
return True
import plpy
warned = set()
a,b,c = v[:3]
for d in v[2:]:
if a == b == c:
if a not in warned:
warned.add(a)
plpy.warning('The character %r is repeated more than twice in a row.' % a)
a,b,c = b,c,d
return True
$$ LANGUAGE 'plpython3u' IMMUTABLE;
I'm writing long digit arythmetics. This is a function for adding to longint long binary digits. I need to output the sum inside the function, to debug it. How could I do it, without creating new variables?
function add(var s1,s2:bindata;shift:longint):bindata;
var l,i:longint;
o:boolean;
begin
writeln(s1.len,' - ',s2.len);
o:=false;
l:=max(s1.len,s2.len);
add.len:=0;
for i:=1 to l do begin
if o then Begin
if s1.data[i+shift] then Begin
if (s2.data[i]) then add.data[i+shift]:=true
Else add.data[i+shift]:=false;
End
else if s2.data[i] then add.data[i+shift]:=false
else Begin
add.data[i+shift]:=true;
o:=false;
End;
End
Else Begin
if s1.data[i+shift] then Begin
if s2.data[i] then
Begin
add.data[i+shift]:=false;
o:=true;
End
Else add.data[i+shift]:=true;
End
else if s2.data[i] then add.data[i+shift]:=true
else add.data[i+shift]:=false;
End;
output(add); //Can I output a variable?
end;
add.len:=l;
if o then Begin
inc(add.len);
add.data[add.len]:=true;
End;
end;
You are accumulating the result of the function within the function result variable, which is generally fine, but uses an outdated style, and leads to exactly the problem you're facing here. You're trying to report an intermediate value of the function result, and to do that, you're trying to reference the name of the function, add. When you do that, though, the compiler interprets it as an attempt to report the function itself, rather than the expected return value of this particular invocation of the function. You'll get the address of the function, if output is defined to accept function addresses; otherwise, you'll get a compiler error.
If your compiler offers a certain common language extension, then you should use the implicit Result variable to refer to the intermediate return value instead of continuing to refer to it by the function name. Since Result is declared implicitly, you wouldn't have to create any other variables. The compiler automatically recognizes Result and uses it as an alias for the function's return value. Simply find every place you write add within the function and replace it with Result. For example:
if o then begin
Inc(Result.len);
Result.data[Result.len] := True;
end;
Turbo Pascal, Free Pascal, GNU Pascal, and Delphi all support the implicit Result variable, but if you've managed to get stuck with a compiler that doesn't offer that extension, then you have no choice but to declare another variable. You could name it Result, and then implement your function with one additional line at the end, like so:
function add(var s1, s2: bindata; shift: longint): bindata;
var
l, i: longint;
o: boolean;
Result: bindata;
begin
{
Previous function body goes here, but with
`add` replaced by `Result`
}
{ Finally, append this line to copy Result into the
function's return value immediately before returning. }
add := Result;
end;