sql >> Database teknologi >  >> RDS >> PostgreSQL

Hvordan gemmer man en data med varierende komma i karakter, der passerer gennem en trigger?

Du kan bruge format() for at gøre oprettelsen af ​​en dynamisk SQL-forespørgsel meget nemmere, da den automatisk vil håndtere identifikatorer og bogstaver korrekt. En ting, som folk normalt overser, er, at du kan udvide et enkelt postudtryk til alle dets kolonner ved hjælp af (...).* - dette virker også for NEW og OLD registrere variable i en trigger, f.eks. select (new).*

Du kan også sende variabler til en dynamisk SQL med using nøgleordet for execute udmelding. Det er ikke nødvendigt at konvertere posten frem og tilbage mellem en post og en tekstrepræsentation.

Ved at bruge denne mulighed kan din triggerfunktion forenkles til:

DECLARE 
  l_sql text;
BEGIN
    IF TG_TABLE_SCHEMA = 'public' THEN
      newtable := TG_TABLE_NAME || '_actividad';
    ELSE
      newtable := TG_TABLE_SCHEMA || '_' || TG_TABLE_NAME || '_actividad';
    END IF;

    PERFORM creartablaactividad(TG_TABLE_SCHEMA, TG_TABLE_NAME);
    l_sql := 'INSERT INTO actividad.%I  SELECT current_user, current_timestamp, %L, ($1).*';

    IF TG_OP = 'DELETE' THEN
      execute format(l_sql, newtable, 'D') using OLD;
      RETURN OLD;
    ELSE
      -- covers UPDATE and INSERT
      execute format(l_sql, newtable, 'U') using NEW;
      RETURN NEW;
    END IF;

    RETURN NULL; -- result is ignored since this is an AFTER trigger
END;

Brug af pladsholdere som %I og %L gør det også muligt kun at definere den faktiske SQL én gang og genbruge den. Disse "parametre" erstattes af format() funktion (som bevarer $1 )

Bemærk brugen af ​​($1).* inde i SQL-strengen. Det vil få execute sætning udvide postparameteren $1 til alle dens kolonner. Selve posten videregives "native" med USING søgeord.

Brugen af ​​INSERT uden en målkolonneliste (insert into some_table ... i stedet for insert into some_table (col1, col2, ...) ... ) er en ret skrøbelig ting at gøre. Hvis kilden og målet ikke stemmer overens, kan indsatsen fejle ganske let. .

Hvis du ikke kører massiv rapportering på revisionstabellerne (hvor det ville være meget mere effektivt at have eksplicitte kolonnenavne), vil du måske tænke på en mere generisk revisionstrigger ved hjælp af en JSON eller HSTORE kolonne for at gemme hele posten. Der er flere færdige revisionstriggere tilgængelige:




  1. Kan InnoDB bruge en stopordsfil?

  2. Valg af værdier fra Oracle Table Variable/Array?

  3. grupper efter dato, bekræft, afventer

  4. Har du problemer med MS Access Crashing? Prøv disse løsninger først