Sql 从2个参考列中获取两个日期之间的差异

Sql 从2个参考列中获取两个日期之间的差异,sql,database,oracle,plsql,Sql,Database,Oracle,Plsql,我是SQL新手,我正在尝试获取两个参考列值之间的两个值之间的日期。 我目前的表格设置如下: 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 (P

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

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)
插入的数据如下所示:

我试图用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;

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

Oracle 11g R2架构设置:

问题1:

:


也为3个表发布DDL。已更新。你指的是表格插入,对吗?不。我需要表格的DDL结构脚本电影表格、人物表格和角色_Table@XING-从类型来看,这是不言而喻的-创建表Person\u表Person\u类型@lesovren'11-NOV-1974'不是日期,而是字符串文字-Oracle将尝试使用to_DATE和NLS_DATE_FORMAT会话参数作为格式模型将其隐式转换为日期;但是,该会话参数可以由用户随时更改,并且会在不同国家/地区和语言之间更改其默认值,从而导致有趣且难以调试的问题。更好的做法是使用日期文字“1974-11-11”或明确说明格式模型和语言为“1974年11月11日”、“DD-MON-YYYY”,“NLS_DATE_LANGUAGE=ENGLISH”这将不起作用-Role_表可以有多行,并且您不需要将它们过滤到当前行,除了这样一个事实,即您不需要从整个表中进行选择,因为对象是表行,您可以只使用对象的属性,并且当PersonId是REF时,您不能使用PersonId.DateBorn-您可以需要使用DEREF PersonId.DateBorn。
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;
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;
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'
)
/
SELECT Name,
       r.Actor_Age()
FROM   Role_table r
|        NAME | R.ACTOR_AGE() |
|-------------|---------------|
| Some Person |            30 |