Nightmare
10-10-2006, 10:27
Ho un dubbio abbastanza semplice e che non pregiudica l'esito dei risultati ottenuti ma vorrei sapere secondo voi quale è il modo migliore per affrontare il problema.
Ho 2 tabelle con campi non completamente uguali, ma questo non mi interessa, i campi che mi servono sono identici.
Devo leggere tutte e 2 le tabelle nello stesso modo.
Secondo voi è meglio creare 2 cursori dinamici, dichiarandoli 2 volte, aprendoli 2 volte e fetchando prima uno e poi l'altro e poi richiuderli ambedue o creare un unico cursore che sia la join tra le 2?
trallallero
10-10-2006, 13:01
ti interessano piú le prestazioni o la leggibilitá ?
comunque mi sembra piú una "union"che una join ;)
Non so se ho capito bene il tuo problema, ma da quello che ho capito credo ti convenga fare una cosa così (pseudo pl/sql):
begin
for record in ( select t1.x, t1.y, t1.z
from tabella1 t1
union
select t2.x, t2.y, t2.z
from tabella2 t2 )
loop
...fai quello che vuoi con il record....
end loop;
end;
Nightmare
10-10-2006, 13:22
si scusami ho sbagliato a scrivere, è una union, nel titolo c'è scritto union cmq
mi interessano le prestazioni.
la select finale è molto massiccia e ricca di condizioni a seconda di cosa l'utente vuole visualizzare (query dinamica) e non so assolutamente quanto una union possa incidere rispetto alla gestione di 2 cursori anziche uno solo piu grande
trallallero
10-10-2006, 13:29
si scusami ho sbagliato a scrivere, è una union, nel titolo c'è scritto union cmq
mi interessano le prestazioni.
la select finale è molto massiccia e ricca di condizioni a seconda di cosa l'utente vuole visualizzare (query dinamica) e non so assolutamente quanto una union possa incidere rispetto alla gestione di 2 cursori anziche uno solo piu grande
é vero c'é nel titolo :doh:
allora va bene quello che ha scritto shinya se usi pl/sql
io dichiaro il cursore poi faccio
for rec in cursore ...
ma immagino sia giusto come l'ha scritto shinya ... anzi, carino, rapido :D
Nightmare
10-10-2006, 13:38
Devo farlo in cobol tramite una "prepare nome_cursore from stringa_sql" di sql embedded ma non è un problema questo, mi interessa la logica cioè, tu is meil che uan? o uan is meil che tu?
io credo che una union che faccia tutto, sia migliore sia prestazionalmente che in leggibilità
e a quanto pare lo ritenete anche voi :)
volevo sapere voi cosa ne penzavate
tnx :)
trallallero
10-10-2006, 13:50
Devo farlo in cobol tramite una "prepare nome_cursore from stringa_sql" di sql embedded ma non è un problema questo, mi interessa la logica cioè, tu is meil che uan? o uan is meil che tu?
io credo che una union che faccia tutto, sia migliore sia prestazionalmente che in leggibilità
e a quanto pare lo ritenete anche voi :)
volevo sapere voi cosa ne penzavate
tnx :)
non conosco il cobol, ma veramente per niente, peró ti parlo dell'ambiente oracle/unix:
fare 2 query (diciamo semplici) una dopo l'altra, é indubbiamente piú lento che unirle con una union.
Posso prevedere che ci metta il doppio del tempo, perché aprire 2 istanze o 1 ad oracle non cambia molto quindi puó scandire 2 tabelle contemporaneamente senza cali di resa.
Io alla Vodafone (tramite l'HP) ho risolto un problema che avevano quando fetchavano la tabella clienti e puntualmente dava l'errore "rollback segment too short ...".
Il prog dell'HP memorizzava il rowid del record e continuava da li dopo l'errore :Puke:
Io l'ho cambiato prendendo il MinId e il MaxId (ottenendo il numero di records), dividendo il tutto in piú pacchetti che venivano fetchati contemporaneamente. E i tempi erano quasi gli stessi col vantaggio dell'assenza di errori ;)
Poi se cominci ad avere queries con join a destra e a manca allora il discorso cambia ...
Nightmare
10-10-2006, 14:44
posso farti l'esempio di questa select con la union
SELECT DISTINCT(SG02_MATR),
NVL(SGUNION_COGNOME,' '),
NVL(SGUNION_NOME,' '),
NVL(SGUNION_PROFILO,' '),
NVL(SGX08_DESCRIZIONE,' '),
NVL(SGX03_DESCRIZIONE,' '),
SG03_ENTE_CORSO,
NVL(SGX02_DESCRIZIONE,' '),
NVL(SGX02_CODICE,'0'),
NVL(SG03_TIPO,'0'),
TO_CHAR(SG02_DATA_INIZIO,'DD/MM/YYYY'),
TO_CHAR(SG03_DATA_FINE,'DD/MM/YYYY') ,
NVL(SGUNION_ENTE,' '),
NVL(SGUNION_DIREZ_CENTRALE,'0'),
NVL(SG02_ORE,'0'),
NVL(SG02_GIORNI,'0'),
NVL(SG02_PROV_ENTE_CORSO,' '),
NVL(SG02_CATEGORIA,'0'),
NVL(SG02_PROFILO_CORSO,' '),
NVL(SG02_ENTE_APPAR,' '),
NVL(SG02_DIREZ_APPAR,'0'),
NVL(SG02_ESAME,' '),
NVL(SG02_ESITO,' '),
NVL(SG02_VOTAZIONE,' '),
NVL(SG02_NOTE,' '),
SG02_PROGRESSIVO,
SGUNION_TIPODIP
FROM (SELECT sg01_matr AS sgunion_matr,
sg01_cognome AS sgunion_cognome,
sg01_nome AS sgunion_nome,
sg01_profilo AS sgunion_profilo,
sg01_ente AS sgunion_ente,
sg01_direz_centrale AS sgunion_direz_centrale,
'Dipendente AAMS' AS sgunion_tipodip
FROM sg01_dipens_giur
WHERE sg01_matr NOT IN (SELECT sg11_matr
FROM sg11_pensione)
UNION
SELECT sg06_matr AS sgunion_matr,
sg06_cognome AS sgunion_cognome,
sg06_nome AS sgunion_nome,
sg06_pos_econ AS sgunion_profilo,
sg06_ente AS sgunion_ente,
sg06_direz_centrale AS sgunion_direz_centrale,
'Dipendente Distaccato' AS sgunion_tipodip
FROM sg06_dist_com
WHERE to_date(sg06_data_fine_dist,'DD-MM-YYYY') > TO_DATE(SYSDATE,'DD-MM-YYYY')),
SG02_CORSI_FRUITI,
SG03_CORSI_PIANIF,
SGX02_TITOLO_CORSO,
SGX03_AREA_TEMATICA,
SGX08_POSIZIONE
WHERE SG02_MATR = SGUNION_MATR AND
SG02_TITOLO = SG03_TITOLO AND
TO_CHAR(SG02_DATA_INIZIO,'YYYY/MM/DD') BETWEEN TO_CHAR(SG03_DATA_INIZIO,'YYYY/MM/DD') AND TO_CHAR(SG03_DATA_FINE,'YYYY/MM/DD') AND
SG02_TITOLO = SGX02_CODICE(+) AND
SG03_AREA = SGX03_CODICE(+) AND
SGUNION_PROFILO = SGX08_CODICE(+) AND
SG02_MATR = '3285425' AND
TO_CHAR(SG02_DATA_INIZIO,'DD/MM/YYYY') = '12/05/2003' AND
SG03_AREA = 07 AND
SG02_TITOLO = 00038 AND
SG03_ENTE_CORSO = 03
alla fine ho optato per la union e senza avrei dovuto fare 2 select distinte con le medesime condizioni per poter trovare l'impiegato con la matricola o le condizioni che preferisco
trallallero
10-10-2006, 14:49
hai fatto bene secondo me. Non sembrano query costose quindi raddoppi le prestazioni e la leggibilitá forse addirittura ne guadagna perché si capisce che ti servono i dati contemporaneamente ;)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.