2010-08-18 4 views
6

Je gère un processus ETL qui transforme les entrées de fichiers plats en une table de base de données SqlServer. Le code est presque 100% T-SQL et s'exécute dans la base de données. Je ne possède pas le code et ne peux pas changer le flux de travail. Je ne peux que vous aider à configurer le SQL "traduction" qui prend les données du fichier et les convertit en données de table (plus sur cela plus tard).Conversion/conversion d'un nVarChar avec un séparateur de virgules en notation décimale

Maintenant que les non-responsabilité sont hors du chemin ...

L'un de nos fournisseurs de fichiers ont récemment changé la façon dont ils représentent une somme d'argent '12345.67'-'12,345.67'. Notre SQL qui transforme la valeur ressemble à SELECT FLOOR(CAST([inputValue] AS DECIMAL(24,10))) et ne fonctionne plus. C'est-à-dire que la virgule casse la distribution.

Étant donné que je dois conserver la valeur finale Decimal (24,10) datatype (oui, je me rends compte de la FLOOR efface toute la précision post-point décimal - le concepteur n'a pas été en phase avec le client), que puis-je faire lancer cette corde efficacement?

Nous vous remercions de vos idées.

+0

Est-ce que l'une de ces réponses a permis de résoudre votre problème? –

+0

@KM: Je discute de ces suggestions avec notre groupe DBA maintenant. De mon côté, l'approche commune proposée (using Replace()) semble fonctionner. Mettra à jour bientôt. – SethO

Répondre

7

essayer d'utiliser REPLACE (Transact-SQL):

SELECT REPLACE('12,345.67',',','') 

SORTIE:

12345.67 

il serait donc:

SELECT FLOOR(CAST(REPLACE([input value],',','') AS DECIMAL(24,10))) 
+0

+1 ... Remplacez et PUIS castez, afin que votre fonctionnalité d'origine soit conservée. – Fosco

1

Cela fonctionne pour moi:

DECLARE @foo NVARCHAR(100) 
SET @foo='12,345.67' 

SELECT FLOOR(CAST(REPLACE(@foo,',','') AS DECIMAL(24,10))) 

Ceci est probablement valable uniquement pour les collations/culture où la virgule est pas le séparateur décimal (ex: espagnol)

+0

Vous soulevez un bon point, David. Je sais que certaines entrées proviennent d'Europe et d'Asie, ce qui pourrait gâcher n'importe quelle manipulation de chaîne par des virgules. Je vais devoir faire un suivi avec le client à ce sujet. – SethO

+0

Il est préférable que votre application détecte les paramètres régionaux de l'utilisateur, convertisse en un nombre décimal typé, puis passe au serveur SQL en tant que valeur décimale typée. Le problème disparaît. – David

1

SELECT FLOOR (CAST(REPLACE([inputValue], ',', '') AS DECIMAL(24,10)))

2

Bien que pas nécessairement la meilleure approche pour ma situation, je voulais laisser une solution potentielle pour une utilisation future que nous avons découvert tout en recherchant ce problème.

Il semble que le type de données SqlServer MONEY peut être utilisé comme distribution directe pour les chaînes avec une virgule séparant la partie non décimale. Donc, où SELECT CAST('12,345.56' AS DECIMAL(24,10)) échoue, SELECT CAST('12,345.56' AS MONEY) réussira. L'une des mises en garde est que le type de données MONEY a une précision de 4 décimales et nécessiterait une distribution explicite pour l'obtenir en DECIMAL, si vous en avez besoin.

Questions connexes