Newsgroup: it.comp.lang.visual-basic
Titolo: [? ADO-ACCESS] Se non e' un baco mi dite cos'e'? (lungo)

Ci ho messo tutta la domenica per capirci qualcosa, credo di essere arrivato
ad una conclusione ma
ma mi sembra molto strana, credo che mi sto perdendo in un bicchier d'accqua
ma ho fatto centinaia di
tentativi arrivando alle stesse conclusioni quindi vi espongo il
problema...se qualcuno ha qualche
idea e' bene accetta perche' sto andando via di testa!
Allora ho 5 tabelle in Access cosi' definite (IN SINTESI...HO MESSO SOLO I
CAMPI "INTERESSANTI")
CREATE TABLE people (
 ID_people int(11) NOT NULL  auto_increment,
 people_Name varchar(100) NOT NULL  ,
 PRIMARY KEY (ID_people),
 unique index (ID_people)
)
CREATE TABLE project (
 ID_people int(11) NOT NULL,
 ID_project int(11) NOT NULL  auto_increment,
 project_name varchar(50) NOT NULL  ,
 PRIMARY KEY (ID_project),
 index (ID_people),
 unique index (id_project)
)
CREATE TABLE kit (
 ID_kit int(11) NOT NULL  auto_increment,
 Kit_Name varchar(50)   ,
 PRIMARY KEY (ID_it),
 unique INDEX (ID_kit)
)
CREATE TABLE relation (
 ID_project int(11) NOT NULL  DEFAULT '0' ,
 ID_Kit int(11) NOT NULL  DEFAULT '0' ,
 index (ID_project),
 index (ID_Kit)
)
CREATE TABLE feedback (
 ID_project int(11) NOT NULL ,
 description varchar(50),
 INDEX ID_Job (ID_project)
)
Descrizione sommaria DB:
La tabella people contiene l'anagrafica delle persone che possono avere
molti progetti a loro collegati
(quindi 1 a molti fra people e project).
Ogni progetto puo'essere composto da molti kit e viceversa differenti kit
possono appartenere a differenti
progetti (quindi molti a molti tra project e kit, da cui la tabella
relation)
Infine ogni progetto puo' avere molti feedback (quindi 1 a molti tra project
e feedback).
Non ho messo le varie relazioni cmq ovviamente la tabella people "comanda":
se non c'e' un people di
riferimento non ci possono essere progetti a lui collegati nella tabella
project; e ugualmente se non
ci sono progetti non ci possono essere kit e/o feeback nelle altre 2
tabelle.
La mia necessita' e' estrarre tutti i dati di ogni people con tutti i
relativi progetti/kit/feedback (se ne ha!)
L'idea e' stata di fare una select con piu' LEFT JOIN e quindi di questo
tipo
select * from  (((people left join project on
people.id_people=project.id_people) left join feedback
  on project.id_project=feedback.id_project) left join relation on
  project.id_project=relation.id_project)left join kit on
relation.id_kit=kit.id_kit
Da un punto di vista logico mi sembra che le cose dovrebbero tornare e
questa query infatti fatta girare sotto Access
mi ritorna i risultati sperati ma le cose non sono le stesse quando tento di
fare la medesima cosa con ADO.
Infatti (posto che nel database c'e' almeno un people!) dovrebbe ritornarmi
un recordset di 11 campi con almeno i primi due
non vuoti (ID_people e people_name)
Invece mi ritorna un recorda di 11 campi vuoti!
Quindi vuol dire che la query in qualche modo gira ma non come dovrebbe.
E mi sono accorto che questo accade quando un progetto non ha un kit
collegato quindi in pratica quando l'ultima left ritorna
un risultato nullo.
Ma se ci sono dei dati sulle tabelle di sx (people e project) non dovrebbe
funzionare lo stesso attaccando dei record con campi
nulli dopo quelli "pieni"
Ora da quello che so io con una left join mi dovrebbe ritornare tutti i
campi della tabella people, anche quelli che non
"matchano" con le tabelle di destra (come e' il caso in cui ho solo una
persona nel DB). O mi sbaglio?
La query sotto ADO si comporta come se fosse una INNER JOIN.
Ripeto che sotto Access (dal suo query analizer) la query funziona
correttamente.
Da VB utilizzo questo codice
 Dim rec As ADODB.Recordset
 Dim cnn As ADODB.Connection
 Dim cmd As ADODB.Command
 Dim prm As ADODB.Parameter
 Set cnn = New ADODB.Connection
 Set rec = New ADODB.Recordset
 Set cmd = New ADODB.Command
 Set prm = New ADODB.Parameter
 cnn.ConnectionString = "Driver={Microsoft Access Driver
(*.mdb)};DBQ=C:\matteo\dbbug.mdb"
 cnn.CursorLocation = adUseClient
 cnn.Open
 Set cmd.ActiveConnection = cnn
 cmd.CommandType = adCmdText
 cmd.CommandText = "select * from  (((people left join project on
people.id_people=project.id_people) left join feedback on
project.id_project=feedback.id_project) left join relation on
project.id_project=relation.id_project)left join kit on
relation.id_kit=kit.id_kit"
 Set rec = cmd.Execute
Ho provato anche a spezzare la query di sopra in quattro query distinte nel
modo seguente
(PRIMA)
SELECT *
FROM kit LEFT JOIN relation ON [kit].[id_kit]=[relation].[id_kit];
(SECONDA)
SELECT *
FROM feedback LEFT JOIN prima ON
[feedback].[id_project]=[prima].[id_project];
(TERZA)
SELECT *
FROM project LEFT JOIN seconda ON
[project].[id_project]=[seconda].relation.id_project;
(QUARTA)
SELECT *
FROM people LEFT JOIN terza ON [people].[id_people]=[terza].[id_people];
e poi a richiamarle da VB con il codice di sopra con queste modifiche
 cmd.CommandType = adStoredProcedure
 cmd.CommandText = "quarta"
ma il risultato e' sempre lo stesso!
Ho fatto anche altri tentativi raggruppando a due a due le query, a tre a
uno etc etc ....ma la sostanza non cambia...
in definitiva sono arrivato alla conclusione che quella left join con ADO
non si comporta come dovrebbe...cioe' si
comporta come fosse una inner join.
E' possibile che ci sia una baco di queste dimensioni?
Io non credo, sono sempre convinto che sto sbagliando grossolanamente da
qualche parte, la domanda e' quindi semplice:DOVE???
Grazie a chiunque mi dara' qualche suggerimento illuminante!
Teo

 (*.mdb)};DBQ=C:\matteo\dbbug.mdb"
Premetto che per la fretta non ho letto tutto e approfonditamente, ma prova
ad aprire usando OLEDB, quindi:
cnn.ConnectionString="PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA
SOURCE=C:\matteo\dbbug.mdb;USER ID=;PASSWORD=;"

 wrote in message
news:4sZM8.29853$K4.7...@twister2.libero.it...

grazie del suggerimento, avevo gia' provato e funziona ma siccome sono quasi
alla fine del mio programma e avevo fatto tutti i test e le prove con ODBC
non vorrei che passando ad OLEDB mi trovassi con dei problemi "nascosti" nel
codice.
Non conosco le differenze tra ODBC e OLEDB...ma gia' questa differenza di
comportamento mi mette paura nel caso ce ne fossero altre...
Ma questo vuol dire che effettivamente c'e' qualcosa che non va con ODBC o
cos'altro?

 cos'altro?
Francamente non so, non conosco ODBC verso database di tipo Access. Credo di
poter dire che ODBC è più stabilizzato e mi sembra strano che non si
comporti come deve (francamente, se fossi in te, spenderei ancora un po' di
tempo su quel punto che non va e/o sulle versioni). ADO/OLEDB è più giovane
(e guai selvatici a chi mi contraria ;-) ) e ha più di un buco (vedi un po'
in questi post), ma viene spinto molto anche se, con l'avvento di .NET,
chissà mai se verrà mantenuto/aggiornato/supportato per bene.


guarda..le ho provate proprio tutte ma non riesco a "cavarne un ragno dal
buco"!!
ripeto vorrei mantenere ODBC per evitare problemi e per evitare di dover
ri-testare tutto il mio progetto....
se qualcun altro ha delle idee o mi puo' spiegare questo STRANO
comportamento di ADO con ODBC gliene
sarei molto grato.
grazie in anticipo
teo

 sarei molto grato.
Sinceramente il motivo lo ignoro. Tuttavia ODBC dipende dalla configurazione
del sistema su cui gira l'applicativo, mentre OLE-DB richiede solo che
esistano sul PC determinate librerie.
Sei sicuro che proprio non vuoi cambiare la stringa di connessione da ODBC
in OLEDB?
Ciao
Alberto


Ciao Teo,
se ti fai un giretto su Google.Groups con "ODBC+LEFT+JOIN"
per esempio, c'è un'intera letteratura sui problemi che possono
insorgere... qua e là c'è qualche dritta, tipo specificare singolarmente
per ogni tabella coinvolta nei JOIN, i nomi dei campi, ma in
generale è un gran casino... se posso darti un consiglio, anche se
ti costerà un po' di lavoro in più, passa ad un provider OLE DB
nativo, anche perchè l'accoppiata ADO + ODBC non è delle
migliori ... comunque dai un'occhiata, magari trovi la dritta giusta.
Ciao
 Valter

  Valter
provero' ad andare a fare il giretto vedere anche su google pero'
l'accoppiata malefica credo che sia ADO+ODBC+ACCESS perche' con ODBC su
MySQL il baco (a questo punto lo chiamo cosi'!) non si presenta...
quindi non credo sia un problema strettamente legato solo ad ODBC....o
almeno le mie conoscenze attuali mi fanno dedurre questo....