Search code examples
phpsqlregexsap-ase

Discover primary / unique keys in Sybase ASE: Regular Expression and PHP


I get this info from sp_helpconstraint iyas_grandtest.

constraint_name         definition
iyas_grand_2317208971   PRIMARY KEY INDEX ( id) : CLUSTERED
iyas_grand_2317208972   UNIQUE INDEX ( unik) : NONCLUSTERED
iyas_grand_2317208973   UNIQUE INDEX ( comp_unik1, comp_unik2) : NONCLUSTERED

I want to extract:

  1. id from PRIMARY,
  2. unik from UNIQUE,
  3. comp_unik1 and comp_unik2 from UNIQUE

as follows:

  1. $keys[] = id
  2. $unique['iyas_grand_2317208972'][] = unik
  3. $unique['iyas_grand_2317208973'][] = comp_unik1
  4. $unique['iyas_grand_2317208973'][] = comp_unik1

note that sometimes the PRIMARY key could be PRIMARY KEY INDEX ( id, id2).

What I have now has flaw (only detect 1 key for composite key, and truncate name if has _, i.e 'comp_unik1' become 'comp').

$sql = sybase_query("sp_helpconstraint iyas_grandtest");        
while( $row = sybase_fetch_assoc($sql) ) {
            $txt= $row['definition'];
            $re1='(PRIMARY)';   # Word 1
            $re2='.*?'; # Non-greedy match on filler
            $re3='(?:[a-z][a-z]+)'; # Uninteresting: word
            $re4='.*?'; # Non-greedy match on filler
            $re5='(?:[a-z][a-z]+)'; # Uninteresting: word
            $re6='.*?'; # Non-greedy match on filler
            $re7='((?:[a-z][a-z]+))';   # Word 2

             if ($c=preg_match_all ("/".$re1.$re2.$re3.$re4.$re5.$re6.$re7."/is", $txt, $matches))
            {
                $word =$matches[2][0];
                    $keys = explode(",", $word);
            }

    }

Solution

  • You can try and match:

    ^\w+\s+(?:PRIMARY KEY|UNIQUE) INDEX \(([^)]+)\)
    

    for each line, then capture $1 which is what is between parentheses, and use explode as you already do on $1.