I am editing a record using a dbedit component, I have a cancel button but I'm not sure on how I can make it so all of the changes made using the dbedit components are reverted.
I was thinking about copying the record either to a temp table or duplicate the record within the same table which would let me remove the old record if the changes are saved or delete the copied record (leaving the original) if the input is cancelled.
I'm just wanting to know the best way to handle this without creating useless tables, creating too many procedures.
If I'm not mistaken changes to a paradox table only get written to the database after a post command.
If you want to cancel the change, just do
TForm1.CancelButtonPresss(Sender: TObject);
begin
ParadoxTable.Cancel;
end;
TForm1.OKButtonPress(Sender: TObject);
begin
ParadoxTable.Post;
end;
BTW, its been a long long time since I've worked with paradox tables, so my recollection my be incorrect, please feel free to vote down this answer if I'm mistaken.
I'm typing this on the mac, so I cannot check it now.
Will see if I can supply you with a more informed answer later.
To Compliment Johan's answer (use TDataSet.Cancel), if you use a TCustomClientDataSet, you also can use the RevertRecord method to remove the modifications to the current record, provided they are still in the change log.
You can also set a snapshot with SavePoint and revert to that state, cancelling all modifications done in the meantime.
Johan's answer is good for single record. If you are working with a SQL database (Oracle, MSSql, MySql, Firebird, etc) there is an additional approach that can be used for multiple records: transactions. Using ADO as an example
TForm1 = class(TForm)
ADOConnection: TADOConnection;
…
// start the transaction
ADOConnection.BeginTrans;
…
// create records and post them
…
// rollback removes the records posted
// since the transaction was started
ADOConnection.RollbackTrans;
… or …
// commit completes saving the records posted
// since the transaction was started
ADOConnection.CommitTrans;
If you do not explicitly start a transaction, one is automatically started and committed as records are posted to the database.
François's answer is similar to transactions, but only works with ClientDatasets.
Related
I have a weird problem where data in a postgresql table gets cleared completely daily. I don't see any scripts or anything that runs the delete query. Is there a way i can find which script/process deletes the data from the particular table?
You can see more about log_statement parameter. Set it to all so, all queries executed will be saved and you can do an analysis in what is happening with your database.
If you're on linux environment, the logs (normally) will be in /var/log/postgresql/local0.* files. And you can see what's happening.
Also, you can do more improvements on logs (like choose log only delete statements), as described on official documentation below.
More info at: https://www.postgresql.org/docs/9.5/runtime-config-logging.html
You will need to restart you postgres to the changes take effect.
Finally found a way to log the delete query even without restarting the server
Write a trigger function as below
CREATE OR REPLACE FUNCTION log_delete() RETURNS trigger AS $BODY$
BEGIN
RAISE LOG 'Deleting row % (statement is %)', OLD, current_query();
RETURN NULL;
END;
$BODY$ LANGUAGE plpgsql VOLATILE COST 100;
Call the trigger function by
CREATE TRIGGER ondelete
AFTER DELETE
ON public.tablename
FOR EACH ROW
EXECUTE PROCEDURE public.log_delete();
And that's it. your log will have the delete query that fired!
Ref : Postgresql - Determining what records are removed from a cascading delete
I am updating a column in a SQL table and I want to check if it was updated successfully or it was updated already and my query didn't do anything
as we get ##rowcount in SQL Server.
In my case, I want to update a column named lockForProcessing, so if it is already processing, then my query would not affect any row, it means someone else is already processing it, else I would process it.
If I understand you correctly, your problem is related to a multi threading / concurrency problem, where the same table may be updated simultaneously.
You may want to have a look at the :
Chapter 11. Transactions And Concurrency
The ISession is not threadsafe!
The entity is not stored the moment the code session.SaveOrUpdate() is executed, but typically after transaction.Commit().
stored and commited are two different things.
The entity is stored after any session.Flush(). Depending on the IsolationLevel, the entity won't be seen by other transactions.
The entity is commited after a transaction.Commit(). A commit also flushes.
Maybe all you need to do is choose the right IsolationLevel when beginning transactions and then read the table row to get the current value:
using (var transaction = session.BeginTransaction(IsolationLevel.Serializable))
{
session.Get(); // Read your row
transaction.Commit();
}
Maybe it is easier to create some locking or pipeline mechanism in your application code though. Without knowing more about who is accessing the database (other transactions, sessions, processes?) it is hard to answer more precisely.
I want to migrate my database from v1.0 to v1.1 and one of the changes is updates on some of the values in Table1. I know that for INSERT, I can easily include a rollback command of deleting the values I just added, but how about a table alteration? Is there a way to store the current value and use this information for the rollback process (in the future)?
Thanks.
You can specify a <rollback> block (docs) in your changeset to describe how to roll back the change. Within your rollback tag you can use raw SQL or a <createTable> tag to re-describe what the table looked like before it was altered.
You can also specify the changeSetId and changeSetAuthor in the rollback tag to point to an existing changeSet that will recreate the table. This approach can be easier if there has been no other changes since the object was created but doesn't work as well if there has been multiple changeSets that modified the object since it was first created.
Any DDL operation (ALTER TABLE being one of them) in SQL Server is transactional.
It means that you can open a transaction, do alterations to the database objects, and rollback the transaction as if it never happened.
There are some exceptions, mainly actions involving filesystem operations (adding a file to database and such).
I'm new to triggers and I need to fire a trigger when selecting values from a database table in sql server. I have tried firing triggers on insert/update and delete. is there any way to fire trigger when selecting values?
There are only two ways I know that you can do this and neither are trigger.
You can use a stored procedure to run the query and log the query to a table and other information you'd like to know.
You can use the audit feature of SQL Server.
I've never used the latter, so I can't speak of the ease of use.
No there is no provision of having trigger on SELECT operation. As suggested in earlier answer, write a stored procedure which takes parameters that are fetched from SEECT query and call this procedure after desired SELECT query.
SpectralGhost's answer assumes you are trying to do something like a security audit of who or what has looked at which data.
But it strikes me if you are new enough to sql not to know that a SELECT trigger is conceptually daft, you may be trying to do something else, in which case you're really talking about locking rather than auditing - i.e. once one process has read a particular record you want to prevent other processes accessing it (or possibly some other related records in a different table) until the transaction is either committed or rolled back. In that case, triggers are definitely not your solution (they rarely are). See BOL on transaction control and locking
Let's assume we have a bunch of LINQ2SQL InsertOnSubmit statements against a given DataContext. If the SubmitChanges call is successful, is there any way to automatically generate a list of SQL commands (or even LINQ2SQL statements) that could undo everything that was submitted at a later time? It's like executing a rollback even though everything worked as expected.
Note: The destination database will either be Oracle or SQL Server, so if there is specific functionality for both databases that will achieve this, I'm happy to use that as well.
Clarification:
I do not want the "rollback" to happen automatically as soon as the inserts have succesfully completed. I want to have the ability to "undo" the INSERT statements via DELETE (or some other means) up to 24 hours (for example) after the original program finished inserting data. We can ignore any possible referential integrity issues that may come up.
Assume a Table A with two columns: Id (autogenerated unique id) and Value (string)
If the LINQ2SQL code performs two inserts
INSERT INTO Table A VALUES('a') // Creates new row with Id = 1
INSERT INTO Table A VALUES('z') // Creates new row with Id = 2
<< time passes>>
At some point later I would want to be able "undo" this by executing
DELETE FROM A Where Id = 1
DELETE FROM A Where Id = 2
or something similar. I want to be able to generate the DELETE statements to match the INSERT ones. Or use some functionality that would let me capture a transaction and perform a rollback later.
We cannot just 'reset the database' to a certain point in time either as other changes not initiated by our program could have taken place since.
It is actually quite easy to do this, because you can pass in a SqlConnection into the LINQ to SQL DataContext on construction. Just run this connection in a transaction and roll that transaction back as soon as you're done.
Here's an example:
string output;
using (var connection = new SqlConnection("your conn.string"))
{
connection.Open();
using (var transaction = connection.StartTransaction())
{
using (var context = new YourDataContext(connection))
{
// This next line is needed in .NET 3.5.
context.Transaction = transaction;
var writer = new StringWriter();
context.Log = writer;
// *** Do your stuff here ***
context.SubmitChanges();
output = writer.ToString();
}
transaction.Rollback();
}
}
I am always required to provide a RollBack script to our QA team for testing before any change script can be executed in PROD.
Example: Files are sent externally with a bunch of mappings between us, the recipient and other third parties. One of these third parties wants to change, on an agreed date, the mappings between the three of us.
Exec script would maybe update some exisiting, delete some now redundant and insert some new records - scope_identity used in subsequent relational setup etc etc.
If, for some reason, after we have all executed our changes and the file transport is fired up, just like in UAT, we see some errors not encountered in UAT, we might multilaterally make the decision to roll back the changes. Hence the roll back script.
SQL has this info when you BEGIN TRAN until you COMMIT TRAN or ROLLBACK TRAN. I guess your question is the same as mine - can you output that info as a script.
Why do you need this?
Maybe you should explore the flashback possibilities of Oracle. It makes it possible to travel back in time.
It makes it possible to reset the content of a table or a database to how it once was at a specific moment in time (or at a specific system change number).
See: http://www.oracle.com/technology/deploy/availability/htdocs/Flashback_Overview.htm