在 Oracle 中生成 .Net 报价

Posted

技术标签:

【中文标题】在 Oracle 中生成 .Net 报价【英文标题】:Generate a .Net ticks in Oracle 【发布时间】:2012-09-28 16:27:30 【问题描述】:

是否有人知道如何在 PL/SQL 存储过程中生成 .Net DateTime.Ticks,而无需在 Oracle 数据库中使用 .Net 程序集?

我在 .Net 中有一项服务,将 DateTime.Ticks 值存储在 [Oracle 数据库] 列中。 现在我必须创建一个存储过程来创建类似的信息,但我必须匹配该特定列中的 .Net 刻度。

【问题讨论】:

【参考方案1】:

使用 Oracle 函数计算从纪元(0001 年 1 月 1 日午夜 12:00:00)开始的秒数,忽略闰秒,乘以 10e6(一千万)得到滴答声。

.NET时间刻度的定义见here。

【讨论】:

@ColeJohnson:这是 Unix 时间戳的时代。但这个问题与生成 Unix 时间戳无关。【参考方案2】:

我弄清楚了整个算法并构建了一个函数。它就像一个魅力......

这里是:

CREATE OR REPLACE FUNCTION GLOBAL.Get_DotNet_Ticks
(
       inTimestamp IN TIMESTAMP
) RETURN NUMBER AS
-- **********************************************************************************
-- File name:         Get_DotNet_Ticks
-- Original Author:   Roberto Lopes
-- Creation Date:     October 2012
-- Description:       Returns the number of ticks for the provided timestamp, based
--                    on the Microsoft .Net algorithm
-- **********************************************************************************
BeginDate TIMESTAMP := TO_TIMESTAMP('0001-01-03', 'YYYY-MM-DD'); --.Net Ticks are counted starting from this date
BEGIN
    RETURN (EXTRACT(DAY FROM(inTimestamp - BeginDate)) * 86400000 + (TO_NUMBER(TO_CHAR(inTimestamp, 'SSSSSFF3'))))*10000;
END Get_DotNet_Ticks;

【讨论】:

【参考方案3】:

我不熟悉 Oracle PL/SQL,但以下 DateToTicks() C# 函数(直接取自 Mono 的开源 DateTime 实现)揭示了在给定 DateTime 值的各个组件的情况下如何计算刻度的详细信息。也许它有帮助。

祝你好运!

      public const long TicksPerDay = 864000000000L;
      private static readonly int[] daysmonth =  0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ;
      private static readonly int[] daysmonthleap =  0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ;

      private static int AbsoluteDays(int year, int month, int day) 
         int[] days;
         int temp = 0, m = 1;

         days = (IsLeapYear(year) ? daysmonthleap : daysmonth);

         while( m < month )
            temp += days[m++];
         return ((day - 1) + temp + (365 * (year - 1)) + ((year - 1) / 4) - ((year - 1) / 100) + ((year - 1) / 400));
      

      public static bool IsLeapYear(int year) 
         if( year < 1 || year > 9999 )
            throw new ArgumentOutOfRangeException();
         return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
      


      internal static bool CalculateTicks(int days, int hours, int minutes, int seconds, int milliseconds, out long result) 
         // there's no overflow checks for hours, minutes, ...
         // so big hours/minutes values can overflow at some point and change expected values
         int hrssec = (hours * 3600); // break point at (Int32.MaxValue - 596523)
         int minsec = (minutes * 60);
         long t = ((long)(hrssec + minsec + seconds) * 1000L + (long)milliseconds);
         t *= 10000;

         result = 0;

         bool overflow = false;
         // days is problematic because it can overflow but that overflow can be 
         // "legal" (i.e. temporary) (e.g. if other parameters are negative) or 
         // illegal (e.g. sign change).
         if( days > 0 ) 
            long td = TicksPerDay * days;
            if( t < 0 ) 
               long ticks = t;
               t += td;
               // positive days -> total ticks should be lower
               overflow = (ticks > t);
             else 
               t += td;
               // positive + positive != negative result
               overflow = (t < 0);
            
          else if( days < 0 ) 
            long td = TicksPerDay * days;
            if( t <= 0 ) 
               t += td;
               // negative + negative != positive result
               overflow = (t > 0);
             else 
               long ticks = t;
               t += td;
               // negative days -> total ticks should be lower
               overflow = (t > ticks);
            
         

         if( overflow ) 
            return false;
         

         result = t;
         return true;
      

      public static bool  DateToTicks (int year, int month, int day, int hour, int minute, int second, int millisecond, out long result) 
         return CalculateTicks(AbsoluteDays(year, month, day), hour, minute, second, millisecond, out result);
      

【讨论】:

【参考方案4】:

Ticks property 是 long,因此您需要使用合适的 Oracle 类型:'Number'

【讨论】:

这个想法是在 oracle 中生成刻度。它不是来自任何 .Net 应用程序(我已经拥有)。

以上是关于在 Oracle 中生成 .Net 报价的主要内容,如果未能解决你的问题,请参考以下文章

如何使用现有的Oracle序列在hibernate中生成id?

在 Oracle 的同一个假脱机中生成输出

在 Oracle 中生成动态 SQL

ORA-00904 Linq 在 Oracle 的 SQL 查询中生成错误

执行在 Oracle 中生成 csv 文件的过程时目录路径无效(在 Windows 中)

在 Oracle SQL 中生成动态列值