简体   繁体   English

如何正确地使用日期参数调用函数?

[英]How to properly call a function with date parameter?

I had to create a function that computes how many people are born from the given date as a parameter. 我必须创建一个函数来计算从给定日期出生的人数作为参数。

I have a table named Person with date of birth written as "YY/MM/DD". 我有一个名为“人”的表,出生日期写为“ YY / MM / DD”。

The function is as follows : 功能如下:

create or replace function persons_count(p_date date) RETURN NUMBER IS cnt NUMBER; 
BEGIN`
  SELECT COUNT(*) INTO cnt FROM person
  WHERE date_of_birth > To_Date(p_date,'dd.mm.yyyy'); 
  RETURN cnt;
END;

And i tried to run this function : 我试图运行此功能:

SET SERVEROUTPUT ON

DECLARE
  num NUMBER;
BEGIN
  num := persons_count('82/11/01');
  dbms_output.put_line(num);
END;

but it doesn't work. 但这不起作用。 I get a message that number of parameters is not valid or that tha day/month is invalid. 我收到一条消息,指出参数数量无效或日/月无效。

Your function takes a date parameter, but you are passing a string; 您的函数有一个date参数,但是您要传递一个字符串。 and within the function you're converting an argument that is already a date into a date, which doesn't make much sense. 并且在函数中,您正在将已经是日期的参数转换为日期,这没有多大意义。 Both are relying on your session NLS_DATE_FORMAT to do do implicit conversions. 两者都依靠您的会话NLS_DATE_FORMAT进行隐式转换。 Inside the function you're effectively doing: 在功能内,您实际上是在做:

WHERE date_of_birth > To_Date(to_char(p_date, NLS_DATE_FORMAT),'dd.mm.yyyy'); 

while in the call you're doing: 在通话中,您正在执行以下操作:

persons_count(to_date('82/11/01', NLS_DATE_FORMAT));

If you're lucky your session will be set up right, but here you're relying on conflicting formats, so one or the other will fail or get an unexpected answer. 如果幸运的话,您的会话将正确设置,但是在这里,您将依靠相互冲突的格式,因此一个或另一个将失败或得到意外的答案。 You shouldn't rely on NLS settings, and you shouldn't convert a date to a string and back. 您不应该依赖NLS设置,也不应将日期转换为字符串然后返回。

You want something more like: 您想要更多类似的东西:

create or replace function persons_count(p_date date)
RETURN NUMBER IS
  cnt NUMBER; 
BEGIN
  SELECT COUNT(*) INTO cnt
  FROM person
  WHERE date_of_birth > p_date;
  RETURN cnt;
END;

Although you may actually want >= p_date . 尽管您实际上可能想要>= p_date And then call it with an explicit date, such as: 然后使用明确的日期进行调用,例如:

num := persons_count(to_date('1982/11/01', 'YYYY/MM/DD));

(note the four-digit year; don't use two-digit years, even with the RR format model element), or an ANSI date literal: (请注意四位数字的年份;即使使用RR格式模型元素,也不要使用两位数的年份)或ANSI日期文字:

num := persons_count(DATE '1982-11-01');

I have a table named Person with date of birth written as "YY/MM/DD" 我有一个名为Person的表,出生日期写为“ YY / MM / DD”

If your column has data type DATE then it has no intrinsic format. 如果您的列的数据类型为DATE,则它没有内部格式。 If you query the table and see date values formatted like that then your NLS_DATE_FORMAT is YY/MM/DD or maybe RR/MM/DD; 如果查询该表并看到格式设置为日期的值,则您的NLS_DATE_FORMAT为YY / MM / DD或RR / MM / DD; or a client setting is formatting the date implicitly. 或客户端设置隐式格式化日期。 It isn't stored like that and changing the client/session settings will change how it's displayed. 它不是那样存储的,更改客户端/会话设置将更改其显示方式。 It's possible you actually have it stored as a formatted string, but that would be a really bad idea, and your question implies it is actually a date. 您实际上可能将其存储为格式化的字符串,但这是一个非常糟糕的主意,您的问题暗示它实际上是一个日期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM