元のアプローチには 2 つの問題がありました。
- テーブルへの挿入時に、行が実際に挿入された順序になること
ORDER BY
は保証されませんでした。INSERT ... SELECT ... ORDER BY
- そこから選択した場合、SQL Server は、挿入順序などの特定の順序で行が返されること
SELECT
を保証しません。ORDER BY
2012 年には、項目 1 に関して動作が変更されたように見えます。現在は、通常ORDER BY
、SELECT
ステートメントのソースであるステートメントを無視しています。INSERT
DECLARE @T TABLE(number int)
INSERT INTO @T
SELECT number
FROM master..spt_values
ORDER BY name
2008年計画

2012年計画

動作が変更された理由は、以前のバージョンの SQL Server では、SET ROWCOUNT 0
(off) とSET ROWCOUNT N
. ソート演算子は、プランがゼロ以外のROWCOUNT
セットでセッションによって実行された場合に正しいセマンティクスを保証するためだけにありました。そのTOP
左側の演算子はROWCOUNT TOP
.
ROWCOUNT 0
SQL Server 2012 では、2 つのケースに対して個別の計画が作成されるようになったため、これらを計画のバージョンに追加する必要はありません。
SELECT
が明示的にTOP
定義されている場合 ( 以外) 、2012 年の計画にも並べ替えが表示されることがありますが、それでも行TOP 100 PERCENT
の実際の挿入順序は保証されません。TOP N
たとえば、インデックス順。
あなたの質問の例では、呼び出しコードを調整して、ORDER BY name
それが必要かどうかを指定します。
SQL Server での順序付けの保証sort_id
からのアイデアに関しては、テーブルに挿入するときに、これらが割り当てられる順序が次のとおりになることが保証されているので、次のこともできます。IDENTITY
ORDER BY
DECLARE @Customer TABLE (
Sort_Id INT IDENTITY PRIMARY KEY,
Customer_ID INT,
Name INT,
Expired BIT )
INSERT INTO @Customer
SELECT Customer_ID,
Name,
CASE
WHEN Expiry_Date < Getdate() THEN 1
WHEN Expired = 1 THEN 1
ELSE 0
END
FROM Customer
ORDER BY Name
ただし、それsort_id
なしでは順序付けが保証されないため、選択クエリで順序付けする必要があります (おそらくsort_id
、順序付けに使用される元の列がテーブル変数にコピーされていない場合に、このアプローチが役立つ場合があります)。