web-dev-qa-db-ja.com

Select句内の関数は、where句の前に渡された列を評価しますか?

(そうではない)単純な関数を使用する単純なselectステートメントがあります。この質問の目的のために、私は自分の能力を最大限に単純化して実証しようとします。

            select submission_identifier,
                   submitted_by_person_id,
                   submission_date,
                   form_version_date_time,
                   form_id,
                   func_get_open_days_2(
                     submitted_by_person_id, 
                     submission_date, 
                     form_version_date_time, 
                     form_id)` open_days
            from form_submission
            where submission_identifier = 2070;

submit_identifierはform_submissionテーブルのPKであるため、当然、このクエリは1つの結果を返します。

ご覧のとおり、この関数は4つのパラメーターを取ります。これらのパラメーターの値は、where句が評価された後のクエリの結果であると想定しています。これが関数のスニペットです。

create or replace function        func_get_Open_Days_2
   ( SUBMITTED_BY_PERSON_ID in number,
  SUBMISSION_DATE in date,
  FORM_VERSION_DATE_TIME in timestamp,
  FORM_ID in number
   )
RETURN number

IS
   n1 number:=0;
   n2 number:=0;

   cursor records is
      SELECT 
        SUBMITTED_BY_PERSON_ID,
        SUBMISSION_DATE,
        FORM_ID,
        FORM_VERSION_DATE_TIME,
        AUDIT_DATE_TIME,
        STATUS_DATE,
        SUBMISSION_STATUS_CODE,
        CREATE_USER_ID
      from form_state_audit_trail t
      where
        t.submitted_by_person_id = SUBMITTED_BY_PERSON_ID and
        t.form_id = FORM_ID and
        t.submission_date = SUBMISSION_DATE and
        t.form_version_date_time = FORM_VERSION_DATE_TIME and 
        t.submission_status_code NOT IN (3469, 3462);
        order by t.status_date asc;

   rec records%ROWTYPE;

BEGIN

dbms_output.put_line('submitted by person id ='||submitted_by_person_id);
dbms_output.put_line('form id ='||form_id);
dbms_output.put_line('submission date ='||submission_date);
dbms_output.put_line('form_version_date_time ='||form_version_date_time);

  -- go through all the durations in audit_trail table
  FOR rec in records
  LOOP

戻り値をハードコーディングして、このカーソル選択クエリに入れてみました。結果を1つ受け取ります。

これは、「records」配列またはリストの長さが1つの結果のみであることを示唆しています。 ただし、現状では多数の結果が得られています。期待する4つの値/結果を使用してwhere句が評価されていないことを示す「レコード」が返されます何がわかりません私は間違っています。 「dbms_output.put_line」はBEGINですが、LOOPの前に、期待値が関数に到達していることを確認します。

1
daniel9x

関数のWHERE句の参照は、引数リストではなく、そのSELECT句の同じ名前の列と比較されています。次のように変更してみてください(WHERE句の引数名と述語にARG_が追加されていることに注意してください)。

create or replace function        func_get_Open_Days_2
   ( ARG_SUBMITTED_BY_PERSON_ID in number,
  ARG_SUBMISSION_DATE in date,
  ARG_FORM_VERSION_DATE_TIME in timestamp,
  ARG_FORM_ID in number
   )
RETURN number

IS
   n1 number:=0;
   n2 number:=0;

   cursor records is
      SELECT 
        SUBMITTED_BY_PERSON_ID,
        SUBMISSION_DATE,
        FORM_ID,
        FORM_VERSION_DATE_TIME,
        AUDIT_DATE_TIME,
        STATUS_DATE,
        SUBMISSION_STATUS_CODE,
        CREATE_USER_ID
      from form_state_audit_trail t
      where
        t.submitted_by_person_id = ARG_SUBMITTED_BY_PERSON_ID and
        t.form_id = ARG_FORM_ID and
        t.submission_date = ARG_SUBMISSION_DATE and
        t.form_version_date_time = ARG_FORM_VERSION_DATE_TIME and 
        t.submission_status_code NOT IN (3469, 3462);
      order by t.status_date asc;
1
Joe DeRose