sql - Table-Valued function - Order by is ignored in output -
we moving sql server 2008 sql server 2012 , noticed our table-valued functions no longer deliver temp table contents in correctly sorted order.
code:
insert @customer select customer_id, name, case when expiry_date < getdate() 1 when expired = 1 1 else 0 end customer **order name** in sql server 2008 function returns customers sorted name. in sql server 2012 returns table unsorted. "order by" ignored in sql 2012.
do have re-write functions include sort_id , sort them when called in main application or there easy fix??
there 2 things wrong original approach.
- on inserting table never guaranteed
order byoninsert ... select ... order byorder rows inserted. - on selecting sql server not guarantee
selectwithoutorder byreturn rows in particular order such insertion order anyway.
in 2012 looks though behaviour has changed respect item 1. ignores order by on select statement source insert
declare @t table(number int) insert @t select number master..spt_values order name 2008 plan

2012 plan

the reason change of behaviour in previous versions sql server produced 1 plan shared between executions set rowcount 0 (off) , set rowcount n. sort operator there ensure correct semantics in case plan run session non 0 rowcount set. top operator left of rowcount top.
sql server 2012 produces separate plans 2 cases there no need add these rowcount 0 version of plan.
a sort may still appear in plan in 2012 if select has explicit top defined (other top 100 percent) still doesn't guarantee actual insertion order of rows, plan might have sort after top n established rows clustered index order example.
for example in question adjust calling code specify order name if requires.
regarding sort_id idea ordering guarantees in sql server guaranteed when inserting table identity order these allocated per order by
declare @customer table ( sort_id int identity primary key, customer_id int, name int, expired bit ) insert @customer select customer_id, name, case when expiry_date < getdate() 1 when expired = 1 1 else 0 end customer order name but still need order sort_id in selecting queries there no guaranteed ordering without (perhaps sort_id approach might useful in case original columns used ordering aren't being copied table variable)
Comments
Post a Comment