salve,
andrea99999 ha scritto:
Intanto grazie per l'aiuto; i dbms li faremo il prox anno, ma volevo iniziare ad imparare le SP ed i trigger, quindi sono alle prime armi ...
personalmente non ho mai cominciato le "cose" direttamente "facendo", ma prima studiando l'architettura, ma forse questo e' un problema mio :)
con questo non dico che imbrattarsi subito le mani scrivendo queries sia sbagliato, ma prima, almeno personalmente, mi piacerebbe sapere "cosa sto facendo".. poi il resto va tutto bene, sempre che se ne sia compresa la "filosia" di base, sia dell'architettura che della scelta fatta..
Ecco le risposte: uso SQL Server 2008 express; il tipo booleano è un "bit" e non un "byte", mi ero confuso,
il bit, in SQL Server, non e' un vero valore booleano.. e' infatti un numero nel dominio degli interi, ma limitato ad accettare 3 sole valorizzazioni:
1 (solitamente accettato come "True")
0 (solitamente accettato come "False")
NULL
questo potrebbe essere il tuo problema circa l'ordinamento inaspettato.. se pensavi che True fosse = -1, e quindi l'ordinamento standard crescente : -1 , 0
allora sei purtroppo stato tratto in inganno.. infatti un ordinamento crescente per una colonna di tipo bit restituisce prima 0 e poi 1..
anche i RETURN ho sbagliato il cut/paste, infatti i due parametri li ho dicharati come OUTPUT ma non sò come legarli ai parametri t1.descrizione e t2.valore della SELECT principale ... come scrivo questa associazione???
non avviente un'associazione bensi' un'assegnazione.. che avviene direttamente nell'esecuzione della proiezione, quindi nello statement di SELECT..
tipicamente avrai quindi
DECLARE @p1 int, @p2 int;
SELECT @p1 = col1, @p2 = col2
FROM ....
WHERE ....;
non indico un order by per un motivo molto semplice.. come sicuramente ben sai, l'operazione di ORDER BY e' un'operazione di cursore che avviene al termine della proiezione stessa.. la worktable risultante dalla proiezione, includente tutte le eventuali subquery e tutte le join, viene alla fine ordinata secondo quanto indicato nella clausola ORDER BY..
visto che nel caso in esame parliamo di un'assegnazione ad una variabile, la cosa ha poco senso in quanto l'assegnazione dovrebbe essere di per se unica, cioe' il filtro di WHERE dovrebbe ritornare una ed una sola riga, cosi' che l'assegnazione possa avere un senso.. in caso diverso, per ogni riga risultante, si avrebbe un'assegnazione dei parametri. cio' sta ad indicare che, qualora fossero ritornate piu' righe, solo l'ultima riga sarebbe risultante (e vincitrice) nell'assegnazione dei parametri.
questo in SQL Server, ma probabilmente anche in altri dbms.. dico questo in quanto, ad esempio in FireBird, questo tipo di sintassi viene utilizzata per vere e proprie operazioni sia di cursore che di restituzione dei dati, e la sintassi di SELECT prevede un vero e proprio datapump al chiamante con l'istruzione SUSPEND, che invia la riga ritornata al chiamante prima di riprendere l'esecuzione del ciclo.. in questo c'e' una grossa differenza con SQL Server, in quanto in FireBird ogni singola riga viene materializzata conseguentemente, e va in questo modo processata (ripeto, sia restituendola al chiamante che magari internamente per successive operazioni row based), mentre in SQL Server verra' solamente materializzato un (o diversi, in quanto SQL Server consente ad esempio stored procedure che ritornino piu' di un resultset) resultset al termine della proiezione completa, che verra' poi ritornato al chiamante non riga per riga ma come un set di dati, serializzato in uno stream, il T(abular) D(ata) S(tream), un protocollo proprietario Microsoft, che al suo interno contiene sia resultset, che messaggi, che valorizzazione di parametri in Input/Output.. questa e' una delle piu' grosse differenze architetturali che puoi trovare, e se non sbaglio anche Oracle opera similarmente.. spesso infatti i programmatori Oracle che arrivano a SQL Server si trovano in difficolta' per questo diverso modus operandi, che forza il programmatore ad operare in maniera "set based" e non "row based".. ma stiamo divagando :)
tornando al problema, personalmente non ti consiglierei l'utilizzo dei parametri di output, ma ovviamente non conosco il "tuo problema"..
ritornerei quindi al chiamante direttamente la proiezione desiderata, quindi
SELECT col_List FROM .. WHERE .. (ORDER BY..[nel caso di set di dati con piu' di una riga]);
e sara' poi il chiamante a consumare i dati come desiderato..
ovviamente puoi anche prendere la strada dei parametri in Input/Output e nulla lo vieta, sempre che il risultato della proiezione sia al massimo mono riga..
Ho comunque modificato la SP come mi hai indicato e funziona (ad esclusione ovviamente di quei due parametri di outout), inoltre volevo chiederti a cosa serve il DROP TABLE finale ... non vorrei che mi cancellasse i dati nelle mie tabelle ...
quando si prepara un esempio, e' buona norma fornirne uno che includa "il tutto".. con questo si intende sia il codice DDL di creazione degli oggetti coinvolti, le eventuali righe di INSERT INTO per popolare le tabelle come desiderato, il codice DML eventualmente provato/da provare/consigliato come soluzione, (nel caso di domanda e non di risposta si deve indicare anche cosa si desidera ottenere in base ai dati forniti), ed "infine", il codice di cleanup che provveda alla pulizia di quanto "fatto".. il DROP finale che ho messo, appunto, provvede alla eliminazione delle tabelle che faccio generare, in modo che, alla fine dell'esecuzione dello script, la macchina sulla quale e' stato eseguito sia esattamente nelle medesime condizioni (in termini di catalogo e ovviamente non in termini di risorse consumate, quali memoria etc) di prima dell'esecuzione dello stesso.. e' quindi una forma civile e di buon senso per una serena "convivenza" :) avrai tra l'altro notato che la seconda istruzione dello script, dopo SET NOCOUNT ON; (che serve a rimuovere la messaggistica emessa da SQL Server relativamente al numero di righe interessate dall'operazione da eseguirsi), sia USE tempdb; , che serve a "spostare" l'ambito di esecuzione di tutto lo script non gia' in un database utente qualsiasi, bensi' nel database di sistema "tempdb", il database utilizzato da SQL Server per tante funzionalita', che vanno dallo storage temporaneo per worktable, agli ordinamenti, etc.. quindi gli oggetti generati nel contesto dello script non "sporcheranno" mai dei database "importanti"..
quindi, tornando alla tua domanda, quelle istruzioni di DROP cancellano fisicamente le tabelle che prima avevo fatto generare e, ovviamente, non vanno lasciate nel database finale di destinazione :)
saluti