T-SQLで数値と文字列を連結して数値をフォーマットする方法


105

以下の機能があります

ALTER FUNCTION [dbo].[ActualWeightDIMS]
(
    -- Add the parameters for the function here
    @ActualWeight int,
    @Actual_Dims_Lenght int,
    @Actual_Dims_Width int,
    @Actual_Dims_Height int
)
RETURNS varchar(50)
AS
BEGIN

DECLARE @ActualWeightDIMS varchar(50);
--Actual Weight
     IF (@ActualWeight is not null) 
          SET @ActualWeightDIMS = @ActualWeight;
--Actual DIMS
     IF (@Actual_Dims_Lenght is not null) AND 
          (@Actual_Dims_Width is not null) AND (@Actual_Dims_Height is not null)
          SET @ActualWeightDIMS= @Actual_Dims_Lenght + 'x' + @Actual_Dims_Width + 'x' + @Actual_Dims_Height;


     RETURN(@ActualWeightDIMS);

END

しかし、使用しようとすると、「varchar値 'x'をデータ型intに変換するときに変換に失敗しました」というエラーが発生しました。次のselectステートメントを使用すると

select 
 BA_Adjustment_Detail.ID_Number [ID_Number],
 BA_Adjustment_Detail.Submit_Date [Submit_Date],
 BA_Category.Category [category],
 BA_Type_Of_Request.Request [Type_Of_Request],
 dbo.ActualWeightDIMS(BA_Adjustment_Detail.ActualWeight,BA_Adjustment_Detail.Actual_Dims_Lenght,BA_Adjustment_Detail.Actual_Dims_Width,BA_Adjustment_Detail.Actual_Dims_Height) [Actual Weight/DIMS],
 BA_Adjustment_Detail.Notes [Notes],
 BA_Adjustment_Detail.UPSCustomerNo [UPSNo],
 BA_Adjustment_Detail.TrackingNo [AirbillNo],
 BA_Adjustment_Detail.StoreNo [StoreNo],
 BA_Adjustment_Detail.Download_Date [Download_Date],
 BA_Adjustment_Detail.Shipment_Date[ShipmentDate],
 BA_Adjustment_Detail.FranchiseNo [FranchiseNo],
 BA_Adjustment_Detail.CustomerNo [CustomerNo],
 BA_Adjustment_Detail.BillTo [BillTo],
 BA_Adjustment_Detail.Adjustment_Amount_Requested [Adjustment_Amount_Requested]
from BA_Adjustment_Detail
inner join BA_Category 
on BA_Category.ID = BA_Adjustment_Detail.CategoryID
inner join BA_Type_Of_Request
on BA_Type_Of_Request.ID = BA_Adjustment_Detail.TypeOfRequestID

私がしたいのは、ActualWeightがnullでない場合、「実際の重量/ DIMS」のActualWeightを返すか、Actual_Dims_Lenght、Width、およびHeightを使用することです。

DIMSの場合、出力をLenghtxWidhtxHeight(15x10x4)にフォーマットします。ActualWeight、Adcutal_Dims_Lenght、Width、およびHeightはすべてint(整数)値ですが、「実際の重量/ DIMS」の出力はvarchar(50)になります。

どこで間違っているのですか?

感謝

編集:ユーザーはASP.netページで重量またはDIMSのいずれかを選択できます。ユーザーがDIMSを選択した場合、長さ、幅、高さを指定する必要があります。そうしないと、ASP.netページでエラーがスローされます。SQL側で心配する必要がありますか?

回答:


211

いくつかの簡単なメモ:

  • 「長さ」ではなく「長さ」
  • クエリのテーブルエイリアスはおそらくそれをはるかに読みやすくします

今問題に...

パラメーターを連結する前に、パラメーターを明示的にVARCHARに変換する必要があります。SQL Serverが@my_int + 'X'を検出すると、@ my_intに数値「X」を追加しようとしていると見なし、それを実行できません。代わりに:

SET @ActualWeightDIMS =
     CAST(@Actual_Dims_Lenght AS VARCHAR(16)) + 'x' +
     CAST(@Actual_Dims_Width  AS VARCHAR(16)) + 'x' +
     CAST(@Actual_Dims_Height  AS VARCHAR(16))

6
:あなたは、常にvarchar型の長さを指定する必要がありsqlblog.com/blogs/aaron_bertrand/archive/2009/10/09/...
ユージンRyabtsev

ありがとう。少し遅れましたが、長さパラメータを追加しました。
トムH

53

使用している場合は、SQL Serverを2012+を使用できCONCATの我々はすべての明示的な変換を行う必要はありませんした関数を

SET @ActualWeightDIMS = Concat(@Actual_Dims_Lenght, 'x', @Actual_Dims_Width, 'x' 
                        , @Actual_Dims_Height) 

私はCONCAT()、よりも速く実行されるいくつかの主張に遭遇しましたCAST()。パフォーマンス調査の信頼できる情報源は有用でしょう。
Hammerを使用したコード

ベンチマークで測定可能だったとしても驚くことはありませんが、通常のクエリに影響を与えたとしても非常に驚くことでしょう。通常の操作時間を使い果たすには、膨大な数のキャストが必要です。
SilverbackNet

8

これを変える:

SET @ActualWeightDIMS= @Actual_Dims_Lenght + 'x' + 
    @Actual_Dims_Width + 'x' + @Actual_Dims_Height;

これに:

SET @ActualWeightDIMS= CAST(@Actual_Dims_Lenght as varchar(3)) + 'x' + 
    CAST(@Actual_Dims_Width as varchar(3)) + 'x' + 
    CAST(@Actual_Dims_Height as varchar(3));

これを変える:

SET @ActualWeightDIMS = @ActualWeight;

これに:

SET @ActualWeightDIMS = CAST(@ActualWeight as varchar(50));

CASTを使用する必要があります。データ型が重要であるため、ここでCASTとCONVERTについてすべて学んでください。



4

整数をvarcharに連結しようとするときは、整数を文字列としてキャストする必要があります。

すなわち

 SELECT  @ActualWeightDIMS = CAST(@Actual_Dims_Lenght AS varchar(10)) 
                              + 'x' + 
                             CAST(@Actual_Dims_Width as varchar(10)) 
                             + 'x' + CAST(@Actual_Dims_Height as varchar(10));

SQL Server 2008では、次のSTR関数を使用できます。

   SELECT  @ActualWeightDIMS = STR(@Actual_Dims_Lenght) 
                              + 'x' + STR(@Actual_Dims_Width) 
                              + 'x' + STR(@Actual_Dims_Height);

2
STR関数は、デフォルトで数値を10文字に埋め込むため、大量のスペースが追加されます。たとえばSTR(1)、9つのスペースの後に1CAST実際にうまくいきます。
Tahir Hassan

2

最初に整数をvarcharにキャストしてください!


丁度。文字列 'x'は、無意味なint declsを完全にハンマーします。UDFには演算がありません。
bvj 14

2

文字列の連結を行う前に、数値データを文字列にキャストする必要があるため、たとえば、&​​cのCAST(@Actual_Dims_Lenght AS VARCHAR)代わりに使用し@Actual_Dims_Lenghtます。


2

私はそれが私のためにうまくいく以下のクエリを試しました

 with cte as(

   select ROW_NUMBER() over (order by repairid) as'RN', [RepairProductId] from [Ws_RepairList]
  )
  update CTE set [RepairProductId]= ISNULL([RepairProductId]+convert(nvarchar(10),RN),0) from cte

1

文字列に追加する前に、intをvarcharにキャストしてみてください。

SET @ActualWeightDIMS = cast(@Actual_Dims_Lenght as varchar(8)) + 
   'x' + cast(@Actual_Dims_Width as varchar(8)) + 
   'x' + cast(@Actual_Dims_Height as varhcar(8))

1

IntegerをStrに変換すると、Scientific Numberになる可能性があります...より安全な方法は

SET @ActualWeightDIMS = STR(@Actual_Dims_Width); OR Select STR(@Actual_Dims_Width) + str(@Actual_Dims_Width)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.