Database Journal
MS SQL Oracle DB2 Access MySQL PostgreSQL Sybase PHP SQL Etc SQL Scripts & Samples Links Database Forum

» Database Journal Home
» Database Articles
» Database Tutorials
MS SQL
Oracle
DB2
MS Access
MySQL
» RESOURCES
Database Tools
SQL Scripts & Samples
Links
» Database Forum
» Sitemap
Free Newsletters:
DatabaseDaily  
News Via RSS Feed


follow us on Twitter
Database Journal |DBA Support |SQLCourse |SQLCourse2
 

Featured Database Articles

MySQL

Posted Dec 13, 2005

MySQL Stored Functions - Page 2

By Ian Gilfillan

Information about existing stored functions

As with stored procedures, there are various ways to get to the metadata about existing stored functions. There is SHOW CREATE FUNCTION, and SHOW FUNCTION STATUS. The former returns the CREATE statement applied to the supplied function, while the latter returns metadata about all existing functions, as follows.

mysql> SHOW CREATE FUNCTION WEIGHTED_AVERAGE\G
*************************** 1. row ***************************
       Function: WEIGHTED_AVERAGE
       sql_mode:
Create Function: CREATE FUNCTION 'WEIGHTED_AVERAGE'(n1 INT, n2 INT, n3 INT, n4 INT) 
 RETURNS int(11)
    DETERMINISTIC
BEGIN
   DECLARE avg INT;
   SET avg = (n1+n2+n3*2+n4*4)/8;
   RETURN avg;
  END
1 row in set (0.01 sec)
mysql> SHOW FUNCTION STATUS\G
*************************** 1. row ***************************
           Db: test
         Name: WEIGHTED_AVERAGE
         Type: FUNCTION
      Definer: root@localhost
     Modified: 2005-12-07 13:21:37
      Created: 2005-12-07 13:21:37
Security_type: DEFINER
      Comment:
*************************** 2. row ***************************
           Db: test
         Name: WEIGHTED_AVERAGE2
         Type: FUNCTION
      Definer: root@localhost
     Modified: 2005-12-07 13:41:07
      Created: 2005-12-07 13:41:07
Security_type: DEFINER
      Comment:
*************************** 3. row ***************************
           Db: test
         Name: WEIGHTED_AVERAGE3
         Type: FUNCTION
      Definer: root@localhost
     Modified: 2005-12-07 15:51:16
      Created: 2005-12-07 15:51:16
Security_type: DEFINER
      Comment:
*************************** 4. row ***************************
           Db: test
         Name: WEIGHTED_AVERAGE_UPDATE
         Type: FUNCTION
      Definer: root@localhost
     Modified: 2005-12-07 16:03:26
      Created: 2005-12-07 16:03:26
Security_type: DEFINER
      Comment:
4 rows in set (0.00 sec)

Another way to get the same information is to query the mysql.proc table. As you may know, the mysql database stores all sorts of data about permissions, and you can UPDATE the user or db table to change the MySQL privileges. Since MySQL 5, the mysql.proc table also contains metadata about stored procedures and functions.

mysql> SELECT * FROM mysql.proc\G
*************************** 1. row ***************************
              db: test
            name: WEIGHTED_AVERAGE
            type: FUNCTION
   specific_name: WEIGHTED_AVERAGE
        language: SQL
 sql_data_access: CONTAINS_SQL
is_deterministic: YES
   security_type: DEFINER
      param_list: n1 INT, n2 INT, n3 INT, n4 INT
         returns: int(11)
            body: BEGIN
   DECLARE avg INT;
   SET avg = (n1+n2+n3*2+n4*4)/8;
   RETURN avg;
  END
         definer: root@localhost
         created: 2005-12-07 13:21:37
        modified: 2005-12-07 13:21:37
        sql_mode:
         comment:
*************************** 2. row ***************************
              db: test
            name: WEIGHTED_AVERAGE2
            type: FUNCTION
   specific_name: WEIGHTED_AVERAGE2
        language: SQL
 sql_data_access: CONTAINS_SQL
is_deterministic: YES
   security_type: DEFINER
      param_list: v1 VARCHAR(50)
         returns: int(11)
            body: BEGIN     
                    DECLARE i1,i2,i3,i4,avg INT;    
                    SELECT mark1,mark2,mark3,mark4 INTO i1,i2,i3,i4 FROM sf1_data WHERE name=v1;    
                    SET avg = (i1+i2+i3*2+i4*4)/8;    
                    RETURN avg;   
                  END
         definer: root@localhost
         created: 2005-12-07 13:41:07
        modified: 2005-12-07 13:41:07
        sql_mode:
         comment:
*************************** 3. row ***************************
              db: test
            name: WEIGHTED_AVERAGE3
            type: FUNCTION
   specific_name: WEIGHTED_AVERAGE3
        language: SQL
 sql_data_access: CONTAINS_SQL
is_deterministic: YES
   security_type: DEFINER
      param_list: n1 INT,n2 INT,n3 INT,n4 INT,v1 VARCHAR(50)
         returns: int(11)
            body: BEGIN
   DECLARE i1,i2,i3,i4,avg INT;
   INSERT INTO sfdata VALUES(n1,n2,n3,n4,v1);
   RETURN 1;
  END
         definer: root@localhost
         created: 2005-12-07 15:51:16
        modified: 2005-12-07 15:51:16
        sql_mode:
         comment:
*************************** 4. row ***************************
              db: test
            name: WEIGHTED_AVERAGE_UPDATE
            type: FUNCTION
   specific_name: WEIGHTED_AVERAGE_UPDATE
        language: SQL
 sql_data_access: CONTAINS_SQL
is_deterministic: YES
   security_type: DEFINER
      param_list: n1 INT,n2 INT,n3 INT,n4 INT,v1 VARCHAR(50)
         returns: int(11)
            body: BEGIN
   DECLARE i1,i2,i3,i4,avg INT;
   UPDATE sfdata SET mark1=n1,mark2=n2,mark3=n3,mark4=n4 WHERE name=v1;
   RETURN 1;
  END
         definer: root@localhost
         created: 2005-12-07 16:03:26
        modified: 2005-12-07 16:03:26
        sql_mode:
         comment:
4 rows in set (0.00 sec)

Note that querying the mysql.proc table returns more complete data than either of the first two methods, effectively returning the sum of both of those methods.

However, people coming from other DBMS', familiar with the ANSI standard, may be uncomfortable with these MySQL-specific methods. The standard way is to query the INFORMATION_SCHEMA. It is a highly flexible way of getting what you want, but can be a bit of an overkill, hence MySQL's provision of the more simple SHOW methods. I will leave a more complete explanation of INFORMATION_SCHEMA for another day, as it extends well beyond stored procedures and functions. For now, suffice to say that you can query INFORMATION_SCHEMA.ROUTINES to get similar metadata as the above, as follows:

mysql> SELECT * FROM INFORMATION_SCHEMA.ROUTINES\G
*************************** 1. row ***************************
     SPECIFIC_NAME: WEIGHTED_AVERAGE
   ROUTINE_CATALOG: NULL
    ROUTINE_SCHEMA: test
      ROUTINE_NAME: WEIGHTED_AVERAGE
      ROUTINE_TYPE: FUNCTION
    DTD_IDENTIFIER: int(11)
      ROUTINE_BODY: SQL
ROUTINE_DEFINITION: BEGIN
   DECLARE avg INT;
   SET avg = (n1+n2+n3*2+n4*4)/8;
   RETURN avg;
  END
     EXTERNAL_NAME: NULL
 EXTERNAL_LANGUAGE: NULL
   PARAMETER_STYLE: SQL
  IS_DETERMINISTIC: YES
   SQL_DATA_ACCESS: CONTAINS SQL
          SQL_PATH: NULL
     SECURITY_TYPE: DEFINER
           CREATED: 2005-12-07 13:21:37
      LAST_ALTERED: 2005-12-07 13:21:37
          SQL_MODE:
   ROUTINE_COMMENT:
           DEFINER: root@localhost
*************************** 2. row ***************************
     SPECIFIC_NAME: WEIGHTED_AVERAGE2
   ROUTINE_CATALOG: NULL
    ROUTINE_SCHEMA: test
      ROUTINE_NAME: WEIGHTED_AVERAGE2
      ROUTINE_TYPE: FUNCTION
    DTD_IDENTIFIER: int(11)
      ROUTINE_BODY: SQL
ROUTINE_DEFINITION: BEGIN
                      DECLARE i1,i2,i3,i4,avg INT;    
                      SELECT mark1,mark2,mark3,mark4 INTO i1,i2,i3,i4 FROM sf1_data WHERE name=v1;    
                      SET avg = (i1+i2+i3*2+i4*4)/8;    
                      RETURN avg;   
                    END
     EXTERNAL_NAME: NULL
 EXTERNAL_LANGUAGE: NULL
   PARAMETER_STYLE: SQL
  IS_DETERMINISTIC: YES
   SQL_DATA_ACCESS: CONTAINS SQL
          SQL_PATH: NULL
     SECURITY_TYPE: DEFINER
           CREATED: 2005-12-07 13:41:07
      LAST_ALTERED: 2005-12-07 13:41:07
          SQL_MODE:
   ROUTINE_COMMENT:
           DEFINER: root@localhost
*************************** 3. row ***************************
     SPECIFIC_NAME: WEIGHTED_AVERAGE3
   ROUTINE_CATALOG: NULL
    ROUTINE_SCHEMA: test
      ROUTINE_NAME: WEIGHTED_AVERAGE3
      ROUTINE_TYPE: FUNCTION
    DTD_IDENTIFIER: int(11)
      ROUTINE_BODY: SQL
ROUTINE_DEFINITION: BEGIN
   DECLARE i1,i2,i3,i4,avg INT;
   INSERT INTO sfdata VALUES(n1,n2,n3,n4,v1);
   RETURN 1;
  END
     EXTERNAL_NAME: NULL
 EXTERNAL_LANGUAGE: NULL
   PARAMETER_STYLE: SQL
  IS_DETERMINISTIC: YES
   SQL_DATA_ACCESS: CONTAINS SQL
          SQL_PATH: NULL
     SECURITY_TYPE: DEFINER
           CREATED: 2005-12-07 15:51:16
      LAST_ALTERED: 2005-12-07 15:51:16
          SQL_MODE:
   ROUTINE_COMMENT:
           DEFINER: root@localhost
*************************** 4. row ***************************
     SPECIFIC_NAME: WEIGHTED_AVERAGE_UPDATE
   ROUTINE_CATALOG: NULL
    ROUTINE_SCHEMA: test
      ROUTINE_NAME: WEIGHTED_AVERAGE_UPDATE
      ROUTINE_TYPE: FUNCTION
    DTD_IDENTIFIER: int(11)
      ROUTINE_BODY: SQL
ROUTINE_DEFINITION: BEGIN
   DECLARE i1,i2,i3,i4,avg INT;
   UPDATE sfdata SET mark1=n1,mark2=n2,mark3=n3,mark4=n4 WHERE name=v1;
   RETURN 1;
  END
     EXTERNAL_NAME: NULL
 EXTERNAL_LANGUAGE: NULL
   PARAMETER_STYLE: SQL
  IS_DETERMINISTIC: YES
   SQL_DATA_ACCESS: CONTAINS SQL
          SQL_PATH: NULL
     SECURITY_TYPE: DEFINER
           CREATED: 2005-12-07 16:03:26
      LAST_ALTERED: 2005-12-07 16:03:26
          SQL_MODE:
   ROUTINE_COMMENT:
           DEFINER: root@localhost
4 rows in set (0.00 sec)

The MySQL documentation gives a complete overview about the INFORMATION_SCHEMA structure, and some MySQL oddities, if you want to pursue that further.

Conclusion

Stored procedures and stored functions open a whole new world to MySQL developers, and mean that MySQL is starting to attract attention from developers of entirely new types of applications. While the implementation in MySQL 5.0 is still raw (MySQL 5.1 is out in alpha now, and develops things further, as will MySQL 6.0), most of what is needed is already there. Not all of the my applications are running on MySQL 5 yet, but the itch to move everything is starting to get stronger every time I do further development, and have to make do with more unwanted logic in the application. I came across a query recently from one poor developer bemoaning the lack of features in MySQL 3.23. Upgrading legacy systems is not fun, but for those of you lucky enough to start with a clean slate, enjoy the new world of MySQL 5, stored procedures and stored functions!

» See All Articles by Columnist Ian Gilfillan



MySQL Archives

Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 




Latest Forum Threads
MySQL Forum
Topic By Replies Updated
MySQL in high availability and transction secure banking application klamor 1 August 28th, 10:24 AM
MySQL rollback UAL225 1 August 28th, 10:15 AM
Browsing a DB file that uses MySql finleytech 1 July 26th, 10:51 AM
php cookie won't pass variable to next page ITdevGirl 0 June 22nd, 12:13 PM