Professional Documents
Culture Documents
<tag>_ <tag>_%
This solution requires the use of the first option. The trick is going to be converting the user input for a specific value into a series of wildcard matches to take advantage of an index, then using the Upper() function to look for the exact match.
The information in this document is provided as-is. The information is believed to be correct, but future releases of the BusinessObjects software may render suggestions or strategies provided here useless, inappropriate, or incompatible. All information is copyright integra solutions, inc, and may not be redistributed in any form or via any media electronic or otherwise without obtaining prior written consent from the author(s).
Obviously some of these seem a bit ridiculous, but data entry errors can occur. Have you ever left the cAPS lOCK kEY on by mistake? It can happen. If the database does not enforce consistent data entry it is impossible to guarantee data formats. But would you want to have to enter all of these (and the rest of the) possible choices just to make sure that you find all of the Bakers? It turns out that looking for variations on the first two letters is enough to make effective use of an index, if there is one. In other words, the following four pattern matches would be sufficient to find every possible form of the name Baker:
BA% Ba% bA% ba% Starts Starts Starts Starts With With with with BA Ba bA ba
Once these four patterns are used, then the challenge becomes finding just Baker, and not Bakersfield, Bakerson, Bakersdozen, and so on. The final piece of the condition has to force both sides of the condition to the same format for an equality test.
Upper(customer.last_name) = Upper(Baker)
Note: Most databases contain a function that serves this purpose. It may not be Upper(); consult your database documentation to find the equivalent. (Microsoft Access uses ucase(), Oracle uses Upper() as shown here. Other databases may vary.) If there is an index on customer.last_name, that last condition would not be able to use it. That is because an index is on the last_name, not on the uppercase version of the last name. The database would be force to look at every single last name available. But, in combination with the first four pattern matching tests which will use an index, if available, this becomes a powerful search mechanism.
There are two problems with this. First, the user has no way of providing the Upper() function for the last condition unless they create a user defined object. Second, this is an extremely nonintuitive solution! Users should not have to make up for a databases deficiencies. So it is up to the designer to provide a better solution.
The information in this document is provided as-is. The information is believed to be correct, but future releases of the BusinessObjects software may render suggestions or strategies provided here useless, inappropriate, or incompatible. All information is copyright integra solutions, inc, and may not be redistributed in any form or via any media electronic or otherwise without obtaining prior written consent from the author(s).
BusinessObjects provides the concept of Predefined Condition Objects in a universe. This is a very powerful feature that is often under utilized. By creating predefined conditions, the designer takes on the task of doing strange logic like that shown above, and hiding the complexities from the user. To build this object the designer needs to do two tasks: Strip out the first two characters of the condition object (in this case the customers name) and build the first four pattern matching conditions Force the complete name into upper case for the fifth and final condition
A solution will provided for the Oracle database. (Since Microsoft Access is already case insensitive by default there is no need for this trick.) To demonstrate the solution a predefined condition called Case Insensitive Customer Name Search will be created.
Functions
Database functions required for this task are listed below. Functionality Substring Find a portion of a string Upper Translate a string to upper case Lower Translate a string to lower case Oracle Database Function Syntax substr(string, start position, length)
upper(string) lower(string)
The BusinessObjects @Prompt function will also be used for this solution. This function is used by the universe designer to prompt the user for a value, in this case a customer name to search for. The syntax for the @Prompt function is shown below.
@Prompt('message','type',[{'value1'[,'value2',...]},class_name\object_name'],mo no/multi,free/constrained)
The message is the prompt text that appears on the dialog box. The type is one of A (alphanumeric), N (numeric), or D (date) and specifies the validation logic that will be used by BusinessObjects. The third argument is optional, and can be used to provide a list of values. The list can either be hard coded into the prompt, or borrowed from an existing object. The fourth item is either mono (single value allowed) or multi (multiple values allowed). This item is optional. The fifth and final item is either free (user allowed to type values) or constrained (user must select from a list). This item is optional.
The information in this document is provided as-is. The information is believed to be correct, but future releases of the BusinessObjects software may render suggestions or strategies provided here useless, inappropriate, or incompatible. All information is copyright integra solutions, inc, and may not be redistributed in any form or via any media electronic or otherwise without obtaining prior written consent from the author(s).
The designer wants to build an object that will allow the user to find all Fondas in the system, no matter how the name is entered. Step 1 will be to prompt the user for a name to search for. Using the syntax outlined previously, a prompt can be defined as:
@prompt('Enter customer name','A',,mono,free)
No list of values will be provided. If a list is used, then the user would see both versions of Fonda and could simply select both of them. Once the user enters the name FONDA, the designer needs to construct the first four parts of the case insensitive search. The first will be to take the first character and force it to upper case, take the second character and force it to lower case, concatenate them together with the % wildcard symbol. Examine the following logic:
upper(substr(@prompt('Enter customer name','A',,mono,free),1,1)) || lower(substr(@prompt('Enter customer name','A',,mono,free),2,1)) || '%'
The first line takes the first character of the prompted value and forces it to upper case. The second line takes the second character and forces it to lower case. The Oracle concatenation symbol is the ||, which is used to put the two characters together with the % wildcard.
The information in this document is provided as-is. The information is believed to be correct, but future releases of the BusinessObjects software may render suggestions or strategies provided here useless, inappropriate, or incompatible. All information is copyright integra solutions, inc, and may not be redistributed in any form or via any media electronic or otherwise without obtaining prior written consent from the author(s).
Assuming the user had entered the value fonda for a search condition, this would translate into:
Customer.last_name like Fo%
Adding three more tests would result in a condition with the following logic:
(Customer.last_name like upper(substr(@prompt('Enter lower(substr(@prompt('Enter Customer.last_name like lower(substr(@prompt('Enter lower(substr(@prompt('Enter Customer.last_name like lower(substr(@prompt('Enter upper(substr(@prompt('Enter Customer.last_name like upper(substr(@prompt('Enter upper(substr(@prompt('Enter customer name','A',,mono,free),1,1)) || customer name','A',,mono,free),2,1)) || '%' customer name','A',,mono,free),1,1)) || customer name','A',,mono,free),2,1)) || '%' customer name','A',,mono,free),1,1)) || customer name','A',,mono,free),2,1)) || '%' customer name','A',,mono,free),1,1)) || customer name','A',,mono,free),2,1)) || '%')
OR
OR
OR
Note that the last line of code could have been written as:
Customer.last_name like upper(substr(@prompt('Enter customer name','A',,mono,free),1,2)) || '%'
The same thing could be said for the second test, where both initial characters are forced to lower case. The designer could decide which version he or she preferred. Note: if the same prompt is used more than once, as in this example, then BusinessObjects will only prompt once for the value and use the user input in every location that the prompt appears. This ensures that the same value is used throughout the condition logic, which is critical! Step 2 of the condition logic is to force an exact match. This is done with the following:
upper(Customer.last_name) = upper(@prompt('Enter customer name','A',,mono,free))
Normally this is not recommended, as the upper() function on the customer last name database column would invalidate an indexed search, as mentioned previously. However, the four Like operations built previously will use the index. This final step is just provided to find the exact match that the query writer is looking for.
The information in this document is provided as-is. The information is believed to be correct, but future releases of the BusinessObjects software may render suggestions or strategies provided here useless, inappropriate, or incompatible. All information is copyright integra solutions, inc, and may not be redistributed in any form or via any media electronic or otherwise without obtaining prior written consent from the author(s).
OR
OR
OR
|| || '%' ) AND
Without the parenthesis the logic will fail. The net result is a predefined condition that can be used to do a case insensitive search on the customer name field!
The information in this document is provided as-is. The information is believed to be correct, but future releases of the BusinessObjects software may render suggestions or strategies provided here useless, inappropriate, or incompatible. All information is copyright integra solutions, inc, and may not be redistributed in any form or via any media electronic or otherwise without obtaining prior written consent from the author(s).
The only customer that matched was the one with the exact case match, in this case HENRY FONDA. What about lower case matches?
The information in this document is provided as-is. The information is believed to be correct, but future releases of the BusinessObjects software may render suggestions or strategies provided here useless, inappropriate, or incompatible. All information is copyright integra solutions, inc, and may not be redistributed in any form or via any media electronic or otherwise without obtaining prior written consent from the author(s).
As before, only the exact case match was displayed. The user would have to define all possible case searches (in this case FONDA and fonda) to find the appropriate values. Or use the new and improved Case Insensitive Customer Name Search predefined condition object!
The information in this document is provided as-is. The information is believed to be correct, but future releases of the BusinessObjects software may render suggestions or strategies provided here useless, inappropriate, or incompatible. All information is copyright integra solutions, inc, and may not be redistributed in any form or via any media electronic or otherwise without obtaining prior written consent from the author(s).
The predefined condition can easily be added to the query panel in place of a user defined condition.
When the query is run, the prompt asks the user for a customer name:
In this example note that the user entered the name Fonda which does not even exist in the database! At least not in that form The resulting data set:
In this case both of the Fonda customers showed up, whether the name was in upper or lower case. And both names were different from what the user entered in the prompt box!
The information in this document is provided as-is. The information is believed to be correct, but future releases of the BusinessObjects software may render suggestions or strategies provided here useless, inappropriate, or incompatible. All information is copyright integra solutions, inc, and may not be redistributed in any form or via any media electronic or otherwise without obtaining prior written consent from the author(s).
Conclusion
With this idea, a universe designer can take any character object and create a predefined condition that will result in a case insensitive search. The utility of this trick, of course, depends on the format of the data in the database. If all of the data is already in upper case, it may be easier to simply train users accordingly. But if mixed case data is included, this trick can save a lot of effort on the user side. The trick is based on the idea that searching for the four variations on the initial two letters of a prompted value is enough to effectively reduce the number of rows searched. By first reducing the rows (hopefully via an indexed search) the final comparison of Upper(value) to Upper(prompt) will not cause a performance problem as it might otherwise.
The information in this document is provided as-is. The information is believed to be correct, but future releases of the BusinessObjects software may render suggestions or strategies provided here useless, inappropriate, or incompatible. All information is copyright integra solutions, inc, and may not be redistributed in any form or via any media electronic or otherwise without obtaining prior written consent from the author(s).