How do I get around case sensitive fields when in SQL - sql

My code is:
CURSOR get_party_description is
select party_name
from ifsapp.IDENTITY_PAY_INFO_ALL
where party_type = :NEW.PARTY_TYPE
and identity = identity_
:NEW_PARTY_TYPE = 'SUPPLIER' while the value in the field is 'Supplier'. This code will pull back no records but if I change it to 'Supplier', it finds the record
How do I change to search with out matching the case?

You can convert both the variable and the field to upper or lower case.
where UPPER(party_type) = UPPER(:NEW.PARTY_TYPE)
This might cause a table space scan as the index on the field would be Case sensitive.
you can get around this by adding a generated column that is upper case and indexing that.

Change both of your values to upper case. Example:
CURSOR get_party_description is
select party_name
from ifsapp.IDENTITY_PAY_INFO_ALL
where UPPER(party_type) = UPPER('SUPPLIER')
and identity = identity_

Besides converting both strings to the same case (upper- or lower-) and then comparing them for equality, most SQL dialects allow one to do a case-insensitive comparison by using the LIKE operator, as follows:
CURSOR get_party_description is
select party_name
from ifsapp.IDENTITY_PAY_INFO_ALL
where party_type LIKE :NEW.PARTY_TYPE
and identity = identity_

Related

SQL full text search behavior on numeric values

I have a table with about 200 million records. One of the columns is defined as varchar(100) and it's included in a full text index. Most of the values are numeric. Only few are not numeric.
The problem is that it's not working well. For example if a row contains the value '123456789' and i look for '567', it's not returning this row. It will only return rows where the value is exactly '567'.
What am I doing wrong?
sql server 2012.
Thanks.
Full text search doesn't support leading wildcards
In my setup, these return the same
SELECT *
FROM [dbo].[somelogtable]
where CONTAINS (logmessage, N'28400')
SELECT *
FROM [dbo].[somelogtable]
where CONTAINS (logmessage, N'"2840*"')
This gives zero rows
SELECT *
FROM [dbo].[somelogtable]
where CONTAINS (logmessage, N'"*840*"')
You'll have to use LIKE or some fancy trigram approach
The problem is probably that you are using a wrong tool since Full-text queries perform linguistic searches and it seems like you want to use simple "like" condition.
If you want to get a solution to your needs then you can post DDL+DML+'desired result'
You can do this:
....your_query.... LIKE '567%' ;
This will return all the rows that have a number 567 in the beginning, end or in between somewhere.
99% You're missing % after and before the string you search in the LIKE clause.
es:
SELECT * FROM t WHERE att LIKE '66'
is the same as as using WHERE att = '66'
if you write:
SELECT * FROM t WHERE att LIKE '%66%'
will return you all the lines containing 2 'sixes' one after other

Access update query using two tables

I am a novice when it comes to Access SQL - I have two tables, (Master and Extract) I need to update the Master table where the same Case exists (this is the unique key on both tables) but only if the Case Text is "NA".
UPDATE Master
SET ( 'Master.Date Closed' )
= (Date())
FROM Extract
WHERE ('Master.Case' = 'Extract.Case' AND 'Extract.Clarification Case Text' = "NA");
I am not sure how I get the Case ID into the query, how the structure would look etc.
So if the Case ID appears in both tables and the Clarification Case Text is "NA" then put today's date into Master.Date Closed.
Thanks for any help with this.
I think you intend this:
UPDATE Master
SET [Date Closed] = Date()
WHERE EXISTS (SELECT 1
FROM Extract
WHERE Master.Case = Extract.Case AND
Extract.[Clarification Case Text] = "NA"
);
Note: Only use single and double quotes for string and date constants. The escape character for field and column names is the square braces. Although other characters can be used, they tend to be confusing -- either to humans or to the SQL parser.

Coldfusion Query of Queries with Empty Strings

The query I start out with has 40,000 lines of empty rows, which stems from a problem with the original spreadsheet from which it was taken.
Using CF16 server
I would like to do a Query of Queries on a variably named 'key column'.
In my query:
var keyColumn = "Permit No."
var newQuery = "select * from source where (cast('#keyColumn#' as varchar) <> '')";
Note: the casting comes from this suggestion
I still get all those empty fields in there.
But when I use "City" as the keyColumn, it works. How do the values in both those columns differ when they both say [empty string] on the query dump?
Is it a problem with column names? What kind of data are in those cells?
where ( cast('Permit No.' as varchar) <> '' )
The problem is the SQL, not the values. By enclosing the column name in quotes, you are actually comparing the literal string "P-e-r-m-i-t N-o-.", not the values inside that column. Since the string "Permit No." can never equal an empty string, the comparison always returns true. That is why the resulting query still includes all rows.
Unless it was fixed in ColdFusion 2016, QoQ's do not support column names containing invalid characters like spaces. One workaround is to use the "columnNames" attribute to specify valid column names when reading the spreadsheet. Failing that, another option is to take advantage of the fact that query columns are arrays and duplicate the data under a valid column name: queryAddColumn(yourQuery, "PermitNo", yourQuery["Permit No."]) (Though the latter option is less ideal because it may require copying the underlying data internally):

How to compare strings in sql ignoring case?

How do I write a query in Oracle ignoring the case of the strings being compared? For example "angel", "Angel", "ANGEL", "angel", "AngEl" would all be equal when compared.
If you are matching the full value of the field use
WHERE UPPER(fieldName) = 'ANGEL'
EDIT: From your comment you want to use:
SELECT
RPAD(a.name, 10,'=') "Nombre del Cliente"
, RPAD(b.name, 12,'*') "Nombre del Consumidor"
FROM
s_customer a,
s_region b
WHERE
a.region_id = b.id
AND UPPER(a.name) LIKE '%SPORT%'
You could use the UPPER keyword:
SELECT *
FROM Customers
WHERE UPPER(LastName) = UPPER('AnGel')
You can use:
select * from your_table where upper(your_column) like '%ANGEL%'
Otherwise, you can use:
select * from your_table where upper(your_column) = 'ANGEL'
Which will be more efficient if you are looking for a match with no additional characters before or after your_column field as Gary Ray suggested in his comments.
before comparing the two or more strings first execute the following commands
alter session set NLS_COMP=LINGUISTIC;
alter session set NLS_SORT=BINARY_CI;
after those two statements executed then you may compare the strings and there will be case insensitive.for example you had two strings s1='Apple' and s2='apple', if yow want to compare the two strings before executing the above statements then those two strings will be treated as two different strings but when you compare the strings after the execution of the two alter statements then those two strings s1 and s2 will be treated as the same string
reasons for using those two statements
We need to set NLS_COMP=LINGUISTIC and NLS_SORT=BINARY_CI in order to use 10gR2 case insensitivity. Since these are session modifiable, it is not as simple as setting them in the initialization parameters. We can set them in the initialization parameters but they then only affect the server and not the client side.
More detail on Mr Dredel's answer and tuinstoel's comment.
The data in the column will be stored in its specific case, but you can change your session's case-sensitivity for matching.
You can change either the session or the database to use linguistic or case insensitive searching. You can also set up indexes to use particular sort orders.
eg
ALTER SESSION SET NLS_SORT=BINARY_CI;
Once you start getting into non-english languages, with accents and so on, there's additional support for accent-insensitive.
Some of the capabilities vary by version, so check out the Globablization document for your particular version of Oracle. The latest (11g) is here
SELECT STRCMP("string1", "string2");
this returns 0 if the strings are equal.
If string1 = string2, this function returns 0 (ignoring the case)
If string1 < string2, this function returns -1
If string1 > string2, this function returns 1
https://www.w3schools.com/sql/func_mysql_strcmp.asp
To avoid string conversions comparisons, use COLLATE SQL_Latin1_General_CP1_CI_AS.
EXAMPLE:
SELECT UserName FROM Users
WHERE UserName COLLATE SQL_Latin1_General_CP1_CI_AS = 'Angel'
That will return any usernames, whether ANGEL, angel, or Angel, etc.
I don't recall the exact syntax, but you may set the table column to be case insensitive. But be careful because then you won't be able to match based on case anymore and if you WANT 'cool' to not match 'CoOl' it will no longer be possible.

What is the best way to select string fields based on character ranges?

I need to add the ability for users of my software to select records by character ranges.
How can I write a query that returns all widgets from a table whose name falls in the range Ba-Bi for example?
Currently I'm using greater than and less than operators, so the above example would become:
select * from widget
where name >= 'ba' and name < 'bj'
Notice how I have "incremented" the last character of the upper bound from i to j so that "bike" would not be left out.
Is there a generic way to find the next character after a given character based on the field's collation or would it be safer to create a second condition?
select * from widget
where name >= 'ba'
and (name < 'bi' or name like 'bi%')
My application needs to support localization. How sensitive is this kind of query to different character sets?
I also need to support both MSSQL and Oracle. What are my options for ensuring that character casing is ignored no matter what language appears in the data?
Let's skip directly to localization. Would you say "aa" >= "ba" ? Probably not, but that is where it sorts in Sweden. Also, you simply can't assume that you can ignore casing in any language. Casing is explicitly language-dependent, with the most common example being Turkish: uppercase i is İ. Lowercase I is ı.
Now, your SQL DB defines the result of <, == etc by a "collation order". This is definitely language specific. So, you should explicitly control this, for every query. A Turkish collation order will put those i's where they belong (in Turkish). You can't rely on the default collation.
As for the "increment part", don't bother. Stick to >= and <=.
For MSSQL see this thread: http://bytes.com/forum/thread483570.html .
For Oracle, it depends on your Oracle version, as Oracle 10 now supports regex(p) like queries: http://www.psoug.org/reference/regexp.html (search for regexp_like ) and see this article: http://www.oracle.com/technology/oramag/webcolumns/2003/techarticles/rischert_regexp_pt1.html
HTH
Frustratingly, the Oracle substring function is SUBSTR(), whilst it SQL-Server it's SUBSTRING().
You could write a simple wrapper around one or both of them so that they share the same function name + prototype.
Then you can just use
MY_SUBSTRING(name, 2) >= 'ba' AND MY_SUBSTRING(name, 2) <= 'bi'
or similar.
You could use this...
select * from widget
where name Like 'b[a-i]%'
This will match any row where the name starts with b, the second character is in the range a to i, and any other characters follow.
I think that I'd go with something simple like appending a high-sorting string to the end of the upper bound. Something like:
select * from widgetwhere name >= 'ba' and name <= 'bi'||'~'
I'm not sure that would survive EBCDIC conversion though
You could also do it like this:
select * from widget
where left(name, 2) between 'ba' and 'bi'
If your criteria length changes (as you seemed to indicate in a comment you left), the query would need to have the length as an input also:
declare #CriteriaLength int
set #CriteriaLength = 4
select * from widget
where left(name, #CriteriaLength) between 'baaa' and 'bike'