2010-04-07 3 views
2

Lorsque nous essayons de créer une vue dans une fonction, nous obtenons ERROR: il n'y a pas de paramètre $ 1. Ceci est l'exemple de code.

Begin 

CREATE VIEW artikelnr AS 
SELECT datum, 'uitgifte' as "type", CASE WHEN 'test'='test' THEN 0 END as "aantal ontvangen", aantal as "aantal uitgegeven" 
FROM uitgifteregel 
JOIN artikel ON artikel.artikelnr = new.artikelnr 
JOIN uitgifte ON uitgifte.uitgiftenr = uitgifteregel.uitgiftenr 

UNION 
SELECT datum, 'ontvangst' as "type", aantal as "aantal ontvangen" , CASE WHEN 'test'='test' THEN 0 END as "aantal uitgegeven" 
FROM ontvangstregel 
JOIN artikel ON artikel.artikelnr = new.artikelnr 
JOIN ontvangst ON ontvangst.ontvangstnr = ontvangstregel.ontvangstnr; 
Return new; 
end; 

Quand on remplace new.artikelnr en ligne 7 avec la valeur 1, il fonctionne comme il se doit, mais la fonction doit travailler avec différents Artikelnr de.

exemple la ligne 7: JOIN artikel ON artikel.artikelnr = new.artikelnr

S'il vous plaît nous indiquer la bonne direction.

Réponse: Nous devons créer cette vue à des fins éducatives. J'ai téléchargé une image de la vue et la tablestructure de notre base de données:

http://img208.imageshack.us/img208/5655/tablesk.jpg

Notre premier but était de créer une vue pour une artikel. Nous y sommes parvenus avec le code suivant:

CREATE VIEW artikelmutatiestotaal AS 
SELECT null as "datum",'totaal' as "type",sum(ontvangstregel.aantal)as "aantal ontvangen",sum(uitgifteregel.aantal) as "aantal uitgegeven" 
FROM uitgifteregel, ontvangstregel 
UNION 
SELECT datum,'uitgifte' as "type", CASE WHEN 'test'='test' THEN 0 END as "aantal ontvangen", aantal as "aantal uitgegeven" 
FROM uitgifteregel 
JOIN artikel ON artikel.artikelnr = 1 
JOIN uitgifte ON uitgifte.uitgiftenr = uitgifteregel.uitgiftenr 
UNION 
SELECT datum,'ontvangst' as "type", aantal as "aantal ontvangen" , CASE WHEN 'test'='test' THEN 0 END as "aantal uitgegeven" 
FROM ontvangstregel 
JOIN artikel ON artikel.artikelnr = 1 
JOIN ontvangst ON ontvangst.ontvangstnr = ontvangstregel.ontvangstnr 

La seule chose que nous ne pouvons pas atteindre est d'obtenir la valeur de Artikelnr de notre déclaration d'insertion.

CREATE FUNCTION addview() returns trigger as ' 
Begin 
CREATE VIEW artikelnr AS 
SELECT null as "datum",'totaal' as "type",sum(ontvangstregel.aantal)as "aantal ontvangen",sum(uitgifteregel.aantal) as "aantal uitgegeven" 
FROM uitgifteregel, ontvangstregel 
UNION 
SELECT datum,'uitgifte' as "type", CASE WHEN 'test'='test' THEN 0 END as "aantal ontvangen", aantal as "aantal uitgegeven" 
FROM uitgifteregel 
JOIN artikel ON artikel.artikelnr = new.artikelnr 
JOIN uitgifte ON uitgifte.uitgiftenr = uitgifteregel.uitgiftenr 
UNION 
SELECT datum,'ontvangst' as "type", aantal as "aantal ontvangen" , CASE WHEN 'test'='test' THEN 0 END as "aantal uitgegeven" 
FROM ontvangstregel 
JOIN artikel ON artikel.artikelnr = artikelnr 
JOIN ontvangst ON ontvangst.ontvangstnr = ontvangstregel.ontvangstnr 
end; 
'language plpgsql; 

Lorsque nous remplaçons JOIN artikel ON artikel.artikelnr = new.artikelnr en ligne 7 avec

JOIN artikel ON artikel.artikelnr = 1 

il fonctionne très bien. Désolé de poster ma question très déstructurée. Je ne sais pas très bien quelle information est importante pour répondre à cette question.

+0

Voir les nouvelles modifications à ma réponse – zendar

+0

Pourquoi voulez-vous créer plusieurs vues différentes portant le même nom? Ça ne va pas marcher. Et juste un artikelnr différent pour chaque vue? Quelle est ta cible? Quel est le problème sous-jacent que vous essayez de résoudre? –

Répondre

0

Quelle base de données est-ce?

Qu'est-ce que ce mot clé new? Ce code est-il copié à partir d'un déclencheur?

  • Remplacez new par le nom correct de la table dans la clause JOIN.
  • enlever Return new;

Si je me souviens bien, MsAccess signale une erreur similaire lorsque vous avez mal orthographié le nom du champ.
La prochaine chose serait de vérifier tous les noms de champs. Vous pouvez également utiliser un générateur de requêtes visuel et créer ces requêtes d'union pour vous assurer que tous les noms de champs sont corrects.

Je pense que vous pouvez perdre ces instructions CASE et écrivez juste 0 AS "Some Fieldname"

Essayez ceci. Ça devrait marcher. (Je ne l'ai pas testé contre la base de données)

CREATE OR REPLACE VIEW artikelnr AS 
    SELECT datum, 'uitgifte' as "type", 0 as "aantal ontvangen", 
     aantal as "aantal uitgegeven" 
    FROM uitgifteregel 
    JOIN artikel ON artikel.artikelnr = uitgifteregel.artikelnr 
    JOIN uitgifte ON uitgifte.uitgiftenr = uitgifteregel.uitgiftenr 

UNION 
    SELECT datum, 'ontvangst' as "type", aantal as "aantal ontvangen" , 
     0 as "aantal uitgegeven" 
    FROM ontvangstregel 
    JOIN artikel ON artikel.artikelnr = ontvangstregel.artikelnr 
    JOIN ontvangst ON ontvangst.ontvangstnr = ontvangstregel.ontvangstnr; 

Edit:
Je ne sais pas beaucoup sur Postgresql, mais vous avez probablement devrais regarder dans EXECUTE SCRIPT - envoyer artikelnr en tant que paramètre puis construis pour une vue en DDL scénario.D'après mon expérience avec d'autres bases de données (Oracle et SQL Server), je ne pense pas que vous devriez créer une vue pour chaque enregistrement. Qu'essayez-vous d'accomplir avec cette approche?

Si le but est d'avoir des vues précompilées et cette vitesse d'exécution du gain, la même chose peut probablement être réalisée avec une requête paramétrée. Mettez-le dans la procédure stockée et envoyez artikelnr en tant que paramètre.

Si ce n'est pas pour des raisons de performance, pouvez-vous expliquer pourquoi faites-vous comme ça.

Edit 2:
Re Réponse: Vous ne pouvez pas créer vue de cette façon. Le problème est que CREATE VIEW prend des déclarations sans remplacer les valeurs - il essaie de créer une vue avec new.artikelnr et ensuite il échoue parce que vous n'avez pas la table new en dehors du déclencheur. Vous devez construire l'instruction en tant que chaîne ou en tant que fichier, puis exécuter cette instruction. J'ai vérifié la documentation pour PostgreSQL et il y a la commande EXECUTE qui est utilisée pour construire et exécuter des commandes dynamiques. Quelque chose comme cela devrait probablement travailler:

EXECUTE 
    'CREATE OR REPLACE VIEW artikelnr AS ' 
    || ' SELECT datum, 'uitgifte' as "type", 0 as "aantal ontvangen",' 
    || ' aantal as "aantal uitgegeven" ' 
    || ' FROM uitgifteregel ' 
    || ' JOIN artikel ON artikel.artikelnr = ' 
    || new.artikelnr 
    || ' JOIN uitgifte ON uitgifte.uitgiftenr = uitgifteregel.uitgiftenr ' 
    || ' UNION ' 
    || ' SELECT datum, 'ontvangst' as "type", aantal as "aantal ontvangen" , ' 
    || '  0 as "aantal uitgegeven" ' 
    || ' FROM ontvangstregel ' 
    || ' JOIN artikel ON artikel.artikelnr = ' 
    || new.artikelnr 
    || ' JOIN ontvangst ON ontvangst.ontvangstnr = ontvangstregel.ontvangstnr; ' 

Ceci est un concat géant avec new.artikelnr valeur insérée sur place droite. Il "insère" la valeur littérale de artikelnr dans le code SQL, puis vous obtenez le code SQL qui est exécuté via l'instruction EXECUTE.

S'il vous plaît noter que le code ci-dessus ne prend pas soin de citer et il ne fonctionnera certainement pas comme est (puisque cet exemple est à des fins éducatives, il est laissé au lecteur de corriger comme exercice :).

Dans le documentation for EXECUTE statement vous trouverez des exemples qui utilisent des fonctions de citation qui devraient être utilisées pour construire correctement la commande ci-dessus.

+0

Merci pour la réponse rapide. La base de données que nous utilisons est postgresql. Ce morceau de code est d'une fonction qui sera exécutée par le déclencheur suivant. CRÉER TRIGGER addview APRÈS INSÉRER SUR ARTIKLE pour CHAQUE RANG PROCÉDURE D'EXÉCUTION addview(); Le déclencheur fonctionne lorsque nous insérons un nouvel article. Artikelnr signifie la même chose que productnr. artikelnr est la clé primaire de la table artikel. new.artikelnr références à artikelnr dans notre instruction d'insertion. J'espère que cela clarifie certaines choses. – user311064

+0

Salut. J'ai modifié le message, car le commentaire laisse trop peu d'espace pour ajouter l'information. J'espère que c'est utile. – user311064

+0

Merci de votre aide. Je vais chercher la documentation et utiliser la commande execute. – user311064

Questions connexes