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).
Related
I have two tables, one of student and one of staff that look as such:
create table student (
id int not null primary key
)
create table staff (
id int not null primary key
)
I want the id in each to be unique. I know this isn't how it should be in production but I'm just trying to see why my check constraint doesn't work and I'm using a simpler example to explain.
I then alter the tables to include the check as follows:
alter table student add constraint not_staff check (id not in (select id from staff))
alter table staff add constraint not_student check (id not in (select id from student))
These checks seem to be invalid.
My question is whether we're allowed to have these kinds of SQL statements inside of a check constraint. If so, why is the above constraint invalid and how would I go about fixing it.
Thanks!
You can't use queries in a check constraint in Db2. Refer to the description of the CREATE TABLE statement.
CHECK (check-condition)
Defines a check constraint. The search-condition must be true or unknown for every row of the table.
search-condition
The search-condition has the following restrictions:
...
The search-condition cannot contain any of the following (SQLSTATE 42621):
Subqueries
The easiest way to achieve your goal is not to create constraints, but create a sequence and use it in before triggers on both tables.
I'm trying to create a default constraint here, but the system is generating a weird name for it. If I want to name it df_MY_TABLE_GUID or something, how could I specify that name be used?
ALTER TABLE MY_TABLE
ADD MY_GUID uniqueidentifier NOT NULL
CONSTRAINT uq_MY_TABLE_GUID UNIQUE (MY_TABLE_GUID)
DEFAULT NEWID() WITH VALUES
Just specify the constraint name with the full syntax, like the UNIQUE in your example:
ALTER TABLE MY_TABLE ADD MY_GUID UNIQUEIDENTIFIER NOT NULL
CONSTRAINT uq_MY_TABLE_GUID UNIQUE (MY_TABLE_GUID)
CONSTRAINT df_MY_TABLE_GUID DEFAULT NEWID() WITH VALUES ;
As a matter of routine, I always prefer and encourage to always name every single constraint I create, for the sake of easy reference latter on.
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;
I have following indexes/unique constraints in my table.
INDNAME COLNAMES
SQL160215110206240 +ID
SQL160215110206360 +ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME
SQL160215145445420 +ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME+PROVISIONING_CONFIG_ID
Now I run following code segment on my darabase.
BEGIN
DECLARE v_rcount VARCHAR(128);
DECLARE STMT VARCHAR(200);
select INDNAME into v_rcount from SYSCAT.INDEXES WHERE TABNAME='IDP_PROVISIONING_ENTITY' AND COLNAMES='+ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME';
SET STMT = 'ALTER TABLE IDP_PROVISIONING_ENTITY DROP CONSTRAINT ' || v_rcount;
PREPARE S1 FROM STMT;
EXECUTE S1;
END
When I run it for the 1st time, I am getting following response.
DB20000I The SQL command completed successfully.
But when I list the indexes of the table, I am still seeing all 3 indexes as before.
And also when I run the same code segment again, I am getting following error.
SQL0204N "SQL160215110206360" is an undefined name. SQLSTATE=42704
Not only this index, if I try to drop any other index in the same database, I am getting the same error. What is the reason for this? How can I solve this?
The cause for this issue is, I am getting the name from SYSCAT.INDEXES. So there it is returning the name of INDEX. Even though a INDEX is created to each unique constraint, name of index can be different from name of Constraint. So here I have dropped the constraint and then I have checked the index table if it has removed. That's the reason why I can see the same index name still after removing the constraint.
Also every index name in SYSCAT.INDEXES will not refer to a constraint. So everytime I run DROP CONSTRAINT with a name from SYSCAT.INDEXES will not return success.
IBM DB2 behaves little bit differently compared to other well known databases when comes to constraints and indexes. So let me explain the solution for your problem in detail.
You have the following table.
CREATE TABLE IDP_PROVISIONING_ENTITY (
ID INTEGER NOT NULL,
PROVISIONING_CONFIG_ID INTEGER NOT NULL,
ENTITY_TYPE VARCHAR(255) NOT NULL,
ENTITY_LOCAL_USERSTORE VARCHAR(255) NOT NULL,
ENTITY_NAME VARCHAR(255) NOT NULL,
ENTITY_VALUE VARCHAR(255) NOT NULL,
TENANT_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
UNIQUE (ENTITY_TYPE, TENANT_ID, ENTITY_LOCAL_USERSTORE, ENTITY_NAME),
UNIQUE (PROVISIONING_CONFIG_ID, ENTITY_TYPE, ENTITY_VALUE),
FOREIGN KEY (PROVISIONING_CONFIG_ID) REFERENCES IDP_PROVISIONING_CONFIG(ID) ON DELETE CASCADE)
/
It has a primary key and two unique constraints. The DB2 will automatically create indexes for these three constraints.
The problem is, we have not defined the constraints as named constraints. Therefore we have to take an extra effort to find out the names of the indexes and the constraints which are auto generated by DB2.
These are the two unique constraints that we have in the table.
UNIQUE (ENTITY_TYPE, TENANT_ID, ENTITY_LOCAL_USERSTORE, ENTITY_NAME),
UNIQUE (PROVISIONING_CONFIG_ID, ENTITY_TYPE, ENTITY_VALUE)
You can find the auto generated names for the unique constraints by running the following query. the constraintyp='U' for unique constraints and it is 'P' for primary keys.
db2 "select NAME from sysibm.systabconst where tbname='IDP_PROVISIONING_ENTITY' and constraintyp='U'"
NAME
--------
SQL160219074557840
SQL160219074557920
Above is the result I got. You will get different values in your database as these are random generated.
You can run the following query to see the indexes created for the IDP_PROVISIONING_ENTITY' table.
db2 "SELECT NAME, COLNAMES FROM SYSIBM.SYSINDEXES WHERE TBNAME='IDP_PROVISIONING_ENTITY'"
NAME COLNAMES
SQL160219074557290 +ID
SQL160219074557790 +PROVISIONING_CONFIG_ID+ENTITY_TYPE+ENTITY_VALUE
SQL160219074557860 +ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME
Now we know the constraint names for the two unique constraints and the index names for the IDP_PROVISIONING_ENTITY table.
You can find the particular index you need to drop by adding a where clause for the above query as below.
db2 "SELECT NAME FROM SYSIBM.SYSINDEXES WHERE TBNAME='IDP_PROVISIONING_ENTITY' and COLNAMES='+ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME'"
NAME
----------
SQL160219074557860
In IBM DB2, you cannot drop an index which is generated for a constraint (primary key or unique) directly. For that, you need to drop the constraint which will drop the index also.
But the problem is we do not know what is the name of the unique constraint that is associated with the index "+ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME". We already know that the index name we need to drop is SQL160219074557860.
You can find it out which constraint is associated with which index by running the following query.
db2 "select CONSTNAME, BNAME from SYSCAT.CONSTDEP where TABNAME = 'IDP_PROVISIONING_ENTITY'"
CONSTNAME BNAME
SQL160219074557790 SQL160219074557290
SQL160219074557840 SQL160219074557790
SQL160219074557920 SQL160219074557860
Based on the results, you can get to know the name of the constraint.
So the constraint name associated with the index name "SQL160219074557860" is "SQL160219074557920".
So since we know the constraint name now, we can drop the unique constraint.
db2 "ALTER TABLE IDP_PROVISIONING_ENTITY DROP UNIQUE SQL160219074557920"
This will drop the constraint as well as the index created for the constraint.
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.