title: Of what data type are the :OLD and :NEW variables in a trigger?
body: <p>Suppose you have a trigger on <code>MY_CUSTOMER_TABLE</code> and that it has a variable declared of type <code>MY_CUSTOMER_TABLE%ROWTYPE</code>. How can I assign the <code>OLD</code> value into that variable?</p>
  
  <pre><code>CREATE TRIGGER CUSTOMER_BEFORE
    BEFORE UPDATE ON MY_CUSTOMER_TABLE
    FOR EACH ROW
  DECLARE
    old_version MY_CUSTOMER_TABLE%ROWTYPE;
  BEGIN
    old_version := :OLD; /* Causes a PLS-00049 bad bind variable 'OLD' */
    old_version := OLD;  /* Causes a PLS-00201 identifier 'OLD' must be declared */
  END;
  </code></pre>
  
  <p><strong>Edit:</strong> </p>
  
  <p>To clarify, this came about because I am using triggers to archive rows from <code>MY_CUSTOMER_TABLE</code> into <code>MY_CUSTOMER_TABLE_HISTORY</code>. Depending upon the action being performed (<code>INSERT</code>, <code>UPDATE</code>, <code>DELETE</code>), I need all the fields from either <code>OLD</code> or <code>NEW</code>:</p>
  
  <pre><code>CREATE TRIGGER CUSTOMER_BEFORE
    BEFORE UPDATE ON MY_CUSTOMER_TABLE
    FOR EACH ROW
  DECLARE
    historical_record MY_CUSTOMER_TABLE_HISTORY%ROWTYPE;
  
    PROCEDURE
      copy
      (
        source_record      MY_CUSTOMER_TABLE%ROWTYPE,
        destination_record IN OUT MY_CUSTOMER_TABLE_HISTORY%ROWTYPE
      )
    BEGIN
      destination_record.customer_id   := source_record.customer_id;
      destination_record.first_name    := source_record.first_name;
      destination_record.last_name     := source_record.last_name;
      destination_record.date_of_birth := source_record.date_of_birth;
    END;
  
  BEGIN
    /* I didn't want to replicate the same assignment statements for 
       each of the two cases: */
    CASE
      WHEN INSERT OR UPDATING THEN
        copy( source_record =&gt; :NEW, destination_record =&gt; historical_record );
  
      WHEN DELETING THEN
        copy( source_record =&gt; :OLD, destination_record =&gt; historical_record );
  
    END CASE;
  
    /* Some other assignments to historical_record fields... */
  
    INSERT INTO MY_CUSTOMER_TABLE_HISTORY VALUES historical_record;
  END;
  </code></pre>
  
  <p>In this scenario, PL/SQL will not let me pass <code>:OLD</code> or <code>:NEW</code> to a procedure that expects a <code>MY_CUSTOMER_TABLE%ROWTYPE</code> argument.</p>