2010-09-30 3 views
1

J'essaye de créer une fonction pour peupler 2 tables, la deuxième requête contenant le nouvel identifiant de la première insertion.postgres (8.3), en utilisant le résultat de la requête dans la fonction

un exemple de certains de mes tableaux:

CREATE TABLE message 
(
    message_id bigserial NOT NULL, 
    member_id bigint NOT NULL, 
    message character varying(8192) NOT NULL, 
    ... 
) 

CREATE TABLE feed_message 
(
    feed_id bigint NOT NULL, 
    message_id bigint NOT NULL 
) 

ce que je suis en train de faire est d'insérer un nouveau message dans la table des messages et utiliser le message_id généré pour remplir la table de feed_message

i essayé d'écrire une fonction en utilisant le langage de pltcl mais je ne peux pas comprendre comment utiliser le SPI_getvalue pour obtenir le juste créé tupil

ce que j'ai jusqu'à présent:

/* message_post(entity, id, member_id, title, message, reactionTo) */ 
CREATE OR REPLACE FUNCTION message_post() 
RETURNS VOID 
LANGUAGE pltcl 
AS $BODY$ 
ret_status = spi_exec -count 1 "INSERT INTO message (member_id, title, message) VALUES ($3, $4, $5)" 
IF (ret_status == SPI_OK_SELECT && SPI_processed > 0) { 
    //get the tupil from *SPI_tuptable 
    set message_id <the new message_id> 
} 
spi_exec -count 1 "INSERT INTO $1_message ($1_id, message_id) VALUES ($2,$message_id)" 
$BODY$; 

/* useage */ 
SELECT message_post('feed',12,1,'title','message'); 

Répondre

1

Vous avez quelques endroits où votre Tcl usage (PL/Tcl peut être considéré comme un dialecte, avec emballage) est tout simplement faux. Je suppose que c'est correct, basé sur le examples in the PL/Tcl documentation.

CREATE OR REPLACE FUNCTION message_post(text,integer,integer,text,text) 
RETURNS VOID AS $$ 
    set ret_status [spi_exec -count 1 \ 
     "INSERT INTO message (member_id, title, message) \ 
       VALUES ($3, '[quote $4]', '[quote $5]')"] 
    if {$ret_status > 0} { 
     set message_id [spi_lastoid] 
     spi_exec -count 1 "INSERT INTO ${1}_message (${1}_id, message_id) \ 
         VALUES ($2, $message_id)" 
    } 
$$ LANGUAGE pltcl; 

Cependant, je ne considère pas cela comme idiomatique! Après tout, il fait quote et d'autres choses comme ça. Si je comprends bien, ce qui est mieux:

CREATE OR REPLACE FUNCTION message_post(text,integer,integer,text,text) 
RETURNS VOID AS $$ 
    # Precompile the INSERTs if they didn't already exist 
    if {![info exists GD(post_message_plan)]} { 
     set GD(post_message_plan) [spi_prepare \ 
      {INSERT INTO message (member_id, title, message) VALUES ($1, $2, $3)} \ 
      {integer text text}] 
    } 
    if {![info exists GD(assoc_message_plan:$1)]} { 
     set GD(assoc_message_plan:$1) [spi_prepare \ 
      "INSERT INTO ${1}_message (${1}_id, message_id) VALUES (\$1, \$2)" \ 
      {integer integer}] 
    } 
    # Run the pair of INSERTs 
    if {[spi_execp -count 1 $GD(post_message_plan) [list $3 $4 $5]] > 0} { 
     spi_execp -count 1 $GD(assoc_message_plan:$1) [list $2 [spi_lastoid]] 
    } 
$$ LANGUAGE pltcl; 

Autres choses à noter: Je crois qu'il est spi_lastoid que vous êtes à la recherche pour trouver l'identifiant de message, et je ne l'ai pas fait vérifier si votre SQL est correcte . En outre, je peux avoir tort les types d'arguments à diverses choses. (PostgreSQL et Tcl ont des idées différentes sur les types.)

+0

il semble que cela devrait fonctionner, mais le [spi_lastoid] est vide, et un 0 est inséré à la place du nouveau message_id –

+0

@Paul: Eh bien, vous Je vais devoir faire autre chose pour obtenir le dernier identifiant de ligne inséré; Je n'ai pas de déploiement de postgres à portée de main, donc je ne peux pas vraiment le conseiller. Je viens de lire les docs. :-) –

+0

et après avoir recréé les tables avec (ODIS) tout fonctionne –

Questions connexes