Come concatenare numeri e stringhe per formattare numeri in T-SQL?


105

Ho la seguente funzione

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

ma quando ho provato a usarlo, ho ricevuto il seguente errore "Conversione non riuscita durante la conversione del valore varchar 'x' nel tipo di dati int." quando uso la seguente istruzione 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

Quello che voglio fare è che se ActualWeight non è nullo, restituire ActualWeight per "Actual Weight / DIMS" oppure utilizzare Actual_Dims_Lenght, Width e Height.

Se è DIMS, desidero formattare l'output in modo che sia LenghtxWidhtxHeight (15x10x4). ActualWeight, Adcutal_Dims_Lenght, Width e Height sono tutti valori int (numero intero) ma l'output per "Actual Weight / DIMS" dovrebbe essere varchar (50).

Dove sto sbagliando?

grazie

modifica: l'utente può scegliere solo Peso o DIMS sulla pagina ASP.net e se l'utente ha selezionato DIMS, deve fornire Lunghezza, Larghezza e Altezza. Altrimenti genererà un errore nella pagina ASP.net. Dovrei preoccuparmene sul lato sql?

Risposte:


211

Un paio di brevi note:

  • È "length" non "lenght"
  • Gli alias di tabella nella tua query probabilmente la renderebbero molto più leggibile

Ora sul problema ...

È necessario convertire esplicitamente i parametri in VARCHAR prima di provare a concatenarli. Quando SQL Server vede @my_int + 'X', pensa che tu stia cercando di aggiungere il numero "X" a @my_int e non può farlo. Prova invece:

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
Dovresti sempre specificare la lunghezza di un varchar: sqlblog.com/blogs/aaron_bertrand/archive/2009/10/09/…
Eugene Ryabtsev

Grazie. Un po 'in ritardo, ma ho aggiunto i parametri di lunghezza.
Tom H

53

Se stai usando SQL Server 2012+ puoi usare la funzione CONCAT in cui non dobbiamo fare alcuna conversione esplicita

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

Ho riscontrato alcune affermazioni che si CONCAT()comportano più velocemente di CAST(). Sarebbero utili fonti affidabili di studi sulle prestazioni.
Codici con martello

Non sarei sorpreso se fosse misurabile in un benchmark, ma sarei molto sorpreso se avesse avuto un impatto nelle query normali. Dovresti avere un numero enorme di calchi per soffocare il normale tempo di funzionamento.
SilverbackNet

8

Cambia questo:

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

A questa:

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

Cambia questo:

SET @ActualWeightDIMS = @ActualWeight;

A questa:

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

Devi usare CAST. Scopri tutto su CAST e CONVERT qui , perché i tipi di dati sono importanti!



4

È necessario eseguire il cast dei numeri interi come stringa quando si tenta di concatenarli in un varchar.

vale a dire

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

In SQL Server 2008 è possibile utilizzare la STRfunzione:

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

2
La funzione STR per impostazione predefinita completa il numero a 10 caratteri in modo da aggiungere un sacco di spazi. ad esempio, STR(1)mi dà 9 spazi seguiti da 1. CASTeffettivamente funziona meglio.
Tahir Hassan

2

Trasmetti prima gli interi a varchar!


Esattamente. La stringa 'x' martella completamente l'inutile int decl; non c'è aritmetica nell'UDF.
bvj

2

È necessario eseguire il CAST dei dati numerici in stringhe prima di eseguire la concatenazione di stringhe, quindi, ad esempio, utilizzare CAST(@Actual_Dims_Lenght AS VARCHAR)anziché solo @Actual_Dims_Lenght, & c.


2

Ho provato la query seguente che funziona esattamente per me

 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

Prova a trasmettere gli int a varchar, prima di aggiungerli a una stringa:

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

Ci sono possibilità che tu possa finire con Scientific Number quando converti Integer in Str ... il modo più sicuro è

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.