Homepage  Il progetto dsy.it è l'unofficial support site dei corsi di laurea del Dipartimento di Scienze dell'Informazione e del Dipartimento di Informatica e Comunicazione della Statale di Milano. E' un servizio degli studenti per gli studenti, curato in modo no-profit da un gruppo di essi. I nostri servizi comprendono aree di discussione per ogni Corso di Laurea, un'area download per lo scambio file, una raccolta di link e un motore di ricerca, il supporto agli studenti lavoratori, il forum hosting per Professori e studenti, i blog, e molto altro...
In questa sezione è indicizzato in textonly il contenuto del nostro forum


.dsy:it. .dsy:it. Archive > Didattica > Corsi A - F > Basi di dati ~ informatica triennale
 
[plpgsql] usare nomi dinamici per le tabelle
Clicca QUI per vedere il messaggio nel forum
elessard
sto cercando di finire il progetto di quest'anno degli annunci immobiliari e ho riscontrato problemi nell'utilizzare all'interno di funzioni in plpgsql, nomi dinamici assegnati a tabelle, nel caso specifico quando tento di fare una select di una tabella ( il cui nome è inserito come argomento della funzione) per poi scorrerla con un FOR.
questo è il mio codice:

CREATE OR REPLACE FUNCTION create_view_criterio_2 (id integer, citta varchar, metratura integer) RETURNS SETOF sel_annunci AS $$
DECLARE
nome_t varchar;
range_a integer = metratura - 20;
range_b integer = metratura + 20;
annunci sel_annunci;
BEGIN
nome_t = 'view_id_' || id;
EXECUTE 'CREATE TABLE '|| nome_t || '(id_annuncio varchar PRIMARY KEY, titolo varchar, tipo contratto_domain, costo integer, mensile integer, id_unita integer, metratura integer, num_locali integer, categoria cat_domain, citta varchar)';
EXECUTE 'INSERT INTO ' || nome_t || '(SELECT A.id_annuncio, A.titolo, A.tipo, A.costo, A.mensile, U.id_unita, U.metratura, U.num_locali, U.categoria, UB.citta FROM annuncio A, unita_immobiliare U, ubicazione UB WHERE (A.unita_immobiliare = U.id_unita) AND (U.id_unita = UB.id_unita) AND (UB.citta = citta) AND (A.id_annuncio <> '|| id||') AND (U.metratura BETWEEN ' || range_a ||' AND ' || range_b ||'))';
FOR annunci IN SELECT * FROM view_id_5 LOOP
return next annunci;
END LOOP;
return;
EXCEPTION WHEN duplicate_table THEN
RETURN;
END;
$$ LANGUAGE plpgsql;


brevemente, ogni volta che io seleziono un annuncio, questa funzione (che prende come argomento l'annuncio, più altri parametri) crea una vista materializzata che ha come nome 'view_id_' più l'id dell'annuncio.
il mio problema è che non riesco a far girare nel FOR il risultato della select della vista materializzata che ho creato con un nome dinamico, infatti nella riga 'FOR annunci IN SELECT * FROM view_id_5 LOOP' ho messo 'view_id_5' giusto per testare la funzione ma tecnicamente dovrebbe essserci 'view_id_' con il numero che cambia in base all'annuncio.
come posso risolvere? ringrazio in anticipo

aPiso
pizzy sei un nabbo!!

xSharKMaNx
Prima del FOR hai già verificato che l'INSERT INTO garantisce dei record ?

Poi il FOR dovrebbe essere ..... FROM '|| nome_t ||'
visto che hai utilizzato quella variabile.

CowBoy
code:
CREATE OR REPLACE FUNCTION create_view_criterio_2 (id integer, citta varchar, metratura integer) RETURNS SETOF sel_annunci AS $$ DECLARE nome_t varchar; range_a integer = metratura - 20; range_b integer = metratura + 20; annunci sel_annunci; BEGIN nome_t = 'view_id_' || id; EXECUTE 'CREATE TABLE '|| nome_t || '(id_annuncio varchar PRIMARY KEY, titolo varchar, tipo contratto_domain, costo integer, mensile integer, id_unita integer, metratura integer, num_locali integer, categoria cat_domain, citta varchar)'; EXECUTE 'INSERT INTO ' || nome_t || '(SELECT A.id_annuncio, A.titolo, A.tipo, A.costo, A.mensile, U.id_unita, U.metratura, U.num_locali, U.categoria, UB.citta FROM annuncio A, unita_immobiliare U, ubicazione UB WHERE (A.unita_immobiliare = U.id_unita) AND (U.id_unita = UB.id_unita) AND (UB.citta = citta) AND (A.id_annuncio <> '|| id||') AND (U.metratura BETWEEN ' || range_a ||' AND ' || range_b ||'))'; FOR annunci IN SELECT * FROM view_id_5 LOOP return next annunci; END LOOP; return; EXCEPTION WHEN duplicate_table THEN RETURN; END; $$ LANGUAGE plpgsql;


Prova come diceva xSharKMaNx prima oppure prova sostituendo
code:
annunci sel_annunci; con annunci RECORD;

gionavisi
Come si può fare a creare i cluster per la vicinanza geografica?che funzione da inserire in trigger e funzioni si può usare?

come avete questo problema?

elessard
io ho preso le coordinate e le ho usate come se fossero le ordinate e ascisse in un sistema di assi cartesiano x e y; poi ho banalmente usato l'annuncio per il quale volevo creare un cluster, come centro di un quadrato.
tutto ciò che era all'interno di questo quadrato è considerato geograficamente adiacente a quell'unità immobiliare.
secondo me bisogna inserire altri parametri per rendere più preciso il concetto di similarità... ma non ho ancora deciso.
questo l'ho realizzato tutto come funzione, invece il trigger l'ho fato per aggiorare la tabella materializzata usando sempre questo criterio.

CowBoy
In teoria per la soluzione ottima di questo problema è suggerito l'implementazione dei grafi, ma non conosco le richieste del progetto per poterti dire di più.

elessard
Mmm... ma perchè complicarsi la vita con i grafi? Lo scopo non è far vedere che sai utilizzare le viste materializzate?

gionavisi
@elessard

come hai fatto a vedere se una città è all'interno del tuo quadrato? hai fatto una differenza di un valore da te deciso e le coordinate del punto preso in considerazione immagino

elessard
Si praticamente ho fatto così, gli ho dato un range di 0,03 e poi ho visto se il punto era interno a queso segmento immaginario sia per l'asse delle x che per le y; certo sarebbe stata una cosa più fine controllare se si trovava all'interno di un cerchio ma... troppa sbatta xD

gionavisi
ti ringrazio per la risposta, volevo chiedervi sapete dichiarare un tipo record? perchè io ho trovato e provato a fare cosi :

TYPE mio_studente IS RECORD

(nome VARCHAR(30),

cognome VARCHAR(30),

data_nascita DATE);

studente mio_studente;

ma non me lo permette. io vorrei un campo record cn dentro citta long e lat.

elessard
non ci ho mai provato, però mi è stato detto che se passi da postgres a php un record poi da porblemi quando devi fare il parsing del risultato.
io ho fattto tutto con create type:
code:
CREATE TYPE tipo_prova AS (attributo_1 INTEGER, attributo_2 varchar .....);

gionavisi
come si possono usare old e new con le tabelle a nomi dinamici?

Powered by: vbHome (lite) v4.1 and vBulletin v2.3.1 - Copyright ©2000 - 2002, Jelsoft Enterprises Limited
Mantained by dsy crew (email) | Collabora con noi | Segnalaci un bug | Archive | Regolamento |Licenze | Thanks | Syndacate