Mysql
 sql >> Base de données >  >> RDS >> Mysql

Scripts SQL - L'équivalent d'un #define existe-t-il ?

Le préprocesseur C (cpp) est historiquement associé au C (d'où son nom), mais c'est vraiment un traitement de texte générique qui peut être utilisé (ou abusé) pour autre chose.

Considérez ce fichier, nommé location.src (plus à ce sujet plus tard).

// C++ style comments works here
/* C style works also */
-- plain old SQL comments also work,
-- but you should avoid using '#' style of comments,
-- this will confuse the C pre-processor ...

#define LOCATION_LEN 25

/* Debug helper macro */
#include "debug.src"

DROP TABLE IF EXISTS test.locations;
CREATE TABLE test.locations
(
   `location` VARCHAR(LOCATION_LEN) NOT NULL
);

DROP PROCEDURE IF EXISTS test.AddLocation;
delimiter $$
CREATE PROCEDURE test.AddLocation (IN location VARCHAR(LOCATION_LEN))
BEGIN
  -- example of macro
  ASSERT(length(location) > 0, "lost or something ?");

  -- do something
  select "Hi there.";
END
$$

delimiter ;

et le fichier debug.src, qui est inclus :

#ifdef HAVE_DEBUG
#define ASSERT(C, T)                                          \
  begin                                                       \
    if (not (C)) then                                         \
      begin                                                   \
        declare my_msg varchar(1000);                         \
        set my_msg = concat("Assert failed, file:", __FILE__, \
                            ", line: ", __LINE__,             \
                            ", condition ", #C,               \
                            ", text: ", T);                   \
        signal sqlstate "HY000" set message_text = my_msg;    \
     end;                                                     \
    end if;                                                   \
  end
#else
#define ASSERT(C, T) begin end
#endif

Lorsqu'il est compilé avec :

cpp -E location.src -o location.sql

vous obtenez le code que vous recherchez, avec cpp développant les valeurs #define.

Lorsqu'il est compilé avec :

cpp -E -DHAVE_DEBUG location.src -o location.sql

vous obtenez la même chose, plus la macro ASSERT (postée en bonus, pour montrer ce qui pourrait être fait).

En supposant une construction avec HAVE_DEBUG déployé dans un environnement de test (en 5.5 ou version ultérieure puisque SIGNAL est utilisé), le résultat ressemble à ceci :

mysql> call AddLocation("Here");
+-----------+
| Hi there. |
+-----------+
| Hi there. |
+-----------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> call AddLocation("");
ERROR 1644 (HY000): Assert failed, file:location.src, line: 24, condition length(location) > 0, text: lost or something ?

Notez comment le nom de fichier, le numéro de ligne et la condition pointent directement à l'endroit du code source dans location.src où l'assertion est déclenchée, encore une fois grâce au préprocesseur C.

Maintenant, à propos de l'extension de fichier ".src" :

  • vous pouvez utiliser n'importe quoi.
  • Avoir une extension de fichier différente facilite les makefiles, etc., et évite toute confusion.

EDIT :Initialement publié en tant que .xql, renommé en .src pour plus de clarté. Rien à voir avec les requêtes xml ici.

Comme avec tous les outils, l'utilisation de cpp peut conduire à de bonnes choses, et le cas d'utilisation pour maintenir LOCATION_LEN de manière portable semble très raisonnable. Cela peut également conduire à de mauvaises choses, avec trop de #include, un enfer #ifdef imbriqué, des macros, etc. qui à la fin obscurcissent le code, de sorte que votre kilométrage peut varier.

Avec cette réponse, vous obtenez le tout (#define , #include , #ifdef , __FILE__ , __LINE__ , #C , options de ligne de commande à construire), donc j'espère qu'il devrait tout couvrir.