Oracle SQL:检查时间是否在两个实例之间(不包括dd / mm / yyyy)

时间:2015-10-15 20:36:55

标签: sql oracle time oracle-apex

我正在构建一个Oracle APEX应用程序,记者可以在其中引入导演为广播选择的文章,以及新闻阅读器(如果创建广播,他们可以阅读文章)。我有点坚持以下几点:
我想创建一个Oracle SQL查询,它在" user"中选择记录的名字和姓氏。表,当它的可用性(存储在另一个表中," Beschikbaarheid")满足给定的情况时(用户在广播日的开始时间> =广播开始时间和广播日的用户结束时间< =广播)时间结束)。 我自己编写了以下查询。

SELECT voornaam || ' ' || achternaam AS display_value, id AS return_value
FROM Gebruiker
WHERE id NOT IN (SELECT Nieuwslezerselectie.nieuwslezerid FROM Nieuwslezerselectie 
WHERE -- other conditions
AND id IN (SELECT gebruikerid 
           FROM Beschikbaarheid 
           WHERE (dag = to_char(to_date(:P91_DATUM,'DD-MON-YYYY'),'Day'))
           AND (to_date(:P91_BEGINTIJD,'HH24:MI') >= to_date(begintijd,'HH24:MI'))
           AND (to_date(:P91_EINDTIJD,'HH24:MI') <= to_date(eindtijd,'HH24:MI'))
          );

(对不起,如果你在阅读本文时遇到问题,请使用荷兰语命名。请随意询问是否有不明确的内容。)

但是,如果新闻阅读器在广播时可用,则此查询所链接的APEX选择列表不会显示任何内容。我认为问题是&#34; Begintijd&#34;和#34; Eindtijd&#34;存储为时间戳,因为值应该是与日期无关的(哪些时间戳不是),但我不知道如何存储它们。作为varchar可能吗?

我真诚地希望你有任何想法。提前谢谢!

吕克

更新1

在帮助下我重写了查询,现在看起来像这样:

AND id IN (SELECT gebruikerid 
       FROM Beschikbaarheid
       WHERE (dag = to_char(to_date(:P91_DATUM,'DD-MON-YYYY'),'Day','NLS_DATE_LANGUAGE=Dutch'))
       AND (
            to_date('01-01-2000' || ' ' || to_char(to_timestamp(:P91_BEGINTIJD),'HH24:MI'),'DD-MM-YYYY HH24:MI') 
            BETWEEN
            to_date('01-01-2000' || ' ' || to_char(begintijd,'HH24:MI'),'DD-MM-YYYY HH24:MI')
            AND
            to_date('01-01-2000' || ' ' || to_char(eindtijd,'HH24:MI'),'DD-MM-YYYY HH24:MI')
           )
       AND (
            to_date('01-01-2000' || ' ' || to_char(to_timestamp(:P91_EINDTIJD),'HH24:MI'),'DD-MM-YYYY HH24:MI') 
            BETWEEN 
            to_date('01-01-2000' || ' ' || to_char(begintijd,'HH24:MI'),'DD-MM-YYYY HH24:MI')
            AND
            to_date('01-01-2000' || ' ' || to_char(eindtijd,'HH24:MI'),'DD-MM-YYYY HH24:MI')
           )
      );

但是,我现在正在尝试访问页面时, ORA-01840:输入值不足以导致日期格式错误。我还没有发现导致错误的原因。有人有任何线索吗?

更新2

现在我很困惑。原来我的页面变量并不需要to_char等,所以我删除了那些(to_char等)。现在我通常发送到正确的页面,但是我输入的最后一个值&#34;设置这些项目/使用这些值&#34;上一页的文本字段不会发送。这就是我现在在这些文本字段中所拥有的:

set items with values

在此图像中,P85_BEGINTIJD无法发送。我也改变了价值观,但这并没有什么不同。您可以使用请求发送的值的数量是否有限制?

3 个答案:

答案 0 :(得分:0)

不要使用时间戳。一个日期字段,包括日期和时间, 有关oracle中日期字段的更多信息: Oracle Data types, see paragraph Overview of DATE Datatype

答案 1 :(得分:0)

如果我说得对,你有两列数据类型 TIMESTAMP ,你需要用一个参数来限制它,但是只使用一小时的部分

最简单的方法是使用HH格式的字符串参数:MI

 select begintijd, to_char(begintijd,'HH24:MI') begintijd_hhmi, 
 eindtijd, to_char(eindtijd,'HH24:MI') eindtijd_hhmi from tst
 where '22:00' between to_char(begintijd,'HH24:MI')  and to_char(eindtijd,'HH24:MI')
 ;

请注意,您使用 to_char 并使用日期掩码 HH24:MI 来摆脱日期/时间的不相关部分。

可能更好,更灵活的方法是使用 INTERVAL

 with t2 as (
  select 
  begintijd, begintijd - trunc(begintijd) begintijd_hhmi, 
  eindtijd, eindtijd - trunc(eindtijd) eindtijd_hhmi from tst)
 select * from t2
 where INTERVAL '22:00' HOUR TO MINUTE between begintijd_hhmi  and  eindtijd_hhmi
 ;

使用时间戳和截断时间戳的差异来计算间隔(小时和分钟)。但请注意,如果时间戳可以包含秒或其中的一小部分,则可能需要将它们修剪掉,例如:与

 NumToDsInterVal(60*extract(hour from begintijd)+extract(minute from begintijd),'MINUTE') begintijd_hhmi

答案 2 :(得分:0)

好的,最终,我能够解决它。在我的上一次更新中,唯一持久的问题是某些变量未发送到下一页。我无法找到问题的根本原因,所以我做了一个解决方法。

通常发送到下一页的唯一变量是P91_UITZENDING(Uitzending的PK)。幸运的是,我需要的其他变量(begintijd,eindtijd和datum)是Uitzending的属性,所以我能够在相应页面项的源代码中使用这样的语句派生它们:

SELECT to_char(begintijd,'HH24:MI')
-- replace with eindtijd for eindtijd, and for date: to_char(datum,'DD-MON-YYYY')
FROM Uitzending
WHERE id = :P91_UITZENDING

选择框的最终SQL查询:

SELECT voornaam || ' ' || achternaam AS display_value, id AS return_value
FROM Gebruiker
WHERE -- Other statements
AND id IN (SELECT gebruikerid 
           FROM Beschikbaarheid
           WHERE (dag = to_char(to_date(:P91_DATUM,'DD-MON-YYYY'),'fmDay','NLS_DATE_LANGUAGE=Dutch'))
           AND (
                to_date('01-01-2000' || :P91_BEGINTIJD,'DD-MM-YYYY HH24:MI') 
                BETWEEN
                to_date('01-01-2000' || to_char(begintijd,'HH24:MI'),'DD-MM-YYYY HH24:MI')
                AND
                to_date('01-01-2000' || to_char(eindtijd,'HH24:MI'),'DD-MM-YYYY HH24:MI')
               )
           AND (
                to_date('01-01-2000' || :P91_EINDTIJD,'DD-MM-YYYY HH24:MI') 
                BETWEEN 
                to_date('01-01-2000' || to_char(begintijd,'HH24:MI'),'DD-MM-YYYY HH24:MI')
                AND
                to_date('01-01-2000' || to_char(eindtijd,'HH24:MI'),'DD-MM-YYYY HH24:MI')
               )
          );

我仍然不知道为什么开始,eindtijd和数据不能正常发送,但至少它现在正在发挥作用。

谢谢大家的想法和帮助!