循环检查支付期内的所有 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 天的主要内容,如果未能解决你的问题,请参考以下文章
检查字符串(句子空格分隔)以查看它是不是包含数组中的任何字符