I am working on PL/SQL code, My purpose is to declare function with definition then assign it to variable then call it using that variable.
declare
func varchar2(50);
function add(a NUMBER,b NUMBER)
return BOOLEAN is
c NUMBER;
begin
c := a+b;
dbms_output.put_line(c);
end add;
begin
func :='add'; or func :=add;
if (func(10,20)=false) then
dbms_output.put_line('false statement');
else
dbms_output.put_line('true statement');
end if;
end;
But this is not working. So I am not getting how to assign function to variable.
You should build an anonymous block with the function call you need and then call it with EXECUTE IMMEDIATE. You should know how many arguments the function has though.
Something like this:
DECLARE
func VARCHAR2(20);
value1 NUMBER := 10;
value2 NUMBER := 20;
plsql_block VARCHAR2(500);
out_value NUMBER;
BEGIN
func := 'add';
plsql_block := 'BEGIN :v := ' || func || '(:v1,:v2); END;';
EXECUTE IMMEDIATE plsql_block USING OUT out_value, IN value1, value2;
IF out_value > 0 THEN
dbms_output.put_line('TRUE statement');
ELSE
dbms_output.put_line('FALSE statement');
END IF;
END;
Related
I have this query in MySQL
create function is_prime(num int) returns boolean
begin
declare cont;
set cont = 2;
while(cont != num) do
if (num % cont = 0) then
return false;
end if;
cont = cont + 1;
end while;
return true;
end//
VSCode show a syntaxt error. I have checked each line but i dont look the error.
Thanks and sorry for my english.
Declaration has to have a datatype
Also you forgot to Set the increase
DELIMITER //
create function is_prime(num int) returns boolean
begin
declare cont INTEGER;
set cont = 2;
while(cont != num) do
if (num % cont = 0) then
return false;
end if;
SET cont := cont + 1;
end while;
return true;
end//
This is my situation:
I have a procedure that do an update table like this:
PROCEDURE UPDATE_MODEL AS
STR VARCHAR2(10000);
BEGIN
STR:='UPDATE SAE_MODEL_TABLE.....'
EXECUTE IMMEDIATE STR;
I need to do a function that call this UPDATE SAE_MODEL_TABLE...
I tried with this code
FUNCTION GET_MODEL_TABLE RETURN CLOB AS
STR4 VARCHAR2(50);
count_table number;
BEGIN
str4:='select count(1) from SAE_MODEL_TABLE;
execute immediate str4 into count_table;
IF count_table <> 0 then
UPDATE_MODEL ;
I have this error:
ORA-14551: DML operation can not be performed within a query,
I know that refers for add an update...
I do not know why you use dynamic SQL, but if you really want to do it, it might look like this
PROCEDURE UPDATE_MODEL AS
STR VARCHAR2(10000);
BEGIN
STR:='UPDATE SAE_MODEL_TABLE.....'
EXECUTE IMMEDIATE STR;
end;
FUNCTION GET_MODEL_TABLE RETURN CLOB AS
STR4 VARCHAR2(50);
count_table number;
my_clob clob;
BEGIN
str4:='select count(1) from SAE_MODEL_TABLE';
execute immediate str4 into count_table;
IF count_table <> 0 then
UPDATE_MODEL() ;
end if;
return my_clob;
end;
I didn't found anything on the net about this (maybe bad keywords). I'm trying to find a way to give in parameter a function in Pascal. For example :
function foo1(arg1, arg2 : integer) : double;
begin
...
end;
function foo2(func : function, arg1 : integer) : double;
begin
foo2 := foo1(arg1, 2);
end;
And the call should be something like foo2(foo1, arg1).
Is there any way to do that ?
Found this :
type TFunction = function (arg1, arg2 : integer) : integer;
function foo1(arg1, arg2 : integer) : integer;
begin
foo1 := arg1 + arg2;
end;
function foo2(func : TFunction, arg1 : integer) : integer;
begin
foo2 := func(arg1, 2) * 3;
end;
The call should be something like foo2(#foo1, 2)
Yes, it is posibble, and it's more simple than you think, there is no need to send a function as a parameter, every function/procedure that is declared can be used in another modules that are implemented after that declarations (the only exception is trying to call a procedure from a function, you can't do that).
I think this is what you want:
function foo1(arg1, arg2 : integer) : double;
begin
...
end;
function foo2(arg1 : integer) : double;
begin
foo2 := foo1(arg1, 2);
end;
begin
...
foo2(2);
Becuase foo1 is declared before foo2, you can call it from foo2.
help me, please.
I don't know how to fix this error.
Program Polynomial;
type
arrayOfInt = Array[1..21] of Integer;
biggerArrayOfInt = Array[1..41] of Integer;
function isNumber(c : Char): Boolean;
var
res : Boolean;
code : Longint;
begin
code := Ord(c);
if ((code > 47) AND (code < 58)) then begin
res := true
end
else
begin
res := false;
end;
isNumber := res;
end;
function parsePolynomial(polynomial : String): arrayOfInt;
var
coeficients : Array[1..21] of Integer;
number : Integer;
coef : Integer;
tmp : String;
i, j : Integer;
positive : Boolean;
numberPosition, numberLength : Integer;
expectX : Boolean;
begin
i := 1;
for j:=1 to Length(coeficients) do
begin
coeficients[j] := 0;
end;
while (true) do
begin
coef := 0;
number := 0;
positive := true;
expectX := true;
if(polynomial[i] = '-') then begin
positive := false;
i := i + 1;
end;
if(polynomial[i] = '+') then begin
i := i + 1;
end;
if(isNumber(polynomial[i])) then begin
numberPosition:= i;
while (isNumber(polynomial[i])) do
begin
i := i + 1;
end;
tmp := Copy(polynomial, numberPosition, i - numberPosition);
Val(tmp, number);
if(not positive) then begin
number := number * -1;
end;
if ((not(polynomial[i] = '*')) OR (i > length(polynomial))) then
begin
expectX := false;
end
else
begin
i:= i + 1;
end;
end
else
begin
if(positive) then begin
number := 1;
end
else
begin
number := -1;
end;
end;
if (expectX) then begin
if(not(polynomial[i] = 'x')) then begin
write('Bad input!');
exit;
end
else
begin
i := i + 1;
if (polynomial[i] = '^') then begin
i := i + 1;
if (not isNumber(polynomial[i])) then begin
write('Bad input!');
exit;
end;
numberPosition:= i;
while (isNumber(polynomial[i])) do
begin
i := i + 1;
end;
tmp := Copy(polynomial, numberPosition, i - numberPosition);
Val(tmp, coef);
end
else
begin
coef := 1;
end;
end;
end;
coeficients[coef + 1] := number;
if ((length(polynomial)) - 1 < i) then begin
break;
end;
end;
parsePolynomial := coeficients;
end;
function sumPolynomial(polynomial1, polynomial2 : array of Integer): arrayOfInt;
var
coeficients : Array[1..21] of Integer;
i : Integer;
begin
for i := Length(polynomial1) downto 0 do
begin
coeficients[i+1] := polynomial1[i] + polynomial2[i];
end;
sumPolynomial := coeficients;
end;
function productOfPolynomial(polynomial1, polynomial2 : array of Integer): biggerArrayOfInt;
var
coeficients : Array[1..41] of Integer;
i, j : Integer;
begin
for j:=1 to Length(coeficients) do
begin
coeficients[j] := 0;
end;
for i := Length(polynomial1) downto 0 do
begin
for j := Length(polynomial2) downto 0 do
begin
coeficients[i+j+1] := coeficients[i+j+1] + polynomial1[i] * polynomial2[j];
end;
end;
productOfPolynomial := coeficients;
end;
function substractOfPolynomial(polynomial1, polynomial2 : array of Integer): arrayOfInt;
var
coeficients : Array[1..21] of Integer;
i : Integer;
begin
for i := Length(polynomial1) downto 0 do
begin
coeficients[i+1] := polynomial1[i] - polynomial2[i];
end;
substractOfPolynomial := coeficients;
end;
procedure printPolynomial(polynomial: array of Integer);
var
i : Integer;
isFirst : Boolean;
isZero : Boolean;
begin
isFirst := true;
isZero := true;
for i := length(polynomial) downto 0 do
begin
if polynomial[i] <> 0 then begin
isZero := false;
if((not isFirst) AND (polynomial[i] > 0)) then begin
write('+');
end;
if((polynomial[i] = -1)) then begin
write('-');
end;
if(((polynomial[i] > 1) OR (polynomial[i] < -1)) OR ((i = 0) AND not(polynomial[i] = 0))) then begin
write(polynomial[i]);
if((i > 0)) then begin
write('*');
end;
end;
if(i > 0) then begin
write('x');
isFirst := false;
if (i > 1) then begin
write('^', i);
end;
end;
write()
end;
end;
if (isZero) then begin
write(0);
end;
end;
var
polynomial1, polynomial2, result: Array[1..21] of Integer;
polynomialInput: String;
begin
readln(polynomialInput);
polynomial1 := parsePolynomial(polynomialInput);
readln(polynomialInput);
polynomial2 := parsePolynomial(polynomialInput);
printPolynomial(sumPolynomial(polynomial1, polynomial2));
writeln('');
printPolynomial(substractOfPolynomial(polynomial1, polynomial2));
writeln('');
printPolynomial(productOfPolynomial(polynomial1, polynomial2));
end.
Runtime error 201 means range check error. Quick glance over the source code makes me suspect that somewhere some operation returns a value that doens't fit in integer range (-32786..32767 in FreePascal by default). Easiest solution would be to use a larger datatype for example longint (roughly between -2*10^9..2*10^9) or int64 (~9*10^18..9*10^18).
If you use command line compiler using -gl command line option would display line numbers in run-time error backtraces. This would make it easier for you to pinpoint the issue.
I want to create a function with optional arguments in MySQL. For instance, I want to create function that calculates the average of its arguments. I create a function of five arguments, but when user passes just two arguments to the function then it should still run and return the average of the two arguments.
You cannot set optional parameters in MySQL stored procedures.
You can however set optional parameters in a MySQL UDF.
You do know that MySQL has an AVG aggregate function?
Workaround
If you can face the ugliness of this workaround here's samplecode that uses a comma separated string with values as input and returns the average.
DELIMITER $$
CREATE FUNCTION MyAvg(valuestr varchar) RETURNS float
BEGIN
DECLARE output float;
DECLARE arg_count integer;
DECLARE str_length integer;
DECLARE arg float;
DECLARE i integer;
SET output = NULL;
SET i = LENGTH(valuestr);
IF i > 0 THEN BEGIN
SET arg_count = 1;
WHILE i > 0 DO BEGIN
IF MID(valuestr, i, 1)
SET i = i - 1;
END; END WHILE;
/* calculate average */
SET output = 0;
SET i = arg_count;
WHILE i > 0 DO BEGIN
SET arg = SUBSTRING_INDEX(
SUBSTRING_INDEX(valuestr, ',' , i)
, ',', -1 );
SET output = output + arg;
SET i = i - 1;
END; END WHILE;
SET output = output / arg_count;
END; END IF;
RETURN output;
END $$
DELIMITER ;
Use concat_ws to feed the function.
SELECT MyAvg(CONCAT_WS(',',100,200,300,500)) AS test;
You can also write an UDF in C(++) or Delphi/Lazarus
While far from an ideal solution, here's how I solved optional parameters for a concat function I needed:
delimiter ||
create function safeConcat2(arg1 longtext, arg2 varchar(1023))
returns longtext
return safeConcat3(arg1, arg2, '');
||
create function safeConcat3(arg1 longtext, arg2 varchar(1023), arg3 varchar(1023))
returns longtext
return safeConcat4(arg1, arg2, arg3, '');
||
create function safeConcat4(arg1 longtext, arg2 varchar(1023), arg3 varchar(1023), arg4 varchar(1023))
returns longtext
begin
declare result longText;
set result = concat(arg1, arg2, arg3, arg4);
if( result is null) then
set result=arg1;
end if;
return result;
end
||
Note: This means you have to call the method that corresponds to the number of args.
Another approach is to pass only one 'super' parameter which is string with commas in it separating the real parameters. The mysql procedure can then parse the 'super' parameter into the separate real parameters.
Example:
create procedure procWithOneSuperParam(param1 varchar(500))
declare param2 varchar(100);
begin
if LOCATE(',',param1) > 0 then
.. param2=<extract the string after the ',' from param1> ..