Why this sql query doesn't return any error? - sql

When i run these queries:
create table University ( branch text primary key, region text, enrollment int);
create table Student ( sID int primary key, sName text, average int);
create table Apply ( sID int references Student(sID), branch text references University(branch), major text, decision text);
insert into Apply values ( 123, 'stanford', 'CS', 'Y');
It should return an error because i am inserting a tuple that doesn't have a Corresponding value in the reference table. but when i run these commands, this tuple inersts Successfully. What's wrong with this queries?
My DBMS is sqlite and i'm using sqliteman.

You should learn how to enable foreign key support
Quoting docs:
In order to use foreign key constraints in SQLite, the library must be
compiled with neither SQLITE_OMIT_FOREIGN_KEY or SQLITE_OMIT_TRIGGER
defined. If SQLITE_OMIT_TRIGGER is defined but SQLITE_OMIT_FOREIGN_KEY
is not, then SQLite behaves as it did prior to version 3.6.19 -
foreign key definitions are parsed and may be queried using PRAGMA
foreign_key_list, but foreign key constraints are not enforced. The
PRAGMA foreign_keys command is a no-op in this configuration. If
OMIT_FOREIGN_KEY is defined, then foreign key definitions cannot even
be parsed (attempting to specify a foreign key definition is a syntax
error).
Also read sqliteman constraint triggers:
There is one more unsupported SQL feature. Sqlite does not enforce
foreign keys and not null constraints.

Related

SQLite - named constraint syntax

I wonder why the following syntax is working:
CREATE TABLE tab1(id INT,
PRIMARY KEY (id) CONSTRAINT PK_tab1
-- here the CONSTRAINT is after PRIMARY KEY def
);
CREATE TABLE tab3(id INT,
CHECK(id > 10) CONSTRAINT CHK_tab3_id
);
Normally I would expect:
CREATE TABLE tab2(id INT,
CONSTRAINT PK_tab2 PRIMARY KEY (id)
);
db<>fiddle SQLite demo
Based on documentation it seems to be invalid syntax:
CREATE TABLE table_constraint
For PostgreSQL/Oracle/MySQL/SQL Server above syntax returns error: db<>fiddle demo PostgreSQL
Is this some kind of compatibility mode with DB2/Informix?
What you're missing is in the column-def diagram.
Notice the loop in the column-constraint section; a single column can have multiple constraints. So your first example has the primary key, and then a second named constraint that doesn't actually have any actual rules applied to it - which is the unusual bit, as the diagrams suggest that shouldn't be allowed. However, the sqlite3 parser is very, very, very forgiving when it comes to column definitions and allows things the official syntax diagrams suggest it shouldn't.

SQL How to not insert duplicated values

I'm trying to create a procedure that inserts data into a table of registers but i don't want to repeat the second parameter, this is the table
CREATE TABLE Inscription
(
idClass INT references tb_class,
idStudent INT references tb_student,
)
The idea is that a student (idStudent) can register in various classes but not in the same class (idClass), I tried to add a unique constraint in the idStudent column but that only allows a student to register in one single class.
I always suggest that all tables have a numeric primary key. In addition, your foreign key references are not correct. And what you want to do is add a unique constraint.
The exact syntax depends on the database. The following is for SQL Server:
CREATE TABLE Inscriptions (
idInscription int identity(1, 1) primary key
idClass int references tb_classes(idClass),
idStudent int references tb_students(idStudnt)
unique (idClass, idStudent)
);
Notice that I name the tables as the plural of the entity, but the id using the singular.
The Inscriptions table probably wants other columns as well, such as the date/time of the inscription, the method, and other related information.
You are looking to create a constraint on your table that includes both columns idClass and idStudent.
Once that constraint is created, an attempt to insert duplicate class/student will result in an error being raised.
As your table does not seem to include a primary key, you would better make that constraint your primary key.
NB : you did not tell which RDBMS you are using hence cannot give you the exact syntax to use...
Your unique key needs to encompass both idClass and idStudent, so any particular combination cannot repeat itself.

Postgres create table error

I am trying to create my very first table in postgres, but when I execute this SQL:
create table public.automated_group_msg (
automated_group_msg_idx integer NOT NULL DEFAULT nextval ('automated_group_msg_idx'::regclass),
group_idx integer NOT NULL,
template_idx integer NOT NULL,
CONSTRAINT automated_group_msg_pkey PRIMARY KEY (automated_group_msg_idx),
CONSTRAINT automated_group_msg_group_idx_fkey FOREIGN KEY (group_idx)
REFERENCES public.groups (group_idx) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT automated_msg_template_idx_fkey FOREIGN KEY (template_idx)
REFERENCES public.template (template_idx) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
)
WITH (
OIDS = FALSE
);
I get the following error:
ERROR: relation "automated_group_msg_idx" does not exist
Your error is (likely) because the sequence you're trying to use doesn't exist yet.
But you can create a sequence on the fly using this syntax:
create table public.automated_group_msg (
id serial primary key,
... -- other columns
)
Not directly related to your question, but naming columns with the table name in the name of the column is generally speaking an anti-pattern, especially for primary keys for which id is the industry standard. It also allows for app code refactoring using abstract classes whose id column is always id. It's crystal clear what automated_group_msg.id means and also crystal clear that automated_group_msg.automated_group_msg_id is a train wreck and contains redundant information. Attribute column names like customer.birth_date should also not be over-decorated as customer.customer_birth_date for the same reasons.
You just need to create the sequence before creating the table
CREATE SEQUENCE automated_group_msg_idx;

Why can't I add this foreign key?

I'll post only the main part. I have two tables, each one has to have the PK of the other as a FK.
CREATE TABLE apartment
(
cod_apartment INT NOT NULL PRIMARY KEY,
cod_offer INT NOT NULL
);
CREATE TABLE offer
(
cod_offer INT NOT NULL PRIMARY KEY,
cod_apartment INT NOT NULL
);
First I inserted the values on both tables and it was working, I could even search using "select * from...". But then I tried to add the foreign key:
This worked.
ALTER TABLE offer
ADD FOREIGN KEY (cod_apartment ) REFERENCES apartment;
And this not.
ALTER TABLE apartment
ADD FOREIGN KEY (cod_offer) REFERENCES offer;
This is the error message:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK__apartment__cod_offer__6383C8BA". The conflict occurred in database "kleber_apartment", table "dbo.offer", column 'cod_offer'.
The problem is, every time I try to execute, the FK name changes. And this FK actually doesn't exist. I already dropped both tables and tried to insert the values again, but the same happens.
What could be?
That means you're trying to add a foreign key when existing data doesn't obey that constraint. So you have a record in your apartment table where the cod_offer column does not match any value in the cod_apartment table.
Adding a foreign key not only constrains future data, but it requires that any existing data must also follow the rule.
And regarding the 6383C8BA, whenever you add a constraint without giving it a name, SQL Server picks one for you. Personally, I'd recommend something like:
alter table dbo.apartment
add constraint FK_apartment__cod_offer
foreign key (cod_offer) references dbo.offer (cod_offer);
This lets you define names the way you want, and is a little more clear about what you're actually building.

Does SQLite3 not support foreign key constraints?

I am have a problem with SQLITE3.
I have created 2 tables persons and orders using the following SQL script:
sqlite> create table Persons(
P_Id int primary key,
LastName varchar,
FirstName varchar,
Address varchar,
City varchar
);
sqlite> create table Orders(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
FOREIGN KEY (P_Id) REFERENCES Persons(P_Id)
);
sqlite> insert into Orders values(1,77895,3);
sqlite> select * from Orders;
1|77895|3
sqlite>
Even though the persons table is empty rows can be inserted into the orders table.
It does not show any error.
How is this possible.
In SQLite 3.x, you have to make the following query every time you connect to an SQLite database:
PRAGMA foreign_keys = ON;
Otherwise SQLite will ignore all foreign key constraints.
Why every time? Backwards compatibility with SQLite 2.x, according to the the documentation.
In SQLite 4.x, FK constraints will be enabled by default.
SQLite Foreign Key Support
sqlite> PRAGMA foreign_keys = ON;
This will enable foreign key constraint.
Check out if you have foreign key constraints enabled in your SQLite: http://sqlite.org/foreignkeys.html#fk_enable
Did you read the documentation? The main page says it's introduced with version 3.6.19. The link shows how to use foreign keys (Your code is correct).
Does your code give any error messages you omitted? Did you check all preconditions in specified in the documentation?
One important note that other answers do not mention is that the commands to enable/disable foreign constraints checks like:
PRAGMA foreign_keys = ON;
have no effect within a started transaction. Here's the quote from the documentation:
This pragma is a no-op within a transaction; foreign key constraint
enforcement may only be enabled or disabled when there is no pending
BEGIN or SAVEPOINT.
The command should be run before transaction is started. I faced this issue when I tried to disable a FK constraint check temporarily to address a performance issue but this may still cause a problem if the command is used at inappropriate time.