-1

名称:Calc_Anniversary

输入:Pay_Date、Hire_Date、Termination_Date

输出:如果是员工 Hire_Date 的周年纪念日,则为“Y”,如果不是,则为“N”,如果他在周年纪念日之前被解雇,则为“T”。

说明:使用 TO_CHAR 函数创建局部变量来保存员工的 Date_of_Hire、Termination_Date 和处理日期的月份和日期。首先检查他是否在他的周年纪念日之前被终止。周年纪念日可以在支付期内的任何一天,因此将有一个循环来检查支付期内的所有 14 天,以查看其中一天是否是他的周年纪念日。

  CREATE OR replace FUNCTION Calc_anniversary(
   incoming_anniversary_date IN VARCHAR2)
   RETURN BOOLEAN
   IS
 hiredate        VARCHAR2(20);
 terminationdate VARCHAR(20);
 employeeid      VARCHAR2(38);
 paydate         NUMBER := 0;
 BEGIN
SELECT Count(arndt_raw_time_sheet_data.pay_date)
INTO   paydate
FROM   arndt_raw_time_sheet_data
WHERE paydate = incoming_anniversary_date;

WHILE paydate <= 14 LOOP
    SELECT To_char(employee_id, '999'),
           To_char(hire_date, 'DD-MON'),
           To_char(termination_date, 'DD-MON')
    INTO   employeeid, hiredate, terminationdate
    FROM   employees,
           time_sheet
    WHERE  employees.employee_id = time_sheet.employee_id
           AND paydate = pay_date;

    IF terminationdate > hiredate THEN
      RETURN 'T';
    ELSE
      IF To_char(SYSDATE, 'DD-MON') = To_char(hiredate, 'DD-MON')THEN
        RETURN 'Y';
      ELSE
        RETURN 'N';
      END IF;
    END IF;

    paydate := paydate + 1;
END LOOP;
END; 

我正在使用的表格

CREATE TABLE Employees ( EMPLOYEE_ID INTEGER,
FIRST_NAME VARCHAR2(15),
 LAST_NAME VARCHAR2(25),
 ADDRESS_LINE_ONE VARCHAR2(35),
 ADDRESS_LINE_TWO VARCHAR2(35),
 CITY VARCHAR2(28),
 STATE CHAR(2),
 ZIP_CODE CHAR(10),
 COUNTY VARCHAR2(10),
 EMAIL VARCHAR2(16),
 PHONE_NUMBER VARCHAR2(12),
 SOCIAL_SECURITY_NUMBER VARCHAR2(11),
 HIRE_DATE DATE,
 TERMINATION_DATE DATE,
 DATE_OF_BIRTH DATE,
 SPOUSE_ID INTEGER,
 MARITAL_STATUS CHAR(1),
  ALLOWANCES INTEGER,
  PERSONAL_TIME_OFF FLOAT,
  CONSTRAINT pk_employee_id PRIMARY KEY (EMPLOYEE_ID),
   CONSTRAINT fk_spouse_id FOREIGN KEY (SPOUSE_ID) REFERENCES EMPLOYEES (EMPLOYEE_ID))
 /
 CREATE TABLE Arndt_Raw_Time_Sheet_data ( EMPLOYEE_ID INTEGER,
    PAY_DATE DATE,
     HOURS_WORKED FLOAT,
     SALES_AMOUNT FLOAT,
      CONSTRAINT pk_employee_id_pay_date_time PRIMARY KEY (EMPLOYEE_ID, PAY_DATE),
      CONSTRAINT fk_employee_id_time FOREIGN KEY (EMPLOYEE_ID) REFERENCES EMPLOYEES (EMployee_ID));

错误FUNCTION Calc_Anniversary 已编译
警告:执行已完成但有警告

4

2 回答 2

1

函数必须返回一些东西。RETURN 语句通常是函数中的最后一条语句。

您选择不这样做,这就是您收到错误的原因。您所有的 RETURN 语句都嵌入在条件分支中,因此如果您的逻辑从不执行循环,您将永远不会执行 RETURN。

你的循环逻辑很混乱。您正在将您的计数填充paydate为计数(那么为什么将其称为“paydate”?)但是您的初始化查询将“paydate”与您的参数 进行比较,该参数incoming_anniversary_date是一个日期。也许您打算将它与表格列进行比较pay_date?那么谁知道呢你的代码实际上是做什么的?

无论如何,最重要的是在您的函数中引入一些最佳实践:您需要填充一个变量并将自己限制为只有一个 RETURN 语句。

   return_value char(1);

 BEGIN
     return_value := 'X';
     ....   
    WHILE paydate <= 14 LOOP
    ....
    IF terminationdate > hiredate THEN
         return_value :=  'T';
    ELSE
      IF To_char(SYSDATE, 'DD-MON') = To_char(hiredate, 'DD-MON')THEN
        return_value :=   'Y';
      ELSE
        return_value :=  'N';
      END IF;
    END IF;
       ...
  END LOOP;
  RETURN return_value;
END; 

另外,这是错误的:

IF terminationdate > hiredate THEN

您将这些日期转换为字符串,这意味着“23-JAN”>“22-DEC”。这可能不是您想要的结果。

哦,把你的变量重命名paydate为不那么容易混淆的名字,比如l_count.

于 2012-09-29T21:06:50.000 回答
0
 create or replace
 FUNCTION Calc_Anniversary(employee IN VARCHAR2)
 RETURN VARCHAR2

 IS

 counter INTEGER;
 term_date VARCHAR2(15);
  h_date VARCHAR2(15);
  p_date DATE;

  BEGIN

    SELECT TO_CHAR(hire_date, 'DD-MON'), TO_CHAR(termination_date, 'DD-MON'), pay_date INTO h_date, term_date, p_date
   FROM employees e, diaz_raw_time_sheet_data d
   WHERE e.employee_id = d.employee_id
   AND e.employee_id = employee;

FOR counter IN 0 .. 14 LOOP 
  IF term_date > h_date THEN
  RETURN 'T';
  ELSIF TO_CHAR(p_date,'DD-MON') = h_date THEN
  RETURN 'Y';
  END IF;
  p_date := p_date - 1;
END LOOP;
 IF h_date <> TO_CHAR(p_date, 'DD-MON') THEN
RETURN 'N';
 END IF;
 END;
于 2012-10-02T02:26:02.193 回答