Як об'єднати числа та рядки для форматування чисел у 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 не є нульовим, тоді поверніть ActualWeight для "фактичної ваги / DIMS" або використовуйте Actual_Dims_Lenght, Width та Height.

Якщо це DIMS, то я хочу відформатувати висновок, який буде LenghtxWidhtxHeight (15x10x4). ActualWeight, Adcutal_Dims_Lenght, Width та Height - це все ціле (ціле) значення, але вихід для "Фактична вага / DIMS" повинен бути varchar (50).

Де я помиляюся?

спасибі

редагувати: Користувач може вибирати лише Вагу або DIMS на сторінці ASP.net, і якщо користувач обрав DIMS, він повинен надати довжину, ширину та висоту. Інакше це призведе до помилки на сторінці ASP.net. Я повинен турбуватися про це на стороні sql?

Відповіді:


211

Кілька швидких записок:

  • Це "довжина", а не "довжина"
  • Псевдоніми таблиці у вашому запиті, ймовірно, зробить його набагато читабельнішим

Тепер до проблеми ...

Потрібно явно перетворити свої параметри у VARCHAR, перш ніж намагатися їх об'єднати. Коли SQL Server бачить @my_int + 'X', він думає, що ви намагаєтеся додати число "X" до @my_int, і він не може цього зробити. Натомість спробуйте:

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
Ви завжди повинні вказати довжину варшара
Євген Рябцев

Дякую. Трохи пізно, але я додав параметри довжини.
Том Н

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

Ви повинні призначити цілі числа як рядкові, намагаючись об'єднати їх у варчар.

тобто

 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 пробілів, за якими слідує 1. CASTнасправді працює краще.
Тахір Хассан

2

Першими киньте цілі числа на varchar!


Саме так. Рядок 'x' повністю забиває безглузді int decls; в АДС немає арифметики.
bvj

2

Перед тим, як зробити конкатенацію рядків, потрібно КАСИТИ числові дані до рядків, наприклад, використовувати CAST(@Actual_Dims_Lenght AS VARCHAR)просто @Actual_Dims_Lenght, а не c.


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

Спробуйте вкинути вкладиші до 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 ... безпечніший спосіб

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.