I am currently trying to check that every values that are inserted into my MariaDB table the 1st letter of every word in uppercase, so I tried to use CONSTRAINT nombreok CHECK (INITCAP(nombre_director) = nombre_director)); but it doesn't works because it gives me an error saying that function INITCAP() cannot be used in a CHECK... what can I do to solve it?
I think initcap() is not deterministic because the results may depend on the default collation of the database (under some circumstances).
You can ensure that the first characters are capitalized using:
CONSTRAINT nombreok CHECK (not (nombre_director collate latin1_general_cs) REGEXP '(^|[[:space:]])[[:lower:]]')
Here is a db<>fiddle.
If you want to check the lower case as well:
CONSTRAINT nombreok CHECK ((nombre_director collate latin1_general_cs) REGEXP '^([[:upper:]][[:lower:]]+([[:space:]]+|$))+$')
However, you might want to extend this beyond just alphabetical characters.
Here is a db<>fiddle for this.
Related
I am currently trying to create a regular expresion to use in my Oracle database constraints' that is able to check if all the words of a string starts with an uppercase. I already tried to use functions like initcap, but it really doesn't work as expected, because it gives an error when I try to insert values that contains a letter like "ñ" or an acent. Could you please help me?
I think the check constraint that you want is more like this:
check (not regexp_like(mycol, '(^|\W)[[:lower:]]'))
You could do this with a check constraint and a regex, like so:
alter table mytable
add constraint myconstraint
check (not regexp_like(mycol, '(^|\W)[a-z]'))
Regexp (^|\W)[A-Z] means: the beginning of the string or a non-word character followed by an lower case value. not regexp_like(...) forbids such pattern.
Demo on DB Fiddle
As commented by #kfinity, you can also use regex (^|\W)[[:lower:]], that should properly trap special upper characters.
i have a requirement to insert data into a varchar2 column.can anyone please help me how to restrict special characters except space in a table field in oracle and also the field should not accept two consecutive space
You are looking for a check constraint, which seems to need regular expressions. Something like this:
alter table t add constraint chk_t_col
check (regexp_like(col, '^[a-zA-Z0-9 ]+$') and col not like '% %');
I'm not sure what the set of characters is, but the above is for alphanumeric and space.
Note: You can create the regular expression to preclude the double spaces. I find the above easier to follow.
How I have a column Firstname which should be only Alphabets
and phone number which should be only numbers in HSQL
i wrote something like
ALTER TABLE USER
ADD CONSTRAINT CHECK_USER_FIRST_NAME CHECK (FIRST_NAME NOT LIKE '%[^A-Z ]%' )
But it allows Tp1 which i don't want.
Can someone help me with constraint in HSQL
LIKE doesn't support regular expressions. The only wildcards it supports are % for multiple characters and _ for a single character. To match against a regular expression you need regexp_matches()
ALTER TABLE user
ADD CONSTRAINT check_user_first_name
CHECK (regexp_matches(first_name, '[A-Z]+'))
This will allow only uppercase letters, so you probably want to use '[A-Za-z]+' instead. It also requires at least one character in the name. If you want to allow empty strings, change the + to *. This will still allow null values though.
Note that USER is a reserved keyword in SQL. You shouldn't create a table with that name. If you try this e.g. on Oracle or PostgreSQL it will fail. The name requires to be quoted - which is not a good idea. You should find a different name.
I have a column NAME
It must contain only characters and not numbers
How do I use CHECK condition:
CHECK(NAME NOT LIKE '%[0-9]%')
or any other method...
edit: Oracle database is used.
You didn't state your DBMS so I'm assuming PostgreSQL
CHECK(name ~ '^[^0-9]*$')
Double negative Should be standard (not MySQL though) because it uses LIKE:
CHECK(NAME NOT LIKE '%[^a-zA-Z]%')
I'm looking to perform case-insensitive search in a Firebird database, without modifying actual queries. In other words, I'd like all my existing "SELECT/WHERE/LIKE" statements to retrieve BOB, Bob, and bob. Does Firebird configuration allow to modify this behavior?
Try using something like:
Imagine you have a table of persons like this one:
CREATE TABLE PERSONS (
PERS_ID INTEGER NOT NULL PRIMARY KEY,
LAST_NAME VARCHAR(50),
FIRST_NAME VARCHAR(50)
);
Now there is an application, which allows the user to search for persons by last name and/or first name. So the user inputs the last name of the person he is searching for.
We want this search to be case insensitive, i.e. no matter if the user enters "Presley", "presley", "PRESLEY", or even "PrESley", we always want to find the King.
Ah yes, and we want that search to be fast, please. So there must be an index speeding it up.
A simple way to do case insensitive comparisons is to uppercase both strings and then compare the uppercased versions of both strings.
Uppercasing has limitations, because some letters cannot be uppercased. Note also that there are languages/scripts where there is no such thing as case. So the technique described in this article will work best for European languages.
In order to get really perfect results one would need a case insensitive (CI) and/or accent insensitive (AI) collation. However, at the time of this writing (July 2006) there are only two Czech AI/CI collations for Firebird 2.0. The situation will hopefully improve over time.
(You should know the concepts of Character Sets and Collations in order to understand what comes next. I use the DE_DE collation in my examples, this is the collation for German/Germany in the ISO8859_1 character set.)
In order to get correct results from the UPPER() function that is built into Firebird, you must specify a collation. This can be in the DDL definition of the table:
CREATE TABLE PERSONS (
PERS_ID INTEGER NOT NULL PRIMARY KEY,
LAST_NAME VARCHAR(50) COLLATE DE_DE,
FIRST_NAME VARCHAR(50) COLLATE DE_DE
);
or it can be done when calling the UPPER() function:
SELECT UPPER (LAST_NAME COLLATE DE_DE) FROM PERSONS;
http://www.destructor.de/firebird/caseinsensitivesearch.htm
or you can edit your queries and add the lower() function
LOWER()
Available in: DSQL, ESQL, PSQL
Added in: 2.0
Description: Returns the lower-case equivalent of the input string. This function also correctly lowercases non-ASCII characters, even if the default (binary) collation is used. The character set must be appropriate though: with ASCII or NONE for instance, only ASCII characters are lowercased; with OCTETS, the entire string is returned unchanged.
Result type: VAR(CHAR)
Syntax:
LOWER (str)
Important
If the external function LOWER is declared in your database, it will obfuscate the internal function. To make the internal function available, DROP or ALTER the external function (UDF).
Example:
select field from table
where lower(Name) = 'bob'
http://www.firebirdsql.org/refdocs/langrefupd21-intfunc-lower.html
Necromancing.
Instead of a lowercase-field, you can specify the collation:
SELECT field FROM table
WHERE Name = 'bob' COLLATE UNICODE_CI
See
https://firebirdsql.org/refdocs/langrefupd21-collations.html
Maybe you can also specify it as the default character-set for the database, see
http://www.destructor.de/firebird/charsets.htm
Eventually I went with creating shadow columns containing lower-cased versions of required fields.