2017-09-25 7 views
0

J'ai vu beaucoup de messages comme le mien, mais je n'ai pas réussi à trouver une réponse appropriée à ma situation, qui devrait être basique je présume. J'utilise l'extension PostGIS 2.3. Voici mon code:PostgreSQL 9.5: entrée de clause FROM manquante pour la table "new"

CREATE OR REPLACE FUNCTION public.split_cable() 
    RETURNS trigger AS 
$BODY$ 
DECLARE geometrie geometry; 
BEGIN  
geometrie = new.geom;  
create view temp_wire as (
    with brs as (select boite.geom from cablage_pays_gex.boite 
    where st_intersects(boite.geom, new.geom) and boite.geom not in (select st_startpoint(st_linemerge(new.geom))) and boite.geom not in (select st_endpoint(st_linemerge(new.geom))) 
    ) 
    select st_dump(st_split(new.geom, brs.geom)) from brs 
    ); 
RETURN new; 
END 
$BODY$ 
    LANGUAGE plpgsql VOLATILE; 

Comme vous pouvez le voir, j'ai une variable « geometrie » que je ne l'utilise, c'est parce que j'ai essayé de déclarer une variable contenant les données que je veux utiliser, sans succès. L'erreur que j'obtiens est celle qui titille ma question, et elle pointe vers la fonction st_intersects() (donc la première fois que j'essaie d'appeler le nouveau .geom). Qu'est-ce que je fais mal? Et comment puis-je résoudre cela?

EDIT: Voici la déclaration create table sur laquelle le déclencheur agit:

CREATE TABLE public.cable2 
(
    id_cable integer NOT NULL DEFAULT nextval('cable2_seq'::regclass), 
    geom geometry(MultiLineString,2154), 
    CONSTRAINT cable2_pkey PRIMARY KEY (id_cable) 
); 
+0

Montrez-nous l'instruction 'create table' pour la table de déclenchement. Mais créer une vue dans un déclencheur est un ** vraiment **, une très mauvaise idée - et il échouera après la deuxième instruction DML sur la table sous-jacente. Ce qui signifie que vous ne pouvez exécuter qu'une seule instruction DML une seule fois, puis plus jamais parce que vous obtiendrez une erreur pour chaque instruction suivante. –

+0

@a_horse_with_no_name Vous ne savez pas exactement ce que vous voulez dire. Je suis principalement en utilisant QGIS logiciel tiers pour interagir avec la base de données, donc je n'utilise aucune déclaration. Voulez-vous dire l'instruction 'create trigger'? –

+0

Ensuite, ce logiciel tiers cessera de fonctionner car votre déclencheur échouera après la première instruction DML contre cette table. Pour savoir ce qui ne va pas avec votre trigger, nous devons voir l'instruction 'create table' pour la table sur laquelle vous définissez le trigger. –

Répondre

1

TL; DR: dynamique SQL est nécessaire pour la déclaration CREATE VIEW.

Dans plpgsql, les variables ne sont pas interpolées dans les requêtes de définition de données, comme les requêtes CREATE....

Plus généralement, le plpgsql documentation dit comme:

Les paramètres ne seront remplacés dans des endroits où un paramètre ou une référence colonne est syntaxiquement permis

Et dans les requêtes DDL, le lieu où ils sont autorisés est: nulle part.

C'est pourquoi la référence new.geom dans votre requête est prise littéralement, et pourquoi le transférer dans une variable temporaire geometrie ne la ferait pas mieux fonctionner.

Le SQL dynamique consiste essentiellement à créer une chaîne de commande, puis à exécuter cette chaîne comme une instruction avec EXECUTE. Cette chaîne, une fois générée, ne doit plus contenir de référence aux variables. Plus d'informations dans le doc: Executing Dynamic Commands

Indépendamment de cela, comme indiqué dans les commentaires, créer une vue permanente chaque fois qu'une ligne est affectée dans un tableau semble complètement faux, au niveau conceptuel. Il est difficile de comprendre pourquoi vous voulez le faire en premier lieu.

+0

Je comprends pour la mauvaise idée de la création de vue.Mon idée est que j'évite plusieurs CTE en créant d'abord une vue que j'appellerai pour chaque INSERT sur lequel agira mon déclencheur, puis en le déposant à la fin de la transaction. Mais en effet, il peut causer des problèmes en cas d'utilisation simultanée dans d'autres situations. Alors maintenant je me demande, est-ce une meilleure idée de créer un CTE à deux niveaux (un CTE dans un CTE)? –

+1

@GuiOmClair: la réponse ci-dessus explique pourquoi il y a une erreur de syntaxe dans le déclencheur. Que ce soit une bonne idée d'utiliser des CTE imbriqués ressemble à une question totalement différente, que vous pouvez demander dans un autre slot Q/A, mais avec un texte tout à fait différent de celui du code de déclenchement ci-dessus. –