Idiomatiques moyen de mettre à jour un enregistrement avant de le servir

Je suis en train de travailler sur une application RoR que, lorsque vous répondez à un /des besoins en ressources pour tenter une mise à jour de toutes les ressources, en prenant les données à partir d'un service externe. Pour rendre les choses plus claires, le pseudo-code est:

def show
  resource = find_resource
  call_external(resource: resource)
  resource = find_resource
  render
end

Maintenant, ce serait le travail, mais vraiment, je n'aime vraiment pas le double de trouver. Il est certainement légitime que la fiche technique est littéralement à accéder à la ressource, utiliser des attributs pour définir un à partir de toute une gamme de ressources pour la mise à jour (qui peuvent contenir de l'actuel) et d'obtenir la ressource de nouveau, encore, assez laid.

Toute suggestion sur la façon de refactoriser cette? Merci beaucoup

+2
2019-09-17 17:46:49
source
4 réponses

Pourquoi utiliser VARCHAR() pour représenter un intervalle lorsque Oracle a déjà intégré dans INTERVAL type de données?

Je voudrais occuper de votre cas d'utilisation comme suit:

-- create a table to store the interval with the proper data type
CREATE TABLE test (date_last_run DATE, frequence INTERVAL YEAR TO MONTH);

-- insert
INSERT INTO test VALUES (sysdate,  INTERVAL '-1' MONTH);

-- now you can select
SELECT DATE_LAST_RUN +  FREQUENCE FROM  test;

Rendements:

| DATE_LAST_RUN+FREQUENCE |
| :---------------------- |
| 18-AUG-19               |

Démo sur DB Violon

+0
2019-09-18 16:41:22

Si vous faites ce que vous faites, SQL dynamique pourrait aider. Par exemple:

SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';

Session altered.

SQL> select * from test;

DATE_LAST_RUN       FREQUENCE
------------------- ------------------------------
18.09.2019 10:57:34  - INTERVAL '1' MONTH

SQL> declare
  2    l_str varchar2(200);
  3    l_res date;
  4  begin
  5    select 'select to_date(' || chr(39) || date_last_run  || chr(39)   ||
  6                           ', ''dd.mm.yyyy hh24:mi:ss'')' || frequence || ' from dual'
  7      into l_str
  8      from test;
  9
 10    execute immediate l_str into l_res;
 11
 12    dbms_output.put_line('result = ' || l_res);
 13  end;
 14  /
result = 18.08.2019 10:57:34

PL/SQL procedure successfully completed.

SQL>
+0
2019-09-18 16:41:22

Ne pas utiliser INTERVAL YEAR TO MONTH il échoue lorsque la date n'existe pas (c'est à dire de DATE '2019-03-31' - INTERVAL '1' MONTH donnera ORA-01839: date not valid for month specified).

Au lieu de cela, ils ont deux colonnes pour la valeur de l'intervalle et le type d'intervalle et d'utiliser une instruction de CASE et ADD_MONTHS fonction:

Configuration Oracle:

CREATE TABLE test (date_last_run DATE, value NUMBER, frequence VARCHAR2(10) );
INSERT INTO test ( date_last_run, value, frequence )
  SELECT sysdate,           -1, 'MONTH' FROM DUAL UNION ALL
  SELECT DATE '2019-03-31', -1, 'MONTH' FROM DUAL UNION ALL
  SELECT DATE '2020-02-29', -1, 'YEAR'  FROM DUAL;

Requête:

SELECT t.*,
       CASE frequence
       WHEN 'MONTH' THEN add_months( date_last_run, value )
       WHEN 'YEAR'  THEN add_months( date_last_run, 12 * value )
       END AS updated_date
FROM   test t

Sortie:

DATE_LAST_RUN | VALUE | FREQUENCE | UPDATED_DATE
:------------ | ----: | :-------- | :-----------
18-SEP-19     |    -1 | MONTH     | 18-AUG-19   
31-MAR-19     |    -1 | MONTH     | 28-FEB-19   
29-FEB-20     |    -1 | YEAR      | 28-FEB-19   

db<>violon ici

+0
2019-09-18 16:41:22

Merci à tous pour vos réponses.

J'ai trouvé le NUMTOYMINTERVAL/NUMTODSINTERVAL et TO_YMINTERVAL/TO_DSINTERVAL qui peut convertir mes FREQUENCES valeurs si je les adapte un peu.

Au lieu de l'énoncé complet, j'ai ajouté un frequence_type champ :

https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=53c78bd37f0190238ca5010e17448bf3

+0
2019-09-18 16:41:22

Voir d'autres questions sur les étiquettes