2010-11-22 7 views

Antwort

1

gedruckt werden, obwohl Sie eine als UDF schreiben könnte oder sproc meisten DBs haben abyssal String-Handling Kein RDBMS ich weiß. Tun Sie dies in Ihrer Client-App.

0

Ich glaube nicht, dass es eine eingebaute Funktion gibt, aber das ist ein guter Ausgangspunkt.

http://www.novicksoftware.com/udfofweek/Vol2/T-SQL-UDF-Vol-2-Num-9-udf_Num_ToWords.htm

Welche Geschmack von SQL reden wir hier?

Das heißt, wie Sie efefctively die Daten Transformieren, das ist wirklich etwas, das in Ihrem Unternehmen durchgeführt werden shoudl oder auch Präsentationsschicht

EDIT

Brilliant! Gerade getestet, es selbst:

select dbo.udf_Num_ToWords(19264235677575674234234234234223123123) 

Nineteen Undecillion zweihundert vierundsechzig decillion zweihundert fünfunddreißig nonillion sechshundert siebenundsiebzig octillion fünfhundert fünfundsiebzig septillion sechshundert vierundsiebzig zweihunderttausend zweihundert dreiunddreißig Trillionen zweihundert vierunddreißig Billiarden zweihundert vierunddreißig Billionen zweihundert vierunddreißig Milliarden zweihundert dreiundzwanzig Millionen einhundert 23.100 dreiundzwanzig

:-)

ZWEITE EDIT folgende Bemerkung

die Funktion Modified einschließen ‚und ist:

CREATE FUNCTION dbo.udf_Num_ToWords (

    @Number Numeric (38, 0) -- Input number with as many as 18 digits 

) RETURNS VARCHAR(8000) 
/* 
* Converts a integer number as large as 34 digits into the 
* equivalent words. The first letter is capitalized. 
* 
* Attribution: Based on NumberToWords by Srinivas Sampath 
*  as revised by Nick Barclay 
* 
* Example: 
select dbo.udf_Num_ToWords (1234567890) + CHAR(10) 
     + dbo.udf_Num_ToWords (0) + CHAR(10) 
     + dbo.udf_Num_ToWords (123) + CHAR(10) 
select dbo.udf_Num_ToWords() 

DECLARE @i numeric (38,0) 
SET @i = 0 
WHILE @I <= 1000 BEGIN 
    PRINT convert (char(5), @i) 
      + convert(varchar(255), dbo.udf_Num_ToWords(@i)) 
    SET @I = @i + 1 
END 
* 
* Published as the T-SQL UDF of the Week Vol 2 #9 2/17/03 
****************************************************************/ 
AS BEGIN 

DECLARE @inputNumber VARCHAR(38) 
DECLARE @NumbersTable TABLE (number CHAR(2), word VARCHAR(10)) 
DECLARE @outputString VARCHAR(8000) 
DECLARE @length INT 
DECLARE @counter INT 
DECLARE @loops INT 
DECLARE @position INT 
DECLARE @chunk CHAR(3) -- for chunks of 3 numbers 
DECLARE @tensones CHAR(2) 
DECLARE @hundreds CHAR(1) 
DECLARE @tens CHAR(1) 
DECLARE @ones CHAR(1) 
DECLARE @interim VARCHAR(8000) 

IF @Number = 0 Return 'Zero' 

-- initialize the variables 
SELECT @inputNumber = CONVERT(varchar(38), @Number) 
    , @outputString = '' 
    , @counter = 1 
SELECT @length = LEN(@inputNumber) 
    , @position = LEN(@inputNumber) - 2 
    , @loops = LEN(@inputNumber)/3 

-- make sure there is an extra loop added for the remaining numbers 
IF LEN(@inputNumber) % 3 <> 0 SET @loops = @loops + 1 

-- insert data for the numbers and words 
INSERT INTO @NumbersTable SELECT '00', '' 
    UNION ALL SELECT '01', 'one'  UNION ALL SELECT '02', 'two' 
    UNION ALL SELECT '03', 'three' UNION ALL SELECT '04', 'four' 
    UNION ALL SELECT '05', 'five'  UNION ALL SELECT '06', 'six' 
    UNION ALL SELECT '07', 'seven' UNION ALL SELECT '08', 'eight' 
    UNION ALL SELECT '09', 'nine'  UNION ALL SELECT '10', 'ten' 
    UNION ALL SELECT '11', 'eleven' UNION ALL SELECT '12', 'twelve' 
    UNION ALL SELECT '13', 'thirteen' UNION ALL SELECT '14', 'fourteen' 
    UNION ALL SELECT '15', 'fifteen' UNION ALL SELECT '16', 'sixteen' 
    UNION ALL SELECT '17', 'seventeen' UNION ALL SELECT '18', 'eighteen' 
    UNION ALL SELECT '19', 'nineteen' UNION ALL SELECT '20', 'twenty' 
    UNION ALL SELECT '30', 'thirty' UNION ALL SELECT '40', 'forty' 
    UNION ALL SELECT '50', 'fifty' UNION ALL SELECT '60', 'sixty' 
    UNION ALL SELECT '70', 'seventy' UNION ALL SELECT '80', 'eighty' 
    UNION ALL SELECT '90', 'ninety' 

WHILE @counter <= @loops BEGIN 

    -- get chunks of 3 numbers at a time, padded with leading zeros 
    SET @chunk = RIGHT('000' + SUBSTRING(@inputNumber, @position, 3), 3) 

    IF @chunk <> '000' BEGIN 
     SELECT @tensones = SUBSTRING(@chunk, 2, 2) 
      , @hundreds = SUBSTRING(@chunk, 1, 1) 
      , @tens = SUBSTRING(@chunk, 2, 1) 
      , @ones = SUBSTRING(@chunk, 3, 1) 

     -- If twenty or less, use the word directly from @NumbersTable 
     IF CONVERT(INT, @tensones) <= 20 OR @Ones='0' BEGIN 
      SELECT @interim = word 
       FROM @NumbersTable 
       WHERE @tensones = number 

      if rtrim(ltrim(isnull(@interim,''))) <> '' 
      begin 
       set @interim = 'and ' + @interim 
      end  

      SET @outputString = @interim 
        + CASE @counter WHEN 1 THEN '' -- No name 
         WHEN 2 THEN ' thousand ' WHEN 3 THEN ' million ' 
         WHEN 4 THEN ' billion ' WHEN 5 THEN ' trillion ' 
         WHEN 6 THEN ' quadrillion ' WHEN 7 THEN ' quintillion ' 
         WHEN 8 THEN ' sextillion ' WHEN 9 THEN ' septillion ' 
         WHEN 10 THEN ' octillion ' WHEN 11 THEN ' nonillion ' 
         WHEN 12 THEN ' decillion ' WHEN 13 THEN ' undecillion ' 
         ELSE '' END 
           + @outputString 
      END 
     ELSE BEGIN -- break down the ones and the tens separately 

      SET @outputString = ' ' 
          + (SELECT 'and ' + isnull(word,'') 
            FROM @NumbersTable 
            WHERE @tens + '0' = number) 
          + '-' 
          + (SELECT word 
            FROM @NumbersTable 
            WHERE '0'+ @ones = number) 
        + CASE @counter WHEN 1 THEN '' -- No name 
         WHEN 2 THEN ' thousand ' WHEN 3 THEN ' million ' 
         WHEN 4 THEN ' billion ' WHEN 5 THEN ' trillion ' 
         WHEN 6 THEN ' quadrillion ' WHEN 7 THEN ' quintillion ' 
         WHEN 8 THEN ' sextillion ' WHEN 9 THEN ' septillion ' 
         WHEN 10 THEN ' octillion ' WHEN 11 THEN ' nonillion ' 
         WHEN 12 THEN ' decillion ' WHEN 13 THEN ' undecillion ' 
         ELSE '' END 
          + @outputString 
     END 

     -- now get the hundreds 
     IF @hundreds <> '0' BEGIN 
      SET @outputString = (SELECT word 
             FROM @NumbersTable 
             WHERE '0' + @hundreds = number) 
           + ' hundred ' 
           + @outputString 
     END 
    END 

    SELECT @counter = @counter + 1 
     , @position = @position - 3 

END 

-- Remove any double spaces 
SET @outputString = LTRIM(RTRIM(REPLACE(@outputString, ' ', ' '))) 
SET @outputstring = UPPER(LEFT(@outputstring, 1)) + SUBSTRING(@outputstring, 2, 8000) 


RETURN @outputString -- return the result 
END 
+0

Sehr nett, aber für einige von uns sollte es "einhundert _AND_ dreiundzwanzig" sein> ;-) – smirkingman

+0

Yeah bemerkte das. Entsprechend aktualisiert (siehe zweite Änderung!) –

0

Sie haben könnten eine separate Tabelle für die Zahlenübersetzungen (vielleicht eine Spalte für jede Sprache, falls Sie später weitere Sprachen unterstützen wollen) und dann die w durch Hinzufügen der Tabellen. Etwas wie:

SELECT table_with_translations.en 
FROM table_with_numbers 
JOIN table_with_translations ON table_with_numbers.number = table_with_translations.en; 
WHERE table_with_numbers.number = 72; 

nicht die anspruchsvollste Ansatz, und ich glaube nicht, das zu gut skaliert, aber wenn Sie eine schnelle Lösung benötigen, und das Projekt ist eher klein, sollte dies gut funktionieren.

1

Genau das gleiche verwenden wir auch in unserem Projekt. Es gibt keine eingebaute Methode dafür, aber ich habe eine Funktion, die du an deinem Ende ausprobieren kannst. Hoffe, das wird Ihnen helfen - Ofcourse Sie für Ihre Anforderungen optimieren können -

CREATE FUNCTION [dbo].[NumberToWords] 
(
    @NumberString nvarchar(max) 
) RETURNS VARCHAR(8000) 
AS BEGIN 

DECLARE @Number Numeric (38, 0) 
DECLARE @inputNumber VARCHAR(38) 
DECLARE @NumbersTable TABLE (number CHAR(2), word VARCHAR(10)) 
DECLARE @outputString VARCHAR(8000) 
DECLARE @length INT 
DECLARE @counter INT 
DECLARE @loops INT 
DECLARE @position INT 
DECLARE @chunk CHAR(3) 
DECLARE @tensones CHAR(2) 
DECLARE @hundreds CHAR(1) 
DECLARE @tens CHAR(1) 
DECLARE @ones CHAR(1) 

set @Number = cast(@NumberString as Numeric (38, 0)) 

IF @Number = 0 Return 'Zero' 

-- initialize the variables 
SELECT @inputNumber = CONVERT(varchar(38), @Number) 
    , @outputString = '' 
    , @counter = 1 
SELECT @length = LEN(@inputNumber) 
    , @position = LEN(@inputNumber) - 2 
    , @loops = LEN(@inputNumber)/3 

-- make sure there is an extra loop added for the remaining numbers 
IF LEN(@inputNumber) % 3 <> 0 SET @loops = @loops + 1 

-- insert data for the numbers and words 
INSERT INTO @NumbersTable SELECT '00', '' 
    UNION ALL SELECT '01', 'one'  UNION ALL SELECT '02', 'two' 
    UNION ALL SELECT '03', 'three' UNION ALL SELECT '04', 'four' 
    UNION ALL SELECT '05', 'five'  UNION ALL SELECT '06', 'six' 
    UNION ALL SELECT '07', 'seven' UNION ALL SELECT '08', 'eight' 
    UNION ALL SELECT '09', 'nine'  UNION ALL SELECT '10', 'ten' 
    UNION ALL SELECT '11', 'eleven' UNION ALL SELECT '12', 'twelve' 
    UNION ALL SELECT '13', 'thirteen' UNION ALL SELECT '14', 'fourteen' 
    UNION ALL SELECT '15', 'fifteen' UNION ALL SELECT '16', 'sixteen' 
    UNION ALL SELECT '17', 'seventeen' UNION ALL SELECT '18', 'eighteen' 
    UNION ALL SELECT '19', 'nineteen' UNION ALL SELECT '20', 'twenty' 
    UNION ALL SELECT '30', 'thirty' UNION ALL SELECT '40', 'forty' 
    UNION ALL SELECT '50', 'fifty' UNION ALL SELECT '60', 'sixty' 
    UNION ALL SELECT '70', 'seventy' UNION ALL SELECT '80', 'eighty' 
    UNION ALL SELECT '90', 'ninety' 

WHILE @counter <= @loops BEGIN 

    -- get chunks of 3 numbers at a time, padded with leading zeros 
    SET @chunk = RIGHT('000' + SUBSTRING(@inputNumber, @position, 3), 3) 

    IF @chunk <> '000' BEGIN 
     SELECT @tensones = SUBSTRING(@chunk, 2, 2) 
      , @hundreds = SUBSTRING(@chunk, 1, 1) 
      , @tens = SUBSTRING(@chunk, 2, 1) 
      , @ones = SUBSTRING(@chunk, 3, 1) 

     -- If twenty or less, use the word directly from @NumbersTable 
     IF CONVERT(INT, @tensones) <= 20 OR @Ones='0' 
     BEGIN 
      SET @outputString = (SELECT word 
             FROM @NumbersTable 
             WHERE @tensones = number) 
        + CASE @counter WHEN 1 THEN '' -- No name 
         WHEN 2 THEN ' thousand ' WHEN 3 THEN ' million ' 
         WHEN 4 THEN ' billion ' WHEN 5 THEN ' trillion ' 
         WHEN 6 THEN ' quadrillion ' WHEN 7 THEN ' quintillion ' 
         WHEN 8 THEN ' sextillion ' WHEN 9 THEN ' septillion ' 
         WHEN 10 THEN ' octillion ' WHEN 11 THEN ' nonillion ' 
         WHEN 12 THEN ' decillion ' WHEN 13 THEN ' undecillion ' 
         ELSE '' END 
           + @outputString 
      END 
     ELSE BEGIN -- break down the ones and the tens separately 

      SET @outputString = ' ' 
          + (SELECT word 
            FROM @NumbersTable 
            WHERE @tens + '0' = number) 
          + '-' 
          + (SELECT word 
            FROM @NumbersTable 
            WHERE '0'+ @ones = number) 
        + CASE @counter WHEN 1 THEN '' -- No name 
         WHEN 2 THEN ' thousand ' WHEN 3 THEN ' million ' 
         WHEN 4 THEN ' billion ' WHEN 5 THEN ' trillion ' 
         WHEN 6 THEN ' quadrillion ' WHEN 7 THEN ' quintillion ' 
         WHEN 8 THEN ' sextillion ' WHEN 9 THEN ' septillion ' 
         WHEN 10 THEN ' octillion ' WHEN 11 THEN ' nonillion ' 
         WHEN 12 THEN ' decillion ' WHEN 13 THEN ' undecillion ' 
         ELSE '' END 
          + @outputString 
     END 

     -- now get the hundreds 
     IF @hundreds <> '0' BEGIN 
      SET @outputString = (SELECT word 
             FROM @NumbersTable 
             WHERE '0' + @hundreds = number) 
           + ' hundred ' 
           + @outputString 
     END 
    END 

    SELECT @counter = @counter + 1 
     , @position = @position - 3 

END 

SET @outputString = LTRIM(RTRIM(REPLACE(@outputString, ' ', ' '))) 
SET @outputstring = UPPER(LEFT(@outputstring, 1)) + SUBSTRING(@outputstring, 2, 8000) 


RETURN @outputString 
END 
+0

Das sieht verdächtig nach unreferenziertem Code aus, der von der Site kopiert wurde, auf die ich in meinem Post verwiesen habe. Geben Sie Ihren Quellen mindestens einen Kredit –

+0

Btw, diese Version der Funktion ist für SQL Server. –

+0

@ James Wiseman - Wir haben diese Funktion in unserem Projekt geschrieben und wir verwenden dies in unseren Berichten aus den letzten 1 Jahr atleast. –

0

Ich persönlich würde dies tun, indem eine permananet Tabelle erstellen und es mit der Anzahl und den Worten bevölkern.Ich weiß nicht, wie groß Sie damit umgehen müssen, aber die Wörter einmal in eine Tabelle einzufügen (es ist nicht so, als ob sie sich ändern würden), wäre viel effizienter als eine Funktion, um die Wörter zu bestimmen. Wenn Sie mit diesem (oder höher) in die Millionen gehen müssen, könnten Sie ein Skript erstellen, um die Daten für die Tabelle zu generieren, indem Sie die obigen Funktionen als Ausgangspunkt verwenden.

Wenn Sie diese Umwandlung häufig durchführen möchten, wäre eine Tabelle mit einer guten Indizierung, der Sie beitreten können, die beste Methode.

Verwandte Themen