Lenguajes:PHP, PL/SQL
Problema:No consigo que se ejecute ningún procedimiento PL/SQL almacenado desde mi script PHP.
Códigos:Tablas:
/*GOODS TABLE, WILL CONTAIN ALL GOODS*/
CREATE TABLE GOODS(
ID INT(3) AUTO_INCREMENT,
NAME CHAR(20) UNIQUE,
IMGFILE CHAR(20),
L_PRICE INT(4),
S_PRICE INT(4),
H_PRICE INT(4),
C_PRICE INT(4),
PRIMARY KEY(ID));
/*TRADERS TABLE, WILL CONTAIN ALL USERS AND THEIR DATA*/
CREATE TABLE TRADERS(
ID INT(3) AUTO_INCREMENT,
USERNAME CHAR(20) NOT NULL,
PASSWORD CHAR(20) NOT NULL,
MAIL CHAR(40) NOT NULL,
CREDITS CHAR(20) NOT NULL,
PRIMARY KEY(ID));
/*STOCKS TABLE, WILL CONTAIN EACH USER'S (TRADER) STOCK*/
CREATE TABLE STOCKS(
GOOD_ID INT(3),
TRADER_ID INT(3),
AMMOUNT INT(10),
AVG_BUY INT(4),
FOREIGN KEY(GOOD_ID)
REFERENCES GOODS(ID)
ON DELETE CASCADE,
FOREIGN KEY(TRADER_ID)
REFERENCES TRADERS(ID)
ON DELETE CASCADE);
Procedimiento Almacenado a llamar:
/*THIS PROCEDURE ALLOWS THE TRADERS TO BUY STOCKS*/
CREATE PROCEDURE BUY_STOCK(P_GOOD INT,P_TRADER INT,P_AMMOUNT INT)
BEGIN
DECLARE V_PRICE, V_COST INT;
SELECT C_PRICE INTO V_PRICE
FROM GOODS
WHERE ID = P_GOOD;
SET V_COST = V_PRICE*P_AMMOUNT;
IF HAS_CREDITS(P_TRADER,V_COST) THEN
IF HAS_STOCK(P_GOOD,P_TRADER) THEN
UPDATE STOCKS
SET AMMOUNT = AMMOUNT + P_AMMOUNT
WHERE GOOD_ID = P_GOOD
AND TRADER_ID = P_TRADER;
UPDATE STOCKS
SET AVG_BUY = ((AVG_BUY*(AMMOUNT-P_AMMOUNT))+(V_PRICE*P_AMMOUNT))/AMMOUNT
WHERE GOOD_ID = P_GOOD
AND TRADER_ID = P_TRADER;
ELSE
INSERT INTO STOCKS
VALUES(P_GOOD,P_TRADER,P_AMMOUNT,V_PRICE);
END IF;
UPDATE TRADERS
SET CREDITS = CREDITS - V_COST
WHERE ID = P_TRADER;
END IF;
END;
Código PHP que trata de llamar al procedimiento almacenado:
<?php
if($_POST['transaction'] = "Buy")
{
$good = $_POST['goodid'];
$id = $_SESSION['id'];
$ammount = $_SESSION['ammount'];
$db = new PDO("mysql:host=localhost;dbname=trademaster", 'trader', '********');
$x = $db->prepare('CALL BUY_STOCK(:good, :trader, :ammount)');
$x->bindValue(':good', $good, PDO::PARAM_INT);
$x->bindValue(':trader', $id, PDO::PARAM_INT);
$x->bindValue(':ammount', $ammount, PDO::PARAM_INT);
$x->execute();
header("location:stocks.php"); }
?>
Error:PDOStatement::execute(): SQLSTATE[42000]: Syntax error or access violation: 1370 execute command denied to user 'trader'@'localhost' for routine 'trademaster.BUY_STOCK'
Observaciones:El usuario 'trader'@'localhost' que interactúa con la base de datos tiene los permisos de USAGE, SELECT, INSERT, UPDATE, DELETE y EXECUTE sobre todas las tablas de la base de datos (trademaster.*).
Queries hacia la base de datos con SELECT, INSERT y UPDATE funcionan.
El procedimiento almacenado funciona correctamente, ya lo he probado localmente desde una consola MySQL.
La password del objeto PDO la quité por razones evidentes.
Los valores POST y SESSION se recogen adecuadamente, lo he comprobado.