MySQL CREATE FUNCTION fails on a shared webserver - mysql

I have the following function. When I try to create it on a webserver, it fails with
You do not have the SUPER privilege and binary logging is enabled (you might want to use the less safe log_bin_trust_function_creators variable)
I never had the same problem with any other webhosting (and the exact same function), how can I fix this? (I can't change MySQL settings).
CREATE FUNCTION `has_action_access`(in_role VARCHAR(255), in_request VARCHAR(255), in_action VARCHAR(255)) RETURNS tinyint(1)
READS SQL DATA
DETERMINISTIC
BEGIN
DECLARE current_role VARCHAR(255);
DECLARE found, cont TINYINT(1) DEFAULT 0;
SET current_role = in_role;
findattempt: REPEAT
SELECT COUNT(*) FROM cyp_action_access WHERE request = in_request AND action = in_action AND role = current_role INTO found;
IF found = 0 THEN
SELECT COUNT(*) FROM cyp_roles WHERE name = current_role INTO cont;
IF cont = 1 THEN
SELECT inherits FROM cyp_roles WHERE name = current_role INTO current_role;
END IF;
END IF;
UNTIL (cont = 0 OR found > 0) END REPEAT;
RETURN found;
END;
MySQL server's version is 5.0.90-log.

Your user does not have super privilege. You will need to contact your webhosting provider and have them update this. If they will not grant you that option ask them to execute the script for you.

Related

Stored procedure not updating table

Hi still trying to debug this issue so I've stripped things down to the bare basics, following the PHP manual.
SP:
DROP IF EXISTS(`login_validator`);
CREATE PROCEDURE `login_validator` (
IN Username VARCHAR(75),
OUT ReturnValue VARCHAR(1000)
)
BEGIN
END
PHP call:
$SP1SQL = 'call login_validator(:Username, :ReturnValue)';
$Stmt = $DBConnection->Prepare($SP1SQL);
$Stmt->BindParam('Username', $Name, PDO::PARAM_STR);
$Return = null;
$Stmt->BindParam(':ReturnValue', $Return, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 1000);
$Stmt->Execute();
I get:
SQLSTATE[42000]: Syntax error or access violation: 1414 OUT or INOUT argument 2 for routine myDB.login_validator is not a variable or NEW pseudo-variable in BEFORE trigger
Everything I read says this should work...
I'm trying to get this sp to update the user_login_attempts tbl if the user enters the wrong username and return some values to the calling script.
When called The SP runs without errors and returns only one value
I expect it's some flaw in my logic, but I can't spot it...
I'm calling it like this
$SP1 = 'call login_authentication(:Username, :LoginIP, :IPGeoLocation, #ReturnStatus)';
// binding variables
// execute
If I vardump
$SP1RS = $Stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($SP1RS);
I get back the correct value of v_Username and all the other values are set to SP's default declarations
If I call it the usual way
$SP1 = 'call login_authentication(:Username, :LoginIP, :IPGeoLocation, :ReturnStatus)';
I get the error MySQL :: Error 1414 OUT or INOUT argument 4 for routine login_authentication is not a variable or NEW pseudo-variable in BEFORE trigger.
CREATE PROCEDURE `login_authentication`(
IN `v_Username` VARCHAR(75),
IN `v_LoginIP` VARBINARY(16),
IN `v_IPGeoLocation` VARCHAR(30),
INOUT `v_ReturnStatus` VARCHAR(1000)
)
BEGIN
DECLARE v_QueryDB BOOLEAN DEFAULT 1;
DECLARE v_Error BOOLEAN DEFAULT 0;
DECLARE v_ErrorMsg VARCHAR(250) DEFAULT null;
DECLARE v_Attempts TINYINT(1) DEFAULT 0;
DECLARE v_LastAttempt TIMESTAMP DEFAULT null;
DECLARE v_Hash VARBINARY(256) DEFAULT null;
# DECLARE v_LoginIP VARBINARY(16) DEFAULT INET_ATON(v_LoginIP);
SET v_LoginIP = INET_ATON(v_LoginIP);
# Check if user has any previous unsuccessful login attempts
IF EXISTS(SELECT Username FROM users_login_attempts WHERE Username = v_Username AND Attempts > 4) THEN
SELECT Attempts INTO v_Attempts FROM users_login_attempts WHERE Username = v_Username;
SELECT LastAttempt INTO v_LastAttempt FROM users_login_attempts WHERE Username = v_Username; # Get time of last users last login
# User has been timed out
IF (v_Attempts = 5 AND v_LastAttempt > (NOW() - INTERVAL 10 minute)) THEN
SET v_Error = 1;
SET v_ErrorMsg = 'Sorry, you are still timed out!';
SET v_QueryDB = 0;
END IF;
# other conditions
END IF;
# Query DB for valid username
IF (v_QueryDB = 1) THEN
# Query DB for password hash
IF EXISTS(SELECT Password FROM users WHERE(Email = v_Username || Mobile = v_Username)) THEN
SELECT Password INTO v_Hash FROM users WHERE(Email = v_Username || Mobile = v_Username);
ELSE
# Username not found in DB
# Update user logins table with failed attempt if not already locked
IF (v_Attempts < 7) THEN
INSERT INTO users_login_attempts(
Username,
Attempts,
IPAddress,
IPGeoLocation)
VALUES(
v_Username,
v_Attempts,
v_LoginIP,
v_IPGeoLocation)
ON DUPLICATE KEY UPDATE
Attempts = Attempts +1,
IPAddress = VALUES(IPAddress),
IPGeoLocation = VALUES(IPGeoLocation);
# Update Attempts from DB
SELECT Attempts INTO v_Attempts FROM users_login_attempts WHERE Username = v_Username;
END IF;
END IF;
# Set error messages for failed login attempts
IF (v_Attempts > 0) THEN
SET v_ErrorMsg = 'The supplied credentials were not recognised'; # Default msg
IF (v_Attempts = 5) THEN
SET v_Error = 1;
SET v_ErrorMsg = 'Due to repeated failed login attempts, Your account has been temporarily locked for 10 minutes!';
END IF;
# more conditions
END IF;
END IF;
# set output result
IF (v_Hash != null) THEN
SELECT v_Hash AS PasswordHash;
ELSE
SELECT v_ErrorMsg AS ErrorMsg,
v_Attempts AS LoginAttempts,
INET_NTOA(v_LoginIP) AS IPAddress,
v_Username AS Username;
END IF;
END
check this line:
$Stmt->BindParam(':Username', $Name, PDO::PARAM_STR);
especially ':Username'

CREATING FUNCTIONS mysql

im using
CREATE FUNCTION UPDATEGames(usernameIN CHAR(15) ,opponientIN CHAR(15) ,mFilePath TINYTEXT,oFilePath TINYTEXT)
BEGIN
UPDATE games
IF (username = opponientIN AND FilePath = oFilePath) THEN SET opLastTurn = NOW(),Turn=Turn+1
ELSEIF (username = usernameIN AND FilePath = mFilePath) THEN SET myLastTurn = NOW(),Turn=Turn+1
END IF
END;
but it didnt worked, what am i ding wrong?and if it isnt possible to do it so then how can i simulate this logic?
Within the update you can only use the if function, not the if statement. The if statement can only be used to execute different sql statements. Furthermore, the where criteria must be used in the update to restrict the records to be updated.
So, there is no need to use if statement at all, just use two updates. There is no return value either, so I also changed function to procedure.
DELIMITER //
CREATE PROCEDURE UPDATEGames(usernameIN CHAR(15) ,opponientIN CHAR(15) ,mFilePath TINYTEXT,oFilePath TINYTEXT)
BEGIN
UPDATE games SET opLastTurn = NOW(),Turn=Turn+1 WHERE username = opponientIN AND FilePath = oFilePath;
UPDATE games SET myLastTurn = NOW(),Turn=Turn+1 WHERE username = usernameIN AND FilePath = mFilePath;
END//
DELIMITER ;

getting wrong value of out param on mysql procedure

I created a procedure on mysql.
Here's my sql.
drop procedure if exists proc_serial_no;
DELIMITER //
CREATE PROCEDURE `proc_serial_no`(IN comp_code varchar(20), IN meat_rule_one varchar(20),OUT serial_no int)
LANGUAGE SQL
NOT DETERMINISTIC
MODIFIES SQL DATA
SQL SECURITY INVOKER
COMMENT 'serial no generator for trace code'
begin
declare current_no int default 0;
select serial_no into current_no from t_serial_no where comp_code = comp_code and rule = meat_rule_one;
if current_no = 0
then insert into t_serial_no (id,no,comp_code,rule) values ( replace(uuid(),'-',''),1,comp_code,meat_rule_one);
else update t_serial_no set no = no + 1 where comp_code = comp_code and rule = meat_rule_one;
end if;
select serial_no = current_no + 1;
end
I'm expecting the out param [serial_no] to increase every time I call the procedure,but it's always zero.
When I change sql related to the out param to
select no into serial_no from t_serial_no where comp_code = comp_code and rule = meat_rule_one;
It worked!
I could't figure out why. Anyone can answer this would be in great help!
This may be right or wrong. But it may be due to ,
Everytime you call the procedure , the local variable current_no is by its default value it is 0.
When the scope moves out of the procedure and again when you call that procedure, it again starts with its default value 0 again and again.
And also,
May be everytime you pass the value 0 to serial_no param everytime you call that procedure and it again starts with 0 everytime when the scope moves out and comes in.

MySQL Stored Procedure Search another table

I am totally new to Stored Procedures, but know that this could be more efficient than trying to write PHP+MySQL code each time I need to do something like this.
I have two tables. CapitalAssets, Systems
I want find all CapitalAssets.ServerName that are not null
I have to link the two tables together, the Systems table has IP addresses, hostname.
I want to (row-by-row) grab CapitalAssets.ServerName and search Systems.hostname, IF it is found I want to link/print
CapitalAssests: Systems.id, Systems.hostname, Systems.IP, CapitalAssets.id, CapitalAssets.ServerName
Here is my start to my stored procedure, It is wrong. I do not now how to pass the Systems.hostname to do the search (where the ? is)
begin
declare GSATcur cursor for
'select id,NEName,ManagementAddress FROM GSAT WHERE NEName like ?';
declare CapitalCurr CURSOR FOR
'SELECT id,SystemName FROM CapitalAssets WHERE SystemName != ""';
DECLARE start INT DEFAULT 0;
DECLARE sysname_not_found BOOL DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET sysname_not_found = TRUE;
OPEN GSATcur;
OPEN CapitalCur;
loop1:
WHILE start < 5 do
FETCH SystemName INTO NEName;
IF sysname_not_found THEN
LEAVE loop1;
END IF;
END WHILE;
CLOSE CapitalCur;
CLOSE GSATcur;
END;
The two tables are in the same dB.
" grab CapitalAssets.ServerName and search Systems.hostname, IF it is found I want to link/print "
If this is the ultimate goal. Try this
SELECT * FROM Systems
WHERE hostname IN ( SELECT DISTINCT(ServerName)
FROM CapitalAssets WHERE ServerName IS NOT NULL );
UPDATE CapitalAssets
INNER JOIN Systems
ON Systems.hostname = CapitalAssests.ServerName
SET CapitalAssets.ipAddress = Systems.ipAddress;
UPDATE CapitalAssets
SET ipAddress = ( SELECT ipAddress
FROM Systems
WHERE Systems.hostname = CapitalAssests.ServerName );

MySQL Routines in phpmyadmin - Unresolved Declare Error

I'm using phpmyadmin Routines to write a Stored Procedure called ViewUserAccounts.
I am continuously getting ambiguous error messages.
I have one IN parameter named USERNAME of type VARCHAR(45).
The text within the definition box includes:
DECLARE TempUserID INT DEFAULT 0
SET TempUserID = (SELECT idUser FROM User WHERE User.Username = USERNAME)
SELECT * FROM Account WHERE Account.idUser = TempUserID
Well...figured it out myself!
DECLARE requires a BEGIN and END and the DECLARE statement must be directly after the BEGIN statement. In addition, all lines required a semi-colon.