MySQL Function Characteristic - mysql

I want to create a function that basically returns a random string. I don't know what characteristics to assign in this situation. I'm also in an environment that uses binary logging.
Here's a simplified version of my function:
CREATE FUNCTION `MYRAND`() RETURNS char(10) NOT DETERMINISTIC
RETURN CONCAT('rand_', FLOOR(RAND() * 10000));
I get this error when creating the function in my environment.
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in
its declaration and binary logging is enabled (you might want to use
the less safe log_bin_trust_function_creators variable)
Possible characteristics:
NOT DETERMINISTIC - used because this function returns random values
READS/MODIFIES SQL DATA - Function does not read data from tables
NO SQL - I am calling other SQL functions (RAND) so I'm not sure if I should be specifying this or not...
Any advice on how to properly define this function when binary logging is enabled would be appreciated.

MySQL wants you to declare the function as DETERMINISTIC, NO SQL, or READS SQL DATA.
Is it DETERMINISTIC? No - Since it is random.
Does id read SQL DATA? No - Since you have no SELECT statement.
Does it modify SQL DATA? No - Since you have no INSERT, UPDATE or DELETE statement.
Since your function does not touch any data in the DB it's NO SQL.
So you should declare it as NOT DETERMINISTIC and NO SQL
CREATE FUNCTION `MYRAND`() RETURNS char(10) NOT DETERMINISTIC NO SQL
RETURN CONCAT('rand_', FLOOR(RAND() * 10000));

Use somthing like this code:
CREATE FUNCTION get_string(in_strlen int) RETURNS VARCHAR(500) DETERMINISTIC
BEGIN
set #var:='';
while(in_strlen>0) do
set #var:=concat(#var,IFNULL(ELT(1+FLOOR(RAND() * 1000),1,2,3,4,5,6,7,8,9));
set in_strlen:=in_strlen-1;
end while;
RETURN #var;
END

Related

Can someone help me with functions in MySQL?

I run the following script:
USE MODERN_FAMILY;
DROP FUNCTION IF EXISTS compare_news;
DELIMITER $$
CREATE FUNCTION compare_news(n INT, m INT)
RETURNS VARCHAR(20)
BEGIN
DECLARE s VARCHAR(20);
IF n>m THEN SET s='>';
ELSEIF n=m THEN SET s='=';
ELSE SET s='<';
END IF;
SET s = CONCAT(n, ' ', s, ' ',m);
RETURN s; END;$$
First script returns this error :
Error Code: 1418. This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you might want to use the less safe log_bin_trust_function_creators variable).
Then, I run this:
USE MODERN_FAMILY;
SELECT compare_news(2,5);
It returns this error:
Error Code: 2014. Commands out of sync; you can't run this command now.
Does someone know if I have an error with the script? Or is related to my SQL configuration?
log_bin_trust_function_creators variable controls whether binary logging should trust the stored function creators for not to create unsafe stored functions.
Reference: Stored Program Logging
When you create a stored function, you must declare either that it is
deterministic or that it does not modify data. Otherwise, it may be
unsafe for data recovery or replication.
By default, for a CREATE FUNCTION statement to be accepted, at least
one of DETERMINISTIC, NO SQL, or READS SQL DATA must be specified
explicitly. Otherwise an error occurs:
ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL,
or READS SQL DATA in its declaration and binary logging is enabled
(you *might* want to use the less safe log_bin_trust_function_creators
variable)
To relax the preceding conditions on function creation (that you must
have the SUPER privilege and that a function must be declared
deterministic or to not modify data), set the global
log_bin_trust_function_creators system variable to 1.
Solution 1: Make your function which doesn't manipulate data or deterministic in nature
CREATE FUNCTION `compare_news`(
`n` INT,
`m` INT
) RETURNS VARCHAR(20) CHARSET latin1 LANGUAGE SQL DETERMINISTIC NO SQL SQL SECURITY DEFINER COMMENT ''
BEGIN
DECLARE s VARCHAR(20);
IF n>m THEN
SET s='>';
ELSEIF n=m THEN
SET s='=';
ELSE
SET s='<';
END IF;
SET s = CONCAT(n, ' ', s, ' ',m);
RETURN s;
END
Solution 2: Enable MySQL to trust such functions by setting mysql log_bin_trust_function_creators variable to ON.
Reference: log_bin_trust_function_creators
SET GLOBAL log_bin_trust_function_creators = 1;
The variable will change upon restart if you do not update the config to reflect the change.

How To emulate MySQL Function with OUT parameter

As far as I understand MySQL does not support functions with OUT (as well as IN / INOUT) parameter types.
I am creating a function
DROP FUNCTION IF EXISTS `GETGOSTAUTHRUS`;
CREATE DEFINER = `root`#`localhost` FUNCTION `GETGOSTAUTHRUS`(`PublID` int)
RETURNS varchar(1024) CHARSET utf8
BEGIN
RETURN .....;
END;
This function is called from SELECT statement:
SELECT
GETGOSTAUTHRUS(p.ID) `AuthList`,.......
FROM....
Everything works fine. However I need to extend the function and return another value of varchar type but I can not declare out prefix varchar(50) variable in the same way as I do in procedure declaration:
CREATE procedure `GETGOSTAUTHRUS`(PublID int, OUT prefix varchar(50))
BEGIN
The only way out I have invented is to declare another function and call it separately, but it seems not optimal as the second function will fetch and process the same data from the tables.
How can I manage the issue?
Functions are supposed to return only one value, you might have the wrong approach here. We don't know what you're exactly trying to do, so we can't tell if we're dealing with a XY problem here. There may be better solutions to your overall problem.
You can solve this however with user-defined variables. These are session bound, so make sure to reset them in your function.

Why my simple T-Sql Function can not run in Query WIndow?

I created a function in SQL Server 2012 Express with the code below.
CREATE FUNCTION IncAge(#Age AS INT)
RETURNS INT
AS
BEGIN
DECLARE #VAR AS INT;
SET #VAR = #Age + 10;
RETURN #VAR;
END
And when I try to call this function from query window, I get an error.
With SELECT IncAge(20) I get error
'IncAge' is not a recognized built-in function name.
With IncAge(20) I get error
Incorrect syntax near '20'.
So what is the problem??
Function have to always be referenced with their schema:
Try
SELECT dbo.IncAge(20)
It's a generally good idea to always use the schema qualifier (usually dbo. - see Bad Habits to Kick: avoiding the schema prefix) for everything - tables, views, stored procedures - but in the case of functions, they're mandatory

Strange error message: "Must declare the scalar variable" when pass TVP parameters into table-valued function

I have a simple custom type for use it as table valued parameter.
Like this:
CREATE TYPE dbo.PeriodsList AS TABLE
(
PeriodDate NVARCHAR(8) NOT NULL
)
I also have very simple table valued function:
alter FUNCTION GetPeriodsInYear (#periods dbo.PeriodsList READONLY) returns #PeriodsSet Table(period NVARCHAR(8))
BEGIN
insert #PeriodsSet
select
'0' as period
Return
end
But when I try to execute this function in this way
DECLARE #periods1 dbo.PeriodsList
INSERT INTO #periods1
VALUES ('20130916')
select * from GetPurchasesInYear(#periods1)
I receive error message - "Must declare the scalar variable "#periods1".
I have found many examples about stored procedures but not about functions. Is it possible to pass table valued parameters into functions?
And where the mistake in my code?
Check the "compatibility level" of your SQL Server 2008 database. If it's set to 80 (SQL Server 2000), you will get the error you are describing when you try to call a function (but not a stored procedure) that takes a table-valued parameter.
It should work if the compatibility level value is 90 (SQL Server 2005) or higher.
To view the compatibility level of your database, do:
SELECT compatibility_level
FROM sys.databases
WHERE name = 'YOUR_DB_NAME_HERE';
Source: http://msgroups.net/microsoft.public.sqlserver.programming/pass-table-valued-para/97879
Changing the compatibility level (SQL Server 2008): http://technet.microsoft.com/en-us/library/bb510680%28v=sql.100%29.aspx

handling runtime exception for sql functions

I use db2 9.7.6 full edition for windows. I need develop functions which can be use on sql select expression.
Functions must contain modifying sql data and handling runtime exceptions. There are two variants, but I have problems of implementations all requirments in ever variants.
The first variant is implementation of sql table function, e.g.
CREATE FUNCTION func1 (val CHAR(20))
RETURNS table(result varchar(1000))
LANGUAGE SQL
MODIFIES SQL DATA
BEGIN atomic
insert into a values(val);
return (select result from a);
END
It works, but I can't implement handling exception how in sql procedures. When I tried to use block "declare exit handler", I got a syntax errors.
The second variant is implementation of pl/sql function, e.g.
CREATE OR REPLACE FUNCTION bb
RETURN varchar2
MODIFIES SQL DATA
AS
BEGIN
insert into st values ('a');
return 0;
END bb;
But when I tried to execute this function, I got error "SQLCODE=-740, SQLSTATE=51034 is defined with the MODIFIES SQL DATA option, which is not valid in the context where the routine is invoked". Help me please.
best regards, Turkin Andrew.
There are many differences between inlined SQL compound and compiled compound. I wrote the following script, and it runs ok in db2 10.1 for LUW.
Script.sql
CREATE or replace FUNCTION func1a (val CHAR(20))
RETURNS varchar(20)
LANGUAGE SQL
READS SQL DATA
BEGIN
declare ret varchar(20);
declare exit handler for sqlstate '02000' resignal sqlstate '08888';
select C1 into ret from T1 fetch first 1 row only;
return ret;
END#
CREATE or replace FUNCTION func1b (val CHAR(20))
RETURNS table(result varchar(20))
LANGUAGE SQL
MODIFIES SQL DATA
BEGIN atomic
insert into T1 values(val);
return (select C1 from T1);
END#
The execution (In Windows client, but it does not matter)
db2 CREATE TABLE T1 (C1 CHAR(20))
db2 -td# -vf Script.sql
db2 "values func1a('s')"
db2 "SELECT * FROM TABLE (FUNC1b('A'))"
As you can see there are many difference in DB2 10.1 for inlined and compiled SQL:
- Single value return vs table or row return.
- Reads vs modified data.
- Condition handler vs nothing.
Due to the function definition, the calling method is different, in one case it is a scalar value, in the other is a function table.
It just doesn't work.
List of maximum access levels
Routine type Default SQL access level Maximum allowed SQL access level
SQL procedures MODIFIES SQL DATA MODIFIES SQL DATA
SQL functions (scalar functions) READS SQL DATA READS SQL DATA
SQL functions (table functions) READS SQL DATA MODIFIES SQL DATA
External procedures MODIFIES SQL DATA MODIFIES SQL DATA
External functions (scalar functions) READS SQL DATA READS SQL DATA
External functions (table functions) READS SQL DATA READS SQL DATA
For scalar functions the maximum level is "READS SQL DATA". There is probably now way around that, so you have to reconsider your coding.