Detaillierte Erläuterung der Kommentare zu gespeicherten MySQL-Prozeduren

Detaillierte Erläuterung der Kommentare zu gespeicherten MySQL-Prozeduren

0.Umweltbeschreibung:

Software Version
MySQL 8,0
Navicat

1. Gebrauchsanweisung

Eine gespeicherte Prozedur ist ein wichtiges Objekt in der Datenbank, das eine Reihe von SQL -Anweisungen kapseln kann, zum Vervollständigen einer komplexeren Geschäftslogik verwendet werden kann und Parameter eingeben und ausgeben kann (ähnlich dem Schreiben von Methoden in java ).

Es wird bei der Erstellung vorkompiliert und gespeichert, und der Benutzer muss es für nachfolgende Aufrufe nicht erneut kompilieren.

// Vergleiche editUser mit einer gespeicherten Prozedur public void editUser(User user,String username){
    Zeichenfolge a = "nihao";
    user.setUsername(Benutzername);
}
hauptsächlich(){
    Benutzer Benutzer = neuer Benutzer();
 editUser(user,"Benutzer");
    user.getUseranme(); //Java-Grundlagen}

Sie denken vielleicht: „Ich muss die Verwendung von SQL zur Verarbeitung der Geschäftslogik neu erlernen, aber kann ich nicht java zur Verarbeitung der Logik (wie etwa Schleifenbeurteilung, Schleifenabfrage usw.) verwenden?“ Warum also gespeicherte Prozeduren zur Handhabung der Geschäftslogik verwenden?

Vorteil:

In einer Produktionsumgebung können Sie die Geschäftslogik (oder Fehler) ändern, indem Sie die gespeicherte Prozedur direkt ändern, ohne den Server neu zu starten.
Schnelle Ausführungsgeschwindigkeit. Nachdem die gespeicherte Prozedur kompiliert wurde, ist sie schneller, als wenn sie einzeln ausgeführt wird.
Reduzieren Sie den Netzwerkübertragungsverkehr.
Praktisch zur Optimierung.

Mangel:

Prozedurale Programmierung und hoher Wartungsaufwand für komplexe Geschäftsprozesse.
Unbequemes Debuggen
Schlechte Portabilität zwischen verschiedenen Datenbanken. -- Die Syntax verschiedener Datenbanken ist inkonsistent!

2. Vorbereitung

SQL-Skript im Datenbank-Referenzmaterial:

Trennzeichen $$ --Deklarationsendezeichen

3. Grammatik

Offizielle Referenz-Website:

https://dev.mysql.com/doc/refman/5.6/en/sql-statements.html
https://dev.mysql.com/doc/refman/5.6/en/sql-compound-statements.html

#### 3.0 Syntaxstruktur ```sql
-- Gespeicherte Prozedurstruktur CREATE
    [DEFINER = Benutzer]
 PROZEDUR sp_name ([proc_parameter[,...]])
    [Merkmal ...] Routinenkörper
    
-- 1. Der Parameterteil proc_parameter kann wie folgt geschrieben werden:
 [ IN | OUT | INOUT ] Parametername Typ
 -- Der Typ kann jeder von MySQL unterstützte Typ sein -- 2. Im routine_body-Teil können Sie gültige SQL-Anweisungen schreiben BEGIN ... END

Einfache Demonstration:

-- Deklarationsabschlusszeichen. Da MySQL standardmäßig ';' als Abschlusszeichen verwendet und in der gespeicherten Prozedur ';' als Ende einer Anweisung verwendet wird, entsteht ein Konflikt zwischen ';' und dem Trennzeichen $$

PROZEDUR ERSTELLEN hallo_procedure ()
BEGINNEN
 SELECT 'Hallo Prozedur';
ENDE $$

rufen Sie hello_procedure() auf;

3.1 Variablen und Zuweisungen

Vergleichen Sie die Deklaration und Verwendung von lokalen Variablen und Membervariablen in java

Lokale Variablen:

Benutzerdefiniert, gültig in begin/end

Grammatik:
Deklarieren Sie eine Variable, declare var_name type [default var_value];
Beispiel: declare nickname varchar(32);

-- legt den Wert des Trennzeichens $$ fest
Prozedur sp_var01() erstellen
beginnen
 Deklarieren Sie den Spitznamen varchar (32) als Standard „unbekannt“.
 Spitznamen festlegen = "ZS";
 - Spitznamen festlegen := „SF“;
 Spitznamen auswählen;
Ende$$
--in weist das Trennzeichen $$ zu
Prozedur sp_var_into() erstellen
beginnen
 Deklarieren Sie emp_name varchar(32) als Standard „unbekannt“.
 Deklarieren Sie emp_no int als Standardwert 0;
 Wählen Sie e.empno,e.ename in emp_no,emp_name aus emp e, wobei e.empno = 7839;
 wählen Sie Mitarbeiternummer, Mitarbeitername;
Ende$$

Benutzervariablen:
Benutzerdefiniert, gültig für die aktuelle Sitzung (Verbindung). Analogie zu java Membervariablen

Grammatik:
@var_name
Keine Voranmeldung erforderlich, Anmeldung bei Verwendung

-- Trennzeichen $$ zuweisen
Prozedur sp_var02() erstellen
beginnen
 setze @nickname = "ZS";
 - Spitznamen festlegen := „SF“;
Ende$$
rufen Sie sp_var02() auf $$
select @nickname$$ -- Sie können das Ergebnis sehen

Sitzungsvariablen:
Vom System bereitgestellt, gültig für die aktuelle Sitzung (Verbindung)

Grammatik:

@@session.var_name

show session variables; -- Sessionvariablen anzeigen select @@session.unique_checks; -- Eine Sessionvariable anzeigen set @@session.unique_checks = 0; -- Sessionvariablen ändern

Globale Variablen:
Vom System bereitgestellt, gültig für den gesamten MySQL-Server

Grammatik:
@@global.var_name

Beispiel:

-- Zeigen Sie die Datensätze von Variablennamen mit char in globalen Variablen an

globale Variablen wie „%char%“ anzeigen; 

- Zeigen Sie den Wert der globalen Variable character_set_client an. Wählen Sie @@global.character_set_client. 

3.2 Ein- und Ausgabeparameter

-- Grammatik
in | out | inout param_name type

Beispiel:

-- IN-Typ-Demo-Trennzeichen $$
Prozedur sp_param01 erstellen (in age int)
beginnen
 setze @user_age = Alter;
Ende$$
rufe sp_param01(10) auf $$
wählen Sie @user_age$$
-- OUT-Typ, nur für die Ausgabe verantwortlich!
-- Anforderung: Ausgabe der Abteilungsnummer entsprechend der übergebenen Adresszeichenfolge.
Trennzeichen $$

Prozedur sp_param02 erstellen(in loc varchar(64),out dept_no int(11))
beginnen
 Wählen Sie d.deptno in dept_no aus Abteilung d, wobei d.loc = loc;
 --Hier wird betont, dass entweder die Tabelle einen Alias ​​hat oder der Parametername nicht mit dem Feldnamen übereinstimmt. Ende $$
Trennzeichen ;

--Testsatz @dept_no = 100;
rufen Sie sp_param02('DALLAS',@dept_no) auf;
wählen Sie @dept_no;
-- INOUT-Typtrennzeichen $$
Prozedur sp_param03 erstellen(inout name varchar(49))
beginnen
 Name festlegen = concat('Hallo', Name);
Ende$$
Trennzeichen ;

Setzen Sie @Benutzername = "Xiaoming".
rufen Sie sp_param03(@Benutzername) auf;
wählen Sie @Benutzername;

3.3 Prozesskontrolle-Beurteilung

Offizielle Website-Beschreibung
https://dev.mysql.com/doc/refman/5.6/en/flow-control-statements.html

Wenn

-- Syntax WENN Suchbedingung DANN Anweisungsliste
    [ELSEIF Suchbedingung THEN Anweisungsliste] ...
    [ELSE-Anweisungsliste]
ENDE, WENN


Beispiel:

-- Erforderlicher Wissenspunkt: timestampdiff(unit,exp1,exp2) nimmt die Differenz exp2-exp1, die Einheit ist Einheit
Wählen Sie Zeitstempeldifferenz (Jahr, e.Einstellungsdatum, jetzt ()) aus emp e, wobei e.empno = „7499“;
Trennzeichen $$
--VERFAHREN LÖSCHEN, WENN sp_param04 EXISTIERT;
Prozedur sp_param05 erstellen (im Zeitstempel von ages)
beginnen
 Deklariere das Ergebnis varchar(32);
 wenn Zeitstempeldifferenz(Jahr, Alter, jetzt())>40 
  dann setze das Ergebnis = „Veteran“;
 sonstwenn Zeitstempeldifferenz(Jahr,Alter,jetzt())>38 
  dann setze das Ergebnis = „Alter Mitarbeiter“;
 ANDERS 
  SET-Ergebnis = „Neuling“;
 Ende wenn;
 Ergebnis auswählen;
Ende $$
Trennzeichen;
 
rufen Sie sp_param05('1970-02-26 10:00:25') auf;
- Hinweis: Der MySQL-Zeitstempel muss im Jahr 1970 beginnen.

Fall

Diese Syntax kann nicht nur in gespeicherten Prozeduren, sondern auch in Abfrageanweisungen verwendet werden!

- Syntax 1 (ähnlich wie Java-Switch):
CASE Fallwert
    WANN when_value DANN Anweisungsliste
    [WENN When_Value DANN Anweisungsliste] ...
    [ELSE-Anweisungsliste]
FALL ENDE
-- Syntax 2:
FALL
    WANN Suchbedingung DANN Anweisungsliste
    [WENN Suchbedingung DANN Anweisungsliste] ...
    [ELSE-Anweisungsliste]
FALL ENDE


Beispiel:

-- Voraussetzung: Beschäftigungsjahre <= 38 für neue Mitarbeiter > 38 <= 40 für erfahrene Mitarbeiter > 40 für erfahrene Mitarbeiter Trennzeichen $$
Prozedur sp_hire_case() erstellen
beginnen
 Deklariere das Ergebnis varchar(32);
 Deklariere Nachricht varchar(64);
 Fall
    wenn timestampdiff(year,'2001-01-01',now()) > 40 
  Dann 
   Ergebnis festlegen = „Veteran“;
   Nachricht setzen = ,Opa‘;
 wenn timestampdiff(year,'2001-01-01',now()) > 38
  Dann 
   Setze Ergebnis = 'Alter Mitarbeiter';
   Nachricht festlegen = „Schmieriger Mann mittleren Alters“;
 anders 
  Ergebnis festlegen = „Neuling“;
  Nachricht festlegen = „Neuling“;
 Ende des Falls;
 Ergebnis auswählen;
Ende$$
Trennzeichen ;

3.4 Prozess-Regelkreis

Schleife

-- Syntax [begin_label:] LOOP
    Anweisungsliste
ENDE DER SCHLEIFE [end_label]

Beispiel:

Es ist zu beachten, dass es sich loop um eine Endlosschleife handelt und diese manuell beendet werden muss. Zum Beenden können wir leave verwenden.

Sie können sich leave als break in Java vorstellen; entsprechend gibt es iterate (Continue-Schleife) - analog zu continue in Java

--Anforderung: Schleifendruck 1 bis 10
--leave Steuerschleifen-Exit-Begrenzer $$
Prozedur sp_flow_loop() erstellen
beginnen
 Deklarieren Sie c_index als Int-Standard 1.
 Deklarieren Sie result_str varchar(256) als Standard „1“.
 cnt:Schleife
 
  wenn c_index >= 10
  dann verlasse cnt;
  Ende wenn;

  setze c_index = c_index + 1;
  setze result_str = concat(result_str,',',c_index);
  
 Ende der Schleife cnt;
 
 wähle result_str;
Ende$$

-- iterieren + Kontrollschleifen-Trennzeichen verlassen $$
Prozedur sp_flow_loop02() erstellen
beginnen
 Deklarieren Sie c_index als Int-Standard 1.
 Deklarieren Sie result_str varchar(256) als Standard „1“.
 cnt:Schleife

  setze c_index = c_index + 1;
  setze result_str = concat(result_str,',',c_index);
  wenn c_index < 10 dann 
   cnt iterieren; 
  Ende wenn;
  -- Kann folgender Satz vollstreckt werden? Wann wird es umgesetzt? Wenn c_index < 10 falsch ist, führen Sie leave cnt aus;
  
 Ende der Schleife cnt;
 wähle result_str;
 
Ende$$

wiederholen

[begin_label:] WIEDERHOLEN
    Anweisungsliste
UNTIL Suchbedingung -- bis ..., dann die Schleife verlassen END REPEAT [end_label]
-- Anforderung: Schleife und drucke 1 bis 10
Trennzeichen $$
Prozedur sp_flow_repeat() erstellen
beginnen
 Deklarieren Sie c_index als Int-Standard 1.
 -- Ergebniszeichenfolge sammeln, result_str varchar(256) als Standard „1“ deklarieren;
 count_lab:wiederholen
  setze c_index = c_index + 1;
  setze result_str = concat(result_str,',',c_index);
  bis c_index >= 10
 Ende der Wiederholung von count_lab;
 wähle result_str;
Ende$$


während

Analogie zu Javas while(){}
[begin_label:] WHILE Suchbedingung DO
    Anweisungsliste
ENDE WHILE [Ende_Label]
-- Anforderung: Schleife und drucke 1 bis 10
Trennzeichen $$
Prozedur sp_flow_while() erstellen
beginnen
 Deklarieren Sie c_index als Int-Standard 1.
 -- Ergebniszeichenfolge sammeln, result_str varchar(256) als Standard „1“ deklarieren;
 während c_index < 10
  setze c_index = c_index + 1;
  setze result_str = concat(result_str,',',c_index);
 Ende während;
 wähle result_str;
Ende$$

3.5 Prozesssteuerung - Schleife beenden, fortsetzen

verlassen

Analogie zu Javas breake
-- LEAVE kann innerhalb von BEGIN ... END oder Schleifenkonstrukten (LOOP, REPEAT, WHILE) verwendet werden.
LEAVE-Etikett

iterieren

Analogie zu Java weiter
-- ITERATE kann nur innerhalb von LOOP-, REPEAT- und WHILE-Anweisungen vorkommen.
ITERATE-Beschriftung



3.6 Cursor

Verwenden Sie einen Cursor, um einen Ergebnisset abzurufen und die Daten zeilenweise zu verarbeiten.

Analogie zum JDBC-ResultSet
--Deklarationssyntax DECLARE Cursorname CURSOR FOR Select-Anweisung
-- Öffnen Sie die Syntax OPEN Cursorname
- Syntax zum Abrufen von Werten: FETCH cursor_name INTO var_name [, var_name] ...
-- Syntax schließen CLOSE Cursorname
-- Voraussetzung: Abfrage der Mitarbeiter nach Abteilungsname und Anzeige der Mitarbeiter-ID, des Namens und des Gehalts durch Auswahl. (Beachten Sie, dass dies nur eine Demonstration der Cursorverwendung ist.)
-- Ändern Sie das Endzeichen in $$
Trennzeichen $$
-- Erstellen Sie eine gespeicherte Prozedur (mit einem Eingabeparameter)
Prozedur sp_create_table02 erstellen(in dept_name varchar(32))
beginnen
-- Die Variable muss zuerst deklariert werden: declare e_no int;
 deklarieren Sie e_name varchar(32);
 Deklariere e_sal als Dezimalzahl (7,2);
 
 Deklarieren Sie lp_flag als booleschen Standardwert „true“.
-- Als nächstes deklarieren Sie den Cursor: Der Cursorwert ist table(e.empno,e.ename,e.sal), erhalten durch query(dept_name)
 deklarieren Sie den Cursor emp_cursor für 
  Wählen Sie e.empno, e.ename, e.sal
  von Mitarbeiter, Abteilung D
  wobei e.deptno = d.deptno und d.dname = dept_name;
  
-- Deklarieren Sie dann den Handler:
-- Über den Handle: https://blog.csdn.net/qq_43427482/article/details/109898934
-- Wenn Sie dies nach dem Lesen immer noch nicht verstehen, lesen Sie noch einmal: https://www.cnblogs.com/phpper/p/7587556.html
-- SQL STATE ist hier beteiligt: ​​https://blog.csdn.net/u014653854/article/details/78986780
-- Deklarieren Sie den Handler: Wenn jede SQL-Anweisung einen Fehler mit ERROR STATE ohne Wert übergibt, setzen Sie die Variable lp_flag auf false und setzen Sie die Ausführung der SQL-Anweisung fort (wenn sie nicht deklariert ist und eine Schleife einen Fehler meldet, stoppt die gesamte SQL-Anweisung die Schleife direkt).
 Deklarieren Sie den Continue-Handler für NICHT GEFUNDEN und setzen Sie lp_flag = false.
- Öffnen Sie den Cursor open emp_cursor;
-- Offene Schleife: emp_loop
 emp_loop:Schleife
-- Übergeben Sie den Cursorwert an drei Variablen: fetch emp_cursor into e_no, e_name, e_sal;
-- Wenn die Variable lp_flag wahr ist, holen Sie sich die Werte dieser drei Parameter; andernfalls unterbrechen Sie die emp_loop, wenn lp_flag dann
   wähle e_no, e_name, e_sal;
  anders
   verlasse emp_loop;
  Ende wenn;
-- Schleife beenden, Schleife beenden, emp_loop;
-- Benutzervariablen definieren und Werte zuweisen (Benutzervariablen müssen nicht im Voraus deklariert werden und sind nur für die aktuelle Sitzung gültig) > Ich verstehe den Sinn dieses Schritts nicht set @end_falg = 'exit_flag';
-- Schließen Sie den Cursor close emp_cursor;
-- Beenden Sie die gespeicherte Prozedur end$$
-- Wiederherstellen; Endtrennzeichen;

-- Verwenden Sie diese gespeicherte Prozedur und übergeben Sie Parameter call sp_create_table02('RESEARCH');

Besondere Aufmerksamkeit:

In der Syntax müssen Variablendeklaration, Cursordeklaration und handler nacheinander geschrieben werden, da sonst beim Erstellen der gespeicherten Prozedur ein Fehler auftritt.

3.7 Handler in gespeicherter Prozedur

handler Handle wird verwendet, um bedingte Verarbeitungen zu definieren

DECLARE handler_action HANDLER
    FÜR Bedingungswert [, Bedingungswert] ...
    Stellungnahme

handler_action: {
    CONTINUE – Ausführung fortsetzen | EXIT – Ausführung beenden | UNDO – nichts tun}

CONTINUE: Die Ausführung des aktuellen Programms wird fortgesetzt. -- Setzt die Ausführung des aktuellen Programms fort. EXIT: Die Ausführung wird für die zusammengesetzte Anweisung BEGIN ... END beendet, in der der Handler deklariert ist. Dies gilt auch, wenn die Bedingung in einem inneren Block auftritt. -- Stoppt die Ausführung der zusammengesetzten Anweisung BEGIN ... END, in der der Handler deklariert ist. Dies gilt auch, wenn die Bedingung in einem inneren Block auftritt.

Bedingungswert: {
    mysql_fehlercode
  | SQLSTATE [WERT] sqlstate_wert
  | Bedingungsname
  | SQLWARNING
  | NICHT GEFUNDEN
  | SQLEXCEPTION
}

SQLWARNING: Abkürzung für die Klasse der SQLSTATE-Werte, die mit '01' beginnen. – Das heißt, die Klasse, die mit 01 beginnt. NOT FOUND: Abkürzung für die Klasse der SQLSTATE-Werte, die mit '02' beginnen. – Das heißt, die Klasse, die mit 02 beginnt. SQLEXCEPTION: Abkürzung für die Klasse der SQLSTATE-Werte, die nicht mit '00', '01' oder '02' beginnen. – Das heißt, die Klasse, die nicht mit 00, 01 oder 02 beginnt. – Verschiedene Schreibweisen:
 DECLARE exit HANDLER FÜR SQLSTATE '42S01', setze @res_table = 'EXISTIERT';
 DECLARE continue HANDLER FOR 1050 setze @res_table = 'EXISTS';
 DECLARE, weiter HANDLER FÜR nicht gefunden, gesetzt @res_table = 'EXISTIERT';

4. Üben

——Bitte beachten Sie, dass der Geschäftsprozess gespeicherter Prozeduren im Allgemeinen in Java-Code implementiert werden kann. Unsere folgenden Anforderungen gelten für die Praxis gespeicherter Prozeduren.

4.1 Daten mit gespeicherten Prozeduren aktualisieren

Das Gehalt einer Person in einer bestimmten Abteilung (anzugeben) wird um 100 erhöht; handelt es sich um den Firmenpräsidenten, erfolgt keine Gehaltserhöhung.

delimiter // -- Definieren Sie das Abschlusszeichen create procedure high_sal(in dept_name varchar(32)) -- Erstellen Sie eine gespeicherte Prozedur begin -- Starten Sie eine gespeicherte Prozedur declare e_no int; -- Deklarieren Sie eine Variable declare e_name varchar(32);
 Deklariere e_sal als Dezimalzahl (7,2);
 
 Deklarieren Sie lp_flag als booleschen Standardwert „true“.
 
 Deklariere den Cursor emp_cursor für -- Deklariere den Cursor, wähle e.empno, e.ename, e.sal
  von Mitarbeiter, Abteilung D
  wobei e.deptno = d.deptno und d.dname = dept_name;
  
 - Handler-Handle deklarieren (bedingte Verarbeitung)
 Deklarieren Sie den Continue-Handler für NICHT GEFUNDEN und setzen Sie lp_flag = false.
  
 open emp_cursor; -- Öffnet den Cursor emp_loop:loop -- Startet die Schleife fetch emp_cursor into e_no,e_name,e_sal; -- Variablenzuweisung if lp_flag then -- Flusskontrolle if e_name = 'king' then 
    emp_loop iterieren; -- Schleife fortsetzen, sonst 
    update emp e set e.sal = e.sal + 100 wobei e.empno = e_no; – Daten aktualisieren, Ende, wenn;
  anders
   leave emp_loop; – Schleife verlassen end if; – Prozess beenden end loop emp_loop; – Schleife beenden set @end_falg = 'exit_flag'; – Benutzervariablen deklarieren close emp_cursor; – Variablenverhältniscursor end // – gespeichertes Prozedurtrennzeichen beenden; – Terminator wiederherstellen call high_sal('ACCOUNTING');

4.2 Erstellen einer Loop-Tabelle

Erstellen Sie die Tabellen comp_2020_04_01、comp_2020_04_02、...
entsprechend jedem Tag des nächsten Monats comp_2020_04_01、comp_2020_04_02、...

(Simulation) Anforderungsbeschreibung:

Wir müssen eine Tabelle verwenden, um viele Daten aufzuzeichnen, z. B. das Such- und Kaufverhalten eines bestimmten Benutzers (beachten Sie, dass davon ausgegangen wird, dass dies in einer Datenbank gespeichert wird). Wenn es jeden Tag viele Datensätze gibt, ist es zu groß, alle Daten in einer Tabelle aufzuzeichnen, und wir müssen die Tabelle in zwei Teile aufteilen. Unsere Anforderung besteht darin, jeden Tag eine Tabelle zu haben, um die statistischen Daten des Tages zu speichern, was die Erstellung dieser Tabellen im Voraus erfordert - erstellen Sie am Ende jedes Monats Tabellen für jeden Tag des nächsten Monats!

-- Wissenspunkt: Die Verwendung lokaler Variablen nach der Vorverarbeitung der Prepare-Anweisung führt zu einem Fehler -- https://dev.mysql.com/doc/refman/5.6/en/sql-prepared-statements.html
-- Wenn Sie englische Dokumente nicht verstehen, lesen Sie dies: https://www.cnblogs.com/geaozhang/p/9891338.html; Ich sollte auch einige englische technische Dokumente lesen, um PREPARE stmt_name FROM preparable_stmt zu verbessern
AUSFÜHREN stmt_name [VERWENDEN @var_name [, @var_name] ...]
{DEALLOCATE | DROP} PREPARE Anweisungsname

-- Hier ist ein Vorverarbeitungsbeispiel: Verwenden Sie eine Zeichenfolgendefinition, um SQL vorzuverarbeiten (berechnen Sie die Hypothenuse eines rechtwinkligen Dreiecks).
PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypothenuse'; -- POW(x,y)-Funktion, wird verwendet, um x hoch y zu berechnen (http://c.biancheng.net/mysql/pow_power.html); SQRT-Funktion wird verwendet, um die Quadratwurzel zu finden (https://blog.csdn.net/weixin_39554172/article/details/113124290)
Setzen Sie @a = 3;
SET @b = 4; -- Die Verwendung der Benutzervariablen erfolgt durch die Deklaration EXECUTE stmt1 USING @a, @b; -- Das Ergebnis ist 5
DEALLOCATE PREPARE stmt1; 

– Wissenspunkt: Zeitverarbeitung – EXTRACT(unit FROM date) extrahiert den angegebenen Positionswert der Zeit – DATE_ADD(date,INTERVAL expr unit) Datumsoperation – LAST_DAY(date) ruft das Datum des letzten Tages des Datums ab – YEAR(date) gibt das Jahr im Datum zurück – MONTH(date) gibt den Monat des Datums zurück – DAYOFMONTH(date) gibt den Tag zurück – Hinweis: Laut https://stackoverflow.com/questions/35838321/day-vs-dayofmonth-in-mysql ist die Wirkung von DAY(date) tatsächlich dieselbe – Idee: Schleife zum Erstellen der Tabellennamen comp_2020_05_01 bis comp_2020_05_31; und führe die Anweisung „create“ aus.
-- Analyse: 1. Die Tabelle wird in einer Schleife erstellt und nur der Tabellenname ist unterschiedlich. Erwägen Sie die Verwendung einer gespeicherten Prozedur zur Durchführung der Schleifenverarbeitung und verwenden Sie die Vorverarbeitung, um die Effizienz zu verbessern. 2. Zuerst wird eine Variable zum Speichern des ausgeführten SQL benötigt, dann eine Variable für das Jahr, eine Variable für den Monat, eine Variable für das Datum und eine Variable für den verknüpften Tabellennamen. Darüber hinaus wird eine Zahl für die Akkumulation benötigt. Bis jetzt haben wir den Bedarf für mindestens 6 Variablen ermittelt. Um das Datum 0 zu vervollständigen, werden zwei Variablen für Monat und Tag hinzugefügt, um 0 zu ergänzen und so 01, 02 usw. zu bilden. 3. Unter Berücksichtigung des Vorverarbeitungsformats (keine lokalen Variablen nach „from“) schreiben Sie 7 lokale Variablen und 1 Benutzervariablen-Trennzeichen // --Deklarationsterminator create procedure sp_create_table()
beginnen
-- Definieren Sie eine Reihe lokaler Variablen: „next_year int“;
 Deklarieren Sie nächsten_Monat int;
 Deklarieren Sie next_month_maxday int;
  
 deklarieren Sie next_month_str char(2);
 deklarieren Sie next_month_maxday_str char(2);
 
 -- Verarbeiten Sie den Tabellennamen für jeden Tag. Deklarieren Sie table_name_str char (10).
 - Statistische Sequenz deklariert t_index int default 1;
 -- deklarieren Sie create_table_sql varchar(200);
 
 -- Ruft das Jahr des nächsten Monats ab: next_year = year(date_add(now(),INTERVAL 1 month));
 -- Den nächsten Monat festlegen: next_month = month(date_add(now(),INTERVAL 1 month));
 -- Was ist der letzte Tag des nächsten Monats? setze next_month_maxday = dayofmonth(LAST_DAY(date_add(now(),INTERVAL 1 month)));
 
 -- Addieren Sie 0: 01,02····,09 für Januar-September
 wenn nächster_Monat < 10
  dann setze next_month_str = concat('0',next_month);
 anders
  setze nächsten_monat_str = concat('',nächster_monat);
 Ende wenn;
 
 
 während t_index <= next_month_maxday
  
  -- Wie oben, addieren Sie 0 zu den Tagen
  wenn (t_index < 10)
   dann setze next_month_maxday_str = concat('0',t_index);
  anders
   setze next_month_maxday_str = concat('',t_index);
  Ende wenn;
  
  -- 2020_05_01
  setze table_name_str = concat(nächstes_Jahr,'_',nächster_Monat_str,'_',nächster_Monat_maxday_str);
  -- Splice erstellt SQL-Anweisung (Benutzervariable)
  setze @create_table_sql = concat(
     'Tabelle comp_ erstellen',
     Tabellenname_str,
     '(`grade` INT(11) NULL,`losal` INT(11) NULL,`hisal` INT(11) NULL) COLLATE=\'utf8_general_ci\' ENGINE=InnoDB');
  -- Lokale Variablen können nach FROM nicht verwendet werden! Aus diesem Grund verwenden wir Benutzervariablen, um create_table_stmt FROM @create_table_sql vorzubereiten.
  führen Sie create_table_stmt aus;
  DEALLOCATE, bereiten Sie create_table_stmt vor;
  
  setze t_index = t_index + 1;
  
 Ende während; 
Ende//
Trennzeichen;

rufen Sie sp_create_table() auf

-- Das Folgende ist eine vereinfachte Version des Trennzeichens //
CREATE PROCEDURE sp_createtable1 () BEGIN-- DECLARE statistische Sequenz
  t_index INT DEFAULT 1;
 WÄHREND
   t_index <= TAG (
    LETZTER TAG(
    date_add( jetzt(), INTERVALL 1 MONAT ))) DO
   
   SET @create_table_sql = concat(
    'Tabelle comp_ erstellen',
    JAHR (
    date_add(jetzt(), INTERVALL 1 MONAT)),
    '_',
    MONAT (
    date_add(jetzt(), INTERVALL 1 MONAT)),
    '_',
    t_index,
    '(`Klasse` INT(11) NULL,`losal` INT(11) NULL,`hisal` INT(11) NULL) COLLATE=\'utf8_general_ci\' ENGINE=InnoDB' 
   );-- Lokale Variablen können nach FROM nicht verwendet werden! Deshalb verwenden wir Benutzervariablen PREPARE create_table_stmt 
  AUS
   @Tabelle erstellen_sql;
  AUSFÜHREN create_table_stmt;
  DEALLOCATE PREPARE create_table_stmt;
  
  SETZEN Sie t_index = t_index + 1;
  
 ENDE WÄHREND;
 
ENDE // 
Trennzeichen;
Rufen Sie sp_createtable1 () auf

4.3 Andere Szenarien:

Unternehmen, die CRUD-Operationen an mehreren Tabellen erfordern, wie etwa „Einkaufspunkte zu Benutzern hinzufügen und diese in der Tabelle mit den Gesamtpunkten des Benutzers aktualisieren“.
Und Transaktionsbefehle können intern verwendet werden.

5. Sonstiges

5.1 Charakteristik

Eigenschaften:
    KOMMENTAR 'Zeichenfolge'
  | SPRACHE SQL
  | [NICHT] DETERMINISTISCH
  | { ENTHÄLT SQL | KEIN SQL | LIEST SQL-DATEN | ÄNDERT SQL-DATEN }
  | SQL-SICHERHEIT { DEFINER | INVOKER }


Die Bedeutung von SQL SECURITY ist wie folgt:

Gespeicherte MySQL-Prozeduren geben den tatsächlichen Benutzer an, der die gespeicherte Prozedur ausführt, indem sie die SQL SECURITY-Klausel angeben.
Wenn die SQL SECURITY-Klausel als DEFINER angegeben ist, wird die gespeicherte Prozedur unter Verwendung des DEFINER der gespeicherten Prozedur ausgeführt. Dabei wird überprüft, ob der Benutzer, der die gespeicherte Prozedur aufruft, über die execute für die gespeicherte Prozedur verfügt und ob der DEFINER-Benutzer über Berechtigungen für die zugehörigen Objekte verfügt, auf die von der gespeicherten Prozedur verwiesen wird (z. B. Tabellen in der gespeicherten Prozedur).
Wenn die SQL SECURITY-Klausel als INVOKER angegeben ist, führt MySQL die Prozedur als der Benutzer aus, der die gespeicherte Prozedur aktuell aufruft, und überprüft, ob der Benutzer über die execute für die gespeicherte Prozedur und die Berechtigungen für die zugehörigen Objekte verfügt, auf die die gespeicherte Prozedur verweist.
Wenn Sie die SQL SECURITY-Klausel nicht explizit angeben, führt MySQL die gespeicherte Prozedur standardmäßig als DEFINER aus.

5.2 Dead-Loop-Verarbeitung

-- Wenn eine Endlosschleife vorhanden ist, können Sie sie mit dem folgenden Befehl anzeigen und beenden: show processlist;
ID töten;

5.3 Sie können in der Select-Anweisung case schreiben

https://dev.mysql.com/doc/refman/5.6/en/kontrollflussfunktionen.html
wählen 
 Fall
  wenn timestampdiff(year,e.hiredate,now()) <= 38 dann 'Neuling'
  wenn timestampdiff(year,e.hiredate,now()) <= 40 dann ‚Ehemaliger Mitarbeiter‘
  sonst 'Veteran'
 Ende hir_loc,
 e.*
von emp e;


5.4 Temporäre Tabellen

Temporäre Tabellen werden beim Schließen der Sitzung automatisch zerstört.
https://www.runoob.com/mysql/mysql-temporary-tables.html

temporäre Tabelle Tabellenname erstellen(
  Feldname Typ [Einschränkung],
  Name varchar(20) 
)Engine=InnoDB Standard-Zeichensatz utf8;

-- Voraussetzung: Abfrage der Mitarbeiter nach Abteilungsname und Anzeige der Mitarbeiter-ID, des Namens und des Gehalts durch Auswahl. (Beachten Sie, dass dies nur eine Demonstration der Cursorverwendung ist.)
Trennzeichen $$
Prozedur sp_create_table02 erstellen(in dept_name varchar(32))
beginnen
 Deklarieren Sie emp_no int;
 deklarieren Sie emp_name varchar(32);
 Deklarieren Sie emp_sal als Dezimalzahl (7,2).
 Deklarieren Sie exit_flag als Int-Standard 0.
 
 deklarieren Sie den Cursor emp_cursor für
  Wählen Sie e.empno, e.ename, e.sal
  von emp e inner join dept d auf e.deptno = d.deptno, wobei d.dname = dept_name;
 
 Deklarieren Sie den Continue-Handler für nicht gefundenes Set exit_flag = 1;
 
 -- Erstellen Sie eine temporäre Tabelle zum Sammeln von Daten CREATE temporary TABLE `temp_table_emp` (
  `empno` INT(11) NOT NULL COMMENT 'Mitarbeiternummer',
  `ename` VARCHAR(32) NULL COMMENT 'Mitarbeitername' COLLATE 'utf8_general_ci',
  `sal` DECIMAL(7,2) NOT NULL DEFAULT '0.00' COMMENT 'Gehalt',
  PRIMÄRSCHLÜSSEL (`empno`) MIT BTREE
 )
 COLLATE='utf8_general_ci'
 ENGINE=InnoDB; 
 
 emp_cursor öffnen;
 
 c_loop:Schleife
  Holt emp_cursor in emp_no, emp_name, emp_sal;
  
  
  wenn exit_flag != 1 dann
   in temp_table_emp-Werte einfügen (emp_no, emp_name, emp_sal); 
  anders
   verlasse c_loop;
  Ende wenn;
  
 Ende der Schleife c_loop;
 
 wähle * aus temp_table_emp;
 
 select @sex_res; – Nur um zu sehen, ob es ausgeführt wird, bis emp_cursor geschlossen wird;
 
Ende$$

rufen Sie sp_create_table02('RESEARCH') auf;

Anhang: SQL zum Erstellen einer Tabelle in diesem Beispiel

CREATE TABLE `dept` (
 `deptno` INT(11) NOT NULL COMMENT 'Abteilungsnummer',
 `dname` VARCHAR(32) NULL COMMENT 'Abteilungsname' COLLATE 'utf8_general_ci',
 `loc` VARCHAR(64) NULL COMMENT 'Abteilungsadresse' COLLATE 'utf8_general_ci',
 PRIMÄRSCHLÜSSEL (`deptno`) MIT BTREE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
IN ABTEILUNGSWERTE EINFÜGEN
 (10,'BUCHHALTUNG','NEW YORK');
IN ABTEILUNGSWERTE EINFÜGEN (20,'FORSCHUNG','DALLAS');
IN ABTEILUNGSWERTE EINFÜGEN
 (30,'VERKAUF','CHICAGO');
IN ABTEILUNGSWERTE EINFÜGEN
 (40,'BETRIEB','BOSTON');
 
CREATE TABLE `emp` (
 `empno` INT(11) NOT NULL COMMENT 'Mitarbeiternummer',
 `ename` VARCHAR(32) NULL COMMENT 'Mitarbeitername' COLLATE 'utf8_general_ci',
 `job` VARCHAR(10) NULL COMMENT 'Position' COLLATE 'utf8_general_ci',
 `mgr` INT(11) NULL COMMENT 'Übergeordnete Nummer',
 `hiredate` DATUM NICHT NULL KOMMENTAR 'Job-Startzeit',
 `sal` DECIMAL(7,2) NOT NULL DEFAULT '0.00' COMMENT 'Gehalt',
 `comm` DECIMAL(7,2) NULL COMMENT 'Jahresendbonus',
 `deptno` INT(11) NOT NULL COMMENT 'Abteilungsnummer',
 PRIMÄRSCHLÜSSEL (`empno`) MIT BTREE,
 INDEX `FK_emp_dept` (`deptno`) mit BTREE,
 EINSCHRÄNKUNG `FK_emp_dept` FREMDER SCHLÜSSEL (`deptno`) REFERENZEN `procedure_demo`.`dept` (`deptno`) ON UPDATE RESTRICT ON DELETE RESTRICT
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

in emp-Werte einfügen
(7369,'Schmied','Angestellter',7902,'17.12.1980',800,null,20);
in emp-Werte einfügen
(7499,'Allen','Verkäufer',7698,'1981-02-20',1600,300,30);
in emp-Werte einfügen
(7521,'Bezirk','Verkäufer',7698,'1981-02-22',1250,500,30);
in emp-Werte einfügen
(7566,'jones','Manager',7839,'1981-02-04',2975,null,20);
in emp-Werte einfügen
(7654,'Martin','Verkäufer',7698,'28.09.1981',1250,1400,30);
in emp-Werte einfügen
(7698,'blake','Manager',7839,'1981-05-01',2850,null,30);
in emp-Werte einfügen
(7782,'Clark','Manager',7839,'09.06.1981',2450,null,10);
in emp-Werte einfügen
(7788,'Scott','Analyst',7566,'13.07.1987')-85,3000,null,20);
in emp-Werte einfügen
(7839,'König','Präsident',null,'17.11.1981',5000,null,10);
in emp-Werte einfügen
(7844,'Turner','Verkäufer',7698,'1981-09-08',1500,0,30);
in emp-Werte einfügen
(7876,'adams','clerk',7788,'1987-07-13')-51,1100,null,20);
in emp-Werte einfügen
(7900,'James','Angestellter',7698,'1981-12-03',950,null,30);
in emp-Werte einfügen
(7902,'Ford','Analyst',7566,'03.12.1981',3000,null,20);
in emp-Werte einfügen
(7934,'Müller','Angestellter',7782,'1982-01-23',1300,null,10);

Tabelle „salgrade“ erstellen (
 `Klasse` INT(11) NULL,
 `losal` INT(11) NULL,
 `hisal` INT(11) NULL
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
in Salgrade-Werte einfügen (1.700.1200);
in Salgrade-Werte einfügen (2,1201,1400);
in Salgrade-Werte einfügen (3,1401,2000);
in Salgrade-Werte einfügen (4,2001,3000);
in Salgrade-Werte einfügen (5,3001,9999);

Dies ist das Ende dieses Artikels mit der detaillierten Erklärung der Kommentare zu gespeicherten MySQL-Prozeduren. Weitere relevante Inhalte zu gespeicherten MySQL-Prozeduren finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Über die Fallstricke bei der Implementierung der angegebenen Kodierung in MySQL
  • Detaillierte Analyse der MySQL-Indexdatenstruktur
  • Wesentliche bedingte Abfrageanweisungen für MySQL-Datenbanken
  • Beispiel für die Konfiguration der Timeout-Einstellung für MySQL-Datenbanken
  • Detaillierte Erläuterung der Installations-, Konfigurations-, Start- und Herunterfahrmethoden des MySQL-Servers

<<:  Analyse und Lösung der Gründe, warum HTML-externe Referenz-CSS-Dateien nicht effektiv sind

>>:  So implementieren Sie mehrere Parameter in el-dropdown in ElementUI

Artikel empfehlen

CSS3 realisiert den Animationseffekt der Lotusblüte

Schauen wir uns zunächst die Wirkung an: Dieser E...

Vue3.0 Adaptiver Betrieb von Computern mit unterschiedlichen Auflösungen

Zuerst müssen wir einige Abhängigkeiten installie...

Vue implementiert nahtloses Scrollen von Listen

In diesem Artikelbeispiel wird der spezifische Co...

Grundlegende Referenztypen der erweiterten JavaScript-Programmierung

Inhaltsverzeichnis 1. Datum 2. RegExp 3. Original...

SQL Get gespeicherte Prozedur gibt Datenprozessanalyse zurück

Dieser Artikel stellt hauptsächlich die Analyse d...

Zusammenfassung der @-Verwendung in CSS (mit Beispielen und Erklärungen)

Eine At-Regel ist eine Deklaration, die Anweisung...

Eine Frage zum Verständnis mehrerer Parameter des Sortierbefehls in Linux

Der Sortierbefehl wird sehr häufig verwendet, ver...

Lösung für langsame Netzwerkanforderungen im Docker-Container

Bei der Verwendung von Docker wurden mehrere Prob...

Einführung in den CSS BEM-Benennungsstandard (empfohlen)

1 Was ist der BEM-Namensstandard Bem ist die Abkü...