How to rename a table in a database which have referential integrity maintain? - db2

After giving the below command
set integrity for table_name off
I am getting following error
DB2 SQL error: SQLCODE: -290, SQLSTATE: 55039, SQLERRMC: null Message:
Table space access
What could be the possible reason for this?
What I want to achieve is: I want to temporarily disable the constraints so that I can rename the actual table and create a new table with the actual table name. Then i will enable the constraints. Any help of pointers in this regard will be appreciated.

set integrity does not "disable constraints".
As per the SET INTEGRITY statement manual page, set integrity off
Specifies that the tables are placed in set integrity pending state. Only very limited activity is allowed on a table that is in set integrity pending state.
WHen you try to rename a table with constraints you get SQL0750N, which says:
If the error pertains to a RENAME statement, drop the view, materialized query
table, trigger, SQL function, SQL method, check constraint, referential constraint,
expression-based index, or XSR object dependent on the table before issuing the
RENAME statement. Objects dependent on the table can be determined by querying the
catalog.
I.e. you have to drop the constraint, rename the table, then add the constraint back. It is just the way it works. Something like ADMIN_MOVE_TABLE will do the drop and re-create of constraints required, but then that until actually physically moves the table data, so is maybe not a good idea if you simply want to do a rename. Many GUI tolls (such as IBM Data Studio) will generate the required DROP, RENAME, CREATE statements for you.
The error you currently have SQL0290N Table space access is not allowed is a different issue, and will be due to some other cause.

Related

How to alter MQT query

I have not been able to find an example of altering the underlying query defined for a MQT.
Are you supposed to drop the table and recreate it?
If you can would this be the correct way?
ALTER TABLE SCHEMA.MY_TABLE
(SELECT...)
DATA INITIALLY DEFERRED
REFRESH DEFERRED
MAINTAINED BY SYSTEM

Is it possible to access current column data on conflict

I want to get such behaviour on inserting data (conflict on id):
if there is no model with same id in db do INSERT
if there is entry with same id in db and that entry is newer (updated_at field) do NOT UPDATE
if there is entry with same id in db and that entry is older (updated_at field) do UPDATE
I'm using Ecto for that and want to work on constraints, however I cannot find an option to do so in documentation. Pseudo code of constraint could look like:
CHECK: NULL(current.updated_at) or incoming.updated_at > current.updated_at
Is such behaviour possible in Postgres?
PostgreSQL does not support CHECK constraints that reference table
data other than the new or updated row being checked. While a CHECK
constraint that violates this rule may appear to work in simple tests,
it cannot guarantee that the database will not reach a state in which
the constraint condition is false (due to subsequent changes of the
other row(s) involved). This would cause a database dump and reload to
fail. The reload could fail even when the complete database state is
consistent with the constraint, due to rows not being loaded in an
order that will satisfy the constraint. If possible, use UNIQUE,
EXCLUDE, or FOREIGN KEY constraints to express cross-row and
cross-table restrictions.
If what you desire is a one-time check against other rows at row
insertion, rather than a continuously-maintained consistency
guarantee, a custom trigger can be used to implement that. (This
approach avoids the dump/reload problem because pg_dump does not
reinstall triggers until after reloading data, so that the check will
not be enforced during a dump/reload.)
That should be simple using the WHERE clause of ON CONFLICT ... DO UPDATE:
INSERT INTO mytable (id, entry) VALUES (42, '2021-05-29 12:00:00')
ON CONFLICT (id)
DO UPDATE SET entry = EXCLUDED.entry
WHERE mytable.entry < EXCLUDED.entry;

Is it safe to drop a table column constraint in postgres

I'm looking at a production table in postgres with the following constraint which due to third party collaboration we need to remove.
"customer_email_unique" UNIQUE CONSTRAINT, btree (customer_email)
This is a production table, what risks are there if I remove the constraint? If it causes problems can it be recreated after to an existing table, with existing data in it?
It looks like the command to drop the constraint is
ALTER TABLE your_table DROP CONSTRAINT customer_email_unique;
We're a React/ Node stack and I can see what the code is doing with regard to what will happen if the constraint is dropped, my lack of knowledge is more towards data and what happens if you drop a constraint.
Thanks,
This is a production table, what risks are there if I remove the constraint? If it causes problems can it be recreated after to an existing table, with existing data in it?
The risk is that you'll drop the constraint and non-unique entries will be inserted. You won't be able to reapply the unique constraint without deleting the non-unique rows or updating them to be non-unique. Another risk it that you'll drop the wrong constraint, or reapply the constraint incorrectly. Finally, there may be code which assumes that column is unique.
To mitigate this risk, write a script to drop the constraint ("up"), and one to restore uniqueness and reapply the constraint ("down"). Test it on an equivalent table on a non-production database.
This is the general idea of schema migrations. Every schema change is done by two scripts, an "up" script to apply the change and a "down" script to undo the change. Many ORMs, such as typeorm, support migrations. They make schemas reproducible so all environments know they have the same schemas, schemas can be tested, and in general mitigate the risk of schema changes.

Does altering a column will lock the table in postgresql?

Need help figuring this out. Tried googling, but found no specific answer.
Does altering a table in PostgreSQL like this will lock the table?
ALTER TABLE public.account ALTER COLUMN type acc_type VARCHAR(16) USING acc_type::VARCHAR(16);
Yes, that has to take an access exclusive lock, because the metadata change. Depending on what data type it was before that would be a very fast operation (e. g., it was varchar(10) before) or a very slow operation (if the previous type is not binary compatible).

Can Postgres silently ignore column constraint conflicts?

I have a Postgres 9.6 table with certain columns that must be unique. If I try to insert a duplicate row, I want Postgres to simply ignore the insert and continue, instead of failing or aborting. If the insert is wrapped in a transaction, it shouldn't abort the transaction or affect other updates in the transaction.
I assume there's a way to create the table as described above, but I haven't figured it out yet.
Bonus points if you can show me how to do it in Rails.
This is possible with the ON CONFLICT clause for INSERT:
The optional ON CONFLICT clause specifies an alternative action to
raising a unique violation or exclusion constraint violation error.
For each individual row proposed for insertion, either the insertion
proceeds, or, if an arbiter constraint or index specified by
conflict_target is violated, the alternative conflict_action is taken.
ON CONFLICT DO NOTHING simply avoids inserting a row as its
alternative action.
This is a relatively new feature and only available since Postgres 9.5, but that isn't an issue for you.
This is not something you specific at table creation, you'll need to modify each insert. I don't know how this works with Rails, but I guess you'll have to manually write at least part of the queries to do this.
This feature is also often called UPSERT, which is probably a better term to search for if you want to look for an integrated way in Rails to do this.