0

これは私のストアドプロシージャです

 [sp_Get_Data]
   (
   @IdParam INT, 
   @OrderBy varchar(50),
   @Direc varchar(4),
   )
 AS
 BEGIN
select 
   [LogID] //int
  ,[Address]   //varchar
  ,[State]    //varchar
  ,[City]
  ,[Zip]
  FROM LogData 
WHERE IdParam = LogID
order by 

  CASE @Direc 
    WHEN 'desc' THEN  
    CASE @OrderBy 
        WHEN 'LogID' THEN LogID 
        WHEN 'Address' THEN Address
        END 
    END 
    DESC, 
CASE @Direc 
    WHEN 'asc' THEN              
    CASE @OrderBy 
        WHEN 'LogID' THEN LogID 
        WHEN 'Address' THEN Address
        END 
    END 

EXEC [sp_Get_Data] @IdParam ='..' @OrderBy = 'LogID', @Direc = 'asc'   // WORKS FINE
EXEC [sp_Get_Data] @IdParam ='..' @OrderBy = 'Address', @Direc = 'asc'

エラー:

varchar 値 'xyz' をデータ型 int に変換するときに変換に失敗しました。

この動的パラメーターを使用して並べ替えを行う代わりに、合格した場合

ORDER BY Address ASC ....

これは機能します。

ここで欠けている非常に基本的なものはありますか?

4

2 に答える 2

2

CASE の戻り値の型は同じでなければなりません。最初の例では、アドレスに到達しないため、機能します。ただし、「アドレス」については、int である LogId と同じであることが期待されます。したがって、変換は失敗します。

注:タイプに 変換LogIdするとVARCHAR、エラーが数値としてソートbut it would not give you correct orderingされます。したがって、RIGHT関数を使用して次のように取り組みます

RIGHT(REPLICATE('0',11) + CONVERT(VARCHAR(50),LogID), 12)

ここにデモがあります)

SELECT * FROM T
ORDER BY 
   CASE @Direc 
    WHEN 'desc' THEN  
    CASE @OrderBy 
        WHEN 'LogID' THEN RIGHT (REPLICATE('0',11) + CONVERT(VARCHAR(50),LogID), 12)
        WHEN 'Address' THEN Address
        END 
    END 
    DESC, 
CASE @Direc 
    WHEN 'asc' THEN              
    CASE @OrderBy 
        WHEN 'LogID' THEN RIGHT (REPLICATE('0',11) + CONVERT(VARCHAR(50),LogID), 12)
        WHEN 'Address' THEN Address
        END 
    END 
于 2013-01-24T19:37:34.987 に答える
1

問題は、最初の実行 ( を使用LogID) が を使用して実行計画を生成したことINTです。2 番目の呼び出しが実行されたときに、プリコンパイル済みの実行プランでデータ変換例外が発生しました。

1 つの解決策は、常に同じデータ型に遭遇するように型にキャストLogIDすることです。VARCHAR

(...)

CASE @Direc 
WHEN 'desc' THEN  
CASE @OrderBy 
    WHEN 'LogID' THEN CONVERT(VARCHAR(50), LogID)
    WHEN 'Address' THEN Address
    END 
END 
DESC, 
CASE @Direc 
WHEN 'asc' THEN              
CASE @OrderBy 
    WHEN 'LogID' THEN CONVERT(VARCHAR(50), LogID)
    WHEN 'Address' THEN Address
    END 
END 

(...)

しかし、通常、この種の操作 ( ORDER BY) はアプリケーション側で行われます... ただし、そのような方法でパフォーマンスが大幅に向上することを正当化できない場合は除きます。私はあなたが何をしているのか知っていることを確認したいだけです。

注: をOPTION (RECOMPILE)使用せずに、ストアド プロシージャの最後で使用することもできますCONVERT。これは、使用するたびに実行プランが再コンパイルされるためです。このすべての微調整を使用する代わりに、各実行後にストアド プロシージャを再コンパイルする方がCONVERT/ RIGHT/要求が少なくなる可能性がありREPLICATEます。わかるでしょ。

于 2013-01-24T19:33:56.213 に答える