I have a query where I am searching against a string:
SELECT county FROM city WHERE UPPER(name) = \'SAN FRANCISCO\';
Now, this works fine,
I don't know whether this would work in DB2, but I'll tell you how I'd do this in SQL Server. I think the way MSSQL does this is ANSI standard, though the specific collation strings may differ. Anyway, if you can do this without trashing the rest of your application -- are there other places where the "name" column needs to be case-sensitive? -- try making that whole column case-insensitive by changing the collation, then index the column.
ALTER TABLE city ALTER COLUMN name nvarchar(200)
COLLATE SQL_Latin1_General_CP1_CI_AS
...where "nvarchar(200)" stands in for whatever's your current column data type. The "CI" part of the collation string is what marks it as case-insensitive in MSSQL.
To explain... my understanding is that the index will store values in the order of the indexed column's collation. Making the column's collation be case-insensitive would make the index store 'San Francisco', 'SAN FRANCISCO', and 'san francisco' all together. Then you should just have to remove the "UPPER()" from your query, and DB2 should know that it can use your index.
Again, this is based solely on what I know about SQL Server, plus a couple minutes looking at the SQL-92 spec; it may or may not work for DB2.