从 2 个 REF 列中获取两个日期之间的差异

Posted

技术标签:

【中文标题】从 2 个 REF 列中获取两个日期之间的差异【英文标题】:Getting difference between two dates from 2 REF'd columns 【发布时间】:2017-10-06 07:59:36 【问题描述】:

我是 SQL 新手,我正在尝试获取两个 REF 列值之间的两个值之间的日期。 我目前的表格设置如下:

CREATE OR REPLACE TYPE Person_Type AS OBJECT
(PersonId NUMBER,
DateBorn DATE)

CREATE OR REPLACE TYPE Movie_Type AS OBJECT
(MovieId NUMBER,
ReleaseDate DATE)

CREATE OR REPLACE TYPE Role_Type AS OBJECT
(PersonId REF Person_Type,
MovieId REF Movie_Type,
Name VARCHAR2(40),
MAP MEMBER FUNCTION Actor_Age RETURN NUMBER)

数据是这样插入的:

INSERT INTO Person_Table
VALUES (10000, '11-NOV-1974')

INSERT INTO Movie_Table
VALUES(1000000, '19-DEC-1997')

INSERT INTO Role_Table
VALUES((SELECT REF(a) FROM Person_Table a WHERE a.PersonId = 10000),
(SELECT REF(b) FROM Movie_Table b WHERE b.MovieId = 1000000),
'Some Person')

我试图让 Actor_Age 方法返回某人出生日期与电影上映日期之间的差异。我已经尝试了以下,但它不会编译..

CREATE OR REPLACE TYPE BODY Role_Type
AS
   MAP MEMBER FUNCTION Actor_Age
      RETURN NUMBER
   IS
   BEGIN
    RETURN (MONTHS_BETWEEN((SELECT g.PersonId.DateBorn FROM Role_Table g),
(SELECT f.MovieId.Releasedate FROM Role_Table f)/12));
     END;
 END;

【问题讨论】:

也为 3 个表发布 DDL。 已更新。你的意思是表格插入对吗? 没有。我需要表Movie_TablePerson_TableRole_Table的表DDL(结构脚本) @XING - 从类型中不言自明 - CREATE TABLE Person_table OF Person_Type; @lesovren '11-NOV-1974' 不是 DATE 它是一个字符串文字 - Oracle 将尝试使用 TO_DATENLS_DATE_FORMAT 会话参数作为格式模型将其隐式转换为日期;但是,该会话参数可以由用户随时更改,并且会在不同的国家和语言之间改变其默认值(导致有趣且难以调试的问题)。更好的做法是使用日期文字 DATE '1974-11-11' 或明确声明格式模型(和语言)TO_DATE( '11-NOV-1974', 'DD-MON-YYYY', 'NLS_DATE_LANGUAGE=''ENGLISH''' ) 【参考方案1】:

SQL Fiddle

Oracle 11g R2 架构设置

CREATE OR REPLACE TYPE Person_Type AS OBJECT
(PersonId NUMBER,
DateBorn DATE)
/

CREATE OR REPLACE TYPE Movie_Type AS OBJECT
(MovieId NUMBER,
ReleaseDate DATE)
/

CREATE OR REPLACE TYPE Role_Type AS OBJECT
(PersonId REF Person_Type,
MovieId REF Movie_Type,
Name VARCHAR2(40),
MAP MEMBER FUNCTION Actor_Age RETURN NUMBER)
/

CREATE OR REPLACE TYPE BODY Role_Type
AS
  MAP MEMBER FUNCTION Actor_Age
    RETURN NUMBER
  IS
    p_age NUMBER;
  BEGIN
    SELECT MONTHS_BETWEEN(
             DEREF( MovieID ).ReleaseDate,
             DEREF( PersonID ).DateBorn
           ) / 12
    INTO   p_age
    FROM   DUAL;
    RETURN p_age;
  END;
END;
/

CREATE TABLE Person_Table OF Person_Type
/
CREATE TABLE Movie_Table OF Movie_Type
/
CREATE TABLE Role_Table OF Role_Type
/

INSERT INTO Person_Table VALUES ( 10000, DATE '1970-01-01' )
/
INSERT INTO Movie_Table VALUES ( 1000000, DATE '2000-01-01' )
/
INSERT INTO Role_Table VALUES(
  (SELECT REF(a) FROM Person_Table a WHERE a.PersonId = 10000),
  (SELECT REF(b) FROM Movie_Table b WHERE b.MovieId = 1000000),
  'Some Person'
)
/

查询 1

SELECT Name,
       r.Actor_Age()
FROM   Role_table r

Results

|        NAME | R.ACTOR_AGE() |
|-------------|---------------|
| Some Person |            30 |

【讨论】:

【参考方案2】:

在pl sql中你必须使用构造select into

CREATE OR REPLACE TYPE BODY Role_Type
AS
   MAP MEMBER FUNCTION Actor_Age
      RETURN NUMBER
   IS
    v_date_born date ;
    v_realse_date date ;
   BEGIN
     SELECT deref(self.PersonId).DateBorn into v_date_born  FROM dual;
    SELECT deref(self.MovieId).Releasedate into v_realse_date FROM dual;
    RETURN (MONTHS_BETWEEN(v_date_born,v_realse_date)/12);
     END;
 END;

【讨论】:

这不起作用 - Role_Table 可以有多行并且您没有将它们过滤到当前行(除了您不需要从整个表中选择对象是表行,你可以只使用对象的属性),当PersonIDREF 时,你不能使用PersonId.DateBorn - 你需要使用DEREF( PersonId ).DateBorn

以上是关于从 2 个 REF 列中获取两个日期之间的差异的主要内容,如果未能解决你的问题,请参考以下文章

具有共同 id 的组中具有最大天数的两个日期之间的差异

Pandas DataFrame 中两个日期之间的差异

如何获取 MySQL 上两个日期之间的差异天数?

计算同一列中两个日期之间的日期

JavaScript 中两个日期的年、月、日之间的差异

Kotlin:获取两个日期之间的差异(现在和以前的日期)