0

私の質問は、動的クエリを使用してデータを取得するときに、出力の順序が確実に維持されるようにする方法です。利用している動的クエリがいくつかありますが、同じクエリを異なるマシンで実行すると、出力が異なる順序で取得されることに気付きました。現在、出力の順序がローカル マシンと同じであると仮定する一時テーブルに出力されたデータを保存しますが、本番環境ではすべて切り替えられます。クエリが実行されるたびに出力の順序が維持されるように、これをさらに制御するにはどうすればよいですか?

動的クエリで Order BY を使用すると、エラーが発生します

メッセージ 1033、レベル 15、状態 1、行 18 ORDER BY 句は、TOP、OFFSET、または FOR XML も指定されていない限り、ビュー、インライン関数、派生テーブル、サブクエリ、および共通テーブル式では無効です。

 DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX)

           IF EXISTS
                (
                            SELECT *
                            FROM tempdb.dbo.sysobjects
                            WHERE ID = OBJECT_ID(N'tempdb..#ibutes')
                )
                BEGIN
                            DROP TABLE #ibutes
                END
    Create table #ibutes
    (
                ProductID uniqueIdentifier,
            PAID uniqueidentifier, 
            Label nvarchar(50),
            Val nvarchar(3072),
            unit nvarchar(50) 
    )
    ;With Number
As
(
 Select 1 as rownum union all  Select 2 union all Select 3 union all Select 4 union all Select 5 union all Select 6 union all Select 7 union all Select 8 union all Select 9 union all Select 10 union all Select 11 union all Select 12 union all Select 13 union all Select 14 union all Select 15 union all Select 16 union all Select 17 union all Select 18 union all Select 19 union all Select 20 union all Select 21 
),
ProductDetail 
as 
(
   select P.ProdID, N.rownum from IDWProduct P cross join Number N
)
Insert into #ibutes
Select ProdID ,  PAVibuteID, COALESCE(PANAme,''), COALESCE(PAVValue,''), COALESCE(unitLabel,'') 
 from ProductDetail P
Left join 
(select Pr.*, PAName, row_number() over (partition by PAVProductID order by PAVID) as Rn from IDWProductibuteValues Pr  
inner join IDWibutes  on PAID = PAVibuteID Where PAIscustom = 0 AND PAIsManufacturerSpecific =0 AND PANAME NOT IN 
('Brand Name', 'Standard', 'Application', 'Sub Brand', 'Type', 'Special Features')) 
Pr ON rownum = Pr.Rn And PAVProductID = ProdID  
left join IDWUnitofMeasures on Pr.PAVunit = unitID 

--Select * from #ibutes

   select @colsUnpivot = stuff((select ','+quotename(C.name)
         from tempdb.sys.columns as C  
         where C.object_id = object_id('tempdb..#ibutes')  AND  C.name Not in ('ProductID')
         for xml path('')), 1, 1, '')

 --select @colsUnpivot

 select @colsPivot = STUFF((SELECT  ','  + quotename(c.name   + cast(t.rn as varchar(10)))
                    from
                    (
                      select row_number() over(partition by ProductID   order by ProductID) rn  from #ibutes
                    ) t
                     cross apply 
                      tempdb.sys.columns  as C
                   where C.object_id = object_id('tempdb..#ibutes')   AND  C.name Not in ('ProductID')
                   group by c.name, t.rn
                   order by t.rn
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

  --select @colsPivot
  set @query = 'select *
      from
      (
        select ProductID,
            col + cast(rn as varchar(10)) new_col,
            val
        from 
        (
          select   
           Cast (PAID as NVarchar(3072)) PAID
           ,Cast (ProductID as NVarchar(3072)) ProductID
           ,Cast (Label  as NVarchar(3072)) Label
           ,Cast (Val as NVarchar(3072)) Val
           ,Cast (unit as NVarchar(3072))  unit  
            ,row_number() over(partition by ProductID order by ProductID) rn
          from #ibutes

     ) x
        unpivot
        (
          val
          for col in ('+ @colsunpivot +')
        ) u
      ) x1
      pivot
      (
        max(val)
        for new_col in
          ('+ @colspivot +')
      ) p'

exec(@query)    

クエリの実行結果

ローカル/開発マシンで

========================

select *
      from
      (
        select ProductID,
            col + cast(rn as varchar(10)) new_col,
            val
        from 
        (
          select   
       Cast (PAID as NVarchar(3072)) PAID
       ,Cast (ProductID as NVarchar(3072)) ProductID
           ,Cast (Label  as NVarchar(3072)) Label
           ,Cast (Val as NVarchar(3072)) Val
           ,Cast (unit as NVarchar(3072))  unit  
            ,row_number() over(partition by ProductID order by ProductID) rn
          from #ibutes
     ) x
        unpivot
        (
          val
          for col in ([Label],[unit],[Val],[PAID])
        ) u
      ) x1
      pivot
      (
        max(val)
        for new_col in
          ([Label1],[unit1],[Val1],[PAID1],[Label2],[unit2],[Val2],[PAID2],[Label3],[unit3],[Val3],[PAID3],[Label4],[unit4],[Val4],[PAID4],[Label5],[unit5],[Val5],[PAID5],[Label6],[unit6],[Val6],[PAID6],[Label7],[unit7],[Val7],[PAID7],[Label8],[unit8],[Val8],[PAID8],[Label9],[unit9],[Val9],[PAID9],[Label10],[unit10],[Val10],[PAID10],[Label11],[unit11],[Val11],[PAID11],[Label12],[unit12],[Val12],[PAID12],[Label13],[unit13],[Val13],[PAID13],[Label14],[unit14],[Val14],[PAID14],[Label15],[unit15],[Val15],[PAID15],[Label16],[unit16],[Val16],[PAID16],[Label17],[unit17],[Val17],[PAID17],[Label18],[unit18],[Val18],[PAID18],[Label19],[unit19],[Val19],[PAID19],[Label20],[unit20],[Val20],[PAID20],[Label21],[unit21],[Val21],[PAID21])
      ) p 

ただし、生産機械では異なります。の順序の変更に注意してください

select *
      from
      (
        select ProductID,
            col + cast(rn as varchar(10)) new_col,
            val
        from 
        (
          select   
       Cast (PAID as NVarchar(3072)) PAID
       ,Cast (ProductID as NVarchar(3072)) ProductID
           ,Cast (Label  as NVarchar(3072)) Label
           ,Cast (Val as NVarchar(3072)) Val
           ,Cast (Unit as NVarchar(3072))  Unit  
            ,row_number() over(partition by ProductID order by ProductID) rn
          from #ibutes
     ) x
        unpivot
        (
          val
          for col in ([PAID],[Label],[Val],[Unit])
        ) u
      ) x1
      pivot
      (
        max(val)
        for new_col in
          ([PAID1],[Label1],[Val1],[Unit1],[PAID2],[Label2],[Val2],[Unit2],[PAID3],[Label3],[Val3],[Unit3],[PAID4],[Label4],[Val4],[Unit4],[PAID5],[Label5],[Val5],[Unit5],[PAID6],[Label6],[Val6],[Unit6],[PAID7],[Label7],[Val7],[Unit7],[PAID8],[Label8],[Val8],[Unit8],[PAID9],[Label9],[Val9],[Unit9],[PAID10],[Label10],[Val10],[Unit10],[PAID11],[Label11],[Val11],[Unit11],[PAID12],[Label12],[Val12],[Unit12],[PAID13],[Label13],[Val13],[Unit13],[PAID14],[Label14],[Val14],[Unit14],[PAID15],[Label15],[Val15],[Unit15],[PAID16],[Label16],[Val16],[Unit16],[PAID17],[Label17],[Val17],[Unit17],[PAID18],[Label18],[Val18],[Unit18],[PAID19],[Label19],[Val19],[Unit19],[PAID20],[Label20],[Val20],[Unit20],[PAID21],[Label21],[Val21],[Unit21])
      ) p

順序がアルファベット順のように見える違いに注意してください。

[Label1]、[unit1]、[Val1]、[PAID1]、[Label2]、[unit2]。 . . .

本番マシンでは、そうではありません

[PAID1]、[Label1]、[Val1]、[Unit1]、[PAID2]、[Label2]、[Val2]、[Unit2]、.. . . .

4

7 に答える 7

1

明白な答えはただ一つだと思います。order by動的クエリで句を使用します。

于 2012-10-14T17:51:09.807 に答える
1

簡単に言えば、動的であるかどうかにかかわらず、すべてのクエリが異なるマシンで同じ結果になるとは限りません!
結果の順序が重要な場合は、ORDER BY

例えば:

SELECT *
FROM TBL
ORDER BY FIRSTNAME
于 2012-10-14T17:51:16.130 に答える
1

順序が必要な場合は、order by を使用します。
による注文がない場合、注文は保証されません。
同点の場合、ソートが同点で繰り返される保証はありません。
十分な列を使用して、ネクタイはありません。

行ではなく列の順序を参照しているようです。

* を選択すると、テーブルで定義されている順序で列が表示されます。
列の順序を制御する必要がある場合は、* を使用しないでください。

select table1.col4, table1.col2 
from table1
于 2012-10-14T17:51:45.080 に答える
0

これを試すことができるかもしれません

'select *
  from
  (
    select ProductID,
        col + cast(rn as varchar(10)) new_col,
        val
    from 
    (
      select top 100 percent
       Cast (PAID as NVarchar(3072)) PAID
       ,Cast (ProductID as NVarchar(3072)) ProductID
       ,Cast (Label  as NVarchar(3072)) Label
       ,Cast (Val as NVarchar(3072)) Val
       ,Cast (unit as NVarchar(3072))  unit  
        ,row_number() over(partition by ProductID order by ProductID) rn
      from #ibutes
      order by row_number() over(partition by ProductID order by ProductID) asc
 ) x
    unpivot
    (
      val
      for col in ('+ @colsunpivot +')
    ) u
  ) x1
  pivot
  (
    max(val)
    for new_col in
      ('+ @colspivot +')
  ) p'
于 2012-10-14T18:21:29.900 に答える
0

以下を変更してみませんか。

set @query = 'select *
      from

のようなものに

set @query = 'select *
      into #x
      from

#x動的SQLの前に明示的に作成する必要があります。

create table #x
(
blah int,
blah char(8)
)

次に、execステートメントの後にさらにクエリを実行します

select *
from #x
order by whatever 
于 2012-10-14T19:33:37.583 に答える
0

ORDER BY を追加する場所がわかったので、答えはより明確になります。結果が @colsPivot に挿入されるクエリを並べ替えようとしていますが、それが問題です。

ORDER BY は主に最終結果の順序付けに使用されるため、最終クエリ (動的クエリ) で使用する必要があります。
これに対する例外は、「制限」クエリ (TOP 10 など) の一部として使用される場合です。

動的クエリに ORDER BY を追加してみて、うまくいったかどうかお知らせください。

于 2012-10-14T18:37:51.803 に答える