CREATE PROCEDUREsp_name([parameter[,...]]) [characteristic...]routine_bodyCREATE FUNCTIONsp_name([parameter[,...]]) RETURNStype[characteristic...]routine_bodyparameter: [ IN | OUT | INOUT ]param_nametypetype:Any valid MySQL data typecharacteristic: LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER } | COMMENT 'string'routine_body:procedimientos almacenados o comandos SQL válidos
        Estos comandos crean una rutina almacenada. Desde MySQL 5.0.3,
        para crear una rutina, es necesario tener el permiso
        CREATE ROUTINE , y los permisos
        ALTER ROUTINE y EXECUTE se
        asignan automáticamente a su creador. Si se permite logueo
        binario necesita también el permisos SUPER
        como se describe en Sección 19.3, “Registro binario de procedimientos almacenados y disparadores”.
      
        Por defecto, la rutina se asocia con la base de datos actual.
        Para asociar la rutina explícitamente con una base de datos,
        especifique el nombre como
        db_name.sp_name al crearlo.
      
Si el nombre de rutina es el mismo que el nombre de una función de SQL, necesita usar un espacio entre el nombre y el siguiente paréntesis al definir la rutina, o hay un error de sintaxis. Esto también es cierto cuando invoca la rutina posteriormente.
        La cláusula RETURNS puede especificarse
        sólo con FUNCTION, donde es obligatorio. Se
        usa para indicar el tipo de retorno de la función, y el cuerpo
        de la función debe contener un comando RETURN
        value.
      
        La lista de parámetros entre paréntesis debe estar siempre
        presente. Si no hay parámetros, se debe usar una lista de
        parámetros vacía () . Cada parámetro es un
        parámetro IN por defecto. Para especificar
        otro tipo de parámetro, use la palabra clave
        OUT o INOUT antes del
        nombre del parámetro. Especificando IN,
        OUT, o INOUT sólo es
        valido para una PROCEDURE.
      
        El comando CREATE FUNCTION se usa en
        versiones anteriores de MySQL para soportar UDFs (User Defined
        Functions) (Funciones Definidas por el Usuario). Consulte
        Sección 27.2, “Añadir nuevas funciones a MySQL”. UDFs se soportan, incluso
        con la existencia de procedimientos almacenados. Un UDF puede
        tratarse como una función almacenada externa. Sin embargo,
        tenga en cuenta que los procedimientos almacenados comparten su
        espacio de nombres con UDFs.
      
Un marco para procedimientos almacenados externos se introducirá en el futuro. Esto permitira escribir procedimientos almacenados en lenguajes distintos a SQL. Uno de los primeros lenguajes a soportar será PHP ya que el motor central de PHP es pequeño, con flujos seguros y puede empotrarse fácilmente. Como el marco es público, se espera soportar muchos otros lenguajes.
        Un procedimiento o función se considera
        “determinista” si siempre produce el mismo
        resultado para los mismos parámetros de entrada, y “no
        determinista” en cualquier otro caso. Si no se da ni
        DETERMINISTIC ni NOT
        DETERMINISTIC por defecto es NOT
        DETERMINISTIC.
      
        Para replicación, use la función NOW() (o
        su sinónimo) o RAND() no hace una rutina no
        determinista necesariamente. Para NOW(), el
        log binario incluye el tiempo y hora y replica correctamente.
        RAND() también replica correctamente
        mientras se invoque sólo una vez dentro de una rutina. (Puede
        considerar el tiempo y hora de ejecución de la rutina y una
        semilla de número aleatorio como entradas implícitas que son
        idénticas en el maestro y el esclavo.)
      
        Actualmente, la característica DETERMINISTIC
        se acepta, pero no la usa el optimizador. Sin embargo, si se
        permite el logueo binario, esta característica afecta si MySQL
        acepta definición de rutinas. Consulte
        Sección 19.3, “Registro binario de procedimientos almacenados y disparadores”.
      
        Varias características proporcionan información sobre la
        naturaleza de los datos usados por la rutina. CONTAINS
        SQL indica que la rutina no contiene comandos que leen
        o escriben datos. NO SQL indica que la rutina
        no contiene comandos SQL . READS SQL DATA
        indica que la rutina contiene comandos que leen datos, pero no
        comandos que escriben datos. MODIFIES SQL
        DATA indica que la rutina contiene comandos que pueden
        escribir datos. CONTAINS SQL es el valor por
        defecto si no se dan explícitamente ninguna de estas
        características.
      
        La característica SQL SECURITY puede usarse
        para especificar si la rutina debe ser ejecutada usando los
        permisos del usuario que crea la rutina o el usuario que la
        invoca. El valor por defecto es DEFINER. Esta
        característica es nueva en SQL:2003. El creador o el invocador
        deben tener permisos para acceder a la base de datos con la que
        la rutina está asociada. Desde MySQL 5.0.3, es necesario tener
        el permiso EXECUTE para ser capaz de ejecutar
        la rutina. El usuario que debe tener este permiso es el
        definidor o el invocador, en función de cómo la
        característica SQL SECURITY .
      
        MySQL almacena la variable de sistema
        sql_mode que está en efecto cuando se crea
        la rutina, y siempre ejecuta la rutina con esta inicialización.
      
        La cláusula COMMENT es una extensión de
        MySQL, y puede usarse para describir el procedimiento
        almacenado. Esta información se muestra con los comandos
        SHOW CREATE PROCEDURE y SHOW CREATE
        FUNCTION .
      
        MySQL permite a las rutinas que contengan comandos DDL (tales
        como CREATE y DROP) y
        comandos de transacción SQL (como COMMIT).
        Esto no lo requiere el estándar, y por lo tanto, es específico
        de la implementación.
      
        Los procedimientos almacenados no pueden usar LOAD DATA
        INFILE.
      
        Nota: Actualmente, los
        procedimientos almacenados creados con CREATE
        FUNCTION no pueden tener referencias a tablas. (Esto
        puede incluir algunos comandos SET que pueden
        contener referencias a tablas, por ejemplo SET a:=
        (SELECT MAX(id) FROM t), y por otra parte no pueden
        contener comandos SELECT , por ejemplo
        SELECT 'Hello world!' INTO var1.) Esta
        limitación se elminará en breve.
      
        Los comandos que retornan un conjunto de resultados no pueden
        usarse desde una función almacenada. Esto incluye comandos
        SELECT que no usan INTO
        para tratar valores de columnas en variables, comandos
        SHOW y otros comandos como
        EXPLAIN. Para comandos que pueden
        determinarse al definir la función para que retornen un
        conjunto de resultados, aparece un mensaje de error Not
        allowed to return a result set from a function
        (ER_SP_NO_RETSET_IN_FUNC). Para comandos que
        puede determinarse sólo en tiempo de ejecución si retornan un
        conjunto de resultados, aparece el error PROCEDURE %s
        can't return a result set in the given context
        (ER_SP_BADSELECT).
      
        El siguiente es un ejemplo de un procedimiento almacenado que
        use un parámetro OUT . El ejemplo usa el
        cliente mysql y el comando
        delimiter para cambiar el delimitador del
        comando de ; a // mientras
        se define el procedimiento . Esto permite pasar el delimitador
        ; usado en el cuerpo del procedimiento a
        través del servidor en lugar de ser interpretado por el mismo
        mysql.
      
mysql> delimiter //
mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
    -> BEGIN
    ->   SELECT COUNT(*) INTO param1 FROM t;
    -> END
    -> //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> CALL simpleproc(@a);
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @a;
+------+
| @a   |
+------+
| 3    |
+------+
1 row in set (0.00 sec)
        Al usar el comando delimiter, debe evitar el
        uso de la antibarra ('\') ya que es el
        carácter de escape de MySQL.
      
El siguiente es un ejemplo de función que toma un parámetro, realiza una operación con una función SQL, y retorna el resultado:
mysql> delimiter //
mysql> CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50)
    -> RETURN CONCAT('Hello, ',s,'!');
    -> //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> SELECT hello('world');
+----------------+
| hello('world') |
+----------------+
| Hello, world!  |
+----------------+
1 row in set (0.00 sec)
        Si el comando RETURN en un procedimiento
        almacenado retorna un valor con un tipo distinto al especificado
        en la cláusula RETURNS de la función, el
        valor de retorno se coherciona al tipo apropiado. Por ejemplo,
        si una función retorna un valor ENUM o
        SET, pero el comando
        RETURN retorna un entero, el valor retornado
        por la función es la cadena para el miembro de
        ENUM correspondiente de un conjunto de
        miembros SET .
      
Ésta es una traducción del manual de referencia de MySQL, que puede encontrarse en dev.mysql.com. El manual de referencia original de MySQL está escrito en inglés, y esta traducción no necesariamente está tan actualizada como la versión original. Para cualquier sugerencia sobre la traducción y para señalar errores de cualquier tipo, no dude en dirigirse a mysql-es@vespito.com.

