How to make an efficient check constraint for an e-mail field in Firebird - sql

How to make an efficient check constraint for an e-mail field in Firebird (if field value not null)?
thanks, Wilfried

You could use the SIMILAR TO operator to test against regular expression pattern, something like
CHECK(emailfield SIMILAR TO '[[:ALNUM:]._%+-]+#[[:ALNUM:].-]+\.[[:ALPHA:]]+')

IMHO this kind of validation should take place in the application code, and not in the database. Anyway, the suggestion approach with a regular expression seems nice !

Related

How can I use regexp (or equivalent) in MS SQL Server to solve this problem?

I have searched online and in SO to try and find a solution to my problem but I can't find anyone that has solved this.
When creating a table in MS SQL Server, I have a column called composite_name. I want to add a constraint to this column so that it only accepts values of the form:
COMPOSITE1, COMPOSITE2, ..., COMPOSITE[x], ...
where [x] is any integer.
I have tried to do this by adding the below constraint to my table creation statement:
CONSTRAINT [check_composite_name] CHECK (composite_name LIKE 'COMPOSITE[0-9]+')
the table creates, but then when I insert data that has the form mentioned above I get an error. Clearly something is wrong with the string pattern but I'm not sure how to fix this.
I stress that I am using Microsoft SQL Server so there are no functions like REGEXP_LIKE. I thought I had followed the documentation correctly on this given here.
Any help would be greatly appreciated. Thanks in advance
You can use like and not like:
check (composite like 'COMPOSITE[0-9]%' and
composite not like 'COMPOSITE%[^0-9]%'
)
Note: This may also match lower case, depending on the collation of the column.

Struggling with input validation/check constraint

I'm trying to create a table with an email address column and want to make sure that only addresses in the correct format (contains "#") are allowed. I know how to use the LIKE operator in queries but not how to put a value constraint on a column.
You can add the check constraint like this For your basic example:
alter table t add contraint chk_email
(check (email like '%#%') );
Of course, that is really only a betting. Perhaps something more like this:
alter table t add contraint chk_email
(check (email like '%_#[^.]%' and -- one # and something before and after
email not like '%#%#%' and -- not more than one #
email not like '%[^-.a-zA-Z0-9_]%' -- valid characters)
);
This still will allow invalid emails, but it is at least closer.
This would be better to do in a programming language that supports regular expressions or already has a built in isValidEmail method.
Validating an email address using a regular expression or a simple like pattern is pretty darn hard to get right, if not nearly impossible.
You can read more about it on I Knew How To Validate An Email Address Until I Read The RFC - And to quote the part I think illustrates the problem best:
These are all valid email addresses!
Abc#def#example.com
Fred\ Bloggs#example.com
Joe.\Blow#example.com
"Abc#def"#example.com
"Fred Bloggs"#example.com
customer/department=shipping#example.com
$A12345#example.com
!def!xyz%abc#example.com
_somename#example.com
Attempting to get all the logic needed to validate such a wide range of possibilities in a T-SQL statement is like attempting to climb the Everest blind-folded with your hands tied behind your back.
You could have a simple validation that might return a lot of false-positives or false-negatives using a simple like pattern like the one suggested in How to Validate Email Address in SQL Server? by Pinal Dave: '%_#__%.__%', but that's really just a naive attempt to clog a dam with a band-aid.
Having said all that, you might be able to use a CLR Scalar-Valued Function to validate your email addresses, using code like the one from this SO post.
Personally, I have no experience with CLR functions, so it would probably be irresponsible of me to try and write you a code example (especially since I don't really have a test environment to check it before I post this answer), but I hope what I've written so far was helpful enough, and with the help of the links in this answer and some web searches you will be able to solve the problem.

Can we use "if else" in "Check" constraint in sql server

Can i use if else under a check constraint.
Can i use check constraint using a variable
need xplanation with eg.
Your question is a bit vague. What are you trying to do with the IF...ELSE? Check constraints aren't processed code, they're part of the table definition - there is no control flow and no variables. You can use a user-defined function in check constraints, which may be what you're after, but it's hard to tell from your question.
You cannot use IF/ELSE, but you can use inline conditionals: CASE WHEN

Openbase SQL case-sensitivity oddities ('=' vs. LIKE) - porting to MySQL

We are porting an app which formerly used Openbase 7 to now use MySQL 5.0.
OB 7 did have quite badly defined (i.e. undocumented) behavior regarding case-sensitivity. We only found this out now when trying the same queries with MySQL.
It appears that OB 7 treats lookups using "=" differently from those using "LIKE": If you have two values "a" and "A", and make a query with WHERE f="a", then it finds only the "a" field, not the "A" field. However, if you use LIKE instead of "=", then it finds both.
Our tests with MySQL showed that if we're using a non-binary collation (e.g. latin1), then both "=" and "LIKE" compare case-insensitively. However, to simulate OB's behavior, we need to get only "=" to be case-sensitive.
We're now trying to figure out how to deal with this in MySQL without having to add a lot of LOWER() function calls to all our queries (there are a lot!).
We have full control over the MySQL DB, meaning we can choose its collation mode as we like (our table names and unique indexes are not affected by the case sensitivity issues, fortunately).
Any suggestions how to simulate the OpenBase behaviour on MySQL with the least amount of code changes?
(I realize that a few smart regex replacements in our source code to add the LOWER calls might do the trick, but we'd rather find a different way)
Another idea .. does MySQL offer something like User Defined Functions? You could then write a UDF-version of like that is case insesitive (ci_like or so) and change all like's to ci_like. Probably easier to do than regexing a call to lower in ..
These two articles talk about case sensitivity in mysql:
Case Sensitive mysql
mySql docs "Case Sensitivity"
Both were early hits in this Google search:
case sensitive mysql
I know that this is not the answer you are looking for .. but given that you want to keep this behaviour, shouldn't you explicitly code it (rather than changing some magic 'config' somewhere)?
It's probably quite some work, but at least you'd know which areas of your code are affected.
A quick look at the MySQL docs seems to indicate that this is exactly how MySQL does it:
This means that if you search with col_name LIKE 'a%', you get all column values that start with A or a.

Regular expression to match common SQL syntax?

I was writing some Unit tests last week for a piece of code that generated some SQL statements.
I was trying to figure out a regex to match SELECT, INSERT and UPDATE syntax so I could verify that my methods were generating valid SQL, and after 3-4 hours of searching and messing around with various regex editors I gave up.
I managed to get partial matches but because a section in quotes can contain any characters it quickly expands to match the whole statement.
Any help would be appreciated, I'm not very good with regular expressions but I'd like to learn more about them.
By the way it's C# RegEx that I'm after.
Clarification
I don't want to need access to a database as this is part of a Unit test and I don't wan't to have to maintain a database to test my code. which may live longer than the project.
Regular expressions can match languages only a finite state automaton can parse, which is very limited, whereas SQL is a syntax. It can be demonstrated you can't validate SQL with a regex. So, you can stop trying.
SQL is a type-2 grammar, it is too powerful to be described by regular expressions. It's the same as if you decided to generate C# code and then validate it without invoking a compiler. Database engine in general is too complex to be easily stubbed.
That said, you may try ANTLR's SQL grammars.
As far as I know this is beyond regex and your getting close to the dark arts of BnF and compilers.
http://savage.net.au/SQL/
Same things happens to people who want to do correct syntax highlighting. You start cramming things into regex and then you end up writing a compiler...
I had the same problem - an approach that would work for all the more standard sql statements would be to spin up an in-memory Sqlite database and issue the query against it, if you get back a "table does not exist" error, then your query parsed properly.
Off the top of my head: Couldn't you pass the generated SQL to a database and use EXPLAIN on them and catch any exceptions which would indicate poorly formed SQL?
Have you tried the lazy selectors. Rather than match as much as possible, they match as little as possible which is probably what you need for quotes.
To validate the queries, just run them with SET NOEXEC ON, that is how Entreprise Manager does it when you parse a query without executing it.
Besides if you are using regex to validate sql queries, you can be almost certain that you will miss some corner cases, or that the query is not valid from other reasons, even if it's syntactically correct.
I suggest creating a database with the same schema, possibly using an embedded sql engine, and passing the sql to that.
I don't think that you even need to have the schema created to be able to validate the statement, because the system will not try to resolve object_name etc until it has successfully parsed the statement.
With Oracle as an example, you would certainly get an error if you did:
select * from non_existant_table;
In this case, "ORA-00942: table or view does not exist".
However if you execute:
select * frm non_existant_table;
Then you'll get a syntax error, "ORA-00923: FROM keyword not found where expected".
It ought to be possible to classify errors into syntax parsing errors that indicate incorrect syntax and errors relating to tables name and permissions etc..
Add to that the problem of different RDBMSs and even different versions allowing different syntaxes and I think you really have to go to the db engine for this task.
There are ANTLR grammars to parse SQL. It's really a better idea to use an in memory database or a very lightweight database such as sqlite. It seems wasteful to me to test whether the SQL is valid from a parsing standpoint, and much more useful to check the table and column names and the specifics of your query.
The best way is to validate the parameters used to create the query, rather than the query itself. A function that receives the variables can check the length of the strings, valid numbers, valid emails or whatever. You can use regular expressions to do this validations.
public bool IsValid(string sql)
{
string pattern = #"SELECT\s.*FROM\s.*WHERE\s.*";
Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
return rgx.IsMatch(sql);
}
I am assuming you did something like .\* try instead [^"]* that will keep you from eating the whole line. It still will give false positives on cases where you have \ inside your strings.