How to constrain that a table gets multiple values in t-sql? - tsql

I thought of creating a trigger in t-sql that constrains having multiple values of the same column. It has three unique keys - which needs to be unique.
How to get the current row in a t-sql trigger? Is it possible?

If those values are predefined you can create an other table which contain all these unique values and then create FK constraint.
For me it looks like as standard look up table:

Related

PostgresQL: Value is only allowed in one of two columns

I have a database with two tables "Config" and "Config_xml", each consisting of the same columns (id, content, modifier, etc...). The only difference is, that config only contains non-xml strings in its content column, whereas config_xml contains an xml string in its content column.
Now I'd like to combine these two tables into one, providing a content column and an xml_content column, to simplify querying, because at the moment I always have to query on both tables.
Now is there a way to constrain each row to allow a value in either content or xml_content?
Thanks in advance.
You can use a check constraint that requires one column to be null.
alter table the_table
add constraint check_content
check (num_nulls(config, config_xml) = 1);
To also avoid empty strings, you might want to use:
check (num_nulls(nullif(trim(config::text), ''), nullif(trim(config_xml::text), '')) = 1)

Partitioning tables in PostgreSQL by a value stored in a different table

We are using a partitioning scheme that uses a date field in the table to determine the partition that should be used i.e. table foo with child foo_y2016m01.
This works for our simpler tables, but we are researching how to approach some of our more complex table relations to do the same style of partitioning, such as foo having a date field and bar storing the row id of the associated record in foo. The bar table does not have a date field of its own, but we still want to partition the table such that child tables would follow the same format (bar_y2016m01).
Is it possible to format the check constraint on bar such that it can use the date field from foo?
The answer is: Possibly.
You can use an expression in check constraint so you can write a function that will check the other table for you. However it will be only triggered during instert/update on the table so the data might loose integrity and you'll have to use a foreign key or add a trigger to table bar to keep foo correct.

PostgreSQL - Dynamic addition of large no of columns

Assume I have a table named tracker with columns (issue_id,ingest_date,verb,priority)
I would like to add 50 columns to this table.
Columns being (string_ch_01,string_ch_02,.....,string_ch_50) of datatype varchar.
Is there any better way to add columns with single procedure rather than executing the following alter command 50 times?
ALTER TABLE tracker ADD COLUMN string_ch_01 varchar(1020);
Yes, a better way is to issue a single ALTER TABLE with all the columns at once:
ALTER TABLE tracker
ADD COLUMN string_ch_01 varchar(1020),
ADD COLUMN string_ch_02 varchar(1020),
...
ADD COLUMN string_ch_50 varchar(1020)
;
It's especially better when there are DEFAULT non-null clauses for the new columns, since each of them would rewrite the entire table, as opposed to rewriting it only once if they're grouped in a single ALTER TABLE.

Composite key with user-supplied string column, foreign keys

Let's say I have the following table
TABLE subgroups (
group_id t_group_id NOT NULL REFERENCES groups(group_id),
subgroup_name t_subgroup_name NOT NULL,
more attributes ...
)
subgroup_name is UNIQUE to a group(group_id).
A group can have many subgroups.
The subgroup_names are user-supplied. (I would like to avoid using a subgroup_id column. subgroup_name has meaning in the model and is more than just a label, I am providing a list of predetermined names but allow a user to add his owns for flexibility).
This table has 2 levels of referencing child tables containing subgroup attributes (with many-to-one relations);
I would like to have a PRIMARY KEY on (group_id, upper(trim(subgroup_name)));
From what I know, postgres doesn't allow to use PRIMARY KEY/UNIQUE on a function.
IIRC, the relational model also requires columns to be used as stored.
CREATE UNIQUE INDEX ON subgroups (group_id, upper(trim(subgroup_name))); doesn't solve my problem
as other tables in my model will have FOREIGN KEYs pointing to those two columns.
I see two options.
Option A)
Store a cleaned up subgroup name in subgroup_name
Add an extra column called subgroup_name_raw that would contained the uncleaned string
Option B)
Create both a UNIQUE INDEX and PRIMARY KEY on my key pair. (seems like a huge waste)
Any insights?
Note: I'm using Postgres 9.2
Actually you can do a UNIQUE constraint on the output of a function. You can't do it in the table definition though. What you need to do is create a unique index after. So something like:
CREATE UNIQUE INDEX subgroups_ukey2 ON subgroups(group_id, upper(trim(subgroup_name)));
PostgreSQL has a number of absolutely amazing indexing capabilities, and the ability to create unique (and partial unique) indexes on function output is quite underrated.

Setting constraint for two unique fields in PostgreSQL

I'm new to postgres. I wonder, what is a PostgreSQL way to set a constraint for a couple of unique values (so that each pair would be unique). Should I create an INDEX for bar and baz fields?
CREATE UNIQUE INDEX foo ON table_name(bar, baz);
If not, what is a right way to do that? Thanks in advance.
If each field needs to be unique unto itself, then create unique indexes on each field. If they need to be unique in combination only, then create a single unique index across both fields.
Don't forget to set each field NOT NULL if it should be. NULLs are never unique, so something like this can happen:
create table test (a int, b int);
create unique index test_a_b_unq on test (a,b);
insert into test values (NULL,1);
insert into test values (NULL,1);
and get no error. Because the two NULLs are not unique.
You can do what you are already thinking of: create a unique constraint on both fields. This way, a unique index will be created behind the scenes, and you will get the behavior you need. Plus, that information can be picked up by information_schema to do some metadata inferring if necessary on the fact that both need to be unique. I would recommend this option. You can also use triggers for this, but a unique constraint is way better for this specific requirement.