Foxhound is the better* Database Monitor for SQL Anywhere.
*better: More thorough, more relevant, more effective.
...more Alerts, more All Clears, more details, more control in your hands.
|
Breck Carter
Last modified: July 15, 1996
mail to: bcarter@bcarter.com
[Home]
How can I write a SQL update command to find and modify search strings embedded within character columns?
If you're using SQL Anywhere 5 you can use the new PatIndex function:
The pattern parameter isn't restricted to ordinary characters surrounded by percent signs. It can be something like
PatIndex ( '%[_][a-z0-9]%', company_name )
to find a single underscore followed by a lowercase character or digit.
Here are some of the rules for building fancy patterns:
_ Matches any one character. % Matches a string of zero or more characters. [string] Matches any single character in 'string'. The 'string' can contain ranges like a-z which matches any character from a to z. [^string] Matches any single character not in 'string'. The ^ must appear as the first character inside the brackets to have this effect. [x] Matches a single character 'x' which can be one of _ % [ ] ^. In other words, '[_]' and '_' work differently. [x-] Matches either 'x' or '-'. [x%] Matches either 'x' or '%'. [x^] Matches either 'x' or '^'.
It is a peculiarity of PatIndex that the pattern '%string%' returns the position of 'string' within the search target. In other words, the surrounding '%' characters are treated differently from any '%' characters that might be embedded within the 'string' pattern itself.
Here's an example of how valuable and powerful PatIndex is: Repairing
the PowerBuilder Extended Catalog tables. Incorrect use of a product
like ERwin can sometimes cause the PBCATCOL label and header values to
contain the raw column names themselves. For example, "last_updated"
shows up instead of "Last Updated:":
The PatIndex function can be combined with the new "SQL Batch" facility to write a series of commands that regenerate the PBCATCOL label and header values from scratch:
/* PBC_FIX.SQL - Regenerate PBCATCOL Labels and Headers */ /* Before running this from the Database Painter, change */ /* Preferences - Database - TerminatorCharacter to something */ /* other than a semicolon. A backslash is used here. */ begin declare not_done char ( 1 ); declare fix_count integer; declare loop_count integer ; /* Initialize the label and header to match the column name. */ update pbcatcol set pbc_labl = ucase ( left ( pbc_cnam, 1 ) ) + substr ( pbc_cnam, 2 ) + ':', pbc_hdr = ucase ( left ( pbc_cnam, 1 ) ) + substr ( pbc_cnam, 2 ); /* Optional where clause to exclude labels and headers already filled in... where ( ifnull ( pbc_labl, '', trim ( pbc_labl ) ) = '' ) AND ( ifnull ( pbc_hdr, '', trim ( pbc_hdr ) ) = '' ) ; */ /* Strip underscores and capitalize words in labels. */ set fix_count = ( select count(*) from pbcatcol where patindex ( '%[_][a-z0-9]%', pbc_labl ) > 0 ) ; if fix_count > 0 then set not_done = 'T'; else set not_done = 'F'; end if; set loop_count = 0; /* safety limit */ while not_done = 'T' loop set loop_count = loop_count + 1; update pbcatcol set pbc_labl = left ( pbc_labl, patindex ( '%[_][a-z0-9]%', pbc_labl ) - 1 ) + ' ' + ucase ( substr ( pbc_labl, patindex ( '%[_][a-z0-9]%', pbc_labl ) + 1, 1 ) ) + substr ( pbc_labl, patindex ( '%[_][a-z0-9]%', pbc_labl ) + 2 ) where locate ( pbc_labl, '_' ) > 0; set fix_count = ( select count(*) from pbcatcol where patindex ( '%[_][a-z0-9]%', pbc_labl ) > 0 ) ; if fix_count <= 0 then set not_done = 'F'; end if; if loop_count >= 20 then set not_done = 'F'; /* let's stop now */ end if; end loop; /* Strip underscores and capitalize words in headers. */ set fix_count = ( select count(*) from pbcatcol where patindex ( '%[_][a-z0-9]%', pbc_hdr ) > 0 ) ; if fix_count > 0 then set not_done = 'T'; else set not_done = 'F'; end if; set loop_count = 0; /* safety limit */ while not_done = 'T' loop set loop_count = loop_count + 1; update pbcatcol set pbc_hdr = left ( pbc_hdr, patindex ( '%[_][a-z0-9]%', pbc_hdr ) - 1 ) + ' ' + ucase ( substr ( pbc_hdr, patindex ( '%[_][a-z0-9]%', pbc_hdr ) + 1, 1 ) ) + substr ( pbc_hdr, patindex ( '%[_][a-z0-9]%', pbc_hdr ) + 2 ) where locate ( pbc_hdr, '_' ) > 0; set fix_count = ( select count(*) from pbcatcol where patindex ( '%[_][a-z0-9]%', pbc_hdr ) > 0 ) ; if fix_count <= 0 then set not_done = 'F'; end if; if loop_count >= 20 then set not_done = 'F'; /* let's stop now */ end if; end loop; end \
Here's what PBCATCOL looks like after the repairs: