Weiter Zurück [Inhalt] Online Suche im Handbuch

17.10 Stored Procedures

Stored Procedures sind Makro´s oder auch Funktionen, bei denen Parameter übergeben werden können. Normalerweise werden diese bei SQL-Datenbanken mit DECLARE eingeleitet.

Sie sind sehr praktisch, weil man hiermit auch Personen, die kein SQL beherrschen, ermöglicht, z.B. regelmäßige Statistiken zu erstellen. Der Aufruf einer Zeile im SQL-Client reicht da schon aus. Stored Procedures in Verbindung mit z.B. Nested Cursors sorgen allerdings dafür, daß die Prozeduren unglaublich komplex werden. Hier ein kleiner Ausschnitt einer solchen mit nested cursors unter MS SQL 6.5 :

Create Procedure Maintain_Employees
As
/* First declare variables that are going to
be required in this procedure */
Declare     @dtPubDate   datetime,
            @nEmplCount  smallint,
            @nEmplID     empid,
            @nFirstHalf  smallint,
            @nRowCount   integer,
            @nSecondHalf integer,
            @nSQLError   integer,
            @nYtdSales   integer,
            @sLName      varchar(30),
            @sPubID      char(4),
            @sLastType   char(12),
            @sType       char(12)
/* Now declare the cursors to be used.
Note that because variables are used in the
where clause on the second cursor, it is not
required that the second cursor be declared inside the first.
Take advantage of this functionality so that unnecessary
declaring of cursors does not take place (this will
save resources on the server). */
Declare Cur_Empl Cursor
For   Select EMP_ID,    LNAME,
             PUB_ID
      From   EMPLOYEE
      Order By EMP_ID
Declare Cur_Titles Cursor
For   Select  TYPE,   PUBDATE, YTD_SALES
      From    TITLES
      Where   PUB_ID = @sPubID
Order By TYPE
/* Open the outer cursor and fetch the first row */
Open  Cur_Empl
Fetch Cur_Empl
Into  @nEmplID,   @sLName,
      @sPubID
/* Initialize counters */
Select      @nEmplCount = 0
While @@Fetch_Status = 0            /* Fetch only while there are rows left
*/
Begin
      /* increment counter */
      Select @nEmplCount = @nEmplCount + 1
      /* Return a result set to the front-end so that it knows
      what is happening */
      Select      @nEmplID,   @sLName
      If @sLName < 'D'  /* Skip all the D's by using a GOTO */
            Goto Fetch_Next_Empl
      /* Now open inner cursor and count the different types
      of books for this employee's publisher */
      Open Titles
      Fetch Titles
      Into  @sType, @dtPubDate, @nYtdSales
      /* Reset totals */
      Select @nFirstHalf = 0,
            @nSecondHalf = 0,
            @sLastType = NULL
      While @@Fetch_Status = 0
      Begin
            If @sType != @sLastType AND @sLastType != NULL
            Begin
                  /* Send back a total record to the front-end */
                  Select @sLastType, @nFirstHalf, @nSecondHalf
                  /* Reset totals */
                  Select @nFirstHalf = 0,
                        @nSecondHalf = 0
            End
            If @dtPubDate <= 30/95'
                  Select @nFirstHalf = @nFirstHalf + @nYtdSales,
                        @sLastType = @sType
            Else
                  Select @nSecondHalf = @nSecondHalf + @nYtdSales,
                        @sLastType = @sType
            Fetch Titles
            Into  @sType, @dtPubDate, @nYtdSales
      End
      Fetch_Next_Empl:        /* Label to skip inner loop */
      Fetch Cur_Empl
      Into  @nEmplID,   @sLName,
            @sPubID
End
/* Deallocate and close the cursors. Note that for a stored
procedure, this is really unnecessary because the cursor
will no longer exist once the procedure finishes execution.
However, it is good practice to leave the procedure cleaned up. */
Close Cur_Empl
Deallocate Cur_Empl
Deallocate Cur_Titles
/* Send total count of employees to front-end */
Select @nEmplCount
/* End proc */
Return 0
Wer nun immer noch nicht von diesen stored procedures in Verbindung mit cursors geheilt ist, der muß dann von einer einfachen Lösung unter MySQL, die es ebenso tut, auf die komplexeren unter ORACLE, MS-SQL 6.5/7.0 oder SYBASE umsteigen, und viel Geld in KNOW-HOW investieren. Für Internet-Datenbanken jedenfalls sind diese Prozeduren nicht notwendig.

Mit MySQL kann man ebenfalls mehrere SQL-Befehle zusammenfassen, und diese auf der Festplatte ablegen. Mit Hilfe des (siehe Kapitel Batch-Modus) kann man diese Batch-Scripte durch den SQL-Client laden und ausführen lassen. Der wesentliche Unterschied ist, daß man leider noch keine Parameter übergeben kann. Da man die Batch-Scripte auch mit Hilfe der SHELL aufrufen kann, ist es aber so möglich, die Parameter an ein Shellscript übergibt, welches dann die SQL-Befehle zusammenfasst und dann von der SQL-Datenbank ausführen läßt. Ein einfacher, zuverlässiger und vor allem universeller Workaround. Zudem kann man diese Scripte auch über den CRON-Dämon zeitgesteuert starten lassen. Auch wenn MySQL offiziell keine stored procedures beherrscht, es gibt aber dank der freien Verfügbarkeit des Quellcodes die Lösung, die Sprache MySQL nach belieben zu erweitern ! Im Grunde sind stored procedures nur erfunden worden, da es damals noch nicht den Gedanken der OpenSource Bewegung gegeben hat. Mit dem Quellcode in Händen können Sie relativ einfach mit C-Kenntnissen MySQL erweitern. Diese neuen Prozeduren bzw. Funktionen laufen mit einer Geschwindigkeit ab, von der andere Datenbankhersteller nur träumen können.

Hier ein Ausschnitt aus dem originalen Handbuch:

15.1 Procedure analyse
analyse([max elements,[max memory]]) 

This procedure is defined in the Sql/sql_analyse.cc'. This examines the
result from your query and returns an analysis of the results. 

max elements (default 256) is the maximum number of distinct values analyse
will notice per column. This is used by analyse to check if the optimal
column type should be of type ENUM. 
max memory (default 8192) is the maximum memory analyse should allocate per
column while trying to find all distinct values. <p>
SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])

15.2 Writing a procedure.
For the moment, the only documentation for this is the source. :( 

You can find all information about procedures by examining the following
files: 

Sql/sql_analyse.cc' 
Sql/procedure.h' 
Sql/procedure.cc' 
Sql/sql_select.cc' 
Schreiben Sie sich doch einfach einen neuen SQL-Befehl. Da MySQL im Gegensatz zu allen anderen Datenbanken im Quellcode geliefert wird, können Sie sich Ihre eigenen Befehle implementieren, und die Datenbank noch einmal neu kompilieren. In vielen Datenbanken ist in dem Kapitel von stored procedures von Compiler die Rede. Damit keine Verwechselungen aufkommen... Das sind in Wirklichkeit keine Compiler, die die stored procedures in die Maschinensprache der CPU übersetzen, sondern in irgendeine andere interne Sprache der SQL-Datenbank, die dann aber nur interpretiert wird. Der Geschwindigkeitsunterschied zwischen MySQL C++ Prozeduren und Prozeduren bei anderen SQL-DAtenbanken dürfte zwischen 5-20 liegen. MySQL ist kein Spielzeug, sondern ein HI-END Produkt, was wohl auch erklärt, daß fast alle Betreiber großer Internet-Sites MySQL auf NetBSD einsetzen (NetBSD ist schon länger ein 64 Bit Betriebssystem). Insbesondere für Data Mining ist MySQL hervorragend geeignet. (Glaubt mir wahrscheinlich kaum jemand ;-) Data Mining ist der Versuch, aus riesigen Datenbeständen, z.B. den Aufzeichnungen über Unfälle bei Versicherungen, die Einstufung in die Kasko Versicherung für die einzelnen Autotypen zu ermitteln. Die Verfahren grenzen an schwarze Magie und sind sehr stressend für die Datenbank. Unter MySQL könne diese wochenlangen Analysen dramatisch beschleunigt werden.

Sie können auch Prozeduren in PHP3 schreiben. Lesen Sie hierzu im Kapitel Funktionen in PHP3 für MySQL


Weiter Zurück [Inhalt] Online Suche im Handbuch