Làm thế nào để kết hợp số và chuỗi để định dạng số trong T-SQL?


105

Tôi có chức năng sau

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

nhưng khi tôi cố gắng sử dụng nó, tôi gặp lỗi sau "Chuyển đổi không thành công khi chuyển đổi giá trị varchar 'x' thành kiểu dữ liệu int." khi tôi sử dụng câu lệnh chọn sau

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

Điều tôi muốn làm là nếu ActualWeight không rỗng thì hãy trả lại ActualWeight cho "Actual Weight / DIMS" hoặc nếu không thì sử dụng Actual_Dims_Lenght, Width và Height.

Nếu đó là DIMS thì tôi muốn định dạng đầu ra thành LenghtxWidhtxHeight (15x10x4). ActualWeight, Adcutal_Dims_Lenght, Width và Height đều là giá trị int (integer) nhưng đầu ra cho "Actual Weight / DIMS" phải là varchar (50).

Tôi hiểu sai ở đâu?

cảm tạ

chỉnh sửa: Người dùng chỉ có thể chọn Cân nặng hoặc DIMS trên trang ASP.net và nếu người dùng đã chọn DIMS thì họ phải cung cấp Chiều dài, Chiều rộng và Chiều cao. Nếu không, nó sẽ gây ra lỗi trên trang ASP.net. Tôi có nên lo lắng về nó ở phía sql không?

Câu trả lời:


211

Một vài lưu ý nhanh:

  • Đó là "chiều dài" không phải "chiều dài"
  • Bí danh bảng trong truy vấn của bạn có thể làm cho nó dễ đọc hơn nhiều

Bây giờ vào vấn đề ...

Bạn cần chuyển đổi rõ ràng các tham số của mình thành VARCHAR trước khi cố gắng nối chúng. Khi SQL Server nhìn thấy @my_int + 'X', nó nghĩ rằng bạn đang cố thêm số "X" vào @my_int và nó không thể làm điều đó. Thay vào đó hãy thử:

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
Bạn nên luôn luôn xác định độ dài của một varchar: sqlblog.com/blogs/aaron_bertrand/archive/2009/10/09/...
Eugene Ryabtsev

Cảm ơn. Hơi muộn, nhưng tôi đã thêm các tham số độ dài.
Tom H

53

Nếu bạn đang sử dụng SQL Server 2012+, bạn có thể sử dụng hàm CONCAT trong đó chúng tôi không phải thực hiện bất kỳ chuyển đổi rõ ràng nào

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

Tôi đã xem một số tuyên bố hoạt động CONCAT()nhanh hơn CAST(). Các nguồn đáng tin cậy về các nghiên cứu hiệu suất sẽ rất hữu ích.
Codes với Hammer

Tôi sẽ không ngạc nhiên nếu nó có thể đo lường được trong một điểm chuẩn, nhưng tôi sẽ rất ngạc nhiên nếu nó tạo ra bất kỳ tác động nào trong các truy vấn thông thường. Bạn sẽ phải có một số lượng phôi rất lớn để át đi thời gian hoạt động bình thường.
SilverbackNet

8

Thay đổi điều này:

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

Về điều này:

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));

Thay đổi điều này:

SET @ActualWeightDIMS = @ActualWeight;

Về điều này:

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

Bạn cần sử dụng CAST. Tìm hiểu tất cả về CAST và CONVERT tại đây , vì kiểu dữ liệu rất quan trọng!



4

Bạn phải ép kiểu các số nguyên của mình dưới dạng chuỗi khi cố gắng nối chúng vào một varchar.

I E

 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));

Trong SQL Server 2008, bạn có thể sử dụng STRchức năng:

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

2
Hàm STR theo mặc định đệm số thành 10 ký tự để nó thêm vô số khoảng trắng. Ví dụ: STR(1)cho tôi 9 khoảng trắng theo sau 1. CASTthực sự hoạt động tốt hơn.
Tahir Hassan

2

Truyền các số nguyên tới varchar trước!


Chính xác. Chuỗi 'x' hoàn toàn đóng băng int decls vô nghĩa; không có số học trong UDF.
bvj

2

Bạn cần ĐÚC dữ liệu số của mình thành chuỗi trước khi bạn thực hiện nối chuỗi, vì vậy, ví dụ: sử dụng CAST(@Actual_Dims_Lenght AS VARCHAR)thay vì chỉ @Actual_Dims_Lenght& c.


2

Tôi đã thử truy vấn dưới đây, nó hoạt động chính xác với tôi

 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

Thử truyền các int sang varchar, trước khi thêm chúng vào một chuỗi:

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

Có khả năng bạn có thể kết thúc với Số khoa học khi bạn chuyển đổi Số nguyên thành Str ... cách an toàn hơn là

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.