Newsgroup: it.comp.lang.delphi
Titolo: Cliient DataSet e campi da SQLJoin

Lo scopo principale e' poter ordinare secondo un campo
di LookUp;
Se creo un campo LookUp persitente , non posso creare
un indice con CDS... AddIndex (il campo non esiste nella
Tabella anche se fa parte dei campi persistenti del CDS)
Se invece creo una Sql Join, non vengono sollevate eccezioni,
e l'indice sul campo fittizio si comporta come quello su un campo
esistente nella Tabella.
sSQL:='SELECT 
C.ID
,C.CITTA,C.CAP,C.PROVINCIA,C.ID_NAZIONE,N.NAZIONE AS
            ' NOMENAZ'+  ' FROM (TbCitta C INNER JOIN TbNazioni N' +
            ' ON C.ID_NAZIONE=
N.ID
)';
dopo eseguita la Query , posso ordinare secondo il campo risultante
CDS_Citta.AddIndex('Idx_NomeNazione','NOMENAZ',[ixPrimary]);
CDS_Citta.IndexName:='Idx_NomeNazione';
Quando pero' vado a fare il CDS....Post, mi solleva eccezione in
quanto vi e' un campo non presente nella Tabella.
per chiarezza , D2007, Db Firebird 2.0 ; tabelle TbCitta e TbNazioni
TbCitta      : Id,Citta,Cap,Provincia,IdNazione
Id : Primary Key
IdNazioni : ForeignKey su TbNazioni->Id
TbNazioni : Id,Nazione
Id   : Primary Key
il campo fittizio e' NOMENAZ; prima di eseguire il Post ho anche provato ad
eliminare il campo fittizio , che cosi' dai 6 campi iniziali 5 reali + 1
(della Join), diventano 5
// scorro i campi alla ricerca di NOMENAZ e lo elimino
for i := 0 to CDS_Citta.Fields.Count - 1 do
          begin
            if CDS_Citta.Fields[i].FieldName='NOMENAZ' then
              begin
                CDS_Citta.Fields.Remove(CDS_Citta.Fields[i]);
              end;
          end;
nonostante cio' , al momento del Post viene sollevata eccezione (dato che il
campo CDS_CittaNOMENAZ nella tabelle TbCitta non esiste)
potrei usare una Query con Insert Into/ Update From .... legate a SQLDataSet
e Start Transaction , Commit, Rollback legate a SQLConnection;
con i componenti Interbase di D7 usavo
TIBDataBase, TIBTransaction,TIBQuery,TDataSource.
con i dbExpress non l'ho mai fatto e credo che ClientDataSet e
DataSetProvidfer diventino inutili.
che altre strade posso seguire per otenere lo scopo ?
Maurizio

 DataSetProvidfer diventino inutili.
Non diventano inutili. Piuttosto a cosa è impostato il valore del flag
pfInUpdate tra i ProviderFlags per il campo in questione?
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

> pfInUpdate tra i ProviderFlags per il campo in questione?
qui e' l'intoppo questo campo non esiste nella Tabella Citta legata al CDS,
e non mi e' possibile aggiungerlo ai campi persistenti.
esiste nella Tabella Nazioni (con un nome diverso) il cui flag pfInUpdate
e' True
Maurizio 

 e' True
Non ho capito. Tu hai un CDS legato a un componente (tipo TSQLQuery) che
preleva i dati per join o no?. In questo CDS, il campo può essere aggiunto
come persistente e nel caso pfInUpdate deve essere messo a false.



si ho un CDS legato ad un TSQLDataSet , e preleva i dati via Join.
nella proprieta'  CommandText metto questo comando
Select C.*, N.NAZIONE AS NOMENAZ
            FROM (TB_CITTA C INNER JOIN TB_NAZIONI N
            ON C.ID_NAZIONE=
N.ID
)
e successivamente il CDS mi fa aggiungere il campo NOMENAZ come
persistente , setto anche il Flag pfInUpdate=False
provo a modificare un Record, quindi CDS_Citta.Edit ,
e confermo senza modifica alcun campo CDS_Citta.Post;
pertanto AppòlyUpdates funziona
provo a modificare il campo Cap, confermo, Edit e Post, al momento di
eseguire ApplyUpdates solleva un'eccezione
..class DBXError with message columns unknow NOMENAZ
at line 8 column 19,    se scelgo continue
visualizza il messaggio
class DBXError with message unable to find Record no key specified
la Tabella TB_Citta ha ID come primary key e ID_Nazione foreign key
TB_Nazioni ID come primary key ; tutti Integer
Maurizio 

 class DBXError with message unable to find Record no key specified
Questo dipende dal fatto che non hai specificato quali campi sono in
chiave (flag pfInKey).


>
quindi
TClientDataSet->TDataSetProvider->TSqlQuery->
TDataSource->TClientDataSet
con TSqlQuery->TSqlConnection
importo tutti i campi nel ClientDataSet, imposto
ID pfInKey=True ; NomeNaz pfUpdate=False
nel campo NomeNaz tutti i flag ProviderFlag = False
sembra tutto in ordine ma al momento di ApplyUpdates gli
stessi errori
..class DBXError with message columns unknow NomeNaz
at line 8 column 19 e successivamente, unable to find Record no key 
specified
lo fa sempre, anche senza modificare un campo
Maurizio 

Maurizio ha scritto:
<snip>
Bisognerebbe analizzare attentamente la tua applicazione (e la base dati),
cosa che è difficile fare da qui...


> cosa che è difficile fare da qui...
provero' a creare un semplice form , con un datamodule e testare le
condizioni in cui si verifica il problema.
se risolvo , posto dov'era il problema.
grazie comunque.
Maurizio 

> grazie comunque.
ho fatto varie prove usando prima i componenti IBX e
successivamente i DBExpress (in qaunto non specifici
per Interbase).
con DBExpress ho usato
TClientDataSet->TDataSetProvider->TSQLDataSet->
TDataSource->TClientDataSet
come sempre ho usato la query Join, e tutto funziona , ma a patto
che si usino i comandi SQL e non Edit e Post del ClientDataSet,
pena il solito errore sul campo NOMENAZ.
per Ordinare secondo il campo NOMENAZ uso
Order By NOMENAZ
Maurizio
^^^^^^^^^^^
ad es: una sequenza di Update
  sSQL:='UPDATE TB_CITTA ' +
        'SET ID=:Codice,CITTA=:Citta,CAP=:Cap,PROVINCIA=:Provincia,
ID_NAZIONE=:IdNazione' +
        'WHERE ID='+QuotedStr(FloatToStr(iIdCitta));
assegnata a SQLDataSet.CommandText
ed eseguita con SQLDataSet.ExecSQL;
oppure lascire las Quewry statica di selezione Join ed eseguire delle
Stored Procedure per Insert/Update/Delete
ed eseguendo le transazioni
procedure TfrmDati.ConfermaSQL;
var TD: TTransactionDesc;
begin
  TD.TransactionID := 1;
  TD.IsolationLevel := xilREADCOMMITTED;
  SQLConnection1.StartTransaction(TD);
  try
    SQLConnection1.Commit(TD);
  except
    SQLConnection1.Rollback(TD);
  end;
end;

pena il solito errore sul campo NOMENAZ.
Non ci siamo. I comandi SQL devi lasciarli perdere, se lavori col CDS,
cosě come devi lasciar perdere l'uso esplicito delle transazioni (sono
automaticamente gestite dal TDataSetProvider). Lavorare con campi
restituiti da join č possibilissimo, evidentemente sbagli ad impostare
qualcosa.

 di LookUp...
Interessa anche a me.
Ho fatto alcuni piccoli test.
Io sono riuscito a risolvere solo lavorando con il flag
pfInUpdate come diceva Andrea.
Ma la cosa strana e' che quel flag l'ho dovuto
impostare sui campi persistenti del componente query
e non su quelli del clientdataset.
E' normale?
Nell'architettura query+provider+clientdataset non capisco
che ruolo abbiano i campi persistenti "lato query" e che ruolo
abbiano invece quelli "lato clientdataset".
JH