views:

200

answers:

2

Hello,

we have application where database contains large parts of business logic in triggers, with a update subsequently firing triggers on several other tables. I want to refactor the mess and wanted to start by extracting procedures from triggers, but can't find any reliable tool to do this. Using "Extract procedure" in both SQL Developer and Toad failed to properly handle :new and :old trigger variables.

If you had similar problem with triggers, did you find a way around it?

EDIT: Ideally, only columns that are referenced by extracted code would be sent as in/out parameters, like:

Example of original code to be extracted from trigger:

  .....
  if :new.col1 = some_var then
    :new.col1 := :old.col1
  end if
  .....

would become :

  procedure proc(in old_col1 varchar2, in out new_col1 varchar2, some_var varchar2) is
  begin
    if new_col1 = some_var then
      new_col1 := old_col1
    end if;
  end;
  ......
  proc(:old.col1,:new.col1, some_var);
A: 

This is not exactly the answer. I have not enough reputation to edit original question, obviously. The issue is that it is not a "refactoring" as we usually think of. Even when you'll create bunch of procedures from triggers, you'll need to make a proper framework to run them in order to achieve original functionality. I suspect that this will be a challenge as well.

As a solution proposal, I'd go with one python script, based on state machine (see http://www.ibm.com/developerworks/library/l-python-state.html for example). If you put strict definition of what should be translated and how, it will be easy to implement.

dbaranov
I am not sure I understood what you want to say and how do you want to edit the question. I know that the extracting of procedures is not the end unto itself. But it is big difference between having huge, duplicated and unmaintainable chunks of code in triggers and having the same code logically split in procedures (although they will still be called from the same triggers). As for the python script, I would rather go with something tried and tested specifically for PL/SQL. There _is_ such functionality already, it just does not account for :new and :old variables, it seems.
Juraj
Oh, and I can more easily write unit tests for procedures. Testing triggers is PITA.
Juraj
Sorry, my point was that I can't get how to add comment to question instead of answering. And to rephrase my point:1. To create procedures out of triggers is not exactly "refactoring" unless you going to replace bodies of triggers with something like:create or replace trigger "MY_TABLE_INS" before inserton my_table for each rowbegin my_ins_trigger_proc(:new.field,:old.field);end;It is not clear from original answer what you're going to do with procedures "extracted"2. Functionality that you need is just a text transformation, and this is the field of Python, perl etc.
dbaranov
An of course, you're on right track to get rid of triggers. These are BAD. asktom about (:
dbaranov
I have to determine whether to make :new.colX variable (or any PL/SQL variable used in the extracted block) into "in", "in out" or "out" procedure parameter. This involves parsing, so IMHO it's not just some simple text transformation. I want to split the triggers into multiple logically separated blocks of code with more clear interface. In the triggers should remain only procedure calls. Then deduplication (sorely needed) and writing unit tests. Then I can proceed with getting rid of triggers. What is unclear here?
Juraj
+1  A: 

It sounds like you want to carry out transformations on PL/SQL source. To do this reliably, you need a tool that can parse PL/SQL to some kind of compiler data structure, pattern-match against that structure and make directed changes, and then regenerate the modified PL/SQL code.

The DMS Software Reengineering Toolkit is such a tool. It is parameterized by the programming language being translated; it has off-the-shelf front ends for many languages, including C, C++, C#, Java, COBOL and ... PL/SQL.

Ira Baxter