How to alter MQT query - db2

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

Related

DB2 iseries materialized view refresh

I have created the following materialized query table:
CREATE TABLE SCHEMA.TABLE AS
(SELECT * FROM SCHEMA.TABLEEXAMPLE)
DATA INITIALLY DEFERRED
REFRESH DEFERRED
MAINTAINED BY USER
DISABLE QUERY OPTIMIZATION;
When I execute a REFRESH TABLE SCHEMA.TABLE it get locked for others users to read from it.
Reading this doc from IBM https://www.ibm.com/support/knowledgecenter/en/SSEPGG_9.7.0/com.ibm.db2.luw.sql.ref.doc/doc/r0000977.html
I tried to execute this statement:
REFRESH TABLE SCHEMA.TABLE ALLOW READ ACCESS
But I get the following error: SQL State: 42601 Unexpected keyword ALLOW
What I'm missing on statement? Is there other way to allow read access to materialized query table while it is beign updated?
MQTs on Db2 for IBM i lag behind the functionality available in Db2 for LUW.
I've never bother with them, instead an encoded vector index (EVI) with computed columns meets every need I've every considered. (Note that Db2 LUW doesn't have EVIs)
Per Mao's comment, you might try deleting an recreating the MQT with the following:
CREATE TABLE SCHEMA.TABLE AS
(SELECT * FROM SCHEMA.TABLEEXAMPLE)
DATA INITIALLY DEFERRED
REFRESH DEFERRED
MAINTAINED BY USER
DISABLE QUERY OPTIMIZATION
with NC;
But I think a refresh would still require exclusive access to the MQT.
The only options I can think of for "refreshing" an MQT while it is being used
programmatically , using either triggers on the base tables or perhaps a process that uses SQL to update a few rows at a time.
removing the DISABLE QUERY OPTIMIZATION and not accessing the MQT directly. Instead depend on the optimizer to access it when appropriate. Now you can create a version of it every few hours and the Db should start using the newer version for new queries. Once the older one is no longer being used, you delete it (or REFRESH it)

Will making column nullable lock the table for reads?

I want to make one field in my database nullable.
ALTER TABLE answers ALTER COLUMN author_id DROP NOT NULL;
The problem is that I have a lot of data in the database and I'm not sure if the alter command will block the table for write operations.
I know that changing the size or type of the column will cause the row exclusive lock https://www.postgresql.org/docs/current/static/explicit-locking.html#LOCKING-TABLES.
Will the alter I lock the table for writes too or it's safe to use?
Yes, the ALTER will require an exclusive lock on the table (including blocking write access to the table)
However, the duration of the lock is extremely short and does not depend on the size of the table. It is essentially only an update the internal system tables.

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

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.

Why are foreign keys active after disabling triggers on a table?

I'm trying to refresh some data that's referred to by other data - I want to truncate and reload the ms_automobile table, but the rm_automobile table has a foreign key to it.
It looks like the 'DISABLE TRIGGER' statements are working (run as postgres, a superuser):
mobilesurvey=# ALTER TABLE ms_automobile DISABLE TRIGGER ALL;
ALTER TABLE
mobilesurvey=# ALTER TABLE rm_automobile DISABLE TRIGGER ALL;
ALTER TABLE
But I can't then truncate the ms_automobile table:
mobilesurvey=# TRUNCATE TABLE ms_automobile;
ERROR: cannot truncate a table referenced in a foreign key constraint
DETAIL: Table "rm_automobile" references "ms_automobile".
HINT: Truncate table "rm_automobile" at the same time, or use TRUNCATE ... CASCADE.
Again, I do not want to lose the rm_automobile data; after the TRUNCATE I'm planning on doing a pg_restore that includes the missing ms_automobile data.
If possible, I'd like to disable instead of dropping the constraints - there are more of them, and maintaining disable/enable seems a lot less error-prone than maintaining drop/add.
So, how can I actually disable the foreign keys here?
Disabling triggers works as you expect on DELETE (and not on TRUNCATE).
DELETE FROM ms_automobile;
TRUNCATE is implemented in the specific way different from INSERT/UPDATE/DELETE. It doesn't use triggers but checks referential integrity once before its execution.

Create TABLE in many Postgres schemas with a single command

I have two schemas in my Postgres BOOK database, MSPRESS and ORELLY.
I want to create the same table in two schemas:
CREATE TABLE MSPRRESS.BOOK(title TEXT, author TEXT);
CREATE TABLE ORELLY.BOOK(title TEXT, author TEXT);
Now, I want to create the same table in all my schemas with a single command.
To accomplish this, I thought about event triggers available in Postgres 9.3 (http://www.postgresql.org/docs/9.3/static/event-triggers.html). Intercepting CREATE TABLE command by my event trigger, I thought to determine name of table and schema in which it is created and just repeat the same command for all available schemas. Sadly, event trigger procedure does not get name of table being created.
Is there a way to 'real-time' synchronization of Postgres schema?
Currently only TG_EVENT and TG_TAG is available from an event trigger, but this feature will likely be expanded. In the meantime, you can query information_schema for differences and try to add every table, where its missing; but don't forget that this synchronization will also trigger several event triggers, so you should do it carefully.
But if you just want to build several schemas with the same structure (without further synchronization), you could just write schema-less queries to build them & run it on every schema one-by-one, after changing search path with SET search_path / SET SCHEMA.