5

私は、 nvarchar値を適切なタイプに変換するためSELECTに使用CASEするaを実行しています。たとえば、次のようになります。

SELECT CASE 
    WHEN @propType = 'money' THEN convert(money, datavalue)
    [...]
    ELSE datavalue
END
FROM [...]

しかし、お金と等しくない場合でもconvert、常に実行されているようです。実行可能な例:@propType

declare @proptype nvarchar(50)= 'nvarchar'
declare @val nvarchar(10) = 'test'
select 
    case @proptype
        when 'money' then convert(money, @val)
        else @val
    end

これはなぜですか、どうすれば回避できますか?MSDNのドキュメントには次のように書かれています。

CASEステートメントは、その条件を順番に評価し、条件が満たされた最初の条件で停止します。場合によっては、CASEステートメントが式の結果を入力として受け取る前に、式が評価されます。これらの式の評価でエラーが発生する可能性があります。CASEステートメントのWHEN引数に表示される集計式は、最初に評価されてから、CASEステートメントに提供されます。たとえば、次のクエリでは、MAX集計の値を生成するときに、ゼロ除算エラーが生成されます。これは、CASE式を評価する前に発生します。

これが適切かどうかはわかりませんが、非ネイティブにとって言語はやや重いので、多分そうですか?

4

2 に答える 2

3

Transact SQL(T-SQL)でCASEまたはIF関数でCONVERT()を使用する場合は、次の点に注意してください。

最初の考えは、一般的に次のいずれかです。「評価される最初の値は数値であるため、10進数に変換され、他のすべてのデータも10進数であると予想されます」または「SQLServerが任意の値を変換できる場合指定されたタイプに変換すると、すべての値は変換されたタイプであることが期待されます。しかし、それは正しくありません(2番目は近いですが)!

実際の問題は、Caseステートメント内の任意の場所で値を変換することを選択した場合、値を変換するデータ型は、その型であるかどうかに関係なく、すべての値の期待される型であるということです。さらに、実際に変換できる値がない場合でも(コードのConvert行が実行されない場合でも)、すべての値は、Convert関数で指定されたタイプであることが期待されます。

于 2012-08-10T09:13:08.143 に答える
1

何が起こっているのかを明確にするために、then条項は評価されていません。

実行しても同じエラーが表示されます

SELECT CASE @proptype
         WHEN 'money' THEN $1.0 /*<-- Literal of datatype money*/
         ELSE @val
       END 

のドキュメントでCASEは、リターンタイプについて説明しています

の型のセット result_expressionsとオプションの。から最も優先度の高い型を返しますelse_result_expression。詳細については、「データ型の優先順位(Transact-SQL) 」を参照してください。

moneyデータ型の優先順位がより高いnvarcharため、else @valが評価されてからキャストされmoneyて失敗します。

sql_variant考えられる回避策の1つは、両方よりもデータの優先順位が高いため、キャストすることです。

declare @proptype nvarchar(50)= 'nvarchar'
declare @val nvarchar(10) = 'test'
select 
    case @proptype
        when 'money' then convert(money, @val)
        else cast(@val as SQL_VARIANT)
    end
于 2013-10-18T16:43:19.630 に答える