I am mainly from a Sql Server background, and following some issues with getting MySql to work with the Microsoft Sync Framework (namely it does not cater for snapshots), I am having to look into Postgres and try to get that working with the Sync Framework.
The triggers that are needed include a call to function "##DBTS", but I am having trouble finding an equivalent in Postgres for this.
From the microsoft documentation for this it says:
##DBTS returns the current database's last-used timestamp value.
A new timestamp value is generated when a row with a timestamp
column is inserted or updated.
In MySql it was the following:
USE INFORMATION_SCHEMA;
SELECT MAX(UPDATE_TIME) FROM TABLES WHERE UPDATE_TIME < NOW();
Can anyone tell me what this would be in Postgres?
PostgreSQL does not keep track when a table was last modified. So there is no equivalent for SQL Server's ##DBTS nor for MySQL's INFORMATION_SCHEMA.TABLES.UPDATE_TIME.
You also might be interested in this discussion:
http://archives.postgresql.org/pgsql-general/2009-02/msg01171.php
which essentially says: "if you need to know when a table was last modified, you have to add a timestamp column to each table that records that last time the row was updated".
Related
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)
The following SQL Query:
CREATE TABLE "SomeTable" ("dateEnd" DATE)
Creates a table SomeTable with a column dateEnd. However, the database-type is Timestamp, not Date. It used to work, but after reimporting a whole database dump, all the Date data-types are replaced by Timestamp data-types. Even If I create a very simple table, like the one above, the data-type jumps to Timestamp. I am using DB2 express c version 11.1.0.
If your Db2 database was created in Oracle Compatibility mode, then DATE columns are implemented as TIMESTAMP(0) columns to match what Oracle does.
https://www.ibm.com/support/knowledgecenter/SSEPGG_11.1.0/com.ibm.db2.luw.apdv.porting.doc/doc/r0053667.html
https://www.ibm.com/support/knowledgecenter/SSEPGG_11.1.0/com.ibm.db2.luw.admin.config.doc/doc/r0054912.html
BTW you may want to use either Db2 Developer-C or Db2 Developer Community Edition. Those are effectively replacing the old Express-C edition
https://www.ibm.com/uk-en/marketplace/ibm-db2-direct-and-developer-editions
This problem scenario may sounds strange but I am trying to write a trigger to log the query type into another table and so far i havent been able to find anything on google
the database i am using is postgres
i.e.
if i have two tables; table1 and querylog(has a string field called querytype)
and a select query is executed on table1, i want to insert a row into the query log table with the querytype field populated with "select"
anyone have any idea how to reference the query type in a function that will be called by a trigger?
Triggers do not get called for SELECT queries, so that won't work.
If you want to audit queries, you can use the PostgreSQL log file or tools like pgaudit that hook into PostgreSQL to retrieve and log the information.
In SQL Server 2005, I built a trigger that contains a SQL statement that unpivot's some data. Somewhat similar to the following simple example: http://sqlfiddle.com/#!3/cdc1b/1/0. Let's say that the table the trigger is built on is "table1" and it's set run after updates.
Within SSMS whenever I update "table1" everything works fine. Unfortunately, whenever I update "table1" in a proprietary application (which I don't have the source code to), it fails with the message "The type of column conflit with the type of other columns specified in the UNPIVOT list".
After doing a bit of searching I added COLLATE DATABASE_DEFAULT to my cast's in the view without any luck. It was a bit of a long shot because the collation all matched whenever I queried INFORMATION_SCHEMA.COLUMNS.
I then changed the casts from VARCHAR to CHAR and it worked without issue. For obvious reasons, I'd rather use VARCHAR. What is different between a SSMS and application connection? I assume the application isn't using a connection property that SSMS uses.
PS: The database is a bit funky because it does not use NULLs and uses CHAR instead of VARCHAR.
I have a table that contains no date or time related fields. Still I want to query that table based on when records/rows were created. Is there a way to do this in PostgreSQL?
I prefer an answer about doing it in PostgreSQL directly. But if that's not possible, can hibernate do it for PostgreSQL?
Basically: no. There is no automatic timestamp for rows in PostgreSQL.
I usually add a column like this to my tables (ignoring time zones):
ALTER TABLE tbl ADD COLUMN log_in timestamp DEFAULT localtimestamp NOT NULL;
As long as you don't manipulate the values in that column, you got your creation timestamp. You can add a trigger and / or restrict write privileges to avoid tempering with the values.
Second class options
If you have a serial column, you could at least tell with some probability in what order rows were entered. That's not 100% reliable, because the values can be changed by hand, and applications can get values from the sequence and INSERT out of order.
If you created your table WITH (OIDS=TRUE), then the OID column could be some indication - unless your database is heavily written and / or very old, then you may have gone through OID wrap-around and later rows can have a smaller OID. That's one of the reasons, why this feature is hardly used any more.
The default depends on the setting of default_with_oids I quote the manual:
The parameter is off by default; in PostgreSQL 8.0 and earlier, it was
on by default.
If you have not updated your rows or went through a dump / restore cycle, or ran VACUUM FULL or CLUSTER or .. , a plain SELECT * FROM tbl returns all rows in the order they were entered. But this is very unreliable and implementation-dependent. PostgreSQL (like any RDBMS) does not guarantee any order without an ORDER BY clause.