2017-03-22 1 views
0

J'utilise Oracle Managed Data Access Client pour .net. Je dois transmettre mon horodatage (format: MM/jj/aaaa hh: mi: ss: ff AM) à partir du paramètre et également le convertir en timestamp spécifique à Oracle en utilisant la fonction TIME_STAMP(). Si j'injecte directement les valeurs, cela fonctionne. Mais si je passe à travers le paramètre, j'obtiens une erreur. Je crois, il prend le paramètre comme un objet plutôt que varchar/string. Donc, comment puis-je transmettre mes valeurs en tant que OracleParameter et le convertir en timeStamp spécifique à Oracle.Comment analyser la date passée en tant que valeur de paramètre odp.net?

Mais cela ne va pas. Cela affichera les données pour la date mais pas pour l'horodatage spécifié (j'ai même besoin de comparer la fraction de secondes).

string SELECTGROUPSESSIONS = @"SELECT * FROM (
               SELECT Recent.sent_date, Recent.thread_id, Recent.body_string, Recent.body_text, 
               Recent.message_string, Recent.message_text, Recent.body_len, Recent.from_jid , 
               Recent.to_jid, Recent.history_flag 
               FROM JM Recent Left Join 
               (Select * from JM where sent_date > TO_TIMESTAMP(:FromHistory,'MM/dd/yyyy hh:mi:ss:ff AM')) Old 
               on (Recent.body_string=Old.body_string and 
               Recent.body_len=Old.body_len and Recent.from_jid=Old.from_jid and 
               REGEXP_REPLACE(Recent.to_jid , '([/])\w+', '') = REGEXP_REPLACE(Old.to_jid , '([/])\w+', '') 
               and Recent.history_flag=Old.history_flag and Old.sent_date < Recent.sent_date) 
               where Recent.msg_type ='g' 
               and Recent.body_len>0 and Recent.sent_date > TO_TIMESTAMP(:FromDate,'MM/dd/yyyy hh:mi:ss:ff AM') 
               and Recent.sent_date < TO_TIMESTAMP(:ToDate,'MM/dd/yyyy hh:mi:ss:ff AM') 
               and Old.sent_date is null 
               order by Recent.sent_date asc 
               ) 
               WHERE rownum <= {0}"; 

Pour les valeurs:

enter image description here

Ma requête devrait ressembler.

SELECT * FROM ( 
         SELECT Recent.sent_date, Recent.thread_id, Recent.body_string, 
         Recent.body_text, Recent.message_string, Recent.message_text, Recent.body_len, 
         Recent.from_jid , Recent.to_jid, Recent.history_flag FROM JM Recent Left Join 
         (Select * from JM where sent_date > 
         TO_TIMESTAMP('02/19/2017 10:43:00:8357400 AM','MM/dd/yyyy hh:mi:ss:ff AM')) Old on 
         (Recent.body_string=Old.body_string and Recent.body_len=Old.body_len and 
         Recent.from_jid=Old.from_jid and 
         REGEXP_REPLACE(Recent.to_jid , '([/])\w+', '') = REGEXP_REPLACE(Old.to_jid , '([/])\w+', '') 
         and Recent.history_flag=Old.history_flag and Old.sent_date < Recent.sent_date) 
         where Recent.msg_type ='g' and Recent.body_len>0 and Recent.sent_date > 
         TO_TIMESTAMP('03/21/2017 10:43:00:8357400 AM','MM/dd/yyyy hh:mi:ss:ff AM') and 
         Recent.sent_date < TO_TIMESTAMP('03/22/2017 09:02:28:3049506 AM','MM/dd/yyyy hh:mi:ss:ff AM') 
         and Old.sent_date is null order by Recent.sent_date asc ) WHERE rownum <= 500 

C# Codes:

selectCommand = _factory.GetDbCommand(queryStatement, SqlConnection); 

      selectCommand.Parameters.Clear(); 
      using (selectCommand) 
      { 
       if (parameters != null) 
       { 
        foreach (var param in parameters) 
        { 
         selectCommand.Parameters.Add(_factory.CreateParameter(param.Key, param.Value));       

        } 
       } 

       try 
       {      

        using (
         var reader = selectCommand.ExecuteReader()) 
        { 
         processReader(reader); 
        } 

Résultat: Se pourrait-il en raison de non-concordance des formats de date?

enter image description here

+0

Vous n'avez pas besoin tout type d'analyse syntaxique si vous utilisez des paramètres avec le type correct. –

+0

Quels sont ces espaces réservés '{0}'? Ce ne sont pas des identifiants de paramètres Oracle valides. La requête devrait se terminer par 'WHERE rownum <=: num ', pas' WHERE rownum <= {0} '. Utilisez-vous la manipulation de chaînes pour générer la requête? C'est garanti pour vous exposer à des attaques SQL Injection, ou des erreurs de conversion au mieux –

+0

@PanagiotisKanavos désolé c'était juste pour expliquer: si je passe directement les valeurs. Cela fonctionnerait. Mais si je passe la même valeur que le paramètre oracle, ce n'est pas le cas. Je reçois les données, mais elles ne correspondent pas exactement à l'horodatage spécifié. Mon horodatage est au format: 02/09/2017 10: 47: 01: 273161000 AM. –

Répondre

1

Vous devriez essayer d'ajouter les valeurs des paramètres directement, par exemple au lieu de

string SELECTGROUPSESSIONS = "SELECT ... 
... sent_date > TO_TIMESTAMP(:FromHistory,'MM/dd/yyyy hh:mi:ss:ff AM') 

essayer

string SELECTGROUPSESSIONS = "SELECT ... 
... sent_date > :FromHistory ..." 

selectCommand.Parameters.Add("FromHistory", OracleDbType.TimeStamp, ParameterDirection.Input).Value = {the C# DateTime value}; 
+0

J'ai essayé votre méthode et aussi plusieurs autres mais je n'ai aucune idée pourquoi cela ne fonctionne pas. Comme dans l'image affichée ci-dessus, je ne reçois pas les données de l'heure indiquée. Mais si j'exécute directement ma requête avec les valeurs de sqlPlus/developer, j'obtiens la réponse requise. –

+1

@ Avi-B poster ce que vous * actuallly * essayé et les * résultats * réels. Soit vous n'avez pas essayé ce qui est décrit dans cette réponse, soit vous avez exécuté une requête * différente *. Une autre possibilité est que vous changiez de mois et de jours lorsque vous avez codé en dur la chaîne de date. Les paramètres ne sont pas endommagés et ne subissent pas de conversions de format –