Delete data records - keep joined data - asp.net

I was not able to find a better title for this.
Branches Users Attendance
----------- ----------- -----------
branchID^ userID^ courseID^
branchName userName userID*
branchID*
Here's my table. Due to company re-structure I need to delete old branches and the users that belong in them. But when my boss wants to see old Attendances he wants to see old userNames even if they don't exist.
What's the best practice here? I'm thinking to add a Disabled column in Branches/Users so they aren't visible on the web page.

A "soft delete" flag is often used to address the requirement to retain both current and logically deleted data. Alternatively, you could move the rows to archive tables for historical reporting.
Having both current and logically deleted rows in the same table is more convenient if you need combined reporting on both. The downside is the presence of the inactive rows can add more overhead for queries of active data only. Much depends on the percentage of inactive rows and the number of rows.

I use this kind of solution:
Making a Log table:
[Log]
ID (bigint IDENTITY(1,1)) PK
Entity_Id (bigint) FK --'Entity' table is list of my tables
Row_Id (bigint) --Is Id of the row of the `Entity`
Kind (int) --0=Create, 1=Modify, 2=Delete, 3=Undelete
actionDate (datetime) --'= GETDATE()'
user_Id (bigint) FK --'User' table is list of users
Now this query gives me the state of the row:
SELECT TOP(1)
Kind,
actionDate,
user_Id
FROM
[Log]
WHERE
Entity_Id = #Entity_Id AND
Row_Id = #Row_Id
ORDER BY
actionDate DESC
As result is:
0 => Created by `user` in `actionDate`
1 => [Last] Modified by `user` in `actionDate`
2 => [Last] Deleted by `user` in `actionDate`
3 => [Last] Undeleted by `user` in `actionDate`
Note :
If you don't want to clear whole database, don't delete any row.
And when you want to delete do it in a mechanism based on relations.

Related

How to UPDATE a table by using __rowid__ of another table in sqlite3

I am doing CRUD operations using __rowid__ which comes default with the sqlite table. I don't have separate columns for ID's in any of my tables.
My create, read and delete operations are done.
I am searching the database by customer's name.
TABLES
UPDATE query for the customers table
cursor.execute("""
SELECT * FROM customers
WHERE name = ?""", (name_variable.get(),))
cursor.execute("""
UPDATE customers SET
'contact' = ?,
'mail' = ?,
'address' = ?
WHERE name = ?
""",
(
contact_variable.get(),
mail_variable.get(),
address_variable.get(),
name_variable.get()
)
)
My issue is with updating the services & charges table.
What I want is if user changes John's information then how do I UPDATE only John's data to these two tables using __rowid__. I don't understand how to execute that query.
(I am using sqlite3 version 3.31.1 on Ubuntu 20.04).
According to the schema you have shown there is no relationship between Customers, Services and Charges so updating a Customer has no bearing on the other tables. As such you probably want a relationship and the implication of you saying
then how do I UPDATE only John's data to these two tables using rowid
The answer to that is the rowid column, as there are not relationships, does not do anything other than uniquely identify a row in the respective tables.
So first you need to define the relationships which will require either
a column in each of the two tables (services and charges) to cater for a parent (customer) with children (services will be children of a customer and charges will be children of a customer) aka two one (customer) to many (services and charges) relationship, or
a mapping reference table if you need a many-many relationship.
Typically the most efficient way of mapping/reference/relating/linking/associating children to parents is to utilises the always present (but normally hidden) rowid by aliasing it to column name (e.g. id INTEGER PRIMARY KEY).
As such you probably want you table definitions to be something like:-
CREATE TABLE IF NOT EXISTS customers (
customer_id INTEGER PRIMARY KEY,
name TEXT,
contact TEXT,
mail TEXT,
address TEXT
);
the customer_id is an alias of the rowid column
then :-
CREATE TABLE IF NOT EXISTS services (
serviceid INTEGER PRIMARY KEY,
service TEXT, subservice TEXT,
customer_id INTEGER REFERENCES customers(customer_id) ON DELETE CASCADE ON UPDATE CASCADE
);
the service_id column is an alias of the rowid column
the customer_id column references the parent, i.e. the customer to whom the services belongs to.
the REFERENCES keyword along with the table and the associated column defines a constraint that says the customer_id column MUST be a value that exists in the customer_id column of the customers table (i.e. a Foreign Key constraint (rule)).
then :-
- The ON DELETE CASCADE says that if a parent is deleted then all the children of the parent are to be deleted down from the parent.
- The ON UPDATE is similar but cascades any change to the customer_id column in the customers table.
CREATE TABLE IF NOT EXISTS charges (
initialcharges REAL,
taxes REAL,
discount REAL,
advance REAL,
total REAL,
customer_id INTEGER REFERENCES customers(customer_id) ON DELETE CASCADE ON UPDATE CASCADE
);
Similar to services
Now say you then insert some (2) customers (noting that for the demo specific customer_id vales are specified rather than allowing them to be auto generated) using :-
INSERT OR IGNORE INTO customers VALUES
(10,'John','something','something','something')
,(20,'Jane','something','something','something')
;
and then use :-
SELECT *,rowid FROM customers;
Then :-
note that rowid is displayed as customer_id(1) as it now has customer_id as it's alias and that it exactly matches the value of the customer_id column.
Now we add some rows the the services table using:-
INSERT INTO services (service,subservice,customer_id) VALUES
('Exterior','something',10)
,('Interior','something',10)
,('Interior','something',20)
;
Note how the customer_id is a value from the customer_id column of the customers table and hence how you relate each services row to ONE customer.
using: -
SELECT *,rowid FROM services;
results in :-
again the rowid matches it's alias BUT both columns are both just a unique identifier of the row in the services table it has no meaning to the relationship between a service row and it's parent customer (hence why the rowid is of no use for what you want).
the important row, relationship wise, is the customer_id row which specifies the parent.
Similarly for the charges table :-
INSERT INTO charges (initialcharges,taxes,discount,advance,total,customer_id) VALUES
(10.50,0.50,1.5,0,11.50,10),
(105.00,05.00,1.5,0,115,20)
;
SELECT *,rowid FROM charges;
Now say you used-
SELECT customers.*,customers.rowid AS custid,' - ' AS ' ', services.*,services.rowid AS sid,' - ' AS ' ',charges.*,charges.rowid AS cid
FROM customers
JOIN services ON services.customer_id = customers.customer_id
JOIN charges ON charges.customer_id = customers.customer_id
;
then you get :-
If the name of John were changed to Fred using :-
UPDATE customers SET name = 'Fred' WHERE name = 'John';
Then as the John (now Fred) is accessed from the specific row it's change will be seen without any special processing in future queries e.g.
SELECT customers.*,customers.rowid AS custid,' - ' AS ' ', services.*,services.rowid AS sid,' - ' AS ' ',charges.*,charges.rowid AS cid
FROM customers
JOIN services ON services.customer_id = customers.customer_id
JOIN charges ON charges.customer_id = customers.customer_id
;
now results in :-
However, say the id for Jane were changed to 10000 using:-
UPDATE customers SET customer_id = 10000 WHERE customer_id = 20;
Then using the same query results in:-
i.e the ne value (10000) has automatically been applied to the children (not that you would likely change the customer_id often).
NOTE if you updated a child's column (if it did not violate the FK constraint) then that change IS NOT propagated to the parent. The parent would be switched.
Deletion works in a similar way, Delete the parent and the children will be deleted. Delete an child and just that child is child.
So with something like above, all you need to do is update whatever you need to update.
NOTE the above may or may not reflect actually what you want, it is rather a demonstration of the principle.

SQLite, Automatically update field in table after insert in another table

I'm a newbie in databases, so I apologize in advance if this question is about something easy and obvious but I'm not able to figure alone.
Basically, I'm trying to do what follows (for educational purpose, nothing related to anything "serious"):
I have a table courses where each course has
an id
a name
the total number of people enrolled.
Then I have a table of people, each of them has
an id
a name
a course_id
(assuming each person can only enroll in one
course). The course_id is a foreign key related to the id of the course.
What I'd like to know is how to automatically update the number of people enrolled in a course whenever I insert a row in people (increment the number of people enrolled in the specific course the added person is enrolled to).
I read I can do that using triggers but I didn't actually understood how. Anyway I'm querying the db from javascript so basically I'd like to only pass the INSERT query.
You need an AFTER INSERT trigger:
CREATE TRIGGER trg_people_ins AFTER INSERT ON people
BEGIN
UPDATE courses
SET total = COALESCE(total, 0) + 1
WHERE id = NEW.course_id;
END;
Change total to the actual name of the column in courses.
If the default vale of total is 0 then you don't need COALESCE(), so change to:
SET total = total + 1

Keep record even after deleting from application

I have two tables, category (pk) and foreign key table Item(fk).
In item table have itemid, item name,category I'd....and this category I'd is foreign key column with primary table...which is having category I'd, Category name.
And I have relationship between category table as parent and. Item table as child table....category I'd is the relationship between them. When I delete records based on itemid the records should be deleted from the application but maintained at backed level..as I do not want duplicate item...even I have deleted from application.
At Application level I am doing these things with textboxes for and drop down list which should category names.
If I have got you correctly, what you want to do is, maintain the data in the database table even if you delete it from the application interface.
If that is the case, you simply can add a column like 'isDeleted' in both of the tables in the database. In the delete event, just fire the update statement instead of actually deleting the record and set the 'isDeleted' field value to 'True'. At the time of displaying data from the tables, just select the records having 'isDeleted' value equals to 'False'.

How to design DynamoDB table to facilitate searching by time ranges, and deleting by unique ID

I'm new to DynamoDB - I already have an application where the data gets inserted, but I'm getting stuck on extracting the data.
Requirement:
There must be a unique table per customer
Insert documents into the table (each doc has a unique ID and a timestamp)
Get X number of documents based on timestamp (ordered ascending)
Delete individual documents based on unique ID
So far I have created a table with composite key (S:id, N:timestamp). However when I come to query it, I realise that since my id is unique, because I can't do a wildcard search on ID I won't be able to extract a range of items...
So, how should I design my table to satisfy this scenario?
Edit: Here's what I'm thinking:
Primary index will be composite: (s:customer_id, n:timestamp) where customer ID will be the same within a table. This will enable me to extact data based on time range.
Secondary index will be hash (s: unique_doc_id) whereby I will be able to delete items using this index.
Does this sound like the correct solution? Thank you in advance.
You can satisfy the requirements like this:
Your primary key will be h:customer_id and r:unique_id. This makes sure all the elements in the table have different keys.
You will also have an attribute for timestamp and will have a Local Secondary Index on it.
You will use the LSI to do requirement 3 and batchWrite API call to do batch delete for requirement 4.
This solution doesn't require (1) - all the customers can stay in the same table (Heads up - There is a limit-before-contact-us of 256 tables per account)

Update 2 tables using Stored Procedure in MySql

This seems like a simple request. But my query in not working and I'm finding conflicting answers on the internet. Is it possible to have UPDATE and INSERT using a Stored Procedure joining 2 tables in MySql?
I have an Asp.net Webforms website. It has 2 tables Individual and Address. Individual table contains data on an individual, i.e. Phone Number, Fax, Email ect.
The address table has all the address information for an individual. They each table has a column of Individual ID which auto increments. (Note: the individualID in Address table is not a primary key, but individualID in the individual table is a primary key.
Anyway, I have a FormView in Asp.net that with a SELECT statement that joins those 2 tables and display the data fine. But updating new information to both tables keeps failing.
My most recent error is : Duplicate entry '0' for key 'PRIMARY'
Is there a way to write an UPDATE statement that joins 2 Tables?? This has to exist right?
It is possible to update multiple tables with a single query -
UPDATE table1
INNER JOIN table2
ON table1.id = table2.table1_id
SET table1.col1 = 'some value', table2.col1 = 'Another value'
WHERE <some where clause>;

Resources