Ardilla Quio Ardilla Quio

16 de Septiembre de 2011

Procedimientos almacenados en SQL Server desde PHP

Los procedimientos almacenados (stored procedures) son pequeños programas que se almacenan y ejecutan en la base de datos. En el caso de Microsoft SQL Server son grupos de órdenes en Transact-SQL (T-SQL) que se ejecutan siguiendo un plan. A estos procedimientos almacenados, como si fuesen funciones, se les pueden pasar parámetros para su ejecución (por valor o por referencia) y pueden devolver un valor numérico o el resultado de una consulta. En este artículo veremos cómo se pueden llamar estos procedimientos almacenados desde PHP y cómo manejar los parámetros y valores devueltos.

Empezaremos por un ejemplo simple de procedimiento almacenado y veremos cómo se ejecutaría desde PHP. El código del procedimiento almacenado será este:

CREATE PROCEDURE usp_simple
	@cadena VARCHAR(10),
	@entero INT,
	@mensaje VARCHAR(50) OUTPUT
AS
BEGIN
	SET NOCOUNT ON;

	SET @mensaje = 'cadena: ' + @cadena + ', entero: ' + CAST(@entero AS Varchar);

	RETURN 50001
END

Como vemos es un código muy simple, que lo único que hace es asignar un valor a @mensaje y devolver 50001.

Ahora, para ejecutarlo desde PHP:

$conn = mssql_connect('servidor', 'usuario', 'contraseña');
mssql_select_db('base_datos', $conn);

$p_cadena = 'Probando';
$p_entero = 6;
$p_mensaje = '';
$p_salida = 0;

$stmt = mssql_init('usp_simple', $conn);

mssql_bind($stmt, '@cadena', $p_cadena, SQLVARCHAR, false, false, 10);
mssql_bind($stmt, '@entero', $p_entero, SQLINT4);
mssql_bind($stmt, '@mensaje', $p_mensaje, SQLVARCHAR, true, false, 50);
mssql_bind($stmt, 'RETVAL', $p_salida, SQLINT4);

mssql_execute($stmt);
mssql_free_statement($stmt);

echo 'Mensaje:: ', $p_mensaje, "\r\n", 'Salida:: ', $p_salida;

mssql_close($conn);

Los ejemplos aquí expuestos están hechos lo más sencillos posible y, por lo tanto, no deben ser usados "tal cual", ya que habría que hacer todo tipo de comprobaciones de seguridad.

Lo que hacemos en el código es lo siguiente:

  1. Conectamos con la base de datos
  2. Definimos los valores que le pasaremos al procedimiento almacenado
  3. Iniciamos el procedimiento almacenado
  4. Le pasamos al procedimiento almacenado las variables necesarias mediante mssql_bind
  5. Ejecutamos el procedimiento almacenado y liberamos la memoria usada por el mismo
  6. Mostramos lo que el procedimiento almacenado ha puesto en el parámetro de salida @mensaje y el valor que nos devuelve

En este caso, lo que este código mostraría por pantalla sería:

Mensaje:: cadena: Probando, entero: 6
Salida:: 50001

Como es evidente, el procedimiento almacenado podría hacer cosas mucho más útiles con los datos que se le pasan (por ejemplo introducirlos en la base de datos), no tener ningún parámetro de salida o devolver el resultado de una consulta. Para este último caso, veremos ahora un ejemplo.

Devolviendo resultados de consultas

El código que usaremos como ejemplo de procedimiento almacenado será:

CREATE PROCEDURE usp_normal
	@clase VARCHAR(2)
AS
BEGIN
	SET NOCOUNT ON;

	SELECT id, nombre FROM alumnos WHERE clase=@clase;
END

El procedimiento almacenado devolverá los datos de los alumnos de la clase pedida. Para ejecutarlo desde PHP:

$conn = mssql_connect('servidor', 'usuario', 'contraseña');
mssql_select_db('base_datos', $conn);

$stmt = mssql_init('usp_normal', $conn);

$clase = '2B';

mssql_bind($stmt, '@clase', $clase, SQLVARCHAR, false, false, 2);

$result = mssql_execute($stmt);

do
{
	while ($row = mssql_fetch_row($result))
	{
		echo $row[0],  ', ', $row[1], "\r\n";
	}
}
while (mssql_next_result($result) !== false);

mssql_free_result($result);
mssql_free_statement($stmt);

mssql_close($conn);

Este código pasaría por pantalla algo así:

1, Alejandro García
2, Manuel Pérez
3, Luis Fernández
...

En este caso, $result es el conjunto de resultados de la consulta hecha en el procedimiento almacenado. Para poder ir pasando de una fila a la siguiente en la consulta, hay que usar la función mssql_next_result, hasta que ésta devuelva false. Para convertir cada fila en un array, usamos las funciones habituales mssql_fetch_row, mssql_fetch_array, ...

Si el procedimiento almacenado quisiese devolver además del resultado de la consulta un parámetro de salida o un valor de devolución, estos estarían disponibles únicamente después de ejecutar mssql_next_result hasta que ésta devuelva false.

10 comentarios

wagner

19/09/2016 18:04:14

muchas gracias por el aporte, genial el tutorial...

saludos desde colombia

Ezequiel

19/07/2015 01:08:28

Hola amigo, ya tengo una base de datos hecha en Mysql y un triguers que ejecuta las consultas.. quisiera saber si me darias una mano con un ejemplo de un procedimiento que tome un valor y ya calcule un resultado de venta... tengo todo hecho en php maker y me falta saber como hacer para que cuando cargue el precio me muestre automaticamente el resultado del total de productos. Espero que hayas entendido mi duda y espero tu respuesta.. gracias..

proteus8

01/04/2015 23:44:44

Hola a todos tengo una consulta espero me puedan ayudar, quiero ejecutar un procedimiento almacenado en una base de datos Sybase el que quiero ejecutar desde PHP, el código que estoy usando es el siguiente:

<?php

$qry=("Call sp_trendView 'collect', 'analog.AYS52G_01_____P.curval', 'value' , '03/15/15 00:00:00','03/15/15 23:00:00'");

$result=odbc_exec($conn,$qry);

while ($row = odbc_fetch_array($result)){

echo $row['timestamp'] ." ". $row['value'] .'<br>';

}

?>

si ejecuto el procedimiento directo en la base de datos con algún administrador este entrega resultados sin problemas.

pero si lo hago desde PHP me muestra el siguiente error:

Warning: odbc_exec() [function.odbc-exec]: SQL error: [INTERSOLV][ODBC SQL Server driver][SQL Server]Incorrect syntax near 'sp_trendView'. , SQL state 37000 in SQLExecDirect in C:\AppServ\www\prueba\datos_scada.php on line 29

Warning: odbc_fetch_array(): supplied argument is not a valid ODBC result resource in C:\AppServ\www\prueba\datos_scada.php on line 31

debo mencionar que me conecto a la base de datos por ODBC y la conexión funciona sin problemas.

Espero me puedan ayudar.

saludos

Anónimo

29/12/2014 16:44:49

Ese tipo de dato es nativo del membership de microsoft.

Sugiero que lo mandes desde el app web como varchar y dentro del store lo conviertas a uniqueidentifier.

Kam

16/07/2014 17:32:21

Hola tengo un procedimiento almacenado cuyo parametro de entrada es del tipo uniqueidentifier al hacer el mssql_bind($stmt, '@invoiceableid', $cuenta, SQLVARCHAR);

me arroja un error de sql indicando que no se puede colocar un valor caracter como uniqueidentifier

En este caso como hago entonces con el tipo de variable, cual utilizaria o no se si existe otra forma de poder hacer la ejecucion del procedimiento desde php con mssql

Gracias por cualquier informacion q me puedan dar

Anónimo

03/04/2014 23:39:16

buen trabajo

xPapaChox

09/06/2012 18:00:01

Hola.

Muy bueno tu aporte.

Cdwl

08/06/2012 19:51:05

grcias x el aporte...;)

Luis

28/11/2011 09:38:02

Bienvenido Bereess.

Tienes razón, el tercer parámetro de mssql_bind debe ser una variable porque se pasa por referencia, a pesar de que en la página de PHP los ejemplos los ponen así: http://es.php.net/manual/es/function.mssql-bind.php

Ya está cambiado el código. Gracias.

Bereess

25/11/2011 19:40:23

El 2do ejem. dice el siguiente error:

Fatal error: Only variables can be passed by reference

En la linea 7:mssql_bind($stmt, '@clase', '2B', SQLVARCHAR, false, false, 2);

Comentario anónimo
Comentar como usuario