Вы находитесь на странице: 1из 7

Procedimientos almacenados

Las bases de datos de MySQL soportan procedimientos almacenados. Un procedimiento


almacenado es una subrutina almacenada en el catlogo de la base de datos. Las aplicaciones
pueden llamar y ejecutar el procedimiento almacenado. La sentencia de SQL CALL se usa para
ejecutar un procedimiento almacenado.

Parmetros

Los procedimientos almacenados pueden tener parmetros IN, INOUT y OUT, dependiendo de la
versin de MySQL. La interfaz mysqli no tiene una nocin especial de los diferentes tipos de
parmetros.

Parmetro IN

Los parmetros de entrada son proporcionados con la sentencia CALL. Asegrese de que los
valores estn escapados correctamente.

Ejemplo #1 Llamar a un procedimiento almacenado

<?php
$mysqli = new mysqli("ejemplo.com", "usuario", "contrasea", "basedatos");
if ($mysqli->connect_errno) {
echo "Fall la conexin a MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") || !$mysqli-


>query("CREATE TABLE test(id INT)")) {
echo "Fall la creacin de la tabla: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$mysqli->query("DROP PROCEDURE IF EXISTS p") ||


!$mysqli-
>query("CREATE PROCEDURE p(IN id_val INT) BEGIN INSERT INTO test(id) VALUES(id_val); END;"))
{
echo "Fall la creacin del procedimiento almacenado: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$mysqli->query("CALL p(1)")) {
echo "Fall CALL: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!($resultado = $mysqli->query("SELECT id FROM test"))) {


echo "Fall SELECT: (" . $mysqli->errno . ") " . $mysqli->error;
}
var_dump($resultado->fetch_assoc());
?>

El resultado del ejemplo sera:

array(1) {

["id"]=>

string(1) "1"

Parmetro INOUT/OUT

A los valores de los parmetros INOUT/OUT se acceden usando variables de sesin.

Ejemplo #2 Usar variables de sesin

<?php
$mysqli = new mysqli("ejemplo.com", "usuario", "contrasea", "basedatos");
if ($mysqli->connect_errno) {
echo "Fall la conexin a MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP PROCEDURE IF EXISTS p") ||


!$mysqli-
>query('CREATE PROCEDURE p(OUT msg VARCHAR(50)) BEGIN SELECT "Hola!" INTO msg; END;')) {
echo "Fall la creacin del procedimiento almacenado: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$mysqli->query("SET @msg = ''") || !$mysqli->query("CALL p(@msg)")) {


echo "Fall CALL: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!($resultado = $mysqli->query("SELECT @msg as _p_out"))) {


echo "Fall la obtencin: (" . $mysqli->errno . ") " . $mysqli->error;
}

$fila = $resultado->fetch_assoc();
echo $fila['_p_out'];
?>

El resultado del ejemplo sera:

Hola!

Los desarrolladores de aplicaciones y framework pueden proporcionar una API ms conveniente


usando una mezcla de variables de sesiones e inspeccin del catlogo de la base de datos. Sin
embargo, observe el posible impacto de rendimiento de una solucin personalizada basada en la
inspeccin del catlogo.

Manejar conjuntos de resultados

Los procedimientos almacenados pueden devolver conjuntos de resultados. Los conjuntos de


resultados devueltos desde un procedimiento almacenado no se pueden obtener correctgamente
usando mysqli_query(). La funcin mysqli_query() combina la ejecucin de la sentencia y la
obtencin del primer conjunto de resultados dentro de un conjunto de resultados almacenado en
buffer, si existe. Sin embargo, existen unos conjuntos de resultados del procedimiento
almacenado ocultos para el usuario que hacen que mysqli_query() falle al devolver los conjuntos
de resultados esperados por el usuario.

Los conjuntos de resultados devueltos desde un procedimiento almacenado son obtenidos


usandomysqli_real_query() o mysqli_multi_query(). Ambas funciones permiten la obtencin de
cualquier nmero de conjuntos de resultados devueltos por una sentencia, como CALL. El fallo de
la obtencin de todos los conjuntos de resultados devueltos por un procedimiento almacenado
causa un error.

Ejemplo #3 Obtener los resultados de procedimientos almacenados

<?php
$mysqli = new mysqli("ejemplo.com", "usuario", "contrasea", "basedatos");
if ($mysqli->connect_errno) {
echo "Fall la conexin a MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||


!$mysqli->query("CREATE TABLE test(id INT)") ||
!$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3)")) {
echo "Fall la creacin de la tabla: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$mysqli->query("DROP PROCEDURE IF EXISTS p") ||


!$mysqli-
>query('CREATE PROCEDURE p() READS SQL DATA BEGIN SELECT id FROM test; SELECT id + 1 FRO
M test; END;')) {
echo "Fall la creacin del procedimiento almacenado: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$mysqli->multi_query("CALL p()")) {
echo "Fall CALL: (" . $mysqli->errno . ") " . $mysqli->error;
}

do {
if ($resultado = $mysqli->store_result()) {
printf("---\n");
var_dump($resultado->fetch_all());
$resultado->free();
} else {
if ($mysqli->errno) {
echo "Store failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
}
} while ($mysqli->more_results() && $mysqli->next_result());
?>

El resultado del ejemplo sera:

---

array(3) {

[0]=>

array(1) {

[0]=>

string(1) "1"

[1]=>

array(1) {

[0]=>

string(1) "2"

[2]=>

array(1) {

[0]=>

string(1) "3"

---

array(3) {

[0]=>

array(1) {
[0]=>

string(1) "2"

[1]=>

array(1) {

[0]=>

string(1) "3"

[2]=>

array(1) {

[0]=>

string(1) "4"

Uso de sentencias preparadas

No es necesario un trato especial al usar la interfaz de sentencias preparadas para obtener los
resultados del mismo procedimiento almacenado de arriba. Las interfaces de sentencias
preparadas y no preparadas son similares. Obserque que no todas las versioines del servidor de
MYSQL pueden soportar la preparacin de la sentencia SQL CALL.

Ejemplo #4 Procedimientos Almacenados y Sentencias Preparadas

<?php
$mysqli = new mysqli("ejemplo.com", "usuario", "contrasea", "basedatos");
if ($mysqli->connect_errno) {
echo "Fall la conexin a MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

if (!$mysqli->query("DROP TABLE IF EXISTS test") ||


!$mysqli->query("CREATE TABLE test(id INT)") ||
!$mysqli->query("INSERT INTO test(id) VALUES (1), (2), (3)")) {
echo "Fall la creacin de la tabla: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$mysqli->query("DROP PROCEDURE IF EXISTS p") ||


!$mysqli-
>query('CREATE PROCEDURE p() READS SQL DATA BEGIN SELECT id FROM test; SELECT id + 1 FRO
M test; END;')) {
echo "Fall la creacin del procedimiento almacenado: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!($sentencia = $mysqli->prepare("CALL p()"))) {


echo "Fall la preparacin: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$sentencia->execute()) {
echo "Fall la ejecucin: (" . $sentencia->errno . ") " . $sentencia->error;
}

do {
if ($resultado = $sentencia->get_result()) {
printf("---\n");
var_dump(mysqli_fetch_all($resultado));
mysqli_free_result($resultado);
} else {
if ($sentencia->errno) {
echo "Store failed: (" . $sentencia->errno . ") " . $sentencia->error;
}
}
} while ($sentencia->more_results() && $sentencia->next_result());
?>

Por supuesto, tamibin est soportado el uso de la API de vinculacin para la obtencin.

Ejemplo #5 Procedimientos Almacenados y Sentencias Preparadas usando la API de vinculacin

<?php
if (!($sentencia = $mysqli->prepare("CALL p()"))) {
echo "Fall la preparacin: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$sentencia->execute()) {
echo "Fall la ejecucin: (" . $sentencia->errno . ") " . $sentencia->error;
}

do {

$id_out = NULL;
if (!$sentencia->bind_result($id_out)) {
echo "Fall la vinculiacin: (" . $sentencia->errno . ") " . $sentencia->error;
}

while ($sentencia->fetch()) {
echo "id = $id_out\n";
}
} while ($sentencia->more_results() && $sentencia->next_result());
?>

Вам также может понравиться