CREATE VIEW Order
AS
SELECT OrderID,OrderDate, . . .
FROM Customers INNER JOIN Orders
ON Customers.CustomerID = Orders.CustomerID
ORDER BY Customers.CompanyName
QUANDO lo eseguo mi visualizza il messaggio che segue:
Messaggio 1033, livello 15, stato 1, procedura Order, riga 6
La clausola ORDER BY non è consentita in viste, funzioni inline, tabelle
derivate, subquery ed espressioni di tabella comuni a meno che non sia
specificata anche la clausola TOP o FOR XML.
mentre se la creo da Management Studio non ci sono problemi.
Dove sbaglio?
grazie ciao
> Dove sbaglio?
In una vista non bisogna usare la clausola ORDER BY, punto!
Se hai bisogno di risultati ordinati, aggiungerai la clausola ORDER BY
alla query che estrae i dati dalla vista:
SELECT campo1, campo2 FROM vista ORDER BY campo1
Ti sembrerà assurdo, ma se crei una vista come questa:
CREATE VIEW Order
AS
SELECT TOP 50 ord.OrderID, ord.OrderDate
FROM Customers AS cus
INNER JOIN Orders AS ord
ON cus.CustomerID = ord.CustomerID
ORDER BY cus.CompanyName;
e poi estrai i dati con un'istruzione come questa:
SELECT OrderID, OrderDate FROM Order;
SQL Server non ti garantisce che i risultati siano ordinati... certo,
potresti essere fortunato e vederli ordinati, ma quello che devi capire
è che l'ordinamento non è garantito.
Perché? Perché in una vista la clausola ORDER BY serve solo ed
esclusivamente ad ordinare i dati per poi applicare la clausola TOP;
quindi determina *quali* dati saranno restituiti, ma non interviene nel
*come* i dati saranno restituiti.
--
David Martin
Il problema è sostanzialmente di retrocompatibilità (e di lentezza di ms).
Volendo rivedere la sintassi in un'ottica moderna la query:
SELECT TOP 50 ord.OrderID, ord.OrderDate
FROM Customers AS cus
INNER JOIN Orders AS ord
ON cus.CustomerID = ord.CustomerID
ORDER BY cus.CompanyName;
Dovrebbe estrarre 50 records (a caso) e ordinarli per cus.CompanyName.
SELECT TOP(50) over(order by cus.CompanyName), ord.OrderID, ord.OrderDate
FROM Customers AS cus
INNER JOIN Orders AS ord
ON cus.CustomerID = ord.CustomerID
Dovrebbe invece, e in modo disambiguo, estrarre i primi 50 records
secondo l'ordinamento cus.CompanyName e senza specifiche di ordinamento
sul resultset restituito.
Infine:
SELECT TOP(50) over(order by cus.CompanyName), ord.OrderID, ord.OrderDate
FROM Customers AS cus
INNER JOIN Orders AS ord
ON cus.CustomerID = ord.CustomerID
ORDER BY cus.CompanyName;
Dovrebbe estrarre i primi 50 records secondo l'ordinamento
cus.CompanyName e ordinati secondo tale campo.
Non sarebbe di per sé nemmeno tanto complesso passare alla nuova
sintassi (e la clausola over per top è una delle più spinte da Itzik Ben
Gan), ma per retrocompatibilità l'uso ambiguo di "order by" alla fine di
una "select top" dovremo trascinarcelo ancora per moltissimo tempo.
marc.
Una vista è sostanzialmente da usare come se fosse una tabella.
Quindi, così come una tabella non ha un ordinamento proprio ma devi
specificare tu l'ordine di estrazione (se ti serve un determinato
ordine), così in una vista sarà in fase di estrazione dalla vista che
dovrai specificare l'Order By, non all'interno della vista stessa.
Alberto
mm..
al di la' dell'aspetto semantico, che avrebbe sicuramente un senso,
imporrebbe un differenziale comunque interessante.. il fatto di dover prima
processare l'ORDER BY finale (che per definizione e' l'ultimo stage di una
proiezione, e Conor e' sistemico ed irremovibile su questo, ne discuteva
pochi giorni fa sulla mailing list privata MVP) per poi procedere in
definitiva al CROSS APPLY con il fork richiesto per il subset del nested
loop su Orders, in modo da poter discriminare a priori le righe di
cus.CustomerID = ord.CustomerID previste dal resultset finale...
diversamente il prodotto cartesiano della join potrebbe veramente essere
"ingombrante", come in effetti accade comunque a tutt'oggi, non credi? :)
saluti
--
Andrea Montanari (Microsoft MVP - SQL Server)
http://www.asql.biz
DbaMgr2k ver 0.21.1 - DbaMgr ver 0.65.1 and further SQL Tools
http://www.hotelsole.com - http://www.hotelsolericcione.de
--------- remove DMO to reply
Estiquaatsi dice "io letto attentamente parole di uomo bianco, ma
significato sfugge come salmone unto con olio di castoro"
:-)
Comunque, a parte gli scherzi, complimenti.