循环检查支付期内的所有 14 天

Posted

技术标签:

【中文标题】循环检查支付期内的所有 14 天【英文标题】:Loop to check all 14 days in the pay period 【发布时间】:2012-09-29 16:16:18 【问题描述】:

名称: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));

错误 函数 Calc_Anniversary 已编译 警告:执行完成并发出警告

【问题讨论】:

如果你有一个编程问题 需要帮助以正确的方向创建此函数的循环谢谢 西给你最好的风水 作业标签是否已弃用? @Rachel,说真的,努力吧。显示错误或意外输出以及您尝试过的内容。不要只是扔掉一些代码并说“不起作用”。 【参考方案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

【讨论】:

【参考方案2】:
 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;

【讨论】:

我猜我的函数输入错误应该是pay_date、hire_date和termination_date

以上是关于循环检查支付期内的所有 14 天的主要内容,如果未能解决你的问题,请参考以下文章

检查和测试 logrotate 配置的更简单方法

如何检查for循环是不是在中间值

检查字符串(句子空格分隔)以查看它是不是包含数组中的任何字符

这是否可以检查swift数组中的所有值是否为真而不是逐个循环?

带有空主体的while循环检查易失性整数-这是啥意思?

检查 Mollie 付款是不是已支付