Ist es möglich, einen Standardparameter für eine gespeicherte MySQL-Prozedur zu haben?

73

Ich habe dies gegoogelt und immer wieder "Nein, es ist nicht möglich" gefunden, aber diese Beiträge wurden von 2005-2007 datiert, daher frage ich mich, ob dies geändert wurde. Ein Codebeispiel:

CREATE PROCEDURE `blah`
(
  myDefaultParam int = 0 -- This breaks the code for some reason
)
BEGIN
  -- Do something here
END

Eine der Lösungen bestand darin, null zu übergeben, dann nach null zu suchen und die Variable zu setzen. Ich will das nicht und sollte es auch nicht müssen. Wenn dies zutrifft, müssen MySQL-Entwickler aufwachen, da ich mit MSSQL so viel mehr tun kann.

aarona
quelle
1
Duplikat: stackoverflow.com/questions/12652241/…
Patrick Allaert
hat mariaDB das gleiche problem?
Webber Depor

Antworten:

79

Es ist immer noch nicht möglich.

Paul Sonier
quelle
8
Gibt es eine Problemumgehung? Möchten Sie überprüfen, ob der Parameter null ist, und ihm dann einen Standardwert geben?
Papaiatis
1
@papaiatis Ja, Sie können einfach eine if-Anweisung hinzufügen, siehe meinen anderen Beitrag unten.
Dive50
3
Ich weiß nicht, warum dies die akzeptierte Antwort ist, wenn hier unten @ Dive50 eine nützliche Problemumgehung hat, die ich implementieren werde, weil ich vor dem gleichen Problem stehe.
Bokov
4
Deshalb hasse ich MySQL. So eine grundlegende Sache gibt es immer noch nicht
Kamran Shahid
1
Es ist nicht möglich, die vorgeschlagene Syntax zu verwenden, aber das Übergeben von NULL und das anschließende Verwenden von IFNULL ist durchaus möglich und erreicht genau das Gleiche.
Hans
48

Wir haben diese Einschränkung umgangen, indem wir der gespeicherten Prozedur eine einfache IF-Anweisung hinzugefügt haben. Praktisch übergeben wir eine leere Zeichenfolge, wenn wir den Standardwert in der Datenbank speichern möchten.

CREATE DEFINER=`test`@`%` PROCEDURE `myProc`(IN myVarParam VARCHAR(40))
BEGIN
  IF myVarParam = '' THEN SET myVarParam = 'default-value'; END IF;

  ...your code here...
END
Dive50
quelle
7
Warum nicht nullstattdessen verwenden?
Pacerier
2
Dies zeigt, wie viel Liebe Sie MySQL geben können, während Sie in SQL einfach "param_name int (11) = NULL" setzen können ... danke Oracle
Sebastien H.
28
SET myParam = IFNULL(myParam, 0);

Erläuterung: IFNULL(expression_1, expression_2)

Die IFNULLFunktion gibt zurück, expression_1wenn dies expression_1nicht der Fall ist NULL. Andernfalls wird es zurückgegeben expression_2. Die IFNULLFunktion gibt eine Zeichenfolge oder eine Zahl basierend auf dem Kontext zurück, in dem sie verwendet wird.

SKManX
quelle
1
Dies ist eine effizientere Methode.
Ichimaru
12

Wenn Sie sich die CREATE PROCEDURE-Syntax für die neueste MySQL-Version ansehen, werden Sie feststellen, dass der Prozedurparameter nur den IN / OUT / INOUT-Bezeichner, den Parameternamen und den Typ enthalten kann.

Daher sind Standardwerte in der neuesten MySQL-Version immer noch nicht verfügbar.

Michael
quelle
4

Leider unterstützt MySQL keine DEFAULTParameterwerte.

CREATE PROCEDURE `blah`
(
  myDefaultParam int DEFAULT 0
)
BEGIN
  -- Do something here
END

gibt den Fehler zurück:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual
that corresponds to your MySQL server version for the right syntax to use 
near 'DEFAULT 0) BEGIN END' at line 3

Um diese Einschränkung zu umgehen, erstellen Sie einfach zusätzliche Prozeduren, die der ursprünglichen Prozedur Standardwerte zuweisen:

DELIMITER //

DROP PROCEDURE IF EXISTS blah//
DROP PROCEDURE IF EXISTS blah2//
DROP PROCEDURE IF EXISTS blah1//
DROP PROCEDURE IF EXISTS blah0//

CREATE PROCEDURE blah(param1 INT UNSIGNED, param2 INT UNSIGNED)
BEGIN
    SELECT param1, param2;
END;
//

CREATE PROCEDURE blah2(param1 INT UNSIGNED, param2 INT UNSIGNED)
BEGIN
    CALL blah(param1, param2);
END;
//

CREATE PROCEDURE blah1(param1 INT UNSIGNED)
BEGIN
    CALL blah2(param1, 3);
END;
//

CREATE PROCEDURE blah0()
BEGIN
    CALL blah1(4);
END;
//

Führen Sie dann Folgendes aus:

CALL blah(1, 1);
CALL blah2(2, 2);
CALL blah1(3);
CALL blah0();

wird zurückkehren:

+--------+--------+
| param1 | param2 |
+--------+--------+
|      1 |      1 |
+--------+--------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

+--------+--------+
| param1 | param2 |
+--------+--------+
|      2 |      2 |
+--------+--------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

+--------+--------+
| param1 | param2 |
+--------+--------+
|      3 |      3 |
+--------+--------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

+--------+--------+
| param1 | param2 |
+--------+--------+
|      4 |      3 |
+--------+--------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Dann, wenn Sie sicher , dass nur machen verwenden , um die blah2(), blah1()und blah0()Verfahren, wird Ihr Code nicht braucht sofort aktualisiert werden, wenn Sie einen dritten Parameter zum hinzufügen blah()Verfahren.

Ross Smith II
quelle
1

Nein, dies wird in der MySQL-Syntax für gespeicherte Routinen nicht unterstützt.

Sie können eine Funktionsanfrage unter bugs.mysql.com einreichen .

Bill Karwin
quelle
2
Posting dies von der anderen Frage, die ich gestellt habe: bugs.mysql.com/bug.php?id=15975
aarona