Sis divisione

mercoledì 16 dicembre 2009 - 17.24

memmo77 Profilo | Expert

mi trovo in una situazione strana. nel mio ssis su una colonna derivata ho messo un capo NEW_T che viene da:

T/FATTORE

NEW_T è di tipo decimal(24,12) e come risultato ottengo 43848,257756000 invece di 43848,257756600. Ho fatto delle prove e non capisco da cosa dipende. Questi i valori che escono dalla derivata:


FATTORE SEGNO_FATT ANNO T NEW_T
100 / 2008 4384825,775660000 43848,257756000

Grazie

alx_81 Profilo | Guru

>NEW_T è di tipo decimal(24,12) e come risultato ottengo 43848,257756000
>invece di 43848,257756600. Ho fatto delle prove e non capisco
>da cosa dipende. Questi i valori che escono dalla derivata:
>
>
>FATTORE SEGNO_FATT ANNO T NEW_T
>100 / 2008 4384825,775660000
>43848,257756000
Dovresti spiegarmi da dove viene il campo di partenza, di che tipo è, che espressione usi nella derived column e il tipo di output.
A me sembra solo che non faccia la divisione.

>Grazie
di nulla!

--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

memmo77 Profilo | Expert

>>Dovresti spiegarmi da dove viene il campo di partenza, di che tipo è, che espressione usi nella derived column e il tipo di output.
>>A me sembra solo che non faccia la divisione.

Allora, non si tratta della divisione. Cerco di farti un esempio.
Io parto dalla select di un valore T che è di tipo decimal(24,12) del valore di: 4186.48099985000

Nel mio ssis questo dato viene moltiplicato per un fattore, in questo caso uguale a 1, di tipo smallint. Quando metto il dato su una derivata il dato si trasforma in numerico(DT_NUMERICO) 32,12. Giustamente non sa quanto sia il fattore e credo aumenti per poter contenere il dato, giusto?
Infine passo il dato T ad un comando ole db per fare l'update, e controllando in debug il ssis il dato che esce dalla derivata è sempre 4186.48099985000.

Se faccio la select sul db, mi scrive:
4186.481000000000

In pratica perde di precisione, ed è quella che ha me interessa.
Grazie ciao.

alx_81 Profilo | Guru

>In pratica perde di precisione, ed è quella che ha me interessa.
è una cosa molto strana, riesci a passarmi il SSIS?
--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

memmo77 Profilo | Expert

Ok, cerco di prepararti un script per ricostruire le tabelle che servono e una parte del ssis che fa il calcolo. Grazie ancora

memmo77 Profilo | Expert

Ciao Alex. Ti allego un file zip contenente il materiale per testare il problema di associazione delle variabili. sostanzialmente ti riassumo cosa mi succede.
Faccio una select di un valore decimal(24,12) e il ssis da se la attribuisce a virgola mobile perdendomi di precisione. Nella select di esempio noterai una inutile case che ho messo solo per capire se il problema fosse da select.
Grazie mille ciao

alx_81 Profilo | Guru

>Ciao Alex. Ti allego un file zip contenente il materiale per
>testare il problema di associazione delle variabili. sostanzialmente
>ti riassumo cosa mi succede.
Mamma mia che fatica.. ma alla fine ho trovato.
Prendi la sorgente, premi il tasto destro e fai Show Advanced Editor. Nella sezione Input And Output Column, seleziona le OutputColum (non external) e noterai che il tipo automaticamente suggerito è il float (DT_R8 o simili). Infatti il problema si ha proprio all'output della sorgente. La preview, non rispecchia effettivamente il buffer di output.
Sì, lo so.. è terribile, ma non so proprio che dire. Credo che posterò e segnalerò questa cosa.

Comunque, tornando a noi, se tu provi a scrivere la query così:
SELECT CASE FK_ANNO WHEN 2008 THEN CAST(SUM(T) AS DECIMAL(24,12)) ELSE CAST(SUM(T) AS DECIMAL(24,12)) END AS IMPORTO, CAST(SUM(T) AS DECIMAL(24,12)) as prova FROM T_VALORI GROUP BY FK_ANNO

noterai che invece prova è indicato come NUMERIC 24,12.
E anche il preview corrisponde con quello che esce dalla source.
Ricorda che il tasto di anteprima risultati è SQL SERVER come risposta, mentre la suggestion dei tipi su SSIS è del motore di SSIS. Non fidarti mai della preview, ma controlla sempre i metadati, ad esempio usando DATA VIEWERS o facendo anche solo doppio click sulle frecce. Nota infatti questo:


778x451 39Kb


come puoi notare il tipo del metadato è DT_R8, scelto da SSIS
e poi:


450x229 18Kb


il primo data viewer in uscita dalla source mostra già il valore arrotondato.
Di conseguenza, credo di poter affermare che il problema è la CASE, poichè mettendo il cast all'interno di ogni then il motore di SSIS non capisce la corretta conversione forzata e prova a scegliere un tipo corretto. Se invece scrivi la query così:
SELECT CAST( CASE FK_ANNO WHEN 2008 THEN CAST(SUM(T) AS DECIMAL(24,12)) ELSE CAST(SUM(T) AS DECIMAL(24,12)) END AS DECIMAL(24,12)) AS IMPORTO FROM T_VALORI GROUP BY FK_ANNO

vedrai che il tipo suggerito è quello corretto, perchè è tutto "wrappato" dal cast esterno. Per prova fai una nuova sorgente e controlla i metadati. Vedrai che funziona.
Infine ho provato ad utilizzare la CONVERT invece della CAST:

SELECT CASE FK_ANNO WHEN 2008 THEN CONVERT(DECIMAL(24,12), SUM(T)) ELSE CONVERT(DECIMAL(24,12),SUM(T)) END AS IMPORTO FROM T_VALORI GROUP BY FK_ANNO

e, udite udite, funziona! Strano, anche perchè se non erro CAST è più standard di CONVERT..
misteri.

Detto questo, puoi anche pensare di usare un Data Conversion successivamente al Derived Column, se quest'ultimo risulta necessario. Per conversioni di tipo, usa il primo non "sprecare" un Derived Column.

Alla fine, fossi in te userei la convert, ma ricorda che non è ANSI, se usi SQL Server vai tranquillo.
Buonanotte.. posterò questa cosa! Promesso!
--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

memmo77 Profilo | Expert

Ti ringrazio moltissimo dello sforzo fatto. Solo che la cosa si complica. In un task di aggregazione non avevo specificato l'output e anche li mi dava un 26,12 perdendo precisione nei decimali.
Poi in un task di derivata facevo un t1*t2 e anche li il risultato lo approssima come dice lui. Se metto il cast nel task della derivata viene bene. Sembra che qualsiasi operazione si fa all'interno del dataflow lui reimposti le variabili come vuole. Forse per motivi di sicurezza, per contenere i risultati delle operazione. Solo che di conseguenza, se voglio ottenere una certa precisione nei decimali non ci riesco.
Considera che il ssis che ti ho mandato è solo un esempio di quello che ho fatto. In realtà è molto + complesso e ricco di operazioni. Ora mi viene il dubbio di aver fatto a suo tempo la scelta giusta di utilizzare i ssis :). Comunque ora me li sto riguardando tutti passaggio per passaggio. Poi ti faccio sapere.

Ne approfitto oltre che per ringraziarti per farti tanti auguri di buone Feste, Natale e felice anno nuovo ;). Ciao

alx_81 Profilo | Guru

>Considera che il ssis che ti ho mandato è solo un esempio di
>quello che ho fatto. In realtà è molto + complesso e ricco di
>operazioni. Ora mi viene il dubbio di aver fatto a suo tempo
>la scelta giusta di utilizzare i ssis :). Comunque ora me li
>sto riguardando tutti passaggio per passaggio. Poi ti faccio sapere.
Quello che posso dire è che puoi prendere gli advanced editor di ogni task andando a controllare coi data viewer lo stato dell'output e cambiando il tipo di dato dei metadati di conseguenza.

>Ne approfitto oltre che per ringraziarti per farti tanti auguri
>di buone Feste, Natale e felice anno nuovo ;). Ciao
Altrettanto!
--

Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2023
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5