sql >> Database >  >> RDS >> Mysql

SQL-scripts - Bestaat het equivalent van een #define?

De C Pre Processor (cpp) wordt historisch gezien geassocieerd met C (vandaar de naam), maar het is echt een generieke tekstverwerker die voor iets anders kan worden gebruikt (of misbruikt).

Beschouw dit bestand, genaamd location.src (daarover later meer).

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

en bestand debug.src, dat is inbegrepen:

#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

Indien gecompileerd met:

cpp -E location.src -o location.sql

je krijgt de code die je zoekt, met cpp die #define-waarden uitbreidt.

Indien gecompileerd met:

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

je krijgt hetzelfde, plus de ASSERT-macro (gepost als een bonus, om te laten zien wat zou klaar zijn).

Uitgaande van een build met HAVE_DEBUG geïmplementeerd in een testomgeving (in 5.5 of later aangezien SIGNAL wordt gebruikt), ziet het resultaat er als volgt uit:

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 ?

Merk op hoe de bestandsnaam, het regelnummer en de voorwaarde precies verwijzen naar de plaats in de broncode in location.src waar de bewering wordt opgeworpen, nogmaals dankzij de C-preprocessor.

Nu, over de ".src" bestandsextensie:

  • je kunt alles gebruiken.
  • Het hebben van een andere bestandsextensie helpt bij makefiles, enz., en voorkomt verwarring.

EDIT:Oorspronkelijk gepost als .xql, voor de duidelijkheid hernoemd naar .src. Niets gerelateerd aan xml-query's hier.

Zoals met alle tools, kan het gebruik van cpp tot goede dingen leiden, en de use case om LOCATION_LEN op een draagbare manier te onderhouden ziet er heel redelijk uit. Het kan ook tot slechte dingen leiden, met te veel #include, geneste #ifdef hell, macro's, enz. die aan het einde de code verdoezelen, zodat uw kilometerstand kan variëren.

Met dit antwoord krijg je het hele ding (#define , #include , #ifdef , __FILE__ , __LINE__ , #C , opdrachtregelopties om te bouwen), dus ik hoop dat het alles dekt.



  1. converteer het Postgres-geometrieformaat naar WKT

  2. Voeg een procentteken toe aan een getal in MariaDB

  3. Verhoog de prestaties met Bulk Collect in Oracle

  4. Een SQLite-database herstellen