Mysql
 sql >> Datenbank >  >> RDS >> Mysql

SQL-Skripte - Existiert das Äquivalent von #define?

Der C Pre Processor (cpp) ist historisch mit C verbunden (daher der Name), aber es ist wirklich ein generischer Textprozessor, der für etwas anderes verwendet (oder missbraucht) werden kann.

Betrachten Sie diese Datei mit dem Namen location.src (dazu später mehr).

// 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 ;

und die Datei debug.src, die enthalten ist:

#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

Beim Kompilieren mit:

cpp -E location.src -o location.sql

Sie erhalten den gesuchten Code, wobei cpp die #define-Werte erweitert.

Beim Kompilieren mit:

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

Sie erhalten dasselbe plus das ASSERT-Makro (als Bonus gepostet, um zu zeigen, was könnte erledigt werden).

Unter der Annahme eines Builds mit HAVE_DEBUG, das in einer Testumgebung bereitgestellt wird (in 5.5 oder höher, da SIGNAL verwendet wird), sieht das Ergebnis so aus:

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 ?

Beachten Sie, dass der Dateiname, die Zeilennummer und die Bedingung genau auf die Stelle im Quellcode in location.src zeigen, wo die Behauptung ausgelöst wird, wieder dank des C-Präprozessors.

Nun zur Dateierweiterung „.src“:

  • Sie können alles verwenden.
  • Eine andere Dateierweiterung hilft bei Makefiles usw. und verhindert Verwirrung.

BEARBEITEN:Ursprünglich als .xql gepostet, zur Verdeutlichung in .src umbenannt. Hier nichts mit XML-Abfragen zu tun.

Wie bei allen Tools kann die Verwendung von cpp zu guten Dingen führen, und der Anwendungsfall für die Verwaltung von LOCATION_LEN auf portable Weise sieht sehr vernünftig aus. Es kann auch zu schlechten Dingen führen, mit zu vielen #include, verschachtelten #ifdef-Höllen, Makros usw die am Ende den Code verschleiern, sodass Ihre Laufleistung variieren kann.

Mit dieser Antwort bekommt man das Ganze (#define , #include , #ifdef , __FILE__ , __LINE__ , #C , Befehlszeilenoptionen zum Erstellen), also hoffe ich, dass es alles abdecken sollte.