2011-06-29 16 views
8

SQL Server 2005で条件付き注文を含むときに破損しているSQLクエリがあります。私は注文を削除すると、クエリが機能します。条件(例:p.Descriptionによる注文)によって注文を明示的に書くと、それは機能します。で条件付き注文を含めると、エラーが表示されます。SQL Serverの条件付き注文者

'Conversion failed when converting character string to smalldatetime data type' 

SQL Serverはこのエラーの原因となったコード行を表示していません。私はどのように私は条件付きの順序を使用するか、変換で失敗している列のトラブルシューティングをすることができますこれを修正することができますかと思います。

declare @SearchTerm nvarchar(255) 
declare @SortBy nvarchar(255) 
declare @Months int 
declare @VendorID int 
declare @ProductID int 

set @SearchTerm = 'focus' 
set @SortBy = 'product' 
set @Months = 3 
set @VendorID = null 
set @ProductID = null 

-- This makes it so the @Month will filter by n number of months ago. 
declare @PreviousMonths datetime 
if @Months is null 
    begin 
     set @PreviousMonths = 24 
    end 
else 
    begin 
     set @PreviousMonths = DateAdd(month, [email protected], GetDate()) 
    end 

select 
    a.dsAlertID as AlertID, 
    a.ProductID, 
    v.VendorID, 
    p.Description as ProductName, 
    v.LongName as VendorName, 
    a.Introduction, 
    a.Writeup, 
    a.DateAdded 
from 
    ev_ds_Alerts a 
left outer join 
    tblProducts p on a.ProductID = p.ProductID 
left outer join 
    tblVendors v on v.VendorID = p.VendorID 
where 
    (@SearchTerm is null or (a.Writeup like '% ' + @SearchTerm + '%' or a.Introduction like '% ' + @SearchTerm + '%')) 
    and ((@Months is null) or (@Months is not null and a.DateAdded >= @PreviousMonths)) 
    and ((@VendorID is null) or (@VendorID is not null and v.VendorID = @VendorID)) 
    and ((@ProductID is null) or (@ProductID is not null and p.ProductID = @ProductID)) 
order by 
    case @SortBy 
     when 'product' then p.Description 
     when 'vendor' then v.LongName 
     else a.DateAdded 
    end 

-- order by p.Description or v.LongName works when explicitly writing them out! 
+0

'CAST'を使用するee –

+0

データ型キャストエラーを避けるために独立したcase文を作成する –

答えて

15

、試してください:MM:SS

order by case @SortBy when 'product' then p.Description when 'vendor' then v.LongName else convert(VARCHAR(25),a.DateAdded,20)

それは日付文字列YYYY-MM-DD HHがフォーマットされますので、これは、あなたが必要なものを与える必要があります。

+1

+1一貫性のある注文を維持するために、日付をyyyy-mm-dd hh:mm:ssと書式設定することを覚えていました。 –

+0

これはまさに私がする必要があったものでした。どうもありがとうございます! – Halcyon

6

ORDER BYCASE式を使用して - データ型は常に同じでなければなりません戻りました。

INT、DATETIME、VARCHARなど、動的SQLや何らかの形式の決定ロジック(IE:IF)を使用せずに、さまざまなクエリをブレークアウトすることはできません。

この例では、CAST/CONVERTを使用して、DATETIMEデータ型を適切なVARCHARに変更できます。しかし、あなたがを知っていないと、なぜの問題が起こっているのでしょうか、あなたは将来それをやり直す可能性が高いです。前の回答パー

+0

意味があります。どのようなケースの表現を使用して適切な回避策ですか? – Halcyon

+0

@Halcyon:「IF」を使用して、個別のクエリまたは動的SQLのデータ型処理を打ち切ります。 –

+0

優れた説明ですが、OPが注文をどのように実行できるかは説明していません。 @Neilと@gibeathによると:キャスティング。 –

1

オーダーする列のリスト内のNULLは無視されますので、タイプ別に分割することができます。

ORDER BY 
    CASE 
     WHEN @SortBy = 'product' THEN p.Description 
     WHEN @SortBy = 'vendor' THEN v.LongName 
    END 
    , 
    CASE WHEN @SortBy NOT IN ('product', 'vendor') THEN cda.StartDate END 

可能であれば最後の醜いビットです。

CASE WHEN @SortBy = '' THEN cda.StartDate END  
+0

私はあなたの答えから2番目のケースを削除し、単にStartDateを追加することができると思います。最初のケースでは、スペースをデフォルトにするためにelseを使用します。私のコードを参照してください – niktrs

+0

実際には、それはいつも日付の順序を(他の順序の後に)必要とするかもしれないし、必要でないかもしれないということです –

11

あなたは、各データ型の1ケースを使用することができます:あなたは、パフォーマンスを気にする場合は、別のアプローチが必要になる場合があります

order by 
    case @SortBy 
    when 'product' then p.Description 
    when 'vendor' then v.LongName 
    else '' 
    end, 
    case @SortBy 
    when 'added' then a.DateAdded 
    else '1980-01-01' 
    end 
+0

+1。私はあなたの答えを見ていないと私は何かを似て書かれている – niktrs

0

: 1.インラインTVF 2にあなたの選択を包みます。 2つの異なるプランを使用して、2つのプランを得ることができます.1つのプランの一般的なプランよりも効率的です。

IF @SortBy='product' BEGIN 
    SELECT AlertID, 
(snip) 
    FROM MyTvf 
    ORDER BY Description ; 
    RETURN @@ERROR ; 
END 

IF @SortBy='Vendor' BEGIN 
    SELECT AlertID, 
(snip) 
    FROM MyTvf 
    ORDER BY LongName ; 
    RETURN @@ERROR ; 
END 
+0

誰もdownvoted、あなたは精巧に気をつけますか? –

+0

これは考慮すべき良いアドバイスです。 – TTT