Newsgroup: it.comp.software.database
Titolo: Subquery UPDATE di SELECT

Salve a tutti.
Ho il seguente dubbio esistenziale:
è possibile inserire una query UPDATE come subquery di una query
SELECT?
Faccio un esempio:
SELECT tot FROM totdue WHERE asd IN (UPDATE tot SET x=y WHERE j=k) AND
i=u
Ovviamente questa sintassi è errata e mi restituisce errore, mi
serviva conoscere un altro
metodo, anche se privo di senso, l'importante è che venga eseguito
l'UPDATE.
Purtroppo non posso usare due query separate (mysql_query() di php).
Grazie in anticipo,
Alfio

Sembra che Alfio Emanuele Fresta abbia detto :

Ciao,
qual'è il risultato che devi ottenere?
Emanuele Desideri.
-- 
Emanuele Desideri


wrote:

Sto testando una piattaforma per SQL-Injection e devo effettuare una
query di tipo UPDATE.

 query di tipo UPDATE.
Si va bene, ma vorrei capire qual'è il result set che ti aspetti di 
ottenere scrivendo una update dentro una select.
-- 
Emanuele Desideri

 ottenere scrivendo una update dentro una select.
Non ha importanza quale sia il result set, non mi interessa ottenere
dei dati.
Mi basta solo che l'UPDATE venga eseguito con successo, senza alcun
errore di sintassi.
In ogni caso utilizzando una subquery come condizione ipoteticamente
sempre vera,
non dovrebbe cambiare niente.

 non dovrebbe cambiare niente.
Se vuoi solo fare un Update usa la sintassi corretta per il comando di 
update
UPDATE Tabella
SET Campo1 = :mioValore1, Campo2 = :mioValore2, CampoN = :mioValoreN 
WHERE (condizioneDiUpdate)
Al limite se vuoi sapere quanti record sono stati aggiornati usa la 
funzione mysql_affected_rows di php (mi pare che stai lavorando in php 
vero?) che ti ritorna 0 se nessun record è stato aggiornato, -1 in caso 
di errore sulla query.
Se invece ti serve altro, io non l'ho capito quindi dovrai avere la 
pazienza di rispiegarmelo :D
un saluto
-- 
Emanuele Desideri

 l'UPDATE.
l'UPDATE viene eseguito se esegui un comando UPDATE.
la SELECT non puň funzionare perchč la clausola WHERE...IN si aspetta
un insieme di record, e la UPDATE non restituisce un insieme di record.
ciň che puoi fare č eventualmente il contrario
UPDATE tot SET x=y WHERE j IN ( SELECT k FROM totdue WHERE i=u)

> Si va bene, ma vorrei capire qual'è il result set che ti

L'SQL Injection funziona perche' fa terminare il precedente
comando con un carattere (ad esempio) di termine linea, poi
fa una UPDATE che viene eseguita come se fosse sulla
linea successiva (cioe' un nuovo comando).
L'UPDATE non funziona come se fosse una subquery, e forse ho
capito la causa della confusione.
 
Quando scrivo un comando SELECT, il significato di questa
operazione in realta` varia in funzione del contesto: puo'
restituirlo al client chiamante dalla rete, puo' essere la
specificazione di una sub-query (nel qual caso mentalmente
viene omessa), oppure si usa per assegnare una variabile.
 
Ricordo ancora con stupore quando vidi per la prima volta:
 
  SELECT @Variabile = 123
 
...ma la select non serviva per leggere dati? Normalmente
siamo portati a differenziare operatori di assegnazione da
quelli di lettura.
 
 
Immaginate ora una linea in un ipotetico simil-Basic:
 
PRINT "Hello" + (PRINT " world") ;
 
...sarebbe errato, anche intuitivamente! Non posso "sommare"
due comandi, ma posso sommarne gli argomenti; il comune
modus operandi e` che nella prima posizione si scrive il
"comando", poi i "dati" su cui deve agire, poi necessariamente
deve esserci il termine di linea, e solo allora si puo'
scrivere un nuovo comando. Quindi il comando sopra andrebbe
riscritto come:
 
PRINT "Hello" + " world" ;
oppure
PRINT "Hello" ;
PRINT " world" ;
 
Parallelamente varie espressioni SQL accettano, in maniera
apparentemente sorprendente, due comandi:
 
SELECT Col FROM Table WHERE a IN (SELECT Col2 FROM Table2 [...]
 
il secondo SELECT intuitivamente non ci sembra avere la
stessa "forza" del SELECT che sta ad inizio riga;
sappiamo che una query si puo' riscrivere in una forma che
non implica una sub-query, pertanto siamo portati a
"svalutare" il secondo SELECT, ed in effetti ad ometterlo
mentalmente, intendendolo piuttosto come un marcatore
per l'inizio di una sotto-espressione (eppure, come in
algebra, potrebbero bastare le parentesi, cosi' da rendere
piu' pulita la sintassi...).
 
Per contro altre sintassi con due comandi tipo:
SELECT (DELETE FROM ...
danno errore; eppure potrebbe essere utile sapere quali
righe sono state cancellate dal comando delete, basterebbe
che il delete restituisse un recordset.
 
Potrebbe anche essermi utile un ipotetico:
INSERT INTO b (UPDATE ...)
...in modo da avere nella tabella "b" un log delle righe
che sono state variate.
 
Perche` questa disomogeneita` tra comandi?
 
L'idea che sta sotto a questo discorso e` che SELECT e`
(talvolta ma non sempre) una "funzione", gli INSERT,
UPDATE, DELETE sono dei comandi "imperativi".
 
Questo e` davvero un curioso mix di filosofie di linguaggio
differenti, e talvolta risulta sgradito (o causa di
confusione, come nel tuo caso).
 
Ad esempio se volessi inserire una riga, potrebbe non
interessarmi se tale riga esiste gia' oppure no: se non c'e`
la inserisce, altrimenti eventualmente ne aggiorna i valori
(una semantica mista tra un INSERT ed un UPDATE).
 
Siccome lo standard SQL non soddisfava questa esigenza,
come al solito alcuni produttori hanno fatto uno scatto in
avanti inventando estensioni proprietarie al linguaggio;
poi pero' e` arrivato il comando MERGE nello standard SQL, e
l'infelice situazione che si e` venuta a creare e` che
qualche dbms deve supportare sia la sintassi proprietaria
sia quella standard...
 
Questa e` solo una delle varie critiche che si possono
muovere allo standard SQL, uno standard che tra rattoppi ed
invasioni in campi a lui non pertinenti e` ormai arrivato
al capolinea: e` meglio che venga abbandonato prima che
faccia affondare i dbms relazionali.
Nessuna meraviglia infatti se il movimento contro-relazionale
si sia dato il nome "NOSQL".