Wie verkette ich Zahlen und Zeichenfolgen, um Zahlen in T-SQL zu formatieren?


105

Ich habe die folgende Funktion

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

Aber als ich versuchte, es zu verwenden, bekam ich den folgenden Fehler: "Die Konvertierung ist fehlgeschlagen, als der Varchar-Wert 'x' in den Datentyp int konvertiert wurde." wenn ich die folgende select-Anweisung verwende

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

Wenn das ActualWeight nicht null ist, gebe ich das ActualWeight für das "Actual Weight / DIMS" zurück oder verwende Actual_Dims_Lenght, Width und Height.

Wenn es DIMS ist, möchte ich die Ausgabe so formatieren, dass sie LenghtxWidhtxHeight (15x10x4) ist. ActualWeight, Adcutal_Dims_Lenght, Width und Height sind alle int (Integer), aber die Ausgabe für "Actual Weight / DIMS" sollte varchar (50) sein.

Wo verstehe ich das falsch?

danken

Bearbeiten: Der Benutzer kann auf der ASP.net-Seite nur entweder Gewicht oder DIMS auswählen. Wenn der Benutzer DIMS ausgewählt hat, muss er Länge, Breite und Höhe angeben. Andernfalls wird ein Fehler auf der ASP.net-Seite ausgegeben. Sollte ich mir auf der SQL-Seite darüber Sorgen machen?

Antworten:


211

Ein paar kurze Anmerkungen:

  • Es ist "Länge" nicht "Länge"
  • Tabellen-Aliase in Ihrer Abfrage würden sie wahrscheinlich viel lesbarer machen

Nun zum Problem ...

Sie müssen Ihre Parameter explizit in VARCHAR konvertieren, bevor Sie versuchen, sie zu verketten. Wenn SQL Server @my_int + 'X' sieht, glaubt es, dass Sie versuchen, @my_int die Nummer "X" hinzuzufügen, und das kann es nicht. Versuchen Sie stattdessen:

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
Sie sollten immer die Länge eines Varchars angeben: sqlblog.com/blogs/aaron_bertrand/archive/2009/10/09/…
Eugene

Vielen Dank. Ein bisschen spät, aber ich habe die Längenparameter hinzugefügt.
Tom H

53

Wenn Sie SQL Server 2012+ verwenden , können Sie die CONCAT- Funktion verwenden, in der keine explizite Konvertierung durchgeführt werden muss

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

Ich bin auf einige Behauptungen gestoßen, CONCAT()die schneller als CAST(). Zuverlässige Quellen für Leistungsstudien wären nützlich.
Codes mit Hammer

Ich wäre nicht überrascht, wenn es in einem Benchmark messbar wäre, aber ich wäre sehr überrascht, wenn es bei normalen Abfragen Auswirkungen hätte. Sie müssten eine enorme Anzahl von Abgüssen haben, um die normale Betriebszeit zu übertönen.
SilverbackNet

8

Ändere das:

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

Dazu:

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

Ändere das:

SET @ActualWeightDIMS = @ActualWeight;

Dazu:

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

Sie müssen CAST verwenden. Erfahren Sie alles über CAST und CONVERT hier , weil Datentypen wichtig sind!



4

Sie müssen Ihre Ganzzahlen als Zeichenfolge umwandeln, wenn Sie versuchen, sie zu einem Varchar zu verketten.

dh

 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 können Sie die folgende STRFunktion verwenden:

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

2
Die STR-Funktion füllt die Zahl standardmäßig mit 10 Zeichen auf, sodass viele Leerzeichen hinzugefügt werden. zB STR(1)gibt mir 9 Leerzeichen gefolgt von 1. CASTfunktioniert eigentlich besser.
Tahir Hassan

2

Wirf zuerst die ganzen Zahlen auf varchar!


Genau. Die Zeichenfolge 'x' hämmert die sinnlosen int-Deklarationen vollständig; In der UDF gibt es keine Arithmetik.
bvj

2

Sie müssen Ihre numerischen Daten in Zeichenfolgen umwandeln, bevor Sie eine Zeichenfolgenverkettung durchführen. Verwenden Sie daher beispielsweise CAST(@Actual_Dims_Lenght AS VARCHAR)anstelle von nur @Actual_Dims_Lenght& c.


2

Mir wurde die folgende Abfrage versucht, es funktioniert genau für mich

 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

Versuchen Sie, die Ints in Varchar umzuwandeln, bevor Sie sie einer Zeichenfolge hinzufügen:

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

Es besteht die Möglichkeit, dass Sie mit Scientific Number enden, wenn Sie Integer in Str konvertieren. Dies ist sicherer

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.