PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 05/02/2018 16:11:57

arthurr
Membre

CTE + PREPARE = Syntax error

Bonjour à tous,
J'ai une petite erreur de syntaxe avec une CTE + PREPARE + ON CONFLICT

Tables pour tester :

DROP TABLE IF EXISTS file;
DROP TABLE IF EXISTS action;
CREATE TABLE file (id_file SERIAL PRIMARY KEY,name TEXT);
CREATE UNIQUE INDEX unique_name ON file(name);
CREATE TABLE action(id_action SERIAL PRIMARY KEY, action_data JSON,id_file INTEGER);

Le SQL qui ne passe pas :

-- NOT OK
PREPARE insert_file_action_err  AS (
     WITH file_data AS (
         INSERT INTO file (name)
         VALUES ($1)
         ON CONFLICT("name") DO UPDATE SET id_file = file.id_file WHERE file.name = $1
         RETURNING id_file
     )
     INSERT INTO action (id_file, action_data)
     VALUES ((SELECT id_file FROM file_data), $2, $3) RETURNING id_action
 );
-- ERROR:  syntax error at or near "INSERT"
-- LINE 8:      INSERT INTO action (id_file, action_data)

Le SQL qui passe (le même mais sans les parenthèses après le AS du prépare) :

-- OK
PREPARE insert_file_action_ok  AS
     WITH file_data AS (
         INSERT INTO file (name)
         VALUES ($1)
         ON CONFLICT("name") DO UPDATE SET id_file = file.id_file WHERE file.name = $1
         RETURNING id_file
     )
     INSERT INTO action (id_file, action_data)
     VALUES ((SELECT id_file FROM file_data), $2) RETURNING id_action
;

Dans la doc, il n'y a pas de parenthèse après le AS du prépare :

PREPARE nom [ (type_données [, ...] ) ] AS instruction

Pourtant, les 2 cas simples suivants fonctionnent :

-- AVEC () :
PREPARE titi_ok AS (WITH toto AS (SELECT 1) SELECT * FROM toto);
-- SANS ()
PREPARE titi_ok2 AS WITH toto AS (SELECT 1) SELECT * FROM toto;

C'est moi qui rate un truc ? C'est juste normal ?

Merci d'avance

Hors ligne

#2 07/02/2018 12:01:35

comaco
Membre

Re : CTE + PREPARE = Syntax error

Les deux requêtes ne sont pas identiques :
après VALUES, dans la première, il y a 3 valeurs, alors que dans la deuxième, il y en a 2.

Cela explique probablement la différence de résultat.

Hors ligne

#3 07/02/2018 12:08:21

arthurr
Membre

Re : CTE + PREPARE = Syntax error

comaco a écrit :

Les deux requêtes ne sont pas identiques :
après VALUES, dans la première, il y a 3 valeurs, alors que dans la deuxième, il y en a 2.

Cela explique probablement la différence de résultat.

Merci pour ta réponse, mais c'est juste un mauvais copié / collé sad Donc j'ai toujours le problème smile

Hors ligne

#4 08/02/2018 08:40:06

rjuju
Administrateur

Re : CTE + PREPARE = Syntax error

Je ne suis pas certain de comprendre le problème.  Lorsque vous utilisez une syntaxe qui n'est pas indiquée comme supportée dans la documentation, la requête peut échouer?  Pourquoi ne pas utiliser tout simplement toujours la grammaire officielle ?


Sinon, de ce que je vois de la grammaire, les parenthèses sont ignorées autour d'une CTE quand la clause principale est en lecture seule uniquement.  À partir du moment ou il s'agit d'une clause INSERT ou UPDATE, la grammaire n'autorise plus l'ajout de parenthèses excédentaires.

Hors ligne

Pied de page des forums