【问题标题】:Converting SQL Server date to Oracle将 SQL Server 日期转换为 Oracle
【发布时间】:2012-11-04 16:28:18
【问题描述】:

从 SQL Server 中,我需要能够根据日期列从 Oracle 数据库中提取一些信息。

SET @foo = 'SELECT * from OPENQUERY(' + @LinkedServer +
', ''SELECT *
    FROM Table1
    WHERE date_revised > '''''+@myDate+'''''')'

不要介意' 的数字是否关闭...我删减了一些内容以缩短它。我曾尝试在 SQL Server 端使用 convert(),但我似乎找不到 Oracle 接受的格式,因此它不断抛出错误。

至少,我需要日期、小时和分钟。在 SQL Developer (Oracle) 中测试值以找出可接受的格式时,我一直遇到这种行为:

select to_date('2010-11-15 12:21:00', 'yyyy/mm/dd hh:mi:ssam') from dual

15-NOV-10

很明显,我指定了我想要时间,但它就是不同意我的看法。我在这个问题上被困太久了。

简而言之,如何将 SQL Server datetime 格式化为 Oracle 的 to_date 函数将接受的格式,以及如何使该函数正确显示日期和时间?

【问题讨论】:

  • A DATE 没有格式DATE 值的格式化由客户端完成,而不是服务器(这就是您所看到的)。如果您需要特定格式的输出,则需要使用 to_char()(在 Oracle 端)。见这里:sqlfiddle.com/#!4/d41d8/4378
  • @a_horse_with_no_name 为了使用上面指定的@myDate,我需要使用varchar 对吗?当我键入datetime -> varchar 时,它不会以某种方式格式化吗?我尝试了使用 to_char 的建议,但出现错误:OLE DB provider "OraOLEDB.Oracle" for linked server "TED_IMCD" returned message "ORA-01841: (full) year must be between -4713 and +9999, and not be 0". The dynamic sql get evaluate to WHERE date_revised > to_char(timestamp 'Nov 15 2012 11:12AM', 'YYYY.MM.DD HH24:MI:SS')
  • 你需要传递: 1. 一个字符串,代表一个已知格式的日期。 2. TO_CHAR 的参数再次定义了该格式。 to_char(timestamp 'Nov 15 2012 11:12AM', 'YYYY.MM.DD HH24:MI:SS') 没有实现之前的答案。
  • 使用 timestamp '...' 时,格式 必须 为 ISO(我在 SQLFiddle 中显示的方式)。指定日期文字是 (ANSI) SQL 标准。对于这样的 SQL 日期文字,您不能使用任意格式。

标签: sql sql-server oracle


【解决方案1】:

SET @FOO = (SELECT * ...

我对此皱眉,因为您将查询结果以及 *(所有列)分配给变量?

无论如何,a_horse_with_no_name 已经为您提供了您需要提供给 Oracle 的日期时间文本的格式,即 timestamp

SET @query = 'SELECT * FROM Table1
              WHERE date_revised > timestamp ''2010-11-15 12:21:00''';

(我将生成 YYYY-MM-DD HH:MM:SS 文本的练习留给你)

【讨论】:

  • 不,他正在构建一个包含 OPENQUERY 的字符串并将其加载到一个字符串变量中,我猜他稍后会执行......这也可能会引起一些混乱。
  • 不要挑剔,但我正在谈论这个:您正在将查询的结果和 *(所有列)分配给变量?。不是这种情况。他只是分配一个字符串。他没有分配查询的结果。但无论如何你的解决方案是正确的。
  • 我不确定添加时间戳是否有帮助。帮我理解。由于日期是字符串的一部分,因此它按字面意思发送到 Oracle。当 Oracle 解释我的日期时,它会抛出错误。例如,在 SQL 中运行 getdate() 将导致 2012-11-15 17:28:31。在 Oracle 中,如果我运行 select to_char('2012-11-15 17:28:31', 'DD-MON-YYYY') from dual,它会引发错误:ORA-01722: invalid number 01722. 00000 - "invalid number"。我假设它正在尝试查找不存在的数据,因为日期时间已转换为字符串。
  • 您想向 Oracle 提供整个查询文本(所有查询在一天结束时都以文本形式显示,除非涉及参数),包括在日期时间文字之前的“时间戳”关键字。 YYYY-MM-DD HH:MM:SS' 格式。如果您可以使 OPENQUERY 的第二个参数看起来与上图完全一样,它将被 Oracle 接受。
【解决方案2】:

假设@mydate 是 DATETIME,诀窍是在 SQL Server 上将日期时间更改为具有已知格式的字符串,然后使用该格式将其更改回 Oracle 上的 DATE。

SET @foo = 'SELECT * from OPENQUERY(' + @LinkedServer +
', ''SELECT *
     FROM Table1
WHERE date_revised > TO_DATE('''''
                     + CONVERT( varchar( max ), @myDate, 120 )
                     + ''''', ''''yyyy-mm-dd hh24:mi:ss'''') '')'

120 部分告诉 SQL Server 将日期格式化为格式为 yyyy-mm-dd hh24:mi:ss 的字符串,格式部分告诉 Oracle 如何将字符串转回日期。

【讨论】:

  • 我很确定我尝试了所有可用于格式化的选项 (1-131),oracle 并不喜欢其中任何一个。一个接近的是科威特格式(130 或 131,但不完全...)
  • 您可以按照自己喜欢的方式对其进行格式化。您只需在 TO_DATE 函数的另一侧正确地“取消格式化”它。这里发布了很多可行的解决方案。
【解决方案3】:

我想出了自己的解决方案,因为 Oracle 不与我合作。我基本上采用DATEPARTS 并在oracle 中以相同格式构建我自己的日期字符串。感谢您的全部输入。当我有更多时间时,我会尽量让这个工作正常进行。这个创可贴现在可以了。

DECLARE @year varchar(4),
    @month varchar(3),
    @day varchar(2),
    @hour varchar(2),
    @meridian varchar(2),
    @minute varchar(2),
    @second varchar(2),
    @date smalldatetime,
    @OracleTime varchar(50);

SET @date = (SELECT MAX(Processed) FROM MES_CAPP.Signoff)
SET @year = YEAR(@date)
SET @month = DATENAME(m,@date)
SET @day = DAY(@date)
-------------------------------------------------------------------------
IF (DATEPART(hh, @date) >= 12)
BEGIN
    SET @hour = DATEPART(hh, DATEADD(hh, -12, @date))
    SET @meridian = 'PM'
END
ELSE
BEGIN
    SET @hour = DATEPART(hh, @date)
    SET @meridian = 'AM'
END

SET @minute = DATEPART(MINUTE, @date)
SET @second = '00'

SET @OracleTime = @day + '-'  + @month + '-' + @year + ' ' + @hour + ':' + @minute + ':' + @second + ' ' + @meridian

【讨论】:

    【解决方案4】:

    我接受了 Jeff 的回答并将其包装在一个返回 to_date 字符串的函数中。

        CREATE FUNCTION [dbo].[fnOracleTo_DateStringFromMsSqlDate] 
    (
        @InputDate datetime
    )
    RETURNS varchar(100)
    AS
    BEGIN
    
        DECLARE @year varchar(4),
            @month varchar(3),
            @day varchar(2),
            @hour varchar(2),
            @minute varchar(2),
            @second varchar(2),
            @date smalldatetime,
            @OracleTime varchar(50),
            @returnString varchar(100)
    
        SET @year = YEAR(@InputDate)
        SET @month = Month(@InputDate)
        SET @day = DAY(@InputDate)
        -------------------------------------------------------------------------
    
            SET @hour = DATEPART(HH, @InputDate)
    
        SET @minute = DATEPART(MINUTE, @InputDate);
        SET @second = datepart(SECOND, @InputDate);
    
        SET @OracleTime = @day + '-'  + @month + '-' + @year + ' ' + @hour + ':' + @minute + ':' + @second ;
        set @returnString = 'to_date(' + char(39) +  @OracleTime  + char(39) + ',' + char(39) +  'DD-MM-YYYY HH24:MI:SS' + char(39) + ')'
    
        return @returnString;
    END
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-04
      • 2021-05-19
      • 1970-01-01
      相关资源
      最近更新 更多