De SAS à PostgreSQL (édité)

De SAS à PostgreSQL (édité) - SQL/NoSQL - Programmation

Marsh Posté le 17-03-2016 à 16:37:09    

Hello hello,

 

Je dois passer plusieurs fonctions SAS en SQL, et je ne suis pas à l'aise avec la création de fonctions SQL. Les fonctions en SAS ont cette tronche là par exemple :

 
Code :
  1. macro fonction1(table1, table2, table3, result);
  2.  
  3.   proc sql;
  4.      CREATE TABLE temp1 AS SELECT *
  5.      FROM &table1. A
  6.      JOIN &table2. B ON A.foo1 = B.foo1;
  7.   quit;
  8.  
  9.   DATA temp2;
  10.      SET temp1;
  11.      IF foo2 > foo3
  12.         then foo5 = foo4*foo4;
  13.   run;
  14.  
  15.   proc sql;
  16.      CREATE TABLE &result. AS
  17.      SELECT A.foo1, max(A.foo8), max(B.foo2), max(B.foo3), mean(B.foo5), max(C.foo7)
  18.      FROM temp1 A
  19.      JOIN temp2 B ON A.foo1 = B.foo1
  20.      JOIN &table3. C ON A.foo6 = C.foo6
  21.      GROUP BY foo1;
  22.   quit;
  23.  
  24.   /* Etcaetera, d'autres opérations */
  25. mend;
 

(J'ai mis des choses stupides dans mon exemple (genre au niveau de la récupération de foo8 à la dernière étape), j'en suis conscient, je veux juste illustrer qu'il y a des tables temporaires qui sont créées puis réutilisées plus loin dans la fonction, et que tout n'est pas agréable en une seule opération SQL quoi)

 

Ce qu'il se passe réellement au sein de la fonction est pas vraiment ma question, ma question est plutôt : j'ai plusieurs table qui sont manipulées, jointes en des tables temporaires, qui subissent des opérations, des groupages, etcaetera, pour en fin de fonction sortir plusieurs tables. Est-ce que c'est faisable en SQL d'avoir des tables temporaires créées et manipulées au sein d'une fonction ? Si oui, est-ce que vous auriez un template qui me permette de comprendre la syntaxe pour enchaîner les opérations comme c'est fait sous SAS svp ? Si non, quelles solutions ai-je pour faire ça ?

 

Et plus tard, il faudra que je fasse une fonction "capsule" qui appellera les unes après les autres mes autres fonctions, c'est faisable aussi ? Mêmes questions, du coup.

 

(J'espère que je suis clair)

 

Merci d'avance

 

NB : J'utilise pgAdmin III, que je découvre sur le tas :)

 

Edit 1 : question complétée (suite à une erreur d'envoi prématuré)


Message édité par saint malo le 17-03-2016 à 17:25:45
Reply

Marsh Posté le 17-03-2016 à 16:37:09   

Reply

Marsh Posté le 17-03-2016 à 22:52:28    

en postgresql tu peux tout à fait créer des tables temporaire. Elles peuvent etre effacée à la fin de la transaction ( et donc utilisée jusqu'à la fin de la transaction) avec ON COMMIT DROP


---------------

Reply

Marsh Posté le 18-03-2016 à 13:12:58    

Ok, merci. En lisant des dizaines de réponses sur SO, je crois que j'ai fini par comprendre la syntaxe pour faire des tables temporaires au sein d'une fonction

 

Par contre j'ai besoin d'un coup de main sur la syntaxe de départ, je galère. Mettons que je veuille que ma fonction prenne une partie d'une ligne d'une table A, et l'ajoute comme nouvelle ligne à une autre table B (déjà existante), à quoi ressemblerait la syntaxe ?

 

Pour l'instant, je suis arrivé à ça :

 
Code :
  1. CREATE FUNCTION test.fcttest(int)
  2. RETURNS SETOF test.table_b
  3. AS $$
  4.   SELECT A.id, A.field_2
  5.   FROM test.table_a A
  6.   WHERE id = $1;
  7. $$ LANGUAGE SQL;


(Evidemment, ma table B a pour schema (id int, field_2 text), et id et field_2 dans la table A sont aussi des int et text respectivement)

 

Et quand j'entre SELECT test(4) ça me retourne un résultat (sous forme bizarre, une seule colonne avec (4,montexte)) dans la fenêtre de requête, mais n'ajoute rien à la table B. J'ai bien essayé de mettre un INSERT INTO test.table_b avant le SELECT, mais ça me donne une erreur à la création de la fonction :

 
Code :
  1. ERROR:  return type mismatch in function declared to return test.fcttest
  2. DETAIL:  Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING.
  3. CONTEXT:  SQL function "fcttest"


Message édité par saint malo le 18-03-2016 à 13:19:00
Reply

Marsh Posté le 18-03-2016 à 16:36:33    

Bon (oui, je livetweet mes progrès), j'ai avancé dans ma compréhension du schmilblick, j'ai ça :

 
Code :
  1. CREATE FUNCTION test.fcttest(int)
  2. RETURNS SETOF test.table_b   /* (du coup j'avoue que ce que fait cette ligne m'échappe un peu, mais la comprendre n'est pas ma priorité) */
  3. AS $$
  4.    INSERT INTO test.table_b
  5.        SELECT A.id, A.field_2
  6.        FROM test.table_a A
  7.        WHERE id = $1;
  8.    SELECT A.id, A.field_2
  9.        FROM test.table_a A
  10.        WHERE id = $1;
  11. $$ LANGUAGE SQL;
 

puis

 
Code :
  1. SELECT bwe_modele.fcttest(1)
 

qui fonctionne et inscrit bien une nouvelle ligne dans ma table test.table_b. Maintenant, il faut que je comprenne comment faire pour avoir comme paramètre des tables, et m'assurer que je fais bien comme il faut pour tout ce qui est tables temporaires créées pendant que la fonction tourne. Pour ce qui est d'avoir une table en paramètre, pour l'instant, je pars sur du code qui ressemble à ça (mais qui ne fonctionne pas, si quelqu'un a ma solution, je suis preneur) :

 
Code :
  1. CREATE FUNCTION test.fcttest(TABLE, int)  
  2. RETURNS SETOF test.table_b
  3. AS $$
  4.    INSERT INTO test.table_b
  5.        SELECT A.id, A.field_2
  6.        FROM $1 A
  7.        WHERE id = $2;
  8.    SELECT A.id, A.field_2
  9.        FROM $1 A
  10.        WHERE id = $2;
  11. $$ LANGUAGE SQL;


Message édité par saint malo le 18-03-2016 à 16:39:54
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed