I'm currently learning ASP.Net and I was wondering how you can restore an item that was deleted from an SQL Data source.
The item was deleted through a Details View using the "Enable Deleting" option, so I was testing each of the buttons and this happened.
I understand that I can simply recover the same untouched database file, and replace it with the current one I'm using.
However, I'd like to know if restoring the item is possible through other means, like creating a button which will restore the Database Item from deletion. Thanks!
As far as "standard SQL" is concerned, once you do an SQL DELETE on a row, it's gone for good.
If you need "undelete" functionality in your system, you could instead just add a "deleted" column to the database, and set that instead of deleting. That has the major downside that all your SQL needs to take that column into account, so that rows with the delete column set are not returned. Quite a lot of work, and does not sound like what you're looking for in this case.
In certain RDBMS' (SQL server comes to mind), there are ways to recover deleted rows from the transaction log, but that does not sound like what you're looking for either, and it's quite an advanced topic.
Related
I have a web portal set up where customers can add company contacts, etc to a sql database thru gridviews and detail views i created with microsoft Web Developer. I need to have it set up, where although customers that have rights can edit and delete contact records, they cannot delete the last one. There must be one left in the system. I know this sounds like a strange request, but it is a needed one. Is this something that can be done thru VB, SQL, or thru one of web developers objects such as the Details View?
Thank you!
Not a strange request, as I understand the need. The solution we employed is the actual default Admin account did not show up on the delete list, as it was "system generated". That may not be a retooling you can do.
What you can't do is use the automagic drag and drop crap and institute this type of functionality. You will have to either pair down the request to remove the last requested item, write a trigger on the database or write custom code to not delte the last item.
As an example of pairing down: with datasets, since they are disconnected, you can remove the last row prior to sending your delete request. With LINQ and EF, you have similar options to shaping the return data.
Then, if you desire to explicitly control your code (good), you can roll through the items and ensure the last one does not delete.
If you want to make this as "safe" as possible, you might consider a trigger on the table that checks if the delete is last administrator user for a particular organization and abort if so. Then the user might say "delete all" on the web, but the database protects them.
I'm watching an sqlite db which an app uses.
I want to know what changes have been made since
I last checked.
I can dump to sql and diff against the last dump,
but it seems there should be a better way.
Is there?
Thanks,
Kent
PS Not to be coy, specifics: I'm managing photos with Shotwell, which has a great GUI.
I'm mirroring Shotwell's db in Postgresql, where I've restructured and augmented to my liking. After a Shotwell session, which involves adding, tagging, adjusting ... I want
to apply those changes to Postgres.
Add a field named _changed to your table(s). On every manipulation (update, insert into...) of a row set the field to the current timestamp. Now you can check which rows have been updated since.
I have asked a few questions today as I try to think through to the solution of a problem.
We have a complex data structure where all of the various entities are tightly interconnected, with almost all entities heavily reliant/dependant upon entities of other types.
The project is a website (MVC3, .NET 4), and all of the logic is implemented using LINQ-to-SQL (2008) in the business layer.
What we need to do is have a user "lock" the system while they make their changes (there are other reasons for this which I won't go into here that are not database related). While this user is making their changes we want to be able to show them the original state of entities which they are updating, as well as a "preview" of the changes they have made. When finished, they need to be able to rollback/commit.
We have considered these options:
Holding open a transaction for the length of time a user takes to make multiple changes stinks, so that's out.
Holding a copy of all the data in memory (or cached to disk) is an option but there is heck of a lot of it, so seems unreasonable.
Maintaining a set of secondary tables, or attempting to use session state to store changes, but this is complex and difficult to maintain.
Using two databases, flipping between them by connection string, and using T-SQL to manage replication, putting them back in sync after commit/rollback. I.e. switching on/off, forcing snapshot, reversing direction etc.
We're a bit stumped for a solution that is relatively easy to maintain. Any suggestions?
Our solution to a similar problem is to use a locking table that holds locks per entity type in our system. When the client application wants to edit an entity, we do a "GetWithLock" which gets the client the most up-to-date version of the entity's data as well as obtaining a lock (a GUID that is stored in the lock table along with the entity type and the entity ID). This prevents other users from editing the same entity. When you commit your changes with an update, you release the lock by deleting the lock record from the lock table. Since stored procedures are the api we use for interacting with the database, this allows a very straight forward way to lock/unlock access to specific entities.
On the client side, we implement IEditableObject on the UI model classes. Our model classes hold a reference to the instance of the service entity that was retrieved on the service call. This allows the UI to do a Begin/End/Cancel Edit and do the commit or rollback as necessary. By holding the instance of the original service entity, we are able to see the original and current data, which would allow the user to get that "preview" you're looking for.
While our solution does not implement LINQ, I don't believe there's anything unique in our approach that would prevent you from using LINQ as well.
HTH
Consider this:
Long transactions makes system less scalable. If you do UPDATE command, update locks last until commit/rollback, preventing other transaction to proceed.
Second tables/database can be modified by concurent transactions, so you cannot rely on data in tables. Only way is to lock it => see no1.
Serializable transaction in some data engines uses versions of data in your tables. So after first cmd is executed, transaction can see exact data available in cmd execution time. This might help you to show changes made by user, but you have no guarantee to save them back into storage.
DataSets contains old/new version of data. But that is unfortunatelly out of your technology aim.
Use a set of secondary tables.
The problem is that your connection should see two versions of data while the other connections should see only one (or two, one of them being their own).
While it is possible theoretically and is implemented in Oracle using flashbacks, SQL Server does not support it natively, since it has no means to query previous versions of the records.
You can issue a query like this:
SELECT *
FROM mytable
AS OF TIMESTAMP
TO_TIMESTAMP('2010-01-17')
in Oracle but not in SQL Server.
This means that you need to implement this functionality yourself (placing the new versions of rows into your own tables).
Sounds like an ugly problem, and raises a whole lot of questions you won't be able to go into on SO. I got the following idea while reading your problem, and while it "smells" as bad as the others you list, it may help you work up an eventual solution.
First, have some kind of locking system, as described by #user580122, to flag/record the fact that one of these transactions is going on. (Be sure to include some kind of periodic automated check, to test for lost or abandoned transactions!)
Next, for every change you make to the database, log it somehow, either in the application or in a dedicated table somewhere. The idea is, given a copy of the database at state X, you could re-run the steps submitted by the user at any time.
Next up is figuring out how to use database snapshots. Read up on these in BOL; the general idea is you create a point-in-time snapshot of the database, do whatever you want with it, and eventually throw it away. (Only available in SQL 2005 and up, Enterprise edition only.)
So:
A user comes along and initiates one of these meta-transactions.
A flag is marked in the database showing what is going on. A new transaction cannot be started if one is already in process. (Again, check for lost transactions now and then!)
Every change made to the database is tracked and recorded in such a fashion that it could be repeated.
If the user decides to cancel the transaction, you just drop the snapshot, and nothing is changed.
If the user decides to keep the transaction, you drop the snapshot, and then immediately re-apply the logged changes to the "real" database. This should work, since your requirements imply that, while someone is working on one of these, no one else can touch the related parts of the database.
Yep, this sure smells, and it may not apply to well to your problem. Hopefully the ideas here help you work something out.
I've been quite impressed with dynamic data and how easy and quick it is to get a simple site up and running. I'm planning on using it for a simple internal HR admin site for registering people's skills/degrees/etc.
I've been watching the intro videos at www.asp.net/dynamicdata and one thing they never mention is how to handle concurrency control.
It seems that DD does not handle it right out of the box (unless there is some setting I haven't seen) as I manually generated a change conflict exception and the app failed without any user friendly message.
Anybody know if DD handles it out of the box? Or do you have to somehow build it into the site?
Concurrency is not handled out the of the box by DD.
One approach would be to implement this on the database side, by adding a "last updated" timestamp column (or other unique stamp, such as a GUID) to each table.
You then create an update trigger for each table. For each row being updated, is the "last updated" stamp passed in the same as the one on the row in the database?
If so, update the row, but give it a new "last updated" stamp.
If not, raise a specific "Data is out of date" exception.
On the client side, for each row you update, you'd need to refresh the "last updated" stamp.
In the client code you watch for the "Data is out of date" exception and display a helpful message to the user, asking them to refresh the data and re-submit their change.
Hope this helps.
All depends on the definition, what do you mean under "out of the box". Of cause you have to create a lot of code to handle concurrency, but some features help us to implement it.
My favorite model is "optimistic concurrency" based on rowversion datatype of SQL Server. It is like "last updated" timestamp, but you need not use any update trigger for each table. All updates of the corresponding "timestamp" column in your tables will be made automatically by SQL server at every update of data in the table row. I describes it in my old answer Concurrency handling of Sql transactrion. I hope it will be helpful for you.
I was of the impression the Dynamic data does the update on the underlying data source. Maybe you can specify the concurrency model (pessimistic/optimistic) on the data meta model that gets registered on the App_Init section. But you would probably get unable to save changes error, so by default would be pessimistic, last in loses....
Sorry to replay late. Yes DD is too strong when it come to fast development of project. Not only that it is base for .Net 4.0. DD is more enhance and have been included in .Net 4.0.
DD mostly work on Linq to sql. I will suggest you to have a look on that part.
In linq to SQl when you go to property of table you will find a property there which specify wheater to check the old value before updating new value. If you set that true I think your proble will get handle.
wish you best luck.
Let's learn from each other.
The solution given by Binary Worrier works and it's widely used on platforms providing a GUI to merge the changes (e.g. source control programs, wiki engines, etc). That way none of the users lose their changes. In the other hand, it requires much code or using external components or DLLs.
If you are not happy with that, another approach is just to lock the record that is being edited. Nobody else will be able to edit that record until the user commit the changes or his session expires. It has pros and cons but requires little code compared with the first option.
I am designing a standard ASP.Net site with a SQL database. I have a database schema and During the tests I am changing data types amongst other tasks and the data contained inside really is not that important.
I keep getting errors as the old data does not match the new rules. This is not important and I am happy to clear everything but currently, I have to export/publish the database to a .sql file then import it from scratch - which is time consuming.
Is there a quick button / feature that I have missed that allows you to reset autonumbers / IDs to 1 and delete all content, or just speed up what I currently do?
There are a few options you could take, the "fastest" really depends on your database.
To firstly answer your questions on seeding, etc - TRUNCATE TABLE will delete all information in a table (very fast, as it is not logged) and will reset your identity column.
eg:
TRUNCATE TABLE dbo.table
http://msdn.microsoft.com/en-us/library/aa260621(SQL.80).aspx
The significant restriction here is that you cannot use it on a table that is referenced by another table. In this case you can use a standard delete and then use DBCC CHECKIDENT
eg:
DELETE FROM dbo.table
GO
DBCC CHECKIDENT(dbo.table, reseed, 0)
http://msdn.microsoft.com/en-us/library/ms176057.aspx
Remember with delete to make sure you delete information in the correct order (i.e. taking into account foreign keys).
Another approach I often use is simply writing a complete tear-down / rebuild script when I want to reset the database. The basic premise is to tear down, or drop all database objects at the beginning of the script and then recreate them. This is not necessarily a solution for all scenarios, but for basic tasks works well for me. To avoid errors I would usually add my drop statements in IF statements, eg:
IF EXISTS
(
SELECT *
FROM information_schema.tables
WHERE table_name = 'table' AND table_schema = 'dbo'
)
BEGIN
DROP TABLE dbo.table
END
Why don't you write some T-SQL code to delete (or truncate, even quicker) all your tables? Be careful to take into consideration your integrity rules while clearing the tables: allways clean the tables containing the foreign key before cleaning the one containing the primary key.
If you just need to clear out data then just write a script to truncate all the data in each table. The truncate command also resets any IDENTITY fields as well.
TRUNCATE TABLE myTable
For each table you have. Then just run that script each time.
Here'a a quick way to delete all of the data in a table:
TRUNCATE TABLE YourTableName
You could write a script that would truncate all of your tables.
The alternative is to just DROP the table and re-create it.
If you really want to drop all data, then you could detach the database and create a brand new one; it's a bit extreme, but possibly faster than dropping everything first.
As others have suggested I find it preferable to maintain a script that builds the database from scratch and can tear down the database prior to rebuilding it. Develop this script just as you'd develop the rest of the application. I find it easier to understand the database through a script than by building it through a GUI, especially where there are complex relationships, triggers and so on.
It's also useful if you have other developers, and perhaps quicker and less prone to errors than copying your working database and handing it to another developer.
On release you can freeze that script and then create delta scripts for the next release which has just the changes from the initial schema to the new. This could also tear down the new objects created in the delta before recreating them so it can be easily re-run without having to wipe the entire database.
if you use Visual Studio 2010 then
open the App_Data folder of the solution and double click on the MDF File.
right click on your table , in the menu select "Show Table Data".
select all rows and delete all them.