Newsgroup: it.comp.lang.delphi
Titolo: Ado e SQL

Ragazzi, mi date un chiarimento? - sto spulciando qua e la ma in giro le 
opinioni sono discordi
D7, Ado, Access.
Sto studiando quindi non rabbrividite
:-)
Sulla form:
AdoConnection1 <-- AdoDataset1 <-- DataSource1 <-- DBGrid1
AdoCommand1, AdoQuery1
Voglio eseguire un'operazione sui record...č meglio utilizzare:
TADOCommand o TADOQuery?
se io scrivo:
try
  MyUser := edit1.text;
  AdoConnection1.BeginTrans;
  AdoCommand1.CommandText := 'DELETE FROM MYTABLE WHERE 
User='''+MyUser+'''';
  AdoCommand1.Execute;
  AdoCommand1.Requery;
  AdoConnection1.CommitTrans;
except
  AdoConnection1.RollBackTrans;
end;
mi elimina il record e mi refresha la DBGrid regolarmente
ma se invece di AdoCommand1 carico una:
AdoQuery1.SQL.Add('DELETE FROM MYTABLE WHERE User='''+MyUser+'''');
e la eseguo con
AdoQuery1.ExecSQL
la sostanza non cambia ed il risultato č lo stesso...
Forse siamo OT ma brevemente per modifiche/inserimento/cancellazioni dei 
record cosa č meglio usare?
Ciao
V.

 TADOCommand o TADOQuery?
guarda, la guida dice:
"TADOCommand is most often used for executing data definition language 
(DDL) SQL commands or to execute a stored procedure that does not return a 
result set. For SQL statements that return a result set, TADODataSet, 
TADOQuery, or TADOStoredProc is better suited. The Execute method of 
TADOCommand is, however, capable of returning a recordset. To use that 
recordset, however, you will need a separate ADO dataset component."
Chiaro, no? :)
-- 
Mauro Falzari
"Chi domanda comanda".
  (anonimo)

 Chiaro, no? :)
Si, finchè non googli e leggi opinioni discordanti...
chi dice che è meglio in un modo, chi in un altro
insomma vale l'esperienza...che ha da venire
:-)
V

 insomma vale l'esperienza...che ha da venire
in effetti leggendo qua e là si può fare un po' di confusione. Specialmente 
nel tuo caso che una DELETE è un'istruzione DML ma non restituisce un 
recordset (o si? Questo non l'ho controllato).
Comunque mi pare di aver appurato che ADOQuery sia un'oggetto più 
specializzato di ADOCommand, cioè esegue solo istruzioni DML (non DDL, nè 
stored procedures, quindi) e fornisce un recordset bell'e pronto.
-- 
Mauro Falzari
"Creative minds have always been known
to survive any kind of bad training".
  (Anna Freud)

 end;
..ottieni che se x qualche motivo l'operazione fallisce non saprai il 
xche e, sopratutto, non saprai che è fallita.
xche farsi male cosi??
A.

 xche farsi male cosi??
è un estratto di un tutorial in rete...si potrebbe dire: primi passi in
SQL...
V

 è un estratto di un tutorial in rete...
Stai MOLTO attento a cio che trovi sul web...
Non a caso qui si fa spesso riferimento ai "soliti siti".
scrivi al tipo che poi, quando hai il cliente che ti chiama xche "non 
funziona UN CAZZOOOOO! chiami LUi x fare il debug senza avere i msg 
delle eccezioni e, soprauttto, la loro visibilita.
Anzi, dammi il link..... :-|
ihmo, gestire le eccezioni è FONDAMENTALE, ancora di piu se sei in 
contesti multithreading.
Chi non lo fa meglio che cambia lavoro.
Pax vobiscum.
A.


 Anzi, dammi il link..... :-|
l'ho tratto proprio da questo ng...
http://www.itportal.it/developer/delphi/ado/
ma secondo me lo scopo dell'articolo è di fornire una semplice 
infarinatura...
io stesso, quando posto qualche stralcio di codice taglio via il controllo 
delle eccezioni per permettere di focalizzare al meglio il problema e mi 
becco una bella bacchettata sulle dita...
:-)
Ciao
V. 

 ha scritto nel messaggio
Cominciano i primi inc..z..menti...
ok il Delete, ok Insert ma perchè questa Update mi restituisce errore di 
sisntassi?
traggo dai gruppi, proprio con Delphi, Ado e Access:
Il problema sono i doppi apici (") delle stringhe "ciccio" e "mario". Prova
così:
(mia nota: già quel prova è poco incoraggiante...non c'è uno standard?)
        Query1.SQL.Clear;
        Query1.SQL.Add('update ActiveConnections');
        Query1.SQL.Add(' set UTENTE=''ciccio''');
        Query1.SQL.Add('where UTENTE=''mario''');
utilizzando cioè gli apici semplici.
Meglio ancora se fai così:
        Query1.SQL.Clear;
        Query1.SQL.Add('update ActiveConnections');
        Query1.SQL.Add(' set UTENTE  = :nuovonome');
        Query1.SQL.Add('where UTENTE = :vecchionome');
        Query1.ParamByName('vecchionome').AsString := 'mario';
        Query1.ParamByName('nuovoonome').AsString  := 'ciccio';
        Query1.ExecSQL;
Tra l'altro Query1.ParamByName non c'è...lo raggiungo con 
Query1.Parameters.ParamByName ma anche così nessuno dei due suggerimenti va 
a buon fine...
Sono perplesso...
La mia tabella è così strutturata:
nome tabella = TDB
7 campi
dovrei modificare un record che abbia il campo User = old con User = new ed 
il resto dei campi invariati
mi suggerite qualcosa?
V.

         Query1.ParamByName('nuovoonome').AsString  := 'ciccio';
UPDATE ActiveConnections 
  SET UTENTE = " + nuovonome + " 
per questo invece ho un dubbio, perchè dovrebbe bastare così:
  WHERE UTENTE = vecchionome  


 buon fine...
Questo è il metodo giusto, cosa intendi dicendo che
I parametri si passano però così:
Query1.Parameters.ParamByName('NomeParametro').VALUE
sarà poi ado a castarli correttamente
ciao.

 Questo è il metodo giusto, cosa intendi dicendo che
questa riga è figlia di un copia incollavenuto male :)
Leggasi "questo è il metodo giusto, imho"

 correggo il tuo codice
non è il mio codice, è un codice reperito nei gruppi...
l'ho corretto ma non marcia...
sono i primi intoppi, chi può abbia pazienza
se ho capito bene, volendo scrivere una sola stringa SQL:
adoquery1.SQL.Add('Update DBData set User="nuovo" where User="vecchio"');
oppure, una stringa composta:
adoquery1.SQL.Add('Update DBData ');
adoquery1.SQL.Add('set User="nuovo" ');
adoquery1.SQL.Add('where User="vecchio"');
ho provato anche usando l'apice singolo ripetuto due volte al posto delle 
virgolette
ma mi restituisce sempre errore di sintassi
ci sto uscendo di testa...mi potreste correggere la seguente Update come la 
scrivereste voi?
se funzionasse potrei finalmente cominciare con le prove dei parametri 
ecc...?
adoquery1.SQL.Add('Update DBData set User="nuovo" where User="vecchio"');
ve ne sarei grato, sono già impippato con apici e virgolette...
uso D7, ADO, Access 2000
V.

 sarà poi ado a castarli correttamente
no, è che semplicemente ho trovato questo suggerimento in rete e non mi 
ritornava:
Query1.ParamByName('vecchionome').AsString := 'mario';
V.


Usa i parametri come avevi scritto prima :)
adoquery1.SQL.Add('Update DBData ');
adoquery1.SQL.Add('set User=:nuovo ');
adoquery1.SQL.Add('where User=:vecchio');
AdoQyery1.Parameters.ParamByName('nuovo').Value := 'Mario';
AdoQyery1.Parameters.ParamByName('vecchio').Value := 'Giovanni';
AdoQuery1. ExecSQL;

 Usa i parametri come avevi scritto prima :)
Arghhh!
***Errore di sintassi***
procedure TForm1.Button7Click(Sender: TObject);
begin
try
  adoconnection1.BeginTrans;
  adoquery1.SQL.Clear;
  adoquery1.SQL.Add('update DBDATA ');
  adoquery1.SQL.Add('set User=:nuovo ');
  adoquery1.SQL.Add('where User=:vecchio');
  adoquery1.Parameters.ParamByName('nuovo').Value := 'Pippo';
  adoquery1.Parameters.ParamByName('vecchio').Value := 'd';
  adoquery1.ExecSQL;
  adodataset1.Requery;
  adoconnection1.CommitTrans;
except
  on E:exception do
  begin
    memo1.Lines.Add('Errore '+E.Message);
    adoconnection1.RollbackTrans;
  end;
end;
end;
i campi per ogni record sono 7, User č il primo...non č che vadano indicati 
tutti nell'update?
e qualche impostazione nell' Object Inspector?

 sono i primi intoppi, chi può abbia pazienza
se posso darti un consiglio..prima prova il codice SQL direttamente in 
Access (lo so che l'editor dell'sql delle queries fa schifo, io scrivo le 
query in file di testo e poi le incollo lì). Una volta che funziona in 
Access, il primo passo è fatto..poi ti resta da capire come farlo 
funzionare coi parametri, TAdoQuery ecc. in Delphi (non è difficile, te 
l'assicuro).
Stai accedendo a un db Access, ho capito bene vero?
-- 
Mauro Falzari
"La realtà superava i miei timori:
il capitano Achab era sul cassero, a poppa".
  (Herman Melville, in "Moby Dick", Londra 1851)

 Stai accedendo a un db Access, ho capito bene vero?
esatto...
seguo il tuo consiglio e ci provo subito
la cosa che trovo assurda è come può essere che una query postata come 
funzionante da chi ha la mia stessa configurazione (vedi numerosissimi 
esempi in rete) possa non andare e richiedere "aggiustamenti" o 
personalizzazioni...
mah, potenza dell'informatica
V.

 seguo il tuo consiglio e ci provo subito
e bè, però, e come ci arrivavo sennò?
:-)
una cosa di questo tipo, che non funxia:
adoquery1.SQL.Add('Update DBData set User="nuovo" where User="vecchio"');
richiede a quanto pare:
adoquery1.SQL.Add('Update DBData set DBData.[User] = "nuovo" where 
(((DBData.User)="vecchio"))');
probabilmente la potrebbe accettare anche sotto un'altra forma, comunque 
adesso ho un punto di partenza...
Grazie
V. 

 adesso ho un punto di partenza...
esatto, l'importante è un appiglio per iniziare. Forza che ce la puoi fare!
-- 
Mauro Falzari
"Un arcobaleno invisibile circonda quello visibile".
  (Ernst Jünger)

 Query1.ParamByName('vecchionome').AsString := 'mario';
valter...semplicemente query1 non è una tadoquery....
A.

 (((DBData.User)="vecchio"))');
sintassi access...
A.

 ha scritto nel messaggio

quella è la query assemblata da Access ma dopo alcuni tentativi può essere
minimizzata così:
sotto Access:
update DBDATA set User="nuovo" where User="vecchio"
e quindi si torna alla sintassi suggerita in questo thread
ma sotto Delphi:
update DBDATA set [User]="nuovo" where User="vecchio"
in sostanza necessitano le quadre sul nome del campo, ma solo quello dopo
SET
almeno, nel mio caso...visto la variabilità dell'argomento
:-)
V.

 valter...semplicemente query1 non è una tadoquery....
oops!
e luce fu (schiarita toh, non esageriamo)
:-)

 update DBDATA set [User]="nuovo" where User="vecchio"
sì perchè credo che Access, "internamente", metta le parentesi quadre 
attorno ai nomi dei campi (e forse anche delle tabelle), prima di passarle 
al motore db in uso (quello predefinito è Microsoft Jet).
Se non vado errato, da Delphi, non si può nemmeno usare l'AS, che invece in 
Access si può usare:
SELECT
  RC.CAMPO1,
  OP.CAMPO2
FROM
  REGISTRO_CARICO AS RC
INNER JOIN
  OPERAZIONI AS OP
ON
  RC.FK_OP = 
OP.ID
-- 
Mauro Falzari
"Military justice is to justice 
what military music is to music".
  (Groucho Marx)