MySQL5: Leichte Einleitung in eine gespeicherten Verfahren von MySQL5

Z PostgreSQL
Přejít na: navigace, hledání

Über gehen an: Navigation, Suchen

Die Übersetzung: Lenka Lukešová


Dieser Paragraph habe ich voraus Weihnachtszeit in Begeisterung geschrieben, dass MySQL die eingegeben Prozeduren (SP) unterstützen Diese Beschaffenheit war eine Zeit bezeichnet wie der erwarteteste und zuträglichste Beitrag MySQL 5.0. Gesetzmäßig es war eine Reihe des Artikels mit dieser Thematik. Ein bißchen überraschend, nach anfänglich Begeisterung, Aufmerksamkeit um SP heftig abgeflaut. Leider erste Version MySQL beinhalten viele Fehler, die von weitem sind nicht Beseitigung so schnell, wie kann sich es hat gestanden und die Fehler haben nicht einmal Realisierung gelagert von Prozeduren vermeidet. Mit Beendigung Artikels bin wartete an Entfernung Fehler machen unmöglich rekursiv Ruf Prozeduren. Ohne Unterlaß und in Verzion 5.1 ist Entwicklung gelagert von Prozeduren schwierig in Bezug auf elend Fehlerdiagnose und Reihe blind Fehler oder fehlenden Beschaffenheit Sprach. In Ansehung dessen, dass MySQL ist praktisch der letztere O.S. Basisdateien, wo sind eingegeben Prozeduren implementieren, Sprache gelagert von Prozeduren geht aus ANSI SQL und hat nach syntaktisch Seiten von allen O.S. Basisdateien am nächsten zu SQL/PSM. Schon bin erwähnt, dass Vollständigkeit und Qualität des Realisierung SP, es ist nicht vergleichbar mit z.B . Postgresem oder Firebirdem. Ich bin im Bilde dem so, dass Prioritäten MySQL sind woanders: Sammeln, Verteilen und Replikation. Beispiele SQL von Prozeduren, die führe ich auf zu dieser Artikels, sind ausgetestet in MySQL 5.1.9 und fürs einem anderen Version muss nicht dasein funktionell.



Einführung

Sprache S.P. berücksichtigt ANSI SQL (um z B DB2). Vor zwei Jahren bin sich an MySQL klagen an Mangel Beurkundung bezüglich SP. Der ist an Internet jetzt relativ genug, wenn auch zeitweise sind Probleme mit der Qualität oder Aktualität. Manchmal und offiziell Beurkundung enthält verhältnismäßig genug gewichtige Fehler. Außerdem im Rahmen Serie um MySQL sind erschienen, es ahnt mir, zwei Elemente an linuxsoft. Es vorliegt zwei grundlegend Beweggründe, an ihnen sich praktisch alle übereinstimmend, worauf zwei, an die wir höchstwahrcheinlich bereden nicht, weshalb es anwenden:

1. Geschwindigkeit - in einigen Fällen maßgeblich höher Verarbeitungsgeschwindigkeit Aufgaben (im großen und ganzen es kommt an Verhältnisse zwischen Umfang aktuell und resultierend Daten) folgen aus Tatsachen, dass minimieren Überweisung Daten zwischen Klient und Server (Serialisierung, Kommunikation, ...). Soll es getrennt Bedeutung, wenn zwischen Basisdateien und euerer Applikation sind Bremsen Modell ODBC oder BDE. Größer Verarbeitungsgeschwindigkeit Aufgaben muss man selbstverständlich positiv projizieren an gesamte Durchlaßfähigkeit Server. Etwa kaum jemand wird schreiben Aufspeicherung Prozeduren für die numerische Lösung Integral. Nein dass kann es war so im Ganzen von Sachen, solche Scharlatanerie hat aber ein ganz anderes Beweggrund - Punkt 4. Zeitweise erscheint Härten, dass eingegeben Prozeduren sind übersetzte, vorkompilieren. Es in der Regel nein vorstellt, dass kann sich Passwort übertragen nach Befehlsschlüssel, aber dass werden benutzt sog . gefaßt SQL Befehle (vorbereitete Aussagen). Ausnahme sind neu Version Oracle, wo das SP wirklich zu übersetzenden. MySQL fehlende nicht einmal implizit Umwandlung SQL Befehl an voraus-gefaßt SQL Befehle. 2. Sicherheit - mithilfe gelagert von Prozeduren wir dürfen sicher Art vertreiben unsre Rechtswissenschaft zu Tabelle (überzieht zu allein Datum), und es so, dass Defination Prozeduren mit Rechtswissenschaft Autor (SECURITY DEFINER). In zweiten Regime (SECURITY INVOKER) Prozedur wirbt Rechtswissenschaft rufende.

3. Adaptabilität und Portabilita - indem an die ersten zwei Punkt sich praktisch alle interessiert machen gleichlautend, so hier gehen los erste Ansicht Differenzen. Eingegeben Prozeduren Entstehung Schicht zwischen durch eigene Daten und Klient Applikation. Gewöhnlich dies Schicht es ist nicht absolut - zeitweise ein der SELECT in Applikation er bleibt. Bei Umstrukturierung Tabellen, bei Posament Applikation, Sie aber der vergessen SELECT kann schön einwickeln Köpfe. Posament-Zerium und Wirksammachung gelagert von Prozeduren es ist nicht so problematisch, wie kann sich auf den ersten Blick konnte den Anschein haben. Die Größte Begrenzung gelagert von Prozeduren ist absolut Verbot Interaktion mit vom Anwender (Weile es weh tut, ehe sich darauf angewöhnen sich) - können Sie nicht sich abspringen und herunterlassen Anzeige Boxen und fragen sich, ob es Benutzer Tatsache hat gedacht ernst. Erstaunlicherweise es aber verwaltet zu übersichtlich und ablesbar Passwort, welcher sich gelitten modifiziert und hält. Darüber uninteraktive SP sich gut automatomatisiert testen. Die Differenzen in Syntax Sprache sind, aber Unartigkeit real größer Probleme (wenn es mit ihren zählt). Selbstverständlich, dass immer ist etwas, was die Anschlußstelle schwer. Z.B . multirecordset (Staplungsrecordset) ist im PostgreSQL oder Oraclu ein bißchen mühsam Bildung mithilfe Zeiger, und in MySQL oder in T-SQL verkehrt sehr einfach, wie Ergebnis aller leer stehend SELECT.

4. Architektur - so hier es schon sprudelt, hier schon sich hundertprozentig uneinig. Im Kern es geht um Verhältnis Passwort Klient Applikation und gelagert von Prozeduren. Ich bin Maximalist, Optimum sehe so irgendwo 'rum Null. Umgekehrt Extrem ist Degradation Basisdateien an bloß Einlage Daten, so Wert sich nähernd unendlich. Dies Problematik ist um etwas breiter, sich binden an (Un)Abhängigkeit Applikation an Basisdateien, d.i . je mehr will nutzen die Möglichkeiten eines des Systems, desto sich werden von ihm abhängig und auch mehr ich brauche Spezialist. Logik, die das verworfen nach Basisdateien kann anwenden jedes, wer hat Zugang zu Basisdateien - odvarek dezentral der Objekte. Um was die erweitert Passwort Basisdateien, hierum sich verknappt Passwort Applikation - Erwerbs abgerundet Applikation. Hinüber, oft es verwaltet dazu, dass wir müssen einige Teil Passwort duplizieren. Z.B . web. Formular enthält Passwort fürs ergonomische Vergebung den Wert und Datenkontrolle, dieselbe unter Kontrolle enthält Basisdateien. Nochmals sich aber manchmal um nonplusultra dem Problem. Darüber Mehrheit der modernen RDBMS ermöglicht wenigstens einer Art Teilung Bücherschränke zwischen SP und anderen Server side Applikation (Yukon ~ dot NET, Oracle ~ Java, PostgreSQL ~ Perldruck, Python, Php, MsSQL2k - COM).


Abstützung gelagert von Prozeduren in MySQL5 vorstellt, dass überall wo wird installiert dies Basisdateien, zur Verfügung haben gewisse minimal Medium fürs Lauf unseren SQL/PSM Skript. So Stelle Aufgaben wir dürfen zu lösen gerade in MySQL unnötigerweise Installation nächsten nachträglich Software - Bildung Prüfdaten, Absiebung und Datentransformation, usw .

Still setze voraus, dass geneigte Leser weiß, was sind es eingegeben Prozeduren. Bis wohin nein, so geht es um Skript belebt Datenbanksystem und zwar in Aktion an gerade oder indirekt Benutzeranforderung Datenbanksystem. Von üblich Skript sich unterscheiden Aufspeicherung Ursprungskode in der Datenbank und Ausnutzung spezifisch funktionell Grenze ermöglicht Zugang zu internen Funktion Datenbanksystem. Dennoch, nein immer es muß dasein Passwort aufgetragen in der Datenbank (PL/Java) und nein immer muss man ausnutzen API Basisdateien (pl/sh). Jede gespeicherte Prozedur einen Namen haben, Liste Argumente und Körper enthaltend SQL Befehle, Deklaration den örtlichen veränderlich, Fehlerbehandlung, Zyklen und Bedingungen usw . Unterscheiden sich zwischen Prozedur und zwischen Funktion. Gewöhnlich bei Vorschlages Tätigkeit wir müssen respektieren gewisse Einschränkung, können wir sein aber von einer Sache Gebrauch machen in Auftrages SELECT.

Zu Zeiten K&R jedes Handbuch es muß beginnen mit einem Programm Helloworld.

1  DELIMITER //
2  SET sql_mode=ansi //
3  CREATE PROCEDURE hallo (IN wem varchar (20)) SELECT' hallo '|| wem; //
4  DELIMITER ;
5  SATZ sql_mode=' ' ;
6
7  CALL hallo( ' Welt' );

Übergesprungen bin null Varianten Funktion ohne Argumente. Beachten: a) Passwort eingegeben Prozeduren notieren nach Basisdateien DDL mit dem Befehl, b) Aufspeicherung Prozeduren kann anlassen mithilfe beliebig mysql Klient, möge das ist das Abstützung mysql in php oder in interaktive Konsole oder in phpmysqladminu. In diesem Fall Ausstieg aus Prozedur ist verwirklicht leer stehend mit dem Befehl SELECT (Befehl SELECT kann mehr, Ergebnisse ist multirecordset). Weitere Möglichen ist Anwendung OUT Parameter - Analogie umlegen Parameter Hinweis in den klassischen Programmiersprachen.

1  DELIMITER //
2  SET sql_mode=ansi//
3  CREATE PROCEDURE hallo (IN wem varchar(20), OUT Res varchar (40)) SET Res=' hallo' ||wem; //
4  DELIMITER ;
5  SET sql_mode=' ';
6
7  CALL hallo('Welt', @x) ;
8  SELECT @x;
9
10 DROP PROCEDURE hallo;

SQL Befehle in gelagert Prozeduren es muß dasein zum Abschluß gebracht Semikolon. Aber dieser Symbol sich schon angewendet wird in Konsole coby Symbol Enden SQL Auftrages. Bis wohin möchten wir in Konsole einschreiben Aufspeicherung Prozeduren, wir müssen Symbol Enden SQL Auftrages Streitigkeit-definieren - dazu dient Befehl DELIMITER [1]. Einstellung global der Variablen ansi_mode MySQL wird respektieren ANSI SQL Einschreibung. In Anfangsmodus wir haben nicht dafür Operator ||. Wenn auch bestelle ab ansi_mode [5], Prozedur Durchläufe richtig. Weshalb? Gemeinsam mit Passwort Prozeduren sich legt ein und aktuell Verformung MySQL. Leider, und hier ist nochmals Fehler, oder wenigstens bestimmt Unkonzistenz. Systemisch veränderlich max_sp_recursion_depth wir müssen einstellen getrennt bei jedem Anmeldung zu Basisdateien. Prozedur machen weg mit dem Befehl DROP PROCEDURE [10].

Mit dem Präfix @ bezeichnen wir die globalen (session) Variablen. Nirgend deklarieren wir sie nicht, wir reihen ihned gerade den Wert an[7]. Es handelt sich wirklich um der Variablen beiseite Server, also ist können anwenden in jedem Grenze. Global der Variablen verwenden wir nicht nur für Abbild Resultate gelagert von Prozeduren. Sehr oft aufeinander SQL Befehle anschließen, und sind Schnur durch eine bestimmte den Wert, die das Erwerbs dem ersten SELECT. Mit global veränderlich kann eliminieren Zusammenbau SQL an seitig Klient (hauptsächlich droht Risiko falschen Konversion zwischen Server und Ziel- Medium). In Fünfer alles verbleibt an seitig Server, schicke nur SQL Befehle. Außer von einem anderen sich Kloth. verwandelt. lassen geschickt von einer Sache Gebrauch machen fürs Nummerung Zeilen. Sowie in T-SQL Präfix @@ wird verwendet fürs systemisch der Variablen.

1  SET @r = 0;
2  SELECT @r := @r + 1, tab.* FROM tab

Dem häufigsten Klient MySQL wird PHP, was ist Beweggrund fürs Muster Ruf eingegeben Prozeduren daraus Medium (PHP5), weiter sein werden erwähnte Beispiele Perle, und C#. PHP5 enthält neue API fürs MySQL, die erschließene Eigenschaften Version 4.11 und höheren - unter andrem gebundene einläßlich und abgehend der Variablen und gefaßt Befehle (fürs Überschaubarkeit in Beispieles unbedacht Fehlerkontrolle).

1  $mysqli = new mysqli ($host, $user, $password, $db);
2  $stmt = $mysqli->prepare("CALL Hallo(?, @x)");
3  $stmt->bind_param("s", $param); /* s wie string */
4  $Parallele = "Welt";
5  $stmt->execute( );
6  $stmt = $mysqli->prepare("SELECT @x");
7  $stmt->bind_result($col1_x);
8  if ($stmt->fetch( ))
9		printf ("%mit ", $col1_x);
10 $stmt->close( );
11 $mysqli->close( );

Befehl bind_param an Zeile [3] schafft Bindung zwischen dem ersten Parameter Auftrages und veränderlich $param. Dem ersten Argument diesen Methode ist formatiert Kette - eine Merkmal, eine Variable, bestimmend Konversion. Dafür sind vier die Möglichkeiten: i – integer (Ganzzahl), d – double(Doppeltes), s – string(Zeichenkette), b – blob(Blob). Befehl bind_result aus Zeile [6] schafft verkehrt Bindung zwischen dem ersten Säulen Ausgang und veränderlich $col1_x. Nur vollständigkeitshalbe beifüge, dass Variable $param sich liest bis in Auftrages execute [5], und $col1_x füllt mit dem Befehl fetch [8]. Gebundene der Variablen gemeinsam mit gefaßt Befehle sind sehr wirkungsvolle gegen SQL Einspritzung.


Bildung Kreuz- Zusammenstellung

Sprache gelagert von Prozeduren ist verfahrensorientiert Sprache wie alle andren - C, Perl, Modula oder ADA. Wir suchen auf in ihm Deklaration veränderlich, Zyklen, Bedingungen. Besonderheit ist Vorhandensein einläßlich und abgehend Tätigkeit (I/O Tätigkeit), was ist Steuer zu Übertragung an Server (auch nicht möglich ist, damit man in gelagert Prozeduren warten an Interaktion Benutzers - Zeit an Server ist sehr teuer). Die Zweite Besonderheit, sicher überraschend, ist integriert SQL. Weile mir bestehenbleiben, ehe bin dem befallen Geschmack. Es ist mein privat Ansicht, welcher zwinge ich niemandem auf, aber desto, dass SQL Befehle sind nicht Zubruchgehen Anführungszeichen und zu nach Parameter Tätigkeit, sind viel ablesbar. Es spreche nicht davon, dass sich eigentlich nichts Neues lehren ihr müsst nicht: Funktion und Datentypen ihr könnt und benutzen Sie in SQL. Darüber sind nur Bedingungen, Zyklen, der Variablen - Leim, die hält SQL Befehle beisammen. An Internet findet Dutzende schlichter Beispiel, an die ist zwar anschaulich sehen Syntaxnotation der die Konstruktion, aber eigentlich gar kein Beitrag. Eine aus schön Beispiel, die bin gefunden, ist die Procedur erzeugende Kreuz-Zusammenstellung.

Beispiel Lesen aus Blog [1] Rolanda Baumana, welcher übrigens empfehlen zum Durchlesen. Aus Fünfer waren „Blogers“ ganz an Ekstase, und ich wundere ihned nicht Gegenüber Vieren ist es generacni Sprung, darüber abgestützt relativ hochwertig Beurkundung. Im Kern alle features Fünfer sind von Grund aus beschrieben einschließlich gelagert von Prozeduren. Ich muss schätzen ihr Unterstützung Benutzern und es, wie sich hochhält und gebaut Kommuniqué. Passwort bin moderat zu machte zurecht Überzeichnung nach ANSI SQL.

Worum geht es?. Vorzeichnen (anders, ist es sehr geschickt alt allgemein Vorgehen, wie ihr-zaubern Kreuz- Tabelle, ohne daß wir haben gebraucht Unterstützung des Systems):

CREATE TABLE Arbeitslosigkeit (
    id INT selbstinkrementierend PRIMARY KEY,
    Arbeitsplatz _id INT,
    Geschlecht ENUM('m',' f'),
    Name VARCHAR (32),
    Gehalt INT
);

CREATE TABLE Arbeitsplätze (
    Arbeitsplatz_id INT Auto_increment PRIMARY KEY,
    Arbeitsplatz VARCHAR(32)
);

INSERT INTO Arbeitsplätze (Arbeitsplatz)
VALUES ('Zurich'), ('New York City'), ('London');

INSERT INTO Arbeitslosigkeit (Arbeitsplatz _id, Geschlecht, Name, Gehalt)
VALUES
(1,' m',' Jon Simpson', 4500),
(1,' f',' Barbar Breitenmoser', 4700),
(2,' f',' Kirsten Ruegg', 5600),
(3,' m',' Ralph Teller', 5100),
(3,' m',' Peter Jonson', 5200);

Einfach Erwerbs Tabelle um dem Verkauf in London oder in Curychu. Allerdings gewinnen Abhängigkeit um höher dem Verkauf nach der Stadt und Geschlecht Verkäufer ist kompliziert (Säulen: f, m, Ganze; Zeilen: die Städte).

SELECT Arbeitsplätze, 
		SUM(CASE Geschlecht WHEN 'f' THEN Gehalt ELSE 0 END) AS f, 
		SUM(CASE Geschlecht WHEN 'm' THEN Gehalt ELSE 0 END) AS m, 
		SUM(Gehalt) AS Ganze 
	FROM Arbeitslosigkeit INNER JOIN Arbeitsplätze USING (Arbeitsplatz _id)
	GROUP BY Arbeitsplatz

Um die erste Hälfte der Arbeit kümmern sich die Aggregation (GROUP BY), d.i . Abscheidung Daten nach Gruppen aufgrund der Stadt. Weiter schon müssen wir allein zu helfen. In SQL vermochte nicht sorgen, damit sich in der Spalte' f' nein fanden "unrichtige" den Wert, beweisen wir aber sichern, damit diese Wertenich nicht zurechnen und waren ignorieren - CASE Geschlecht WHEN 'f' THEN Gehaltl ELSE 0 END. Rolandova Prozedur macht keine sonst nichts, ehe dass SELECT zu dieser Form generiert und vollstreckt. Kontroll- Frage: wie regulieren dieser Frage, damit darstellen Arithmetik und nein Summen.

1  DELIMITER //
2  SET sql_mode=ansi //
3  CREATE PROCEDURE xtab3(dimx_name VARCHAR(32), dimx_source VARCHAR(32),
                                 dimy_name VARCHAR(32), dimy_source VARCHAR(256),
                                 expr VARCHAR(32))
4  BEGIN
5          SET @col_list_expr =' SELECT  GROUP_CONCAT(DISTINCT '
                ||' \'SUM(CASE ' || dimx_name || ' WHEN \'\'\'||'
                || dimx_name ||' ||\'\'\' THEN ' || expr || ' ELSE 0 END) '
                || ' AS  \'\'\'||'||dimx_name||'||\'\'\'   \')INTO @col_list ' || dimx_source;
                
6          PREPARE col_list_pc FROM @col_list_expr;
7          EXECUTE col_list_pc;
8          DEALLOCATE PREPARE col_list_pc;

9          SET @xtab_expr =' SELECT' ||dimy_name||','||@col_list
                ||' , SUM('||dimx_name||') AS Ganze' || Dimer_source ||' GROUP BY' ||dimy_name;
                                
10        PREPARE xtab FROM @xtab_expr;
11        EXECUTE xtab;
12        DEALLOCATE PREPARE xtab;

13  END //
14  SET sql_mode='//'
15  DELIMITER ;

[5] Anwendung global der Variablen hier ins Auge fallen. Umhergehen sich so Fehler, welche nein ermöglicht in Auftrages PREPARE von einer Sache Gebrauch machen lokal veränderlich. Bildung SELECT anderen SELECT ist schnellste und auch wenigstens ablesbar Art Lösung diesen Aufgaben, wie sich allein können überzeugen. [7,11] Ausführung gefaßt Auftrages - bis wohin sich SQL Erzeugungsanweisung bis zu Flusses Prozeduren, Bezeichnung ihn wie dynamisch Befehl. [7] Generiert Parameterliste, [9] zu Verzeichnisses Beisetzung Legende und Spalte Ganze. Dynamisch Befehle darf nicht beinhalten lokal der Variablen, du sind daneben Sicht. Können sie aber, in Plätzen Parameter oder Teil INTO, beinhalten global der Variablen. Dynamisch SQL Befehl wir müssen voraus allein dem Start "erschweren " - Befehl PREPARE [6,10]. Die generierte Selection (SELECT) wird in dem globalen Variablen @xtab_expr (SELECT @xtab_expr) gespeichert;

mysql> CALL xtab3('Geschlecht','FROM Arbeitslosigkeit',' Arbeitsplatz','FROM Arbeitslosigkeit INNER JOIN Arbeitsplätze USING (Arbeitsplatz_id),''Gehalt');

+-------------------+---------+---------+----------+
| Arbeitsplatz      | m       | f       | Ganze    |
+-------------------+---------+---------+----------+
| London            | 10300   |    0    |  10300   |
| New York City     |     0   | 5600    |   5600   |
| Zurich            |  4500   | 4700    |  10200   |
+-------------------+---------+---------+----------+

Trotzdem dies Prozedur schon irgendeinen Arbeit eintreten, enthält nicht einzige Bedingungen, einzig Zyklus. Ähnlich Funktion können nicht vergüten spezialisierte Instrumente, und nicht einmal sich hierum nein anstrebt. In Fällen, wann reicht aus, Sie erspart Arbeit mit Verformung OLAPU. An Internet bin suchte ähnlich Beispiele klug gelagert von Prozeduren und nein gefunden. Nein gefunden bin nicht einmal kommerziell Bücherschränke, was mir ein bißchen stilllegen. Ein bißchen einfältig bin hoffen, dass mit Ankunft MySQL5 sich Situation verwandelt. Falls Sie haben gewußt um irgendeine schöne und nutzbare Prozeduren oder Packen, geben Sie mir wissen. Vermerkt allgemein gut Bücherschränke gelagert von Prozeduren ist wie Safran und zwar nicht nur für MySQL.


Optimisierung Indexes

Ich habe noch nicht die schöne und gewöhnliche Prozeduren gefunden, und zwar in Blog [2] Markuse Poppa. MySQL ermöglicht Längenregelung Indexes. Es ist nicht praktische indizieren Strings in ganz ihr Länge. Meist haben ausreichende Maß Selektivität schon nach die ersten n (n <20) Markierung. Wie aber feststellen optimal Länge? Markus kommt einher mit Grade, die das nennen Eindeutigkeit und zusammenzählen sie wie Verhältnis zwischen Arithmetik eindeutig identifizierbar Zeilen und gesamt Zeilenzahl.

SELECT count (distinct left(field_name, indexed_length)) / 
   count(*) * 100 FROM table_name;

Markusuv Passwort bin nochmals moderat zu nach-machte zurecht. Passwort angewendet wird ein vorübergehend Tabelle, die sich schafft in Prozeduren. Abschließend sich vollstreckt Ferkel von dieser Tabelle. Dies Technik sich oft angewendet wird an Microsoft SQL Serveru. Ist da allerdings eine klein Unterschied. In T-SQL hat vorübergehend Tabelle Begrenzung Haltbarkeit an Transaktion, in die war hergestellt. An MySQL so was besteht, also in Prozeduren sie wir müssen voraus Abschluss explizit beseitigen.

1  DELIMITER //
2  SET sql_mode=ansi //
3  DROP PROCEDURE IF EXISTS getUniqueness //

4  CREATE PROCEDURE getUniqueness (IN _table VARCHAR(255),
5  	IN _column VARCHAR(255), IN _noFrom INT, IN _noTo INT)
6  BEGIN
7  	DROP TEMPORARY TABLE IF EXISTS tt_uniqueness;
8	CREATE TEMPORARY TABLE tt_uniqueness
9		(noChar int unsigned not Null, uniqueness decimal(10,2) not Null);

10	SET @sql =' insert into tt_uniqueness ' 
11		||' select ?, cast(count(distinct left(' || _column ||' , ?)) / count(*) * 100 AS decimal(10,2)) From'
12		||  _table;
	
13	PREPARE pSql FROM @sql;
14	SET @count = _noFrom;
	
15	WHILE @count < _noTo DO
16		EXECUTE pSql USING @count, @count;
17		SET @count = @count + 1;
18	END WHILE;
	
19	SELECT * FROM tt_uniqueness;
20	DROP TEMPORARY TABLE tt_uniqueness;
21  END//
22  DELIMITER ;

Wofür gehts hier. Nochmals wir benutzen dynamisch SQL Befehl, und zwar weil Name Tabelle darf nicht dasein parametrizovan in statisch SQL Auftrages [10]. Sie-generiert dynamisch Befehl angewendet wird gebundene der Variablen - Symbol ?, und Phrase USING in Auftrages EXECUTE [16]. Sprache PSM (Persistent Stored Modul) in MySQL enthält nicht Zyklus FOR (ANSI SQL3/PSM ihn enthält - fürs Iteration über Tabelle), wir müssen sich auskommen mit klassisch WHILE, END WHILE - ist es eigentlich erste Muster Konstruktion Schleife [15]. Leer stehend SELECTEM zurückgeben Ergebnis [19].

mysql> CALL getUniqueness('phpbb_posts_text',' reicht aus_Text', 4, 10);
+--------+-------------------+
| noChar | uniqueness        |
+--------+-------------------+
|      4 |      51.18        |
|      5 |      59.41        |
|      6 |      67.94        |
|      7 |      71.47        |
|      8 |      78.82        |
|      9 |      84.12        |
|     10 |      85.00        |
+--------+-------------------+

Einfärbung Muster Ruf diesen Prozeduren in Perle (nochmals verkürzt um Fehlerkontrolle) mithilfe Bücherschränke DBI.

use strict; use DBI;
wir $dbh->DBI->connect('' , {RaiseError => 1, AutoCommit => 0});
wir $sth = $dbh->prepare("call getUniqueness(?,?,?,?)");
$sth->bind_param(1, $tbname, $DBI::SQL_VARCHAR);
$sth->bind_param(2, $colname, $DBI::SQL_VARCHAR);
$sth->bind_param(3, $nofrom, $DBI::SQL_INTEGER);
$sth->bind_param(4, $noTo, $DBI::SQL_INTEGER);
$sth->execute();
$sth->finish();
$dbh->disconnect();

Einspruch

Als bin sich zum erstenmal traf mit Einspruch, so bin überhaupt schwer von Begriff sein, worum geht es?. Mehrheit Translator und Interpret sie untestützt, und eher sich manieriert nein rekursiv Lösung. Alten Zeiten - MicroBaze Pascalu, TurboPascalu, ich bin froh, dass ich habe worauf gedenken. Wenn auch noch mir etwas davonlaufen, Zeiten Lochkarte, der Rechner Uran. Zeit, wann Rechnung Auszahlung fürs 10 tausend Menschen gedauert ganze Nacht, und fürs Operator es war Super Abenteuer. Hörte, dass irgendwo sich älter Dame schauen an resultierend Zusammenstellung, und wenn isst etwas passt nicht ganz, so sich rechnen nochmals, bis ißt man es den Anschein haben. Sitzen an nadupaneho Notizbuch, vielleicht 1000x schnell ehe CP/M an meinen Didaktik, und gleich würde umgeformt. Genug Nostalgie. Einspruch vorliegt. Es ist abstrakt Konstruktion, sie durfte uns ansehen um sich. Eine aus Äste Datenbanksystem, bis heute lebend, und wennschon noch lange nicht so markant (ohne Rücksicht, was sich diejenigen Paar Enthusiast denkt) es berücksichtigt, und unterstützen sehr effektiv Arbeit sich Bäume. Sind es sog . Netzwerk Basisdateien. Relational Basisdateien sind nicht an Einspruch von weitem also gut Ausstattung (vorliegen beide Verzweigung - Oracle und ANSI, die folgende Problematik sicher Art löst). 100% unvorbereitet sind Open Source Basisdateien. Fürs PostgreSQL es gibt patt, welcher war aber Ablehnung (fördernd beide Syntax: Oracle, ANSI). Unterstützung Einspruch hätte beinhalten Firebird 3.0. Worum geht es?? Meist um Aufgaben Durchsuchungen Baums nach Breiten oder in die Tiefe. Ohne Unterstützung auf der Ebene SQL wir müssen folgende Aufgaben auflösen an anwendungstechnisch Ebene oder mittels gelagert von Prozeduren. Bemerkung.: vorliegen minimal drei Lösung Aufspeicherung rekursiv Daten, wann wir dürfen gewinnen Liste Nachkommen, ohne daß zu müssen rekursiv rufen Prozeduren.

Implizit MySQL unzulässige rekursiv Ruf von Prozeduren. Es aber nein vorstellt kein dem Problem. Sie durfte ändern systemisch veränderlich max_sp_recursion_depth:

SET @@max_sp_recursion_depth=32;

Eine wichtige Rolle in SQL/PSM spielt das Fangen der Ausnahmen. Ist es gewisse Spezifikum des Sprach und übrigens spezifisch ist und Art wie sind Ausnahme der behandelten. Zum Unterschied von Mehrheit sonstiger Sprache, wo werden benutzt Konstruktion und la strukturiert Ausnahme, SQL/PSM angewendet wird fehlen handlery - subrutiny, die sich aktivieren bei Fehler. Kann man ergreifen konkret und beliebig Fehler. Was allerdings wird nicht empfohlen, weil in MySQL inzwischen besteht Art, wie detektieren Beweggrund Fehler, und somit sie wissen um Fehler überhaupt nichts. Z.B . Iteration über Ergebnisse Anfrage man in SQL/PSM löst wie folgt:

1   BEGIN
2     DECLARE done BOOLEAN DEFAULT false;
3     DECLARE v_a, v_b VARCHAR(20);
4     DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true;
5     DECLARE c CURSOR FOR SELECT a,b FROM mytab;
6     OPEN c;
7     FETCH c INTO v_a, v_b;
8     WHILE NOT DONE DO
9       FETCH c INTO v_und, v_b;
10    END WHILE;
11    CLOSE c;
12  END;    

Osten Fall, dass Zeiger stößt zum Ende Summe in Auftrages FETCH [7,9], sich aktivieren Bedienung Fehler NOT FOUND. In diesem Fall geht es um sog . CONTINUE HANDLER, d.i . sich herunterlassen Fehlerbehandlung (Einstellung der Variablen brachten ein [4]) und treibt fort sich folgenden mit dem Befehl [8,10]. Befehl FETCH öffnet eine Zeile aus einläßlich Summe eröffneten [6] Zeiger. Angelesen Säulen sich legt nach den örtlichen veränderlich v_a und v_b. Vollfüllen, Zeiger man in SQL verwendet fürs sequentiell Datenzugriff. Offen Zeiger sich freisetzt mit dem Befehl CLOSE [11].

Funktionell gleich Passwort demonstrieren Zyklus REPEAT UNTIL:

1   BEGIN
2     DECLARE done BOOLEAN DEFAULT false;
3     DECLARE v_und, v_b VARCHAR(20);
4     DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true;
5     DECLARE c CURSOR FOR SELECT a,b FROM mytab;
6     OPEN c;
7     REPEAT
8       FETCH c INTO v_und, v_b;
9       IF not done THEN
          ...
10      END IF;
11    UNTIL done END REPEAT;
12    CLOSE c;
13  END; 

Sprachlich Purist und Experten sich können sie Freund, welche die Variante ist elegant und besser. Mich persönlich kommt eine zu achtzehn und zweite ohne zwei zu zwanzig. In Beurkundung MySQL wird verwendet zweite die Variante. Beste die Variante ist der, die das inzwischen MySQL untestützt - Anwendung Konstruktion FOR. Als nächstes folgt Beispiel ist Modifikation Beispieles aus Firmen Beurkundung Petra Gultuzana. Habe weggemacht nur sinnlos fing Fehler, was ist Stil, welcher energisch an Öffentlichkeit propagieren Unfall. Als nächstes folgt beide Prozeduren schreiben aus Liste Nachkommen versprochen Einschlags. Ehestens Bildung vorübergehend Tabelle [8], welche sich vollfüllt rekursiv Ruf zweiter Prozeduren [12]. Danach sich vollstreckt leer stehend SELECT diesen Interims Tabelle [14](tj. auf diese Art wir erhalten Ergebnis hinaus aus Prozedur) und vorübergehend Tabelle sich schaffen ab [15]. Zweite Prozedur es ist nicht keineswegs robust. Falls die sollte Daten nicht den Baum repräsentiert haben, so trifft ein zu fehlerhaft Ergebnisses. Zweite Prozedur iterarieren über Nachkommen [28] - legt Anmerkung nach Interims Tabelle (Tabelle mit Ergebnisse) [32] und rekursiv anlassen selbst dich fürs Überwachung Nachkommen [33].

1   DELIMITER //
2   DROP PROCEDURE IF EXISTS hierarchy//
3   CREATE PROCEDURE hierarchy (start_with CHAR(10))
4   BEGIN
5     DECLARE v_person_id, in_father_id INT;
6     DECLARE in_person_name CHAR(20);    
7     DROP TABLE IF EXISTS Temporary_Table;
8     CREATE TEMPORARY TABLE Temporary_Table (
        person_id INT,
        Person_name CHAR(20),
        father_id INT,
        level INT
      );
9     SELECT person_id, person_name INTO v_person_id, v_person_name
        FROM Persons WHERE person_name = Start_with LIMIT 1;
10    IF NOT v_person_id IS NULL THEN
11      INSERT INTO Temporary_Table VALUES
          (v_person_id, v_person_name, v_father_id, 0);
12      CALL hierarchy2 (v_person_id, 1);
13    END IF;
14    SELECT person_id, person_name, father_id, level 
        FROM Temporary_Table ORDER BY level;
15    DROP TEMPORARY TABLE Temporary_Table;
16  END; //
17  DELIMITER ;

18  DELIMITER //
19  DROP PROCEDURE IF EXISTS hierarchy2//
20  CREATE PROCEDURE hierarchy2(start_with INT, level INT)
21  BEGIN
22    DECLARE v_person_id, v_father_id INT;
23    DECLARE v_person_name CHAR(20);
24    DECLARE done BOOLEAN DEFAULT FALSE;
25    DECLARE c CURSOR FOR
        SELECT person_id, person_name, father_id
        FROM Persons WHERE father_id = start_with;
26    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
27    OPEN c;
28    REPEAT
29      SET v_person_id=NULL;
30      FETCH c INTO v_person_id, v_person_name, v_father_id;
31      IF done=FALSE THEN
32        INSERT INTO Temporary_Table VALUES
            (v_person_id, v_person_name, v_father_id, level);
33        CALL hierarchy2(v_person_id,level+1);
34      END IF;
35    UNTIL done END REPEAT;
36    CLOSE c;
37  END; //
38  DELIMITER ;

Daß konnten sie Passwort herunterlassen, wir benötigen Prüfdaten:

CREATE TABLE Persons (
  person_id INT,
  person_name CHAR(20),
  father_id INT
);
INSERT INTO Persons VALUES (1,'Grandpa',NULL);
INSERT INTO Persons VALUES (2,'Pa-1',1),(3,'Pa-2',1);
INSERT INTO Persons VALUES (4,'Grandson-1',2),(5,'Grandson-2',2);

Nach Ingangsetzen Erwerbs Tabelle:

mysql> cal hierarchy ('Grandpa');
call hierarchy('Grandpa');
+----------------+---------------------+------------+--------+
| Personal_id    | Personal_name       | father_id  | Level  |
+----------------+---------------------+------------+--------+
| 1              | Grandpa             | NULL       | 0      |
| 2              | Pa-1                | 1          | 1      |
| 3              | Pa-2                | 1          | 1      |
| 4              | Grandson-1          | 2          | 2      |
| 5              | Grandson-2          | 2          | 2      |
+----------------+---------------------+------------+--------+

Überwachung Wachstum Basisdateien

Inspiration fürs als nächstes folgt Beispiel war Oracle XE. Eingestehen, dass www Grenze mir gut überraschen. An der vorigen Version hätte Gefühl, dass vielleicht mit ihren kein einziger außer Student und Paar verzweifelt kann nicht arbeiten und übrig lieber verwendet Steuerzeile. Einmal aus Tätigkeit ist und Abbild Statistiker Größen und Wachstum Tabellen. Habe geschrieben so Aufspeicherung Prozeduren, welche wird angezeigt zehn der größte Tabellen und zehn schnellste wachsend Tabellen. Außer von einem anderen ist und Muster möglich Anwendung multirecordsetu. Dem ersten Aufgabe ist Erwerbs und Archivierung den Angaben um Größen Tabelle. Allgemein sich diese den Wert Propaganda von systemisch Tabellen. ANSI SQL tragen auf sog . Informations Pläne, die MySQL 5 implementieren. Im Kern geht es um standardisieren Ansichten nach systemisch Tabellen. Danke ihrethalben Fallgestänge eine dem Problem bei Posament Applikation - Durchsuchung Aufbaus Basisdateien. Befehl SELECT Tablett_name FROM information_schema.Tablett wird funktionell an PostgreSQL, MySQL und alle andren Basisdateien, die in diesen Punkt respektieren ANSI SQL.

1   DELIMITER //
2   DROP PROCEDURE IF EXISTS set_stat //
3   CREATE PROCEDURE set_stat (schma VARCHAR(64))
4   BEGIN
5     DECLARE done, cursor_done BOOLEAN DEFAULT FALSE;
6     DECLARE v_table_name VARCHAR(64);
7     DECLARE v_table_rows, v_data_length INTEGER;
8     DECLARE v_hist_rows, v_hist_length INTEGER;
9     DECLARE c CURSOR FOR
10      SELECT table_name, table_rows, data_length
        FROM information_schema.tables WHERE table_schema = schma;
11    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
12    IF (SELECT table_name FROM information_schema.tables
        WHERE table_name = 'size_log') IS NULL THEN
13      CREATE TABLE size_log (
          table_schema VARCHAR(64),
          table_name VARCHAR(64),
          table_rows INTEGER,
          data_length INTEGER,
          inserted TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        );
15    END IF;
16    OPEN c;
17    REPEAT
18      FETCH c INTO v_table_name, v_table_rows, v_data_length;
19      IF v_table_name <> 'size_log' THEN
13        SET cursor_done = done;
14        SET v_hist_rows = NULL;
15        SELECT table_rows, data_length INTO v_hist_rows, v_hist_length
            FROM size_log WHERE table_name = v_table_name AND table_schema = schma
            ORDER BY inserted DESC LIMIT 1;
16        SET done = false; -- je nutno provest reset promenne
17        -- pridavam pouze nove zaznamy nebo zmeny
18        IF (v_hist_rows IS NULL)
            OR (v_hist_rows IS NOT NULL
            AND v_table_rows <> v_hist_rows AND v_data_length <> v_hist_length) THEN
19          INSERT INTO size_log(table_schema, table_name, table_rows, data_length)
              VALUES(schma, v_table_name, v_table_rows, v_data_length);
20        END IF;
21     END IF;
22   UNTIL cursor_done END REPEAT;
23   CLOSE c;
24  END //
25  DELIMITER ;

Prozedur Satz_Gut legt ein Stand Tabellen versprochen Pläne. Im Fall, dass besteht Tabelle size_Log [12], sich schafft [13]. Danach Iteration über alle Tabelle [17] daneben Tabelle size_Log. Aktuell die Angabe Vergleich mit archivieren Wert [18] und bis wohin kam es zu einer Änderung, so legen aktuell die Angabe um Größen Tabelle [19]. In Ansehung dessen, dass mir flag NOT FOUND (und umwegig und Inhalt der Variablen brachten ein) mir kann anwerfen wie Befehl FETCH [18] so Befehl SELECT INTO [15], ich muss sich vorschießen Inhalt der Variablen brachten ein [13] und wiederholt ihn stornieren [16]. Weiter, im Fall, dass SELECT INTO endet ohne Erfolg (Anzeichen NOT FOUND), neprepise sich Inhalt veränderlich in_hist_rows, in_hist_length [15]. Weil veränderlich in_hist_rows Anwendung zu Nachweis, obfalls schon ich habe Anmerkung in Tabelle size_Log, ich muss sie verlängern an NULL [14].

1   DELIMITER //
2   DROP PROCEDURE IF EXISTS stat //
3   CREATE PROCEDURE stat (sort_by CHAR(1), schma VARCHAR(64))
4   BEGIN
5     DECLARE done, cursor_done BOOLEAN DEFAULT FALSE;
6     DECLARE v_table_name VARCHAR(64);
7     DECLARE v_table_rows, v_data_length INTEGER;
8     DECLARE v_hist_rows, v_hist_length INTEGER;
9     DECLARE c CURSOR FOR
10      SELECT table_name, table_rows, data_length
          FROM information_schema.tables WHERE table_schema = schma;
11    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
12    DROP TABLE IF EXISTS tmp_table;
13    CREATE TEMPORARY TABLE tmp_table (
        table_schema VARCHAR(64),
        table_name VARCHAR(64),
        table_rows INTEGER,
        data_length INTEGER
      ); 
14    IF (SELECT table_name FROM information_schema.tables
        WHERE table_name = 'size_log') IS NULL THEN
15      CREATE TABLE size_log (
          table_schema VARCHAR(64),
          table_name VARCHAR(64),
          table_rows INTEGER,
          data_length INTEGER,
          inserted TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );
16    END IF;
17    OPEN c;
18    REPEAT
19      FETCH c INTO v_table_name, v_table_rows, v_data_length;
20      SET cursor_done = done;
21      SET v_hist_rows = NULL;
22      SELECT table_rows, data_length INTO v_hist_rows, v_hist_length
          FROM size_log WHERE table_name = v_table_name AND table_schema = schma
          ORDER BY inserted DESC LIMIT 1;
23      SET done = false; -- je nutno provest reset promenne
24      IF v_hist_rows IS NOT NULL
          AND v_table_rows <> v_hist_rows AND v_data_length <> v_hist_length THEN
25        INSERT INTO tmp_table VALUES(schma, v_table_name,
            v_table_rows - v_hist_rows, v_data_length - v_hist_length);
26      END IF;
27    UNTIL cursor_done END REPEAT;
28    CLOSE c;
29    CASE sort_by
30      WHEN 'r' THEN
31        SELECT table_schema, table_name, table_rows, data_length
            FROM information_schema.tables WHERE table_schema = schma
            ORDER BY table_rows DESC LIMIT 10;
32        SELECT * FROM tmp_table ORDER BY table_rows DESC LIMIT 10;
33      WHEN 'l' THEN
34        SELECT table_schema, table_name, table_rows, data_length
35          FROM information_schema.tables WHERE table_schema = schma
            ORDER BY data_length DESC LIMIT 10;
36        SELECT * FROM tmp_table ORDER BY data_length DESC LIMIT 10;
37    END CASE;
38    DROP TABLE tmp_table;
39  END; //
40  DELIMITER ;

In der Prozedur stat schon fast es ist nicht zu kommentieren. Der größte ZehnTabellen sortieren direkt aus dem Infoschema. Zehn schnellste wachsend Tabellen Erwerbs dynamisch Unterschied den Wert aus aktuell Zustand und Zustand Aufspeicherung in Tabelle size_Log. Zu erwähnt vielleicht steht Wirklichkeit, dass Konstruktion CASE in SQL/PSM es ist nicht identisch mit SQL mit dem Befehl CASE. Ergebnis seht über folgendes Auszug:

Welcome to the MySQL Monitor.  Commands end with ; or \g.
Your MySQL connection id is 1 to Server version: 5.1.9-beta-log

Type' help;' or '\h' for help. Type '\c' es clear the Pufferspeicher.

mysql> call stat('l','mysql');
call stat('l','mysql');
+---------------------+----------------------+-----------------+------------------+
| Tablett_schema      | Tablett_name         | Tablett_rows    | Daten_length     |
+---------------------+----------------------+-----------------+------------------+
| mysql               | help_topisch         | 464             | 253564           |
| mysql               | help_keyword         | 384             | 75648            |
| mysql               | help_category        | 37              | 21497            |
| mysql               | help_relation        | 740             | 6660             |
| mysql               | Prozent              | 8               | 5852             |
| mysql               | size_Log             | 32              | 984              |
| mysql               | Dezibel              | 2               | 880              |
| mysql               | gesetzt              | 4               | 224              |
| mysql               | Persons              | 5               | 145              |
| mysql               | fx2                  | 7               | 49               |
+---------------------+----------------------+-----------------+------------------+


+-------------------+----------------+---------------+----------------+
| table_schema      | table_name     | table_rows    | data_length    |
+-------------------+----------------+---------------+----------------+
| mysql             | fx2            | 1             | 7              |
+-------------------+----------------+---------------+----------------+

Falls möchte ich das letzte Beispiel ausschmücken, würde ich automatisches Ingangsetzung Prozeduren set_stat mittels Event Scheduleru einstellten. Event Scheduler (von Version 5.1) ist die Analogie Hiob in SQL Server oder crontabu in Unixu. Ergebnis (Event) ist Databasen Objekt enthaltend eine oder einige SQL Befehl, die sich führen durch in vorgeschrieben Zeit oder sich führen aus wiederholt in versprochen Intervall. Planungsbearbeiter Ergebnis ist blocken und es ist nötig ihn explizit auflockern: SET @@global.event_scheduler = ER. Zu Ausführung des Auftrages braucht Rechtswissenschaft Super-Benutzers. Fürs Ausprobieren Einleitung Beispiel, welcher jede Minute Beisetzung Anmerkung nach Tabelle Test. Dennoch wenigstens in mein Installation ist und zu dieser Stelle Fehler. Begebenheiten sich aktivieren, dennoch in gegeben Augenblick sich Ergebnis angewiesen SQL Durchlaufanweisung mehrere Male (wenn benutzte ich das einssekunde Intervall). Mit dem einsminütige Intervall sind keine Probleme.

CREATE TABLE Test(t TIMESTAMP);
CREATE EVENT into_Test
  ON SCHEDULE EVERY 1 MINUT DO
    INSERT INTO Test VALUES(CURRENT_TIMESTAMP);

Stelle set_stat bestimmt werden wir nicht rufen nach Minuten. Nehmen wir an einmal wöchentlich. Dann dürfen wir das Ergebnis mit dem Befehl definieren:

CREATE EVENT call_set_stat
  ON SCHEDULE EVERY 1 WEEK STARTS' 2006-07-01 13:00:00' DO
    CALL set_stat( );

Abschließend Einleitung noch Verheißung Beispiel c# Passwort fürs Ruf eingegeben Prozeduren. In Linuxu vorliegen zwei Treiber. Frei zugänglich ByteFX bereits nicht (und auch untestützt eingegeben Prozeduren), aber kann man ihn gewinnen wie RPM Päckchen. Darum sich richten auf zweite Treiber. Treiber MySQL connector/NET zwar unterstützen SP, aber wir müssen ihn installiert manuell (nur Version 1.0.7 und höher sind funktionell und daneben um.mit. MS Windows). Bis wohin Erwerbs Bücherschränke MySQL.Daten.Dll (aus mysql.com), wir müssen sie registrieren mit dem Befehl:

gacutil -i MySql.Data.dll

Als bin versucht Methodologie rufen eingegeben Prozeduren, nochmals bin prallte auf den Fehler. Der allerdings kann verursacht dem Einsatz sich entwickelnde Version MySQL. Darum Prozeduren rufe klassisch SQL mit dem Befehl CALL [13]. Eins Anruf Reader [16] rückkehrt mir zwei „recordset“. Nach durchlesen erste sich Verlagerung an zweite Ruf Methode NextResult() [32]. Anders dieser Beispiel vorstellt paradigmatisch Lesen recordsetu mithilfe ADO.NET.

1   using System;
2   using System.Data;
3   using MySql.Data.MySqlClient;

4   public class Test
5   {
6      public static void Main(string[] args)
7      {
8        string connectionString = "Database=mysql; User ID=root;";
9        IDbConnection dbcon;
10       dbcon = new MySqlConnection(connectionString);
11       dbcon.Open();
12       IDbCommand dbcmd = dbcon.CreateCommand();
13       dbcmd.CommandText = "CALL stat(?type,?scheme)";
14       dbcmd.Parameters.Add( new MySqlParameter("?type","l"));
15       dbcmd.Parameters.Add( new MySqlParameter("?scheme","mysql"));

16       IDataReader reader = dbcmd.ExecuteReader();

17       Console.WriteLine("".PadRight(62,'-'));
18       Console.WriteLine(" {0,-15} | {1,-15} | {2,10} | {3,10}",
                           "table schema",
                           "table name", "table rows", "data length");
19       Console.WriteLine("".PadRight(62,'-'));
20       Console.WriteLine(" Největší tabulky ");
21       Console.WriteLine("".PadRight(62,'-'));

22       while(reader.Read()) {
23         string table_schema = (string) reader["table_schema"];
24         string table_name = (string) reader["table_name"];
25         long table_rows = (long) reader["table_rows"];
26         long data_length = (long) reader["data_length"];
27         Console.WriteLine(" {0,-15} | {1,-15} | {2,10:g} | {3,10:g}",
                     table_schema,
                     table_name, table_rows, data_length);
28       }

29       Console.WriteLine("".PadRight(62,'-'));
30       Console.WriteLine(" Nejrychleji rostoucí tabulky ");
31       Console.WriteLine("".PadRight(62,'-'));

32       reader.NextResult();
33       while(reader.Read()) {
34         string table_schema = (string) reader["table_schema"];
35         string table_name = (string) reader["table_name"];
36         int table_rows = (int) reader["table_rows"];
37         int data_length = (int) reader["data_length"];
38         Console.WriteLine(" {0,-15} | {1,-15} | {2,10:g} | {3,10:g}",
                     table_schema,
                     table_name, table_rows, data_length);
39       }

40       reader.Close();
41       reader = null;
42       dbcmd.Dispose();
43       dbcmd = null;
45       dbcon.Close();
46       dbcon = null;
47     }
48  }

Skript Versetzung und herunterlassen Paar Befehl:

mcs monol-Test.cs -r:System.Data.dll -r:MySql.Data.dll
mono mono-Test.exe

In diesen Artikel bin von weitem unbeschrieben verzüglicher funkcionalitu gelagert von Prozeduren. Stichprobenweise bin opomnel: triggery, Sicherstellung, Kennziffern Funktion (DETERMINISTIC|NON DETERMINISTIC|MODIFIES SQL DATA etc), usw . Nicht einmal bin sich hierum nein versucht. Inzwischen bin sich trägt-gewirkt mit von niemandem, wer kann SP in MySQL 5 benutzt in realistischer Applikation. Es handelt sich inzwischen um allzu glühend Neueste, und einschätzen, dass wird Bedarf minimal Jahr, zwei ehe sein werden vychytany alle Fehler und ehe sich sie zu eigen Programmierer - sieh Einstieg PHP5.


==