Informix to SQL attribute constraint - sql

I have a constraint as follows in my script & I learnt that it's Informix:
create table blaBla
{
var_name_1 not null constraint n255_153,
var_name_1 not null constraint n655_699,
}
I can't find an equivalent to this in SQL. I tried just typing it the same but it doesn't work. What's the equivalent in other DBMS?

You have a number of problems with your SQL, which reads:
create table blaBla
{
var_name_1 not null constraint n255_153,
var_name_1 not null constraint n655_699,
}
Informix uses { and } to enclose comments (also -- to end of line, and /* … */). Both standard SQL and Informix require ( and ) around the body of the CREATE TABLE statement.
All SQL DBMS insist on a type in the column definition, and require different columns in the same table to have distinct names. (The constraint names in a table must be unique across all tables in the database, too.) The comma is a separator, not a terminator, so the final comma must be omitted, too.
Informix also insists on the constraint name after the constraint, but the standard and other SQL DBMS put the constraint name before the constraint. Thus, elsewhere, you'd consider using:
CREATE TABLE blaBla
(
var_name_1 INTEGER CONSTRAINT n255_153 NOT NULL,
var_name_2 CHAR(20) CONSTRAINT n655_699 NOT NULL
)
Speaking frankly, though, most people would not name a NOT NULL constraint at all and would simply write:
CREATE TABLE blaBla
(
var_name_1 INTEGER NOT NULL,
var_name_2 CHAR(20) NOT NULL
)
The system then generates an automatic constraint name similar to the ones you showed. The nXXX_YYY notation means that the table ID (tabid number in the systables system catalog table) was XXX when the constraint was created, and for that table, the constraint was number YYY. Either you have composite notation from several tables, or the table was modified (altered) and the new table number was 655 when the old was 255. That is, however, a quirk of the naming scheme used by Informix and totally unlegislated by standard SQL.

Related

I'm getting (errno: 150 "Foreign key constraint is incorrectly formed") but engine is set to innoDb and types are the same

I basically have 2 simple tables and i reference the primary key of users from the articles table. The engine is set to innoDB and how you can see the data types are int on both ends.
My buddy has the same tables inserted into his database without any errors.
He uses XAMPP and I use Docker if this matters
The errormessage:
ERROR 1005 (HY000) at line 25: Can't create table CMS.Article (errno: 150 "Foreign key constraint is incorrectly formed")
CREATE TABLE IF NOT EXISTS USERS (
id int auto_increment primary key,
username varchar(255) NOT NULL,
password varchar(255) NOT NULL,
role ENUM("user", "admin") NOT NULL
);
CREATE TABLE IF NOT EXISTS Article(
id int auto_increment primary key,
userId int NOT NULL,
title varchar(255) NOT NULL,
date date NOT NULL,
content TEXT NOT NULL,
FOREIGN KEY(userId) REFERENCES users(id)
);
How can i solve this unexpected error?
From "Identifier Case-sensitivity":
Whether objects are case-sensitive or not is partly determined by the underlying operating system. Unix-based systems are case-sensitive, ... while Mac OS X is usually not, but can be if UFS volumes are used.
... table ... names are affected by the systems case-sensitivity, while ... column ... names are never case sensitive.
You very likely have the database on a file system, that is case-sensitive. You named the table USERS in all caps. That follows, that you have to reference it in all caps from now on.
Try:
...
FOREIGN KEY (userid)
REFERENCES USERS
(id)
...
db<>fiddle
Or change the configuration.
Again from "Identifier Case-sensitivity":
The lower_case_table_names server system variable plays a key role. It determines whether table names ... are compared in a case-sensitive manner. ... If set to 1 (the default on Windows), names are stored in lowercase and not compared in a case-sensitive manner.
And as a side note: Don't get used to use double quotes for string or date literals. Yes, sadly MySQL and MariaDB accept that, but in SQL double quotes are usually for identifiers, such as column names. Should you ever use another DBMS (or future MySQL or MariaDB versions become more sane about this) you'll likely get an "invalid object name" error. Always use single quotes for string or date literals.

What is the difference between referencing a column using "()" and "."?

I was trying to create a join table using the following statement:
CREATE TABLE directors_and_films(
id serial PRIMARY KEY,
directors_id int REFERENCES directors.id
films_id int REFERENCES films.id,
);
This causes Postgres to respond with:
ERROR: schema "films" does not exist
When I change it to:
CREATE TABLE directors_films (
id serial PRIMARY KEY,
director_id integer REFERENCES directors (id),
film_id integer REFERENCES films (id)
);
The code executes fine.
My question is what is the difference between accessing a column using () as opposed to a period? What are the differences between these two in SQL generally?
Postgres does indeed support functional notation and attribute notation for column references. So this works for a table tbl with a column col:
SELECT col(tbl) FROM tbl;
The manual:
but this usage is deprecated since it's easy to get confused
See:
Store common query as column?
But that has no bearing on the case at hand. The short syntax for FK constraints in a CREATE TABLE statement requires parentheses around the referenced column. (The column constraint like in your example, can only reference a single column, obviously.) Attribute notation like you tried (directors.id) is a syntax error in this spot.
That's all there is to this. The manual:
REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]

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;

What does DF__role_sett__custo__4589517F in SQL Server database mean?

I have just inherited a database from another developer, and I have looked through the sys.objects table, filtering by constraints.
What does DF__role_sett__custo__4589517F mean - mainly the ID at the end of the string?
I know that DF_role_sett_custo means default constraint of role_setting_customer, but am not sure of the last ID 4589517f.
If you don't name a constraint when it is created, SQL Server will assign it a random name based on the table and column. It appends a random number so that it doesn't clash with existing constraint names.
In almost all cases, it is best to name a constraint when it is created. It's then easier to refer to the constraint by name in other T-SQL statements.
For instance, in the following create statement
CREATE TABLE dbo.some_table(
some_field INT NOT NULL DEFAULT(5)
);
The default constraint will be assigned a random name. In this statement:
CREATE TABLE dbo.some_table(
some_field INT NOT NULL CONSTRAINT DF_some_table_some_field DEFAULT(5)
);
The default constraint will have the name you assigned to it (i.e. DF_some_table_some_field).

Can there be constraints with the same name in a DB?

This is a follow-on question from the one I asked here.
Can constraints in a DB have the same name?
Say I have:
CREATE TABLE Employer
(
EmployerCode VARCHAR(20) PRIMARY KEY,
Address VARCHAR(100) NULL
)
CREATE TABLE Employee
(
EmployeeID INT PRIMARY KEY,
EmployerCode VARCHAR(20) NOT NULL,
CONSTRAINT employer_code_fk FOREIGN KEY (EmployerCode) REFERENCES Employer
)
CREATE TABLE BankAccount
(
BankAccountID INT PRIMARY KEY,
EmployerCode VARCHAR(20) NOT NULL,
Amount MONEY NOT NULL,
CONSTRAINT employer_code_fk FOREIGN KEY (EmployerCode) REFERENCES Employer
)
Is this allowable? Does it depend on the DBMS (I'm on SQL Server 2005)? If it is not allowable, does anyone have any suggestions on how to work around it?
No - a constraint is a database object as well, and thus its name needs to be unique.
Try adding e.g. the table name to your constraint, that way it'll be unique.
CREATE TABLE BankAccount
(
BankAccountID INT PRIMARY KEY,
EmployerCode VARCHAR(20) NOT NULL,
Amount MONEY NOT NULL,
CONSTRAINT FK_BankAccount_Employer
FOREIGN KEY (EmployerCode) REFERENCES Employer
)
We basically use "FK_"(child table)_(parent table)" to name the constraints and are quite happy with this naming convention.
Information from MSDN
That constraint names have to be unique to the schema (ie. two different schemas in the same database can both contain a constraint with the same name) is not explicitly documented. Rather you need to assume the identifiers of database objects must be unique within the containing schema unless specified otherwise. So the constraint name is defined as:
Is the name of the constraint. Constraint names must follow the rules for identifiers, except that the name cannot start with a number sign (#). If constraint_name is not supplied, a system-generated name is assigned to the constraint.
Compare this to the name of an index:
Is the name of the index. Index names must be unique within a table or view but do not have to be unique within a database. Index names must follow the rules of identifiers.
which explicitly narrows the scope of the identifier.
The other answers are all good but I thought I'd add an answer to the question in the title, i.e., "can there be constraints with the same name in a DB?"
The answer for MS SQL Server is yes – but only so long as the constraints are in different schemas. Constraint names must be unique within a schema.
I was always puzzled why constraint names must be unique in the database, since they seem like they're associated with tables.
Then I read about SQL-99's ASSERTION constraint, which is like a check constraint, but exists apart from any single table. The conditions declared in an assertion must be satisfied consistently like any other constraint, but the assertion can reference multiple tables.
AFAIK no SQL vendor implements ASSERTION constraints. But this helps explain why constraint names are database-wide in scope.
It depends on the DBMS.
For example on PostgreSQL, the answer is yes :
Because PostgreSQL does not require constraint names to be unique
within a schema (but only per-table), it is possible that there is
more than one match for a specified constraint name.
Source : https://www.postgresql.org/docs/current/static/sql-set-constraints.html
I've seen Foreign Keys constraint names equals on 2 different tables within the same schema.
Does it depend on the DBMS (I'm on SQL Server 2005)?
Yes, apparently it does depend on the DBMS.
Other answers say it's not permitted, but I have a MS SQL CE ("Compact Edition") database in which I accidentally successfully created two FK contraints, in two tables, with the same contraint name.
Good practice is to create index and constraint names specifying table name at the beginning.
There's 2 approaches, with index/constraint type at the beginning or at the end) eg.
UQ_TableName_FieldName
or
TableName_FieldName_UQ
Foreign keys names should also contain names of referenced Table/Field(s).
One of good naming conventions is to give table names in form of FullName_3LetterUniqueAlias eg.
Employers_EMR
Employees_EMP
BankAccounts_BNA
Banks_BNK
This give you opportunity to use "predefined" aliases in queries which improves readability and also makes Naming of foreign keys easier, like:
EMPEMR_EmployerCode_FK
BNKEMR_EmployerCode_FK