Oracle SQL constraint to ensure data format - sql

I'm trying to ensure that the data that goes into a cell/field in a data row follows the format YYYYAB, YYYYAC, YYYYAD. Meaning that any four number year and then the two characters "AB" or "AC" or "AD" are valid, anything else would be rejected.
Not sure how to compose the constraint with a like condition and the "_" or the "%" wildcards in order to accomplish this when I'm creating the column.
I was hoping to use something with a syntax like:
constraint cksemester check (SEMESTER in ( _ _ _ _ A B, _ _ _ _ A C, _ _ _ _ A D)),
or a combination of % and Regex..... is there a way to restrict the format to essentially any four numbers
and then force the suffix to be any of "AB" or "AC" or "AD" ?
Thank you.

You can do it without regular expressions using the TRANSLATE function:
CONSTRAINT cksemester CHECK (
TRANSLATE(
semester,
'0123456789',
'0000000000'
) IN ('0000AB', '0000AC', '0000AD')
)
If you want to use regular expressions (which typically execute slower than simple string functions, such as TRANSLATE) then you can use:
CONSTRAINT cksemester CHECK ( REGEXP_LIKE(semester, '^\d{4}A[BCD]$') )

You can use a REGEX to validate your field. A check constraint works like a where condition, so:
ALTER TABLE yourTable
add constraint cksemester
check (REGEXP_LIKE(SEMESTER,'[[:digit:]]{4}(AB|AC|AD)','I'));
This regex ensures:
[[:digit:]]{4} : Exact four digits
(AB|AC|AD) : either AB or AC or AD
the 'I' parameter stands for case insensitive
Edit:
As suggested by MT0 in the comments, a better version of the above regex is ^[[:digit:]]{4}(AB|AC|AD)$
^ ensures the string needs to start there, from the 4 digits
$ ensures the string finishes there, it need to end after the "or" expression.
This improved regex, prevent "outbounds" of the original one such as XYZ1234ABCDEF which would be considered valid and it is not.

Related

Oracle SQL - How to Select a substring index inside another Query?

I'm writing a query that returns a bunch of things from multiple tables. The main query is against Table_1. I need to return a substring from a field in table 7. But I'm getting an error that Substring_Index is an invalid identifier. How can I achieve the intended result?
I have a field COLUMN_1 of TABLE_1 that has 3+ pieces of data, separated by " : " (space colon space) and I need to strip out the text before the first delimiter, and return the rest of it (regardless of length).
A simplified example:
SELECT t1.name
,t1.address
,t1.phone
,t2. fave_brand
,SUBSTRING_INDEX(t3.fave_product, ' : ', -1) AS Fave Product
FROM table_1 t1
INNER JOIN table_2 t2
ON t2.brand_SK = t1.fave_brand_FK
INNER JOIN table_3 t3
ON t3.product_list_SK = t1.fave_products
WHERE <a series of constraints>;
Please note, I am NOT normally an SQL developer, but the back-end dev is on vacation and I've been tasked with cobbling this fix together. I'm a beginner at best.
In oracle you could use regexp_replace():
regexp_replace(t3.fave_product, '^[^:]*:', '') "Fave Product"
regexp_replace() replaces the part of the string that matches the regexp given as second argument with the value given as third argument. Here, we use the empty string as third argument, meaning that the matching part of the string is suppressed.
Regexp breakdown:
^ beginning of the string
[^:]* as many characters as possible other than ":" (possibly, 0 characters)
: character ":"
NB: identifiers that contain special characters (such as space) need to be double quoted.
Oracle does not support substring_index(). That is a MySQL function.
You can use regexp_substr(). Without sample data it is a little hard to be 100% sure, but I think the logic you want is:
regexp_substr(t3.fave_product, '[^:]+$') as fave_product

vertica UTF-8 character

I have a table with a column whose type is varchar(32) the value it has is
'Movies & TV' . This data is loaded by Copy command, when I query this table like
select * from activity where name='Movies & TV' (typed this value)
it won't return any record this is mainly because of & character there is something going on with this character.
When I tried
Select ISUTF8(name) from activity it returns true, which means the data is actually stored in the UTF-8 format.
Select length(name) and length('Movies & TV') are also same. However, when I paste these values in the vi editor and saw an extra space in the DB string. In addition, the field name in activity table can have Chines characters too, which is stored correctly in DB now.
Any idea what is going on here? Should I specify explicit UTF-8 when loading the data?
If you are doing it from SQLPLUS use
SET DEFINE OFF
to stop it treading & as a special case.
An alternate solution, use concatenation and the chr function:
SELECT * FROM activity WHERE name= 'Movies ' || chr(38) || ' TV';
Solution from:
How to insert a string which contains an "&"

What does the trim function mean in this context?

Database I'm using: https://uploadfiles.io/72wph
select acnum, field.fieldnum, title, descrip
from field, interest
where field.fieldnum=interest.fieldnum and trim(ID) like 'B.1._';
What will the output be from the above query?
Does trim(ID) like 'B.1._' mean that it will only select items from B.1._ column?
trim removes spaces at the beginning and end.
"_" would allow representing any character. Hence query select any row that starts with "B.1."
For eg.
'B.1.0'
'B.1.9'
'B.1.A'
'B.1.Z'
etc
Optional Wildcard characters allowed in like are % (percent) and _ (underscore).
A % matches any string with zero or more characters.
An _ matches any single character.
I don't know about the DB you are using but trim usually remove spaces around the argument you give to it.
The ID is trimmed to be sure to compare the ID without any white-space around it.
About your second question, Only the ROWS with an ID like 'B.1.' will be selected.
SQL like
SQL WHERE

VB6 Syntax Question

Can anyone tell me what this Asterisk(*) is for. ...tblpersonal where empid like '" & idNumber & "*'". What if I replace it with Percent sign(%), what would be the outcome?
The LIKE condition allows you to use wildcards in the where clause of an SQL statement. This allows you to perform pattern matching. The LIKE condition can be used in any valid SQL statement - select, insert, update, or delete.
The patterns that you can choose from are:
% allows you to match any string of any length (including zero length)
_ allows you to match on a single character
Next, let's explain how the _ wildcard works. Remember that the _ is looking for only one character.
For example,
SELECT * FROM suppliers
WHERE supplier_name like 'Sm_th';
This SQL statement would return all suppliers whose name is 5 characters long, where the first two characters is 'Sm' and the last two characters is 'th'. For example, it could return suppliers whose name is 'Smith', 'Smyth', 'Smath', 'Smeth', etc.
Here is another example,
SELECT * FROM suppliers
WHERE account_number like '12317_';
The same way u can use asterisk (*) instead of (%)
I hope its help to you
The Percent (%) sign in SQL says "match any number of characters here". E.g. LIKE '%test' will match abctest, LIKE 'test%' will match testabc
The Asterisk character looks like it'll match a literal *, e.g. matching all empids ending with an asterisk (depending on the version of SQL - see below)
EDIT: See Microsoft Jet wildcards: asterisk or percentage sign? for a more in depth answer on * vs %
This is much more a SQL syntax question than a VB6 one. :-)
You haven't mentioned what database this is talking to (I assume it's talking to a DB). The asterisk is not generally special in SQL (or VB6 strings), and so that query will look for empid being like whatever's in your idNumber followed by an asterisk. Probably not what was intended. If you replace it with a %, you'll be looking for any empid that starts with whatever's in your idNumber variable. If the column is numeric, it will be converted to text before the comparison.
So for instance, if idNumber contains 100, say, and there are empid values in the database with the values 10, 100, 1000, and 10000, the query would match all but the first of those, since "100", "1000", and "10000" are all like "100%".

Please help me create a regular expression to parse my SQL statement

I want to extract
FROM codes WHERE FieldName='ContactMethod' and IsNull(Deactived,'') != 'T'
from
SELECT FieldDescription,FieldValue FROM codes WHERE FieldName='ContactMethod'
and IsNull(Deactived,'') != 'T' order by fielddescription
using a regular expression. I have a regex like this:
\FROM.*\order
which extracts
FROM codes WHERE FieldName='ContactMethod' and IsNull(Deactived,'') != 'T' order
Also, how can I get rid of the capitalization?
Thanks
The trick here would probably be to capture the part you actually want with parens:
(FROM.*) order
This would greedily match until the last order, if you want only until the first occurrence, match lazily:
(FROM.*?) order
Expanding on Fabian Steeg's answer
Dim regex As Regex = New Regex( _
"(FROM.*?) ORDER", _
RegexOptions.IgnoreCase _
Or RegexOptions.CultureInvariant _
Or RegexOptions.IgnorePatternWhitespace _
Or RegexOptions.Compiled _
)
Dim ms As MatchCollection = regex.Matches(InputText)
where InputText is of course your SQL query string.
ms(1) should hold the parentheses match
If it comes down to it you can ignore capitalization by doing (F|f)(R|r)(O|o)(M|m).
Interactive tools like RegexBuddy ($40) or The Regex Coach (free) would really help you to design and debug regular expressions for most platforms.