Archives de catégorie : Informatique

Explications, démo…

Problème de date dans une base de données

Une autre problématique dès que l’on travaille sur plusieurs bases (Access, Sql Server, Oracle) et que l’on est confronté à des langues différentes au niveau des serveurs… Même le LCID = 1036 (qui permet d’imposer la langue utilisée par le serveur web) ne vient pas à bout de certaines architectures ! En plus la syntaxe SQL de la langue n’est pas identique selon les bases. Donc pour éviter de voir le 7 mai se transformer en 5 juillet, voilà une solution, l’utilisation du format ODBC compatible avec les trois bases citées :

L’idée est de transformer un format de date jj/mm/aaaa ou mm/dd/yyyy en un format identique : {d ‘aaaa-mm-jj} {d ‘yyyy-mm-dd} ou un format comportant les heures : {ts ‘yyyy-mm-dd hh:mm:ss’} ou {ts ‘aaaa-mm-jj hh:mm:ss’}

La requête SQL devient  « … WHERE champ > {d ‘2006-08-23} « 


‘****************************************************************************************************
‘ Fonction     : strODBCDate
‘ Objet        : Preparer l’insertion d’une date dans une requete SQL
‘ Entrée       :
‘               – dtmParam : date a traiter
‘ Retour       : chaine a inserer directement dans le code SQL
‘ Sortie       :
‘ Commentaires : le format final est {d ‘aaaa-mm-jj’}
‘                quelle que soit la langue d’installation de la base cible
‘ Exemple      :
‘****************************************************************************************************
Function strODBCDate(ByVal dtmParam)
 Dim strOut
 If IsNull(dtmParam) Or dtmParam= » » Then
  strOut = Null
 Else
  If Not IsDate(dtmParam) Then
   strOut = Null
  Else
   Dim strMonth, strDay
   Dim dtmMonth, dtmDay
   ‘ Traitement du mois si sur un seul chiffre
   dtmMonth = Month(dtmParam)
   If dtmMonth<10 Then
    strMonth = « 0 » & CStr(dtmMonth)
   Else
    strMonth = CStr(dtmMonth)
   End If
   ‘ Traitement du jour si sur un seul chiffre
   dtmDay = Day(dtmParam)
   If dtmDay<10 Then
    strDay = « 0 » & CStr(dtmDay)
   Else
    strDay = CStr(dtmDay)
   End If
   ‘ Creation de la chaine de retour
   strOut = « {d ‘ » & CStr(Year(dtmParam)) & « – » & strMonth & « – » & strDay & « ‘} »
  End If
 End If
 strODBCDate = strOut
End Function


‘=======================================================================================
‘ Fonction     : strODBCDateTime
‘ Objet        : Preparer l’insertion d’une date dans une requete SQL
‘ Entrée       :
‘               – dtmParam : date et heure a traiter
‘ Retour       : chaine a inserer directement dans le code SQL
‘ Sortie       :
‘ Commentaires : le format final est {ts ‘aaaa-mm-jj hh:mm:ss’}
‘                quelle que soit la langue d’installation de la base cible
‘ Exemple      :
‘=======================================================================================
Function strODBCDateTime(ByVal dtmParam)
 Dim strOut
 If IsNull(dtmParam) Or dtmParam= » » Then
  strOut = Null
 Else
  If Not IsDate(dtmParam) Then
   strOut = Null
  Else
   Dim strMonth, strDay
   Dim dtmMonth, dtmDay
   Dim strHour, strMinutes, strSecondes
   strHour =hour(dtmParam)
   strMinutes= minute(dtmParam)
   strSecondes = second(dtmParam)
   ‘ Traitement du mois si sur un seul chiffre
   dtmMonth = Month(dtmParam)
   If dtmMonth<10 Then
    strMonth = « 0 » & CStr(dtmMonth)
   Else
    strMonth = CStr(dtmMonth)
   End If
   ‘ Traitement du jour si sur un seul chiffre
   dtmDay = Day(dtmParam)
   If dtmDay<10 Then
    strDay = « 0 » & CStr(dtmDay)
   Else
    strDay = CStr(dtmDay)
   End If
   If strHour<10 Then
    strHour = « 0 » & CStr(strHour)
   Else
    strHour = CStr(strHour)
   End If
   If strMinutes<10 Then
    strMinutes = « 0 » & CStr(strMinutes)
   Else
    strMinutes = CStr(strMinutes)
   End If
   If strSecondes<10 Then
    strSecondes = « 0 » & CStr(strSecondes)
   Else
    strSecondes = CStr(strSecondes)
   End If
   ‘ Creation de la chaine de retour
   strOut = « {ts ‘ » & CStr(Year(dtmParam)) & « – » & strMonth & « – » & strDay &  » « & strHour & « : »& strMinutes & « : »& strSecondes& »‘} »
  End If
 End If
 strODBCDateTime = strOut
End Function 


 

Oracle : Mise à jour des sequences après import

Ames sensibles, s’abstenir…

Voilà un sujet qui est abordé sur internet sans forcement apporter de solution. Voici donc un script qui règle le problème.

Problème :

Sous Oracle, les séquences gèrent les « numéro auto » de façon indépendante. Si aucun trigger n’est mis en place, il faut appeler manuellement la valeur suivante de l’id au moment de faire une insertion. Mais dans le cadre d’un import de données brutes, les sequences ne sont pas mises à jour. La valeur « START » de la séquence ne peut être mise à jour…

Solution :

Il faut donc détruire les séquences et les recréer en prenant comme valeur de début, le MAX de l’id de la table en question + 1.

Pour la destruction de l’ensemble des séquences, voilà le script :

begin
  for i in (select sequence_name from user_sequences ) loop
    execute immediate ‘drop sequence ‘||i.sequence_name;
  end loop;
end;
/

Puis pour la création :

DECLARE
 PROCEDURE CREATE_SEQ (table_name IN VARCHAR2, seq_name IN VARCHAR2, column_name IN VARCHAR2, nb_cache IN INTEGER)
 IS 
  cursor_handle INTEGER;
  seq_sql VARCHAR2(400);
  resu INTEGER;
  seq_start INTEGER;
 BEGIN
  
  seq_sql := ‘SELECT MAX(‘ || column_name || ‘) FROM ‘ || table_name;  
    
  cursor_handle := DBMS_SQL.OPEN_CURSOR;
  DBMS_SQL.PARSE(cursor_handle,seq_sql,DBMS_SQL.V7);
  DBMS_SQL.DEFINE_COLUMN (cursor_handle,1,seq_start);
  resu:= DBMS_SQL.EXECUTE (cursor_handle);
  
  IF DBMS_SQL.FETCH_ROWS (cursor_handle) = 0
  THEN
   seq_start:=1;
  ELSE
   DBMS_SQL.COLUMN_VALUE(cursor_handle,1,seq_start);
   IF seq_start IS NULL
   THEN
    seq_start:=1;
   ELSE 
    seq_start:=seq_start + 1;
   END IF; 
  END IF; 
        
  DBMS_SQL.CLOSE_CURSOR (cursor_handle);
  
  seq_sql := ‘CREATE SEQUENCE ‘ || SUBSTR(seq_name,1,26) || ‘ START WITH ‘
    || TO_CHAR(seq_start) || ‘ INCREMENT BY 1 CACHE ‘ || TO_CHAR(nb_cache);
  cursor_handle := DBMS_SQL.OPEN_CURSOR;
  DBMS_SQL.PARSE(cursor_handle,seq_sql,DBMS_SQL.V7);
  resu:= DBMS_SQL.EXECUTE (cursor_handle);
  DBMS_SQL.CLOSE_CURSOR (cursor_handle);
  
  DBMS_OUTPUT.PUT_LINE(‘Sequence ‘ || table_name || ‘ créée.’);
 END;
 
BEGIN
 DBMS_OUTPUT.ENABLE(10000);
 CREATE_SEQ (‘table’, ‘sequence’,’id’, 5);
 CREATE_SEQ (‘table2’, ‘sequence2′,’id2’, 5);
 
END;
/
 

Mots clé anglais sur le sujet :

« Oracle update sequence » « restart sequence max value »