Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Oracle SQL中将用户提示作为日期(甚至字符串)传递_Sql_Oracle_Truncate_Business Objects_Infoview - Fatal编程技术网

在Oracle SQL中将用户提示作为日期(甚至字符串)传递

在Oracle SQL中将用户提示作为日期(甚至字符串)传递,sql,oracle,truncate,business-objects,infoview,Sql,Oracle,Truncate,Business Objects,Infoview,我使用的是业务对象,它运行在Oracle SQL数据库之上。我没有访问PL或任何类型的SQL命令行的权限,也没有对数据库的写访问权限。我只能作为单个命令运行查询,需要输出一组定义的列 我能够从用户提示中获取数据,这些提示在SQL中显示为: @variable('Prompt1') 例如,我可以说: SELECT A.SomeDate FROM A WHERE A.SomeDate BETWEEN @variable('Start') AND @variable('End

我使用的是业务对象,它运行在Oracle SQL数据库之上。我没有访问PL或任何类型的SQL命令行的权限,也没有对数据库的写访问权限。我只能作为单个命令运行查询,需要输出一组定义的列

我能够从用户提示中获取数据,这些提示在SQL中显示为:

@variable('Prompt1')
例如,我可以说:

SELECT
    A.SomeDate
FROM
    A
WHERE
    A.SomeDate BETWEEN @variable('Start') AND @variable('End Date')
这很容易。它运行;请求用户输入一些日期;然后返回它们之间的所有匹配项(包括)

然而,问题是,用户将使用Business Objects的“Infoview”系统来运行查询,提示系统会显示一个日期选择器-默认情况下包括日期的时间部分(“01/01/2016 12:00:00 AM”)

如果用户不删除时间部分,则如果SomeDate值落在所选时间之外,可能会导致丢失记录。例如,如果我想记录今天的所有记录,那么从技术上讲,我想要00:00:00(午夜)到23:59:59之间的所有记录

我真正想做的是围绕查询变量使用TRUNC,如下所示:

WHERE
    A.SomeDate BETWEEN TRUNC(@variable('Start')) AND TRUNC(@variable('End Date'))
。。。但是,这会导致编译错误:“不一致的数据类型:预期的日期编号”。我不知道为什么Oracle会在编译提示符之前将其视为数字数据类型

有人知道我如何将@variable值转换成可以截断为日期值的值吗

因此,我正试图找到一个解决办法。我想到的一件事是,我是否可以使用TO_date将prompt变量显式转换为日期

编辑:有人向我指出TRUNC将不起作用,因为“12:00:00 AM”已经是午夜了。因此,我认为我误解了特鲁克。它似乎将其截短到午夜:而我认为它只是完全删除了日期的时间部分,这意味着匹配将在00:00:00到23:59:59之间的任何时间返回

我真正想要的是:如果某个日期的时间部分为,例如11:03,那么当结束日期提示仅指定日期时,我如何确保将其包括在内?

尝试同时使用
TO_CHAR()
TO_Date()

WHERE
A.SomeDate > TO_DATE(TO_CHAR(@variable('Prompt1'),'ddmmyyyy'),'ddmmyyyy')

如果要在开始时的00:00:00和结束时的23:59:59之间匹配
SomeDate
值,可以将结束日期调整为该时间,而不是默认的午夜,或者使用范围,而不是
之间的

WHERE
    A.SomeDate >= @variable('Start')
AND
    A.SomeDate < @variable('End Date') + 1
或者,如果它实际上是以显示的格式作为字符串传递的,则可以显式转换它:

WHERE
    A.SomeDate >= TO_DATE(@variable('Start'), 'DD/MM/YYYY HH:MI:SS AM')
AND
    A.SomeDate < TO_DATE(@variable('End Date'), 'DD/MM/YYYY HH:MI:SS AM') + 1
在哪里
A.SomeDate>=截止日期(@variable('Start'),'DD/MM/yyyyy HH:MI:SS AM'))
及
A.SomeDate

。。。确保你有正确的格式;根据您的示例,它可能是DD/MM/YYYY或MM/DD/YYYY。

首先,您的问题不是来自提示值中的时间值,而是来自
SomeDate
中的时间值。去掉这个(使日期等于午夜)将解决这个问题

如果你可以选择修改宇宙,你最好的选择就是创建另一个对象。我假设您有一个名为
SomeDate
的对象,其SQL为
a.SomeDate
。创建另一个对象,我们将其称为
SomeDateOnly
,定义为
trunc(a.somedate)
***

由于
SomeDateOnly
始终是午夜值,因此可以在提示中使用等于,这将生成类似以下SQL的SQL:

trunc(a.somedate) = @variable('Prompt1')
由WebI渲染时,将生成:

trunc(a.somedate) = '16-08-2016 00:00:00'
这将返回在2016年8月16日00:00:00和2016年8月16日23:59:59之间带有a.somedate的所有记录

当然,您可以使用BETWEEN来选择日期范围:

 trunc(a.somedate) between @variable('Start Date') and @variable('End Date')
即使您没有访问宇宙的权限,也可以通过修改WebI生成的SQL来使用上述语法。(我想这就是你一直在做的事情)

如果上述方法对您有效,那么以下几点是不相关的,但我还是想解决它:

您收到的“无效数字”错误的原因是WebI为SQL格式化日期的方式。如果查询中有此字符串:

A.SomeDate = TRUNC(@variable('Prompt1'))
然后,WebI将用日期字符串替换@variable(…),并在将其发送到Oracle之前呈现如下所示:

A.SomeDate = TRUNC('16-08-2016 00:00:00')
当然,这对TRUNC()函数没有意义,因为没有任何东西可以告诉它它实际上是一个日期值

您可以先
to_date
prompt,但必须使用正确的日期格式。WebI将每个会话的nls_日期_格式设置为非默认格式,因此您必须使用:

A.SomeDate = TRUNC(to_date(@variable('Prompt1')),'dd-mm-yyyy hh24:mi:ss')
但同样,这是不相关的,因为您需要trunc
somedate
,而不是提示响应值


*更好的方法是将
SomeDate
重命名为
SomeDateTime
,并将新对象命名为
SomeDate


**这是很常见的-对于同一个源字段有多个对象。有时您需要日期/时间值(用于列出特定的事务),但有时您只需要日期(用于按日期计算事务)。因此,两者都可用是非常有用的。

如果日期选择器总是将时间设置为12:00:00 AM,则截断它将没有效果;“已经是午夜了!”亚历克斯·普尔-嗯,知道这个很有意思。当SomeDate值实际上有一个时间部分时会发生什么,例如11:02等等。我简化了上面的示例,但我确实想看看日期之间的情况。例如,如果我想列出今天发生的所有事件,包括11:02时发生的事件,那么“午夜”搜索将无法检索到它们。我认为截断意味着没有搜索时间部分。Oracle日期总是有时间的,你不能删除它-只能将其设置为午夜,这是trunc默认的做法。所以你想匹配记录
A.SomeDate = TRUNC(to_date(@variable('Prompt1')),'dd-mm-yyyy hh24:mi:ss')