PL/SQL REGEXP_LIKE with multiple [0-9][0-9] - sql

I am having a hard time making my PL/SQL code work. I have a constraint that makes sure 5 digits have been input. The constraint works for any number that does not use a 0 first. Example 0, 1, 2, 33, 401 work but 01, 02, 004 do not work. How can I make it so that I can input numbers such as 00009?
CREATE TABLE table1
(
id NUMBER(5)
CONSTRAINT idconstraint
CHECK (REGEXP_LIKE(id, '[0-9][0-9][0-9][0-9][0-9]'))
);
INSERT INTO table1
VALUES ('00009');

You seem to have the wrong constraint or the wrong data type. If you want leading zeros, use varchar2() or char(). Because you seem to want a fixed length string, try this:
CREATE TABLE table1 (
id CHAR(5)
CONSTRAINT idconstraint
CHECK (REGEXP_LIKE(id, '[0-9][0-9][0-9][0-9][0-9]'))
);
Your problem is that the field is declared as a number. The input string is converted to a number, then back to a string. It loses the leading 0's in the process.

Related

SQL - Column string characters has to be greater than 25

When creating a table, can you put a constraint check on a column to check that the string value has to be greater than 25 characters? I know it can be done on numeric, but having difficulty to do it for a string.
Here is my code:
CREATE TABLE TITLE
(Title_ID VARCHAR(8),
Title_Name VARCHAR(MAX) CHECK (Title_Name > 25));
I realize this only checks to see if the numeric value is greater than 25, but how can make it that it checks that the string value is greater than 25 characters
In Oracle, the maximum length of a string in a table is 4000 8-bit characters (as explained here). And you generally use varchar2() for variable length strings. So you can do:
CREATE TABLE TITLE (
Title_ID VARCHAR2(8),
Title_Name VARCHAR2(4000) CHECK (LENGTH(Title_Name) > 25)
);
If you want an unlimited length string, you can use a CLOB, but those are generally a bit more finicky to work with.
If you happen to be using SQL Server (which your syntax suggests), then this would be:
CREATE TABLE TITLE (
Title_ID VARCHAR(8),
Title_Name VARCHAR(MAX) CHECK (LEN(Title_Name) > 25)
);
You should use LENGTH function to check title length:
CREATE TABLE TITLE(
Title_ID VARCHAR2(8),
Title_Name VARCHAR2(400) CHECK (LENGTH(Title_Name) > 25)
);
db<>fiddle demo

CHECK (length(to_char(nif, 'FM999MI')) = 9))

I have a table with a column nif which has to be exactly 9 digits long, after I tried to do:
CREATE TABLE fornecedor(
nif numeric(9) PRIMARY KEY,
nome varchar(64) NOT NULL,
CONSTRAINT nif_tamanho CHECK (length(to_char(nif, 'FM999MI')) = 9));
INSERT INTO fornecedor(nif, nome) VALUES (123456789, 'Pmsmm');
It returns an error saying:
ERROR: new row for relation "fornecedor" violates check constraint "nif_tamanho"
How do I make it so that the inserted number is verified having 9 digits exactly ?
Thanks in advance
As you mention in your comment, you need a string data type if you don't want to lose leading zeroes.
But I think that the correct solution depends on how you want to use the column. It is always good to choose the data type according to the column's semantics.
If you need to do arithmetic or numeric comparisons with the data, choose integer by all means (you can add a check constraint on nif < 100000000). You can always format the value with leading zeroes when you convert it to a string for output.
If you need to do string operations on the value (e.g. substrings), storing the data as a sting type is preferable.

using sysdate in table causing error in not a valid month

so I was doing my homework and the table is
Create TABLE Book
(
bookID number(2,0) not null,
title char(50) not null,
catID char(2),
copyrightYear number(2,0),
isbnNumber char(50),
publisherID char(2),
purchasePrice number(4,2),
coverType char(10),
datePurchased date default sysdate,
pages number(4,0)
)
and when I insert the date inside it becomes an error ( not a valid month)
Insert into Book
values (1, 'Dirk Luchte', 'PS', 93, null,'NE', 23.50,'Hard', '23-nov-1993',1012);
and when I try to use to_date statement
Insert into Book
values (1, 'Dirk Luchte', 'PS', 93, null,'NE', 23.50,'Hard', to_date('23-nov-1993','DD-MM-YYYY'),1012);
the whole oracle crashed to blank, what can I do?
You can use official documentation for your homework, it isn't considered cheating (not at least more than asking in Stack Overflow):
Format Models
Element Specify in TO_* datetime functions? Description
MM Yes Month (01-12; January = 01)
So nov is clearly not a number between 1 and 12, thus the error.
And please learn to not disregard the error messages (you didn't even think about sharing it here): they're here to help.
As about the using sysdate in table causing error title, you're confused. The default value of your column is not used: you assign a explicit value. If you want the default value, you have to leave the column out. That also means that you have to provide a column list in your query (which is anyway a good practice because your app will not break when you add new columns).
The easiest way to specify a date literal is using the ISO format:
DATE '1993-12-23'

SQL (oracle) Check Constraint difficulty - Not sure how to implement

I am creating a small database for a telecom system.
One of the tables (calls) requires that a if a phone number's area code is not contained in a predefined list, then the number should not be added to the table.
The way I have thought about doing this is to put a check constraint within the calls table to not accept numbers that are not a part of this mentioned list. However, this list is quite long and I am not too sure if there would be a better implementation method.
Here is the list:
01 or 02: local/national number. Ex.: 01612 338866.
075, 077, 078, 079: mobile phone number. Ex.: 07747 556647.
0800: free number. Ex.: 08002 223344.
0845, 0870: special service. Ex.: 08451 423456.
08442 to 08449: 5p special service. Ex.: 08444 404404.
08712 to 08719: 10p special service. Ex.: 08713 457893.
090, 091, 098: premium rate special service. Ex.: 09119 229595.
The only way I could think of to do this is as follows:
ALTER TABLE calls ADD (CONSTRAINT area_ck
CHECK area_code ("01" or "02" or "075" or "077" or "078" or "079" or "0800" or
"0845" or "0870" or (BETWEEN ("08442" AND "08449")) or
(BETWEEN ("08712" AND "08719")) or
"090" or "091" or "098")
) ;
My two main issues with this are:
It gives an error as it is implemented incorrectly
If I were to modify it slightly until it did work, would it still be a long way about trying to solve my task?
The more common approach would be to define a table of valid area codes
CREATE TABLE area_code (
area_code VARCHAR2(5) PRIMARY KEY
);
Fill the Area_Code table with the set of valid values
INSERT INTO area_code( area_code ) VALUES( '01' );
INSERT INTO area_code( area_code ) VALUES( '02' );
INSERT INTO area_code( area_code ) VALUES( '075' );
...
or
BEGIN
FOR i IN 1000 .. 2999
LOOP
INSERT INTO area_code( area_code )
VALUES( to_char( i, '00000' ) );
END LOOP;
END;
And then define a foreign key constraint from your Call table to the Area_Code table
CREATE TABLE call (
call_id NUMBER PRIMARY KEY,
area_code VARCHAR2(5) REFERENCES area_code( area_code ),
<<other columns>>
);
That's going to be more efficient to enforce than a CHECK constraint and it will be easier to list the valid area codes.
The first problem is about using = and between together. Do it like:
area_code in ('01', '02', '03') or area_code between ('1000' and '1500') or ....
You could either write area_code='01' OR area_code='02' ... or you can use area_code in ('01','02', ...). You also need to add area_code before between keywords.
But I would suggest you to store the area codes in a table instead of the check constraint and use the area codes as foreign keys. This way the list of area codes can easily be modified.

SQL unique index without leading zeros

I have set-up a table using the following SQL script:
CREATE TABLE MY_TABLE (
ID NUMBER NOT NULL,
CODE VARCHAR2(40) NOT NULL,
CONSTRAINT MY_TABLE PRIMARY KEY (ID)
);
CREATE UNIQUE INDEX XUNIQUE_MY_TABLE_CODE ON MY_TABLE (CODE);
The problem is that I need to ensure that CODE does not have a leading zero for its value.
How do I accomplish this in SQL so that a 40-char value without a leading zero is stored?
CODE VARCHAR2 NOT NULL CHECK (VALUE not like '0%')
sorry - slight misread on the original spec
If you can guarantee that all INSERTs and UPDATEs to this table are done through a stored procedure, you could put some code there to check that the data is valid and return an error if not.
P.S. A CHECK CONSTRAINT would be better, except that MySQL doesn't support them.