Trigger sum of two columns into 3rd SQL - sql

I am trying to set a trigger in Microsoft Server Manager where a 3rd gets populated by a trigger
Eg. I have a table that contains
Column 1: Amount
Column 2: AdminFee
Column 3: TotalAmount
I need each new row in column3 (total amount) to be populated by Amount + AdminFee
I have the following script but it is not updating Column 3
CREATE TRIGGER UpdateActualAmount
ON Event
AFTER INSERT
AS
BEGIN
UPDATE BankTransaction
SET ActualAmount = Amount + AdminFee
END
GO
Can anyone let me know Where I am going wrong?

Run this one time:
ALTER TABLE BankTransaction DROP COLUMN ActualAmount;
ALTER TABLE BankTransaction ADD ActualAmount as (Amount+AdminFee)
Though tbh I'd be doing this in the front end as I don't really feel this kind of calculation has any business case for being part of the table..
If you're desperate to store the result of this sim as a table column and you want to index/query it, then make it a PERSISTED column..

Related

Create table with checksum of all tables in a database?

I'm trying to figure out how to determine if a table has been affected by a number of processes that run in sequence, and need to know what the state of the table is before and after each runs. What I've been trying to do is run some SQL before all the processes run that saves a before checksum of every table in the db to a table, then running it again when each ends and updating the table row with an after checksum. After all the processes are over, I compare the checksums and get all rows where before <> after.
Only problem is that I'm not the best guy for SQL, and am a little lost. Here's where I'm at right now:
select checksum_agg(binary_checksum(*)) from empcomp with (nolock)
create table Test_CheckSum_Record ( TableName varchar(max), CheckSum_Before int, CheckSum_After int)
SELECT name into #TempNames
FROM sys.Tables where is_ms_shipped = 0
And the pseudocode for what I want to do is something like
foreach(var name in #TempNames)
insert into Test_CheckSum_Record(name, ExecuteSQL N'select checksum_agg(binary_checksum(*)) from ' + name + ' with (nolock)', null)
But how does one do this?
Judging by the comments you need to create a trigger that handles all CRUD operations and just places a flag
Syntax is
Create TRIGGER [TriggerName] ON [TableName]
AFTER UPDATE, AFTER Delete, AFTER UPDATE
In the trigger you can do a
select CHECKSUM_AGG([Columns you want to compare against])
from [ParentTable] store that value in a variable and check it against the checksum table before column. If it does not exist you add a new entry with the DELETED tables checksum_AGG value as the before entry
Please note the choice not to use the inserted table is just preference for me on calculated columns
I will edit later when I have more time to add code

How do you update a datetime field in a table every time another field in the same table gets updated?

I have a table called YearTable with three columns (Year, Status, and LastUpdatedTime). Every time someone adds/updates a value into the year or status column LastUpdatedTime needs to be updated. I wrote a trigger for this, but now every time I try to add a new record I get an error message:
ErrorSource: .NetSqlClient Data Provider.
Error Message: Cannot insert the value NULL into Column 'Year', table 'Budget.YearTable'; column does not allow nulls. Insert fails.
This is the trigger:
CREATE TRIGGER UpdateTrigger
ON YearTable
AFTER INSERT,DELETE,UPDATE
AS
BEGIN
insert into tblaudit(LastUpdatedTime)
values(GETDATE())
END
GO
You stated:
I wrote a trigger for this, but now every time I try to add a new record I get an error message:
ErrorSource: .NetSqlClient Data Provider. Error Message: Cannot insert the value NULL into Column 'Year', table 'Budget.YearTable'; column does not allow nulls. Insert fails.
From this, does this mean your updates and deletes are working? If that is the case, then it sounds like just like the error message states. When you're doing an insert into the table, you aren't supplying a value for the year column on the YearTable.
Have you tried disabling the trigger and seeing if the behavior exists when doing the same operations?
After further consideration of your question, I'm now assuming you're meaning that when a row in YearTable is updated, that that same row in YearTable has its LastUpdated column updated. Though now I'm not really sure where your tblAudit is coming from. Or why you would have the trigger created for deletes when there would be no row to update at that point.
I'm going to assume that your key on the table is year - if you don't currently have a key, you probably need one.
To handle the LastUpdated for inserts/updates you could use the following in your trigger (assuming year is your key):
UPDATE YearTable
SET LastUpdated = GetDate()
FROM inserted
where YearTable.Year = inserted.year

Update a table and return both the old and new values

Im writing a VB app that is scrubbing some data inside a DB2 database. In a few tables i want to update entire columns. For example an account number column. I am changing all account numbers to start at 1, and increment as I go down the list. Id like to be able to return both the old account number, and the new one so I can generate some kind of report I can reference so I dont lose the original values. Im updating columns as so:
DECLARE #accntnum INT
SET #accntnum = 0
UPDATE accounts
SET #accntnum = accntnum = #accntnum + 1
GO
Is there a way for me to return both the original accntnum and the new one in one table?
DB2 has a really nifty feature where you can select data from a "data change statement". This was tested on DB2 for Linux/Unix/Windows, but I think that it should also work on at least DB2 for z/OS.
For your numbering, you might considering creating a sequence, as well. Then your update would be something like:
CREATE SEQUENCE acct_seq
START WITH 1
INCREMENT BY 1
NO MAXVALUE
NO CYCLE
CACHE 24
;
SELECT accntnum AS new_acct, old_acct
FROM FINAL TABLE (
UPDATE accounts INCLUDE(old_acct INT)
SET accntnum = NEXT VALUE FOR acct_seq, old_acct = accntnum
)
ORDER BY old_acct;
The INCLUDE part creates a new column in the resulting table with the name and the data type specified, and then you can set the value in the update statement as you would any other field.
A possible solution is to add an additional column (let's call it oldaccntnum) and assign old values to that column as you do your update.
Then drop it when you no longer need it.
Here's what I'd do:
-- create a new table to track the changes.
- with columns identifying a unique key, old-vale, new-value, timestamp
-- create a trigger on the accounts table
to write the old and new values to the new table.
But, not knowing all the conditions, it may not be worth the trouble.

Creating SQL trigger that only affects specific row

I have two tables created inventory and customer_sales. Individuals working in the warehouse can't have access to the customer_sales table.
So I added an additional field to inventory table called num_sales.
I want to create a trigger functions that whenever a new customer sale is added. It will correspond to the specific inventory_item that was sold's row and not the entire table.
This is what I have so far.
ALTER TABLE inventory
ADD num_sales INT
UPDATE movies SET num_sales = 0;
ALTER TABLE movies ALTER COLUMN num_rentals INT NOT NULL;
GO
CREATE TRIGGER tr_movies_num_rentals_add
ON customer_sales FOR INSERT
AS
BEGIN
UPDATE inventory
SET num_sales = num_sales + (SELECT sale_status_code FROM INSERTED)
WHERE 1 = (SELECT sale_status_code FROM INSERTED);
END;
Note:
sale_status_code values: 1=sold, 2=reserved, 3=lost.
UPDATE: I am using Microsoft SQL server management studio. I am newbie and this is a question I have for school.
First assume inserted willhave multiple rows. SQL server triggers do not operate row by row. YOu need to join to inserted not use a subquery. Next if you want this to happen on insert, update and delete, then you need to use more than an INSert trigger. And the delete trigger should use a different formula than inserted and updated becasue you will be subtracting the value from the deleted table from the inventory total.

Adding a new column in a temporary table

I have a temporary table in a PostgreSQL function and I want to insert a new VARCHAR column. It should have a value that depends on another column of the table, named "amount".
When the amount is positive I would like the value of the column row to be credit and when the value is negative the column should be debit.
I have one more request: I want to round the value of amount column in 2 decimal digits
You want ALTER TABLE ... ADD COLUMN followed by an UPDATE.
I initially said ALTER TABLE ... ADD COLUMN ... USING but that was wrong on two counts. ADD COLUMN takes a DEFAULT not USING - and You can't do it in one pass because neither a DEFAULT expression nor a USING expression may not refer to other columns.
So you must do:
ALTER TABLE tablename ADD COLUMN colname varchar;
UPDATE tablename SET colname = ( CASE WHEN othercol < 0 THEN 'Credit' ELSE 'Debit' END );
Think carefully about whether zero should be 'Debit' or 'Credit' and adjust the CASE accordingly.
For rounding, use round(amount,2). There isn't enough detail in your question for me to be sure how; probably by UPDATEing the temp table with UPDATE thetable SET amount = round(amount,2) but without the context it's hard to know if that's right. That statement irreversibly throws information away so it should only be used on a copy of the data.