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.
Related
I am tring to perform a BITOR on a argument that i am passing into a function. so i wrote the below code. Statement 'SET result = arg1 | arg2 ' isnt working. I tried few ways, however i wasnt able to achieve the right result. What do i need to change ?
DELIMITER $$
CREATE FUNCTION BIT_OR(arg1 varchar(255),arg2 varchar(255)) RETURNS varchar(255)
BEGIN
DECLARE result varchar(255);
BEGIN
SET result = arg1 | arg2;
END;
RETURN result;
END $$
DELIMITER ;
select bitwise_OR(00011101,00001111); -- 12127 ( i am expecting 00011111 or 31 (decimal equivalent))
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;
I have a synatx issue with plpgsql. What I want to do is use my arguments as a condition for an if statement. I want to combine to processes into one procedure.
CREATE OR REPLACE FUNCTION fn_name(arg1 int, arg2 date)
returns text as
$body$
DECLARE
arg1 integer;
arg2 date;
Begin
--where I am having the issue
IF EXISTS (%,'%', arg1, arg2)
THEN
INSERT INTO some_table.table
END IF;
RETURN 'complete';
END;
$body$
LANGUAGE plpgsql VOLATILE
Where I know I am having an issue
IF EXISTS (%,'%', arg1, arg2)
THEN
Is there a cleaner way of doing this, or rather, get this to work correctly?
Perhaps you have to check those arguments if they are null by:
IF arg1 is not null and arg2 is not null THEN
--INSERT instruction
END IF;
I have written a code with 8 procedures and 2 functions.
program solar;
var
solararray:array[1..1000000] of longint;
solartrue:array[1..1000000] of boolean;
solarnumber:array[1..1000000] of shortint;
n,counter,counter2,counter3,number,maxn:longint;
fin,fout:text;
procedure Initialize;
begin
assign(fin,'solar.in');
assign(fout,'solar.out');
reset(fin);
rewrite(fout);
end;
procedure FillArray;
begin
read(fin,n);
for counter:=1 to n-1 do
read(fin,solararray[counter]);
close(fin);
end;
procedure First;
begin
if solararray[1] < solararray[2]
then solartrue[1]:=Test_Up(1)
end;
procedure Other;
begin
for counter:=2 to n-1 do
begin
if Test_Up(counter) And Test_Down(counter)
then solartrue[counter]:=true
else solartrue[counter]:=false;
end;
end;
procedure Last;
begin
if solararray[n] > solararray[n-1]
then solartrue[n]:=Test_Down(n)
end;
function Test_Up (place : longint) : boolean;
var
istrue:boolean;
begin
for counter2:=1 to n-1 do
begin
if solararray[place] < solararray[counter2]
then istrue:=true
else;
begin
istrue:=false;
break;
end;
end;
end;
function Test_Down (place : longint) : boolean;
var
istrue:boolean;
begin
for counter3:=place-1 downto 1 do
begin
if solararray[place] > solararray[counter3]
then istrue:=true
else;
begin
istrue:=false;
break;
end;
end;
end;
procedure FindTrues;
begin
number:=0;
for counter:=1 to n do
begin
if solartrue[counter]
then
begin
number:=number+1;
solarnumber[number]:=solararray[counter];
end
end;
end;
procedure Select;
begin
if number=0
then write(fout,'NOT FOUND')
else FindBigger;
end;
procedure FindBigger;
begin
maxn:=solarnumber[1];
for counter:=1 to number do
begin
if solarnumber[counter] > maxn
then maxn:=solarnumber[counter]
end;
write(fout,maxn);
end;
begin
Initialize;
FillArray;
First;
Other;
Last;
FindTrues;
Select;
close(fout);
halt(0);
end.
solar.in looks like the following:
10
3
2
4
1
5
7
8
9
10
8
When I run the program five errors occur:
- solar.pas (28,28) Error: Identifier not found "Test_Up"
- solar.pas (35,13) Error: Identifier not found "Test_Up"
- solar.pas (35,36) Error: Identifier not found "Test_Down"
- solar.pas (44,30) Error: Identifier not found "Test_Down"
- solar.pas (97,17) Error: Identifier not found "FindBigger"
Why it happens and how can I fix it?
Thanks in advance.
In pascal, all functions must be declared before you use them. Move the functions Test_Up, Test_Down and FindBigger higher up the file.
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> ..