Add Items in Sales Transaction table as single transaction - database

I've tables Items table as (Stock) and Sales Transaction so when I want to sale items from Items table Sales Transaction will generate id(auto increment) and will have all items added by user to sale.
But here is problem, how single transaction id can have multiple items in a row or how
Sales Transaction can generate same id for each row?
So even if I'll insert items to Sales Transaction for each item will have different id and so I'll not able to search reports correctly.
That will affect functionality.
I'm thinking to add all items in a single row like this:
So is there any other way to solve my problem?

To add a column, you need to alter the current table:
ALTER TABLE "Sales Transaction"
ADD COLUMN TransactionNumber INT NOT NULL
When you are inserting into this table you will need something like this:
DECLARE #TransNumber INT = (SELECT CASE WHEN MAX(TransactionNumber) IS NULL THEN 1 ELSE MAX(TransactionNumber) + 1 END FROM "Sales Transaction")
INSERT INTO "Sales Transaction" ("Item Name", Qty., Price, "Cust. Name", Tax, Discount, Total, TransactionNumber)
VALUES
('Pen',1,10,'John Smith',0,0,10,#TransNumber),
('Pencil',2,7,'John Smith',0,0,14.00,#TransNumber)
Since the TransactionNumber will be the same for both rows, you can search by that.

Related

Add values to a table from a second table that only match a third table allowing for duplicates

I have been tasked to match a payment file from a bank that has invoices/payments listed on a text file I have imported into a table called Bank. I need to match the invoices to the project/projects that are associated with the invoices - call this table Invoices - which contains every invoice and project we have every had. I want to match the invoices (from Bank) to the project or multiple projects (from Invoices) to another table - called Report - so I can reconcile the payment file. I can get the correct results from Bank and Invoices with the following query
SELECT invoice
FROM Invoices INV
INNER JOIN Bank as BANK
ON INV.Invoice = BANK.Invoice_Number
The Bank file has 100 invoices and I get 169 invoices on this query. But when I try and do and update or insert
Update Report
set Invoice_Num =
(SELECT invoice
FROM Invoices INV
INNER JOIN Bank as BANK
ON INV.Invoice = BANK.Invoice_Number)
I get 0 rows updated.
I have tried to copy the Bank table to the Report table with
Insert into Report(Invoice_Num)
select Invoice_Number from Bank
but can't figure out how to account for the projects that have duplicated invoices when they are found. Of course I might be going at this entirely wrong and someone has a better way entirely.
Thanks!
Does your Report table have anything in to start with? If not, your UPDATE statement will update 0 rows, because there are 0 rows there to update. (Also, with your code as it stands, note that it would update every entry there to have the same, indeterminate value; I don't think that's what you intend.)
If you just want to copy the invoice numbers from Bank to Report, but leave out any duplicates, then your final bit of SQL just needs a DISTINCT added to do that:
Insert into Report(Invoice_Num)
select DISTINCT Invoice_Number from Bank
If you're trying to put in only invoice numbers from Bank that also match Invoice, then your first bit of code almost works, but needs to be an INSERT, not an UPDATE:
INSERT INTO report (invoice_number)
SELECT invoice
FROM Invoices INV
INNER JOIN Bank as BANK
ON INV.Invoice = BANK.Invoice_Number
Again, if you're also dealing with potential duplicates invoice numbers you only want in Report once, make that a SELECT DISTINCT to avoid them.

Iterating over DB2 table by blocks with no row identifier

We must create a process in Spring Framework that reads a DB2 table by blocks.
However, that table does not have a column with an unique identifier that we can use as a cursor, so in second block we don't from which point we must read.
The table has those columns:
BOOK_ID SOLD_AT QUANTITY
The first one is a foreign key to book model, the second one is a date when a book was sold, and the third one the quantity of books sold.
Is it possible to do SELECT ordering by db2's rowId? Unfortunately, this is legacy code so we cannot create an extra column to the db2.
Thanks in advance.
Try this:
select hex(rowid) rowid, t.name, t.creator
from (
select t.*, rid_bit(t) rowid
from sysibm.systables t
) t
order by rowid
fetch first 10 row only;
rid_bit(table-designator) value for the row may change upon physical row movement (reorg, for example, old row is deleted, new row is inserted into the same physical place, etc.)

Logging deletion of rows in table sql server

I have been searching for a way to log the deletion of rows from a table.
Tried this Log record changes in SQL server in an audit table but it didn't help me.
I have a song list database, the log table has the columns: Title / Artist / Year / Position / SentinDate .
There is a list with songs from the years 1999 to 2014, and every year has 2000 songs (top2000 is what it is called in The Netherlands).
Basically what the log table should look like once a certain Year has been deleted:
I need a basic way trigger-log when someone deletes a certain year from the list of 1999-2014.
I hope to have informed enough for you to understand, if not I will try to explain in more detail.
A trigger rejects or accepts each data modification transaction as a whole.
Using a correlated subquery in a trigger can force the trigger to examine the modified rows one by one.
Examples
A. Use an AFTER INSERT trigger
The following example assumes the existence of a table called newsale in the pubs database. This the CREATE statement for newsale:
CREATE TABLE newsale
(stor_id char(4),
ord_num varchar(20),
date datetime,
qty smallint,
payterms varchar(12),
title_id tid)
If you want to examine each of the records you are trying to insert, the trigger conditionalinsert analyzes the insert row by row, and then deletes the rows that do not have a title_id in titles.
CREATE TRIGGER conditionalinsert
ON sales
AFTER INSERT AS
IF
(SELECT COUNT(*) FROM titles, inserted
WHERE titles.title_id = inserted.title_id) <> ##ROWCOUNT
BEGIN
DELETE sales FROM sales, inserted
WHERE sales.title_id = inserted.title_id AND
inserted.title_id NOT IN
(SELECT title_id
FROM titles)
PRINT 'Only sales records with matching title_ids added.'
END
When unacceptable titles have been inserted, the transaction is not rolled back; instead, the trigger deletes the unwanted rows. This ability to delete rows that have been inserted relies on the order in which processing occurs when triggers are fired. First, rows are inserted into the sales table and the inserted table, and then the trigger fires.
Simply create an INSTEAD OF DELETE trigger ! In that trigger, you have a "virtual" table called deletedwhich contains all records which are to be deleted.
So in the trigger, you can just insert all records contained in deleted to your log table, and then you delete the records from our table. (this will then be a DELETE statement with a join to the deleted table)

Insert a row in another table for each row in another table that meets a criteria

I need to insert a new row into one table CUSTOMER_NOTESfor each row in another table CUSTOMER that meets a condition.
If CUSTOMER table column CURRENT is marked as 1, then I need to shove a note into the CUSTOMER_NOTES table, like "THIS IS A CURRENT CUSTOMER". So, if there are 50 current customers (and 240 total customers), there would be 50 entries shoved into the CUSTOMER_NOTES table with the VALUE being "THIS IS A CURRENT CUSTOMER".
Assuming your CUSTOMER and CUSTOMER_NOTES has a column CUSTOMER_ID:
INSERT INTO CUSTOMER_NOTES(
CUSTOMER_ID,
NOTES
)
SELECT
CUSTOMER_ID,
'THIS IS A CURRENT CUSTOMER'
FROM CUSTOMER
WHERE
[CURRENT] = 1

One more question regarding triggers PL/SQL

I have run into a problem with a second trigger we are to write regarding the following:
I have just written a stored procedure and stored function that serve to insert a new row into my Orders table. The row update inserts: Ordernum, OrderDate, Customer, Rep, Manufacturer, Product, Qty, and SaleAmount.
I now have to write a trigger that updates my Offices table by adding the amount of the newly added sale. Problem is, not every salesrep has an office assigned to them. I don't understand if I need to have a when clause under 'FOR EACH ROW' which somehow stipulates this, or if I need to stipulate after my SET Sales line. This is my code so far, but unfortunately, it updates all of the offices sales, not just the one that the salesrep belongs to:
CREATE OR REPLACE TRIGGER UpdateOffices
AFTER INSERT ON Orders
FOR EACH ROW
BEGIN
UPDATE Offices
SET Sales = Sales + :NEW.Amount
WHERE Office IN (SELECT RepOffice
FROM Salesreps
WHERE RepOffice IS NOT NULL);
End;
/
SHOW ERRORS
Sales is the name of the column on the Offices table. Amount if the name used in the stored proc.
You've already been advised to add a predicate on Salesreps, e.g. WHERE Salesrep = :NEW.Rep. Why don't you add it to the subquery?
You are going to run into all sorts of problems implementing your solution using this trigger method.
The Office.Sales column value will become stale as soon as amendments to orders are committed to the database. For example, when the price or quantity on an order is changed or deleted.
I would recommend you implement this requirement as a 'Refresh on Commit' Materialized View.

Resources