2011-03-25 3 views
2

Je travaille sur une application qui implique l'évaluation des modifications apportées aux véhicules, et effectue un certain nombre de calculs à partir de figures stockées dans une base de données Oracle 10g. Malheureusement, je n'ai que des données de texte dans la base de données, mais je dois travailler avec des chiffres et non du texte. Je voudrais savoir si quelqu'un pourrait m'aider à comprendre comment effectuer des opérations de chaîne sur les données de colonne VARCHAR2 dans une base de données Oracle 10g avec PLSQL:PLSQL pour modifier les données de la colonne VARCHAR2

Par exemple: Je dois prendre une colonne VARCHAR2 nommée TOP_SPEED dans une table nommée CARS , analysez les données de texte dans sa colonne pour le diviser en deux nouvelles valeurs et insérez ces nouvelles valeurs dans deux nouvelles colonnes de type NUMBER dans la table CARS, TOP_SPEED_KMH et TOP_SPEED_MPH.

Les données de la colonne TOP_SPEED sont en tant que telles: par ex. "153 km/h (94,62 mph)"

Je souhaite enregistrer la valeur de 153.00 dans la colonne TOP_SPEED_KMH et la valeur 94.62 dans la colonne TOP_SPEED_MPH.

Je pense que ce que je dois faire dans une requête/script est la suivante:

  1. sélectionner les données textuelles dans TOP_SPEED dans une variable texte locale
  2. modifier la variable texte local et enregistrer les nouvelles valeurs dans deux variables nombre
  3. écrire de nouveau les deux variables numériques pour les colonnes de TOP_SPEED_KMH et TOP_SPEED_MPH correspondant

quelqu'un pourrait-il s'il vous plaît confirmer que je suis sur la bonne voie? J'apprécierais aussi vraiment n'importe quel exemple de code si quelqu'un a le temps.

Vive

Répondre

1

Je pense que c'est une meilleure idée d'avoir juste la colonne top_speed_kmh, et de se débarrasser de la mph. Comme le nombre de km dans un mile ne change jamais, vous pouvez simplement multiplier par 0,6 pour convertir en miles.Vous pouvez donc faire la même instruction de mise à jour que N West suggérée sans la colonne mph: UPDATE CARS SET TOP_SPEED_KMH = TO_NUMBER (SUBSTR (1, (INSTR (MAJ (TOP_SPEED), "KM/H") -1)));

Et chaque fois que vous avez besoin de la vitesse mph, faites simplement Sélectionnez top_speed_kmh * 0.6 comme top_speed_mph des voitures;

+0

Cela a fonctionné très bien. La solution finale était la suivante: 'CARS UPDATE SET CAR_TOP_SPEED_KPH = to_number (substr (CAR_TOP_SPEED, 1, instr (UPPER (CAR_TOP_SPEED), KM/H ') -1)), CAR_TOP_SPEED_MPH = to_number (substr (regexp_substr (CAR_TOP_SPEED, '\ ([0-9] +'), 2)); ' – fuzzyanalysis

1

Pour le bit d'analyse syntaxique, vous devrez probablement utiliser soit REGEXP_SUBSTR ou INSTR avec SUBSTR

Utilisez ensuite TO_NUMBER pour convertir en nombre

Vous pouvez créer une fonction PL/SQL pour chaque analyse, renvoie la valeur numérique et exécute une requête UPDATE sur les champs, ou vous pouvez créer une procédure PL/SQL avec un curseur en boucle sur toutes les données à mettre à jour.

Voici les liens som pour quelques-uns des built-ins:

http://psoug.org/reference/substr_instr.html http://download.oracle.com/docs/cd/B14117_01/server.101/b10759/functions116.htm

+0

Cheers. Je continue d'obtenir des erreurs chaque fois que j'essaie d'utiliser des curseurs pour ce genre de choses, donc les simples 'UPDATE ...' AND 'SET' fonctionnent pour l'instant ... peut-être qu'avec plus d'expérience je considérerai boucler :). – fuzzyanalysis

+0

Semble un bon choix, si vous pouvez le résoudre avec UPDATE/SET c'est assez bon! Boucler avec un curseur est la chose que vous avez l'habitude de faire si vous avez besoin de faire des choses plus complexes qui sont difficiles à faire dans un UPDATE/SET. En outre, lorsque vous effectuez des tâches avec des curseurs et des boucles, vous créez du code qui est probablement plus dépendant de la base de données que les instructions UPDATE pures. – Brummo

1

Vous n'avez probablement même pas besoin de faire cela avec PL/SQL.

Tant que les données de la colonne est cohérente « 99,99 km/h (99,99 m/h) », vous pouvez le faire directement avec SQL:

UPDATE CARS 
SET TOP_SPEED_KMH = TO_NUMBER(SUBSTR(1, (INSTR(UPPER(TOP_SPEED), "KM/H") - 1))), 
    TOP_SPEED_MPH = <similar substr/instr combination to pull the 99.99 mph out of code>; 

Set-opérations sont généralement beaucoup plus rapide que la procédure opérations.

+0

Merci, c'était la bonne réponse (voir ma réponse à Brian Fenton) – fuzzyanalysis

1

Je travaille sur une application qui implique modifications apportées à l'évaluation véhicules et fait un peu nombre crissement de chiffres stockés dans une base de données Oracle 10g. Malheureusement, je ne dispose que des données de texte dans la base de données, encore je dois travailler avec des chiffres et pas le texte

On dirait que vous devriez avoir quelques colonnes numériques pour stocker ces valeurs analysées sur. Au lieu de toujours appeler une routine d'analyse syntaxique (que ce soit regexp ou substr ou une fonction personnalisée), passez toutes les données dans les tables une seule fois et remplissez les nouveaux champs numériques. Vous devez également modifier le processus ETL pour remplir les nouveaux champs numériques.

Si vous avez besoin de chiffres et que vous pouvez les analyser, faites-le une fois (si possible dans une zone de transit ou au moins pendant des heures) et disposez ensuite des chiffres souhaités. Maintenant, vous êtes libre de faire l'arithmétique et tout ce que vous attendez d'un nombre réel;)

+0

Oui, c'était ce que je voulais faire dans ma question initiale, ne pas analyser chaque fois :). – fuzzyanalysis

1

with s as 
    (select '153 km/h (94.62 mph)' ts from dual) 
select 
    ts, 
    to_number(substr(ts, 1, instr(ts, ' ') -1)) speed_km, 
    to_number(substr(regexp_substr(ts, '\([0-9]+'), 2)) speed_mph 
from s 
 
+0

Merci, cela m'a aidé à comprendre comment extraire la vitesse dans la partie MPH. – fuzzyanalysis

0

Merci tout le monde, il était agréable de pouvoir utiliser l'entrée de chacun pour obtenir la réponse ci-dessous:

UPDATE CARS 
    SET 
    CAR_TOP_SPEED_KPH = 
     to_number(substr(CAR_TOP_SPEED, 1, instr(UPPER(CAR_TOP_SPEED), ' KM/H') -1)), 
    CAR_TOP_SPEED_MPH = 
     to_number(substr(regexp_substr(CAR_TOP_SPEED, '\([0-9]+'), 2)); 
Questions connexes