in

UGISS Community

Il sito della community dello User Group Italiano di SQL Server

Dati decimal tra SQL 2005 ed altre applicazioni Microsoft

Last post 07-11-2008 13.23 by Navigator2. 1 replies.
Page 1 of 1 (2 items)
Sort Posts: Previous Next
  • 06-23-2008 9.32

    Dati decimal tra SQL 2005 ed altre applicazioni Microsoft

    Buongiorno a tutti,

    premesso che in azienda esiste un gestionale il  cui database è un grosso complimento definirlo mal progettato (e su questo ovviamente posso farci molto poco), e premesso che questo database utilizza di suo quasi ed esclusivamente valori float invece dei decimal, vengo al punto:

    se creo una tabella con una colonna float ed una decimal (riempite con valori come vi pare)

    quindi collego questa tabella (via odbc con driver appropriato) ad un progetto Access ed apro / interrogo questa tabella i valori float li vedo, i valori decimal devo quantomeno fare una cosa del tipo cdbl(nome_campo)/(10^numero decimali del campo) per vedere / manipolare valori corretti

    non parliamo poi di quando voglio incollare in un foglio di excell dati "copiato" da una griglia di risultati di management studio (si, lo so, bisogna definire in excell che il separatore decimale non è la virgola ma il punto... ma in realtà in presenza di più colonne di dati divers, magari contenenti anche date, questo non basta, bisogna PRIMA di incollare i dati andare a dire su ogni singola colonna se verranno incollati dati numerici o di data... che bocce)

    la domanda è: ma voi come fate? é troppo sperare che mamma microsoft si accorga che i dati provenienti da un suo applicativo non sono compatibili con quelli trattati da un altro?... 

    Al vostro buon cuore per consigli, trucchi, suggerimenti

    Mauro

    • Post Points: 20
  • 07-11-2008 13.23 In reply to

    Re: Dati decimal tra SQL 2005 ed altre applicazioni Microsoft

    Ciao Mauro, ricordati che il cast ela convert possono essere utilizzati per trasformare un tipo in un'altro tipo

    ad esempio

    declare @f as float

    set @f = 12.4

    select @f, cast(@f as decimal(10,4)), CONVERT(decimal(10,4),@f),

    [dbo].[FormatNumber] (cast(@f as decimal(10,4)),4,'','')

     

    Se hai bisogno di formattare dei valori numerici puoi utilizzare questa funzione che ho trovato su Internet

    SET ANSI_NULLS ON

    GO

    SET QUOTED_IDENTIFIER ON

    GO

     

    CREATE FUNCTION  [dbo].[FormatNumber] (

     

        @number decimal(38,15),

        @decimalplaces int=0,

        @format varchar(115)='',

        @ifzero varchar(115)=''

    )   RETURNS varchar(256)

    AS  BEGIN

    /*

    Valid @Format arguments (space between args is ignored)

     nothing -  returns the number unformatted

     $ - return the number preceded by a '$' sign

     % - return the number followed by a '%' sign

     , - place a , every 3 zeros in the whole number portion (thousands)

     c - divide the number by 100 - intended to calc percent values

     i - returns integer portion only with no formatting except commas if requested

     d - returns the decimal portion only with no formatting except commas if requested

     b - returns a blank string for 0 values

     ( - encloses negative numbers in brackets

     l - use leading zero

     r[int]r - rounds number outside of the decimal context

     z[int]z - zero fills to [int] width

    */

     

    DECLARE @fmtxt varchar(25), @parsetxt varchar(50)

         , @parsetxtdec varchar(50)

         , @decptloc int, @zerotext varchar(100)

         , @intpart varchar(25), @decpart varchar(25)

         , @ERR_type varchar(15), @roundto varchar(2)

         , @fillto varchar(50), @fillto# varchar(2)

     

    --A little error checking is in order

    IF @number IS NULL

        RETURN  '{ERR-null passed}'

    ELSE IF @decimalplaces < 0

        RETURN  '{ERR-decimal spec <0}'

    ELSE IF @decimalplaces >15

        RETURN  '{ERR-decimal spec >15}'

     

    -- Handle zero values first

    IF @number = 0  RETURN @ifzero

     

    -- Now 'C'alculate the percentage if requested using the '%c' arg.

    IF CHARINDEX('%c',@FORMAT) > 0  SET @number = @number * 100

     

    -- Do rounding outside if applicable

    IF CHARINDEX('r',@FORMAT) > 0 BEGIN

        SET @roundto = SUBSTRING(@FORMAT,CHARINDEX('r', @FORMAT)+1, 115)

        SET @roundto = LEFT(@roundto,CHARINDEX('r',@roundto)-1)

        SET @number = round(@number,cast(@roundto as integer))

    END

     

    -- Get the parsetext variable

    IF CHARINDEX(',',@FORMAT) > 0

        SET @parsetxt = CONVERT(varchar(100),CAST(@number as money),1)

    ELSE

        SET @parsetxt = CONVERT(varchar(100), @number)

     

    -- Grab some basic stuff

    SET @decptloc = ISNULL(CHARINDEX('.',@parsetxt),0)

     

    IF @decptloc = 0

       RETURN @parsetxt

    ELSE

       SET @intpart = SUBSTRING(@parsetxt,1,@decptloc-1)

     

    -- Handle leading zeros

    IF CHARINDEX('l',@FORMAT) = 0 AND @intpart = '0' SET @intpart = ''

     

    -- Now build the decimal portion of the result

    SET @parsetxt = CONVERT(varchar(100),ROUND(@number,@decimalplaces),2)

    SET @decptloc = ISNULL(CHARINDEX('.',@parsetxt),0)

     

     

    IF @decimalplaces = 0

       SET @decpart = ''

    ELSE

       SET @decpart =  LEFT(SUBSTRING(@parsetxt

                                         + REPLICATE('0',@decimalplaces)

                                     ,@decptloc

                                     ,@decptloc+50)

                           ,@decimalplaces+1)

     

    --ASSEMBLE THE RESULTS --

     

    -- for just integer portion

    IF CHARINDEX('i',@FORMAT) > 0

       RETURN @intpart

    -- for just decimal portion

    IF CHARINDEX('d',@FORMAT) > 0

       RETURN  + @decpart

     

    SET @fmtxt =  @intpart  + @decpart

    --SET @fmtxt =  @intpart +'*'+ @decpart

     

    -- Handle brackets if requested

    IF CHARINDEX('(',@FORMAT) > 0 AND @number < 0

             SET @fmtxt = '(' + RIGHT(@fmtxt,LEN(@fmtxt)-1) + ')'

     

    -- Add the symbols

    IF CHARINDEX('$',@FORMAT) > 0

        SET @fmtxt = '$' + @fmtxt

    ELSE IF CHARINDEX('%',@FORMAT) > 0

        SET @fmtxt = @fmtxt + '%'

     

    --Handle zero filling

    IF CHARINDEX('z',@FORMAT) > 0 BEGIN

      SET @fillto = SUBSTRING(@FORMAT,CHARINDEX('z',@FORMAT)+1,115)

      SET @fillto# = CAST(LEFT(@fillto,CHARINDEX('z',@fillto)-1) as INT)

      SET @fmtxt = RIGHT(REPLICATE('0',@fillto#) + @fmtxt,@fillto#)

    END

     

    RETURN  @fmtxt

     

    END

    Non è molto performante e forse si può ottimizzare o trovare di meglio ma il suo lavoro lo fa.

    A questo punto puoi prendere i valori float trasformali in decimal e formattarli con un numero preciso di caratteri e poi, con cast ritrasformali in float o decimal tutti omogenei fra loro. Ricordati che tutte queste traformazioni costano e se i dati su cui lavorare sono molti potresti avere dei tempi molto lunghi.

    Spero che tutto questo ti possa essere utile

     

    Ciao

    Luca

    • Post Points: 5
Page 1 of 1 (2 items)
(C) 2007 User Group Italiano di SQL Server