-1

名前: Calc_Anniversary

入力: Pay_Date、Hire_Date、Termination_Date

出力: が従業員の Hire_Date の記念日の場合は "Y"、そうでない場合は "N"、記念日の前に解雇された場合は "T"。

説明: TO_CHAR 関数を使用して、従業員の雇用日、退職日、および処理日の月と日を保持するローカル変数を作成します。最初に、彼が記念日の前に解雇されたかどうかを確認してください。記念日は支払い期間中のどの日でもかまいません。そのため、支払い期間の 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));

error FUNCTION Calc_Anniversary コンパイルされた
警告: 警告付きで実行が完了しました

4

2 に答える 2

1

関数は何かを返さなければなりません。RETURN ステートメントが関数の最後のステートメントであることは正常です。

これを行わないことを選択したため、エラーが発生しています。すべての RETURN ステートメントは条件付き分岐に埋め込まれているため、ロジックがループを実行しない場合、RETURN を実行することはありません。

あなたのループロジックは混乱しています。カウントとして入力していますpaydate(なぜ「paydate」と呼ばれるのですか?)が、初期化クエリは「paydate」を incoming_anniversary_date日付であるパラメーターと比較します。おそらく、それを表の列と比較するつもりでしpay_dateたか?あなたのコードは実際にやっていますか?

とにかく、最も重要なことは、関数にいくつかのベスト プラクティスを導入することです。変数を設定し、1 つの 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 に答える