I have table named tbl_interest. I am trying to make simple bank database. I want to write a trigger for interest that it will automatically add interest after one year and update details according to it. Interest rate will taken by another value or you can say it will be hard coded. This is schema of tbl_interest:
CREATE TABLE [dbo].[tbl_interest]
(
[int_accno] [varchar](200) NOT NULL,
[int_date] [date] NOT NULL,
[int_oldbal] [float] NOT NULL,
[int_interest] [float] NOT NULL,
[int_totbal] [float] NOT NULL
) ON [PRIMARY]
Also apart from trigger, which way is best to do such operation?
Related
I got a table of the following form in Postgres:
CREATE TABLE contract (
id serial NOT NULL,
start_date date NOT NULL,
end_date date NOT NULL,
price float8 NOT NULL,
CONSTRAINT contract_pkey PRIMARY KEY (id)
);
In Microsoft Powerapps, I create a EditForm to update the table above. For other databases, like MS SQL, I didn't need to supply the id, since it's auto increment. But for some reason, PowerApps keeps demanding to fill in the id for this table, even though it's auto increment and shouldn't be supplied to Postgres.
Anyone with the same experience with Powerapps in combination with Postgres? Struggling with it for hours...
I have many time series stored in a PostgreSQL database over multiple tables. I would like to create a table 'anomalies' which references to time series with particuliar behaviour, for instance a value that is exceptionally high.
My question is the following: what is the best way to link the entries of 'anomalies' with other tables?
I could create a foreign key in each table referencing to an entry in anomaly, but then it would be not so obvious to go from the anomaly to the entry referencing the anomaly.
The other possibility I see is to store the name of the corresponding table in the entries of anomalies, but it does not seem like a good idea, as the table name might change, or the table might get deleted.
Is there a more elegant solution to do this?
CREATE TABLE type_1(
type_1_id SERIAL PRIMARY KEY,
type_1_name TEXT NOT NULL,
unique(type_1_name)
)
CREATE TABLE type_1_ts(
date DATE NOT NULL,
value REAL NOT NULL,
type_1_id INTEGER REFERENCES type_1(type_1_id) NOT NULL,
PRIMARY KEY(type_1_id, date)
)
CREATE TABLE type_2(
type_2_id SERIAL PRIMARY KEY,
type_2_name TEXT NOT NULL,
unique(type_2_name)
)
CREATE TABLE type_2_ts(
date DATE NOT NULL,
value REAL NOT NULL,
state INTEGER NOT NULL,
type_2_id INTEGER REFERENCES type_2(type_2_id) NOT NULL,
PRIMARY KEY(type_2_id, date)
)
CREATE TABLE anomalies(
anomaly_id SERIAL PRIMARY_KEY,
date DATE NOT NULL,
property TEXT NOT NULL,
value REAL NOT NULL,
-- reference to a table_name and an entry id?
table_name TEXT
data_id INEGER
)
What I'd like to do at the end is to be able to do:
SELECT * FROM ANOMALIES WHERE table_name='type_1',
or simply list the data_type corresponding to the entries
I want to add revisioning for records in an existing application which stores data in a PostgreSQL database. I read about strategies e.g. in this question, this question and this blog post.
I think that the approach to create a second history table which will rarely be queried will work best. However I do have some practical problems. Let's say that this is my table I want to add revision control to:
create table people(
id serial not null primary key,
name varchar(255) not null
);
For this very simple table my history table could look like this:
create table people_history(
peopleId int not null references people(id) on delete cascade on update restrict,
revision int not null,
revisionTimestamp timestamptz not null default current_timestamp,
name character varying(255) not null,
primary key(peopleId, revision)
);
And this brings the first problems up:
How do I generate the revision number?
Of course I could create a sequence from which I request revision numbers which would be easy. However that would leave large gaps between revisions per person as many people share the same sequence and it would feel more natural if the revision numbers were ascending numbers without gaps per person.
So I am tempted to find my revision number by select max(revision)+1 from ... where peopleId=.... However that could lead to a race condition if two threads ask for the next revision number and try to insert. That is very unlikely I have to admit (especially in my case where only few updates happen anyway) and would not cause data to corrupt as that would be a duplicate primary key and thus cause a transaction rollback, but it is not pretty either. I wonder if there is a prettier solution.
How do I insert data into the history table?
Two ways come to mind: Manually on every statement that updates the main table or using a trigger. A trigger sounds less error-prone as it is less likely that I forget about a query somewhere. However I cannot communicate to the application exactly which revision number was just created, can I? So if I want to create a couple of event tables like this:
create table peopleUserEditEvent (
poepleId int not null,
revision int not null,
userId int not null references users(id) on delete set null on update restrict,
comment text not null default '',
primary key(paopleId, revision),
foreign key (peopleId, revision) references people_history
);
That lists some metadata for revisions which explains why the revision was changed. In this case a user with a specific ID edited the data and might have supplied a comment.
In another case (and another event table) a cronjob might have changed something and documents the event which probably has no userId and no comment but other metadata.
To add those event data I need the revision id and if the revision id was created by a trigger it will be difficult to find out (or is there a practical way to do so?).
Well, you need one replication strategy for all tables and column you have , you can create one table to maintain all changes and insert on anytime you make a UPDATE INSERT or DELETE statement, maybe with this exemple of framwork idempiere changelog can help you
CREATE TABLE ad_changelog (
ad_changelog_id NUMERIC(10,0) NOT NULL,
ad_session_id NUMERIC(10,0) NOT NULL,
ad_table_id NUMERIC(10,0) NOT NULL,
ad_column_id NUMERIC(10,0) NOT NULL,
isactive CHAR(1) DEFAULT 'Y'::bpchar NOT NULL,
created TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL,
createdby NUMERIC(10,0) NOT NULL,
updated TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL,
updatedby NUMERIC(10,0) NOT NULL,
record_id NUMERIC(10,0) NOT NULL,
oldvalue VARCHAR(2000),
newvalue VARCHAR(2000),
undo CHAR(1),
redo CHAR(1),
iscustomization CHAR(1) DEFAULT 'N'::bpchar NOT NULL,
description VARCHAR(255),
ad_changelog_uu VARCHAR(36) DEFAULT NULL::character varying,
CONSTRAINT adcolumn_adchangelog FOREIGN KEY (ad_column_id)
REFERENCES adempiere.ad_column(ad_column_id)
MATCH PARTIAL
ON DELETE CASCADE
ON UPDATE NO ACTION
DEFERRABLE
INITIALLY DEFERRED,
CONSTRAINT adsession_adchangelog FOREIGN KEY (ad_session_id)
REFERENCES adempiere.ad_session(ad_session_id)
MATCH PARTIAL
ON DELETE NO ACTION
ON UPDATE NO ACTION
DEFERRABLE
INITIALLY DEFERRED,
CONSTRAINT adtable_adchangelog FOREIGN KEY (ad_table_id)
REFERENCES adempiere.ad_table(ad_table_id)
MATCH PARTIAL
ON DELETE CASCADE
ON UPDATE NO ACTION
DEFERRABLE
INITIALLY DEFERRED
)
WITH (oids = false);
CREATE INDEX ad_changelog_speed ON adempiere.ad_changelog
USING btree (ad_table_id, record_id);
CREATE UNIQUE INDEX ad_changelog_uu_idx ON adempiere.ad_changelog
USING btree (ad_changelog_uu COLLATE pg_catalog."default");
I have a tale and built a Crystal straight table report using it via the wizard. The table looks like:
CREATE TABLE [report].[WeekdayPivot](
[Id] [int] IDENTITY(1,1) NOT NULL,
[WeekDayId] [int] NOT NULL,
[IsDeleted] [bit] NOT NULL,
[T06h00] [int] NOT NULL,
[T07h00] [int] NOT NULL,
[T08h00] [int] NOT NULL,
So the wizard places WeekDayId as the second column. I wish to create a formula that converts thet to WeeekDayName, but all I can find is the "Formula" workshop, which doesn't have the usual list of DB fields etc. This is not the right screen, which is very similar, but has a list of DB fields at the top of the right hand tree. How do I find that dialogue?
The dialouges you are looking for may have undocked search for those in the second row from the top and once you find click on them you will be able to see the functions and fields
I'm attempting to model the entities for a resume and in doing so I came to the following issue: all except the most recently held positions have an end date.
Is there a good way to constrain at most one row allowed to be null. Event better would be that the single allowed null also had the latest start date.
Another way of saying this is can you specify a constraint that says "not null unless"?
Note: this is a learning exercise I'm doing (as opposed to working on production code).
Here's the scripted table I'm working with:
CREATE TABLE [dbo].[Employers](
[Id] [uniqueidentifier] NOT NULL,
[City] [nvarchar](max) NULL,
[State] [nvarchar](max) NULL,
[StartMonth] [int] NULL,
[StartYear] [int] NOT NULL,
[EndMonth] [int] NULL,
[EndYear] [int] NULL,
[Name] [nvarchar](max) NULL,
[Label] [nvarchar](max) NULL,
[Resume_Id] [uniqueidentifier] NULL,
[UserProfile_UserId] [int] NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[Employers] WITH CHECK ADD CONSTRAINT [Resume_Employers] FOREIGN KEY([Resume_Id])
REFERENCES [dbo].[Resumes] ([Id])
GO
ALTER TABLE [dbo].[Employers] CHECK CONSTRAINT [Resume_Employers]
GO
ALTER TABLE [dbo].[Employers] WITH CHECK ADD CONSTRAINT [UserProfile_Employers] FOREIGN KEY([UserProfile_UserId])
REFERENCES [dbo].[UserProfile] ([UserId])
GO
ALTER TABLE [dbo].[Employers] CHECK CONSTRAINT [UserProfile_Employers]
GO
You can set a date which is certain to be an invalid one, like 31.12.9999 instead of NULL and then check it on the app side. Otherwise you can set a boolean field to show if a person has quit the position described.
I don't think there is much sense in keeping a single NULL value. If you really need it, then create a procedure to check this and call it before each insert or update operation.
P.S. you didnt't consider the case when a person has no job at the time, so all positions will have an end date.
P.P.S. why do you keep month and year as two different int fields? just use a date.