I'm looking to dial back evolutions that I've previously written !Downs procedures for, how can I trigger that from the command line?
Related
I have some SQL statements in a batch that I want to profile for performance. To that end, I have created a stored procedure that logs execution times.
However, I also want to be able to roll back the changes the main batch performs, while still retaining the performance logs.
The alternative is to run the batch, copy the performance data to another database, restore the database from backup, re-apply all the changes made that I want to profile, plus any more, and start again. That is rather more time-consuming than not including the act of logging in the transaction.
Let us say we have this situation:
BEGIN TRANSACTION
SET #StartTime = SYSDATETIME
-- Do stuff here
UPDATE ABC SET x = fn_LongRunningFunction(x)
EXECUTE usp_Log 'Do stuff', #StartTime
SET #StartTime = SYSDATETIME
-- Do more stuff here
EXEC usp_LongRunningSproc()
EXECUTE usp_Log 'Do more stuff', #StartTime
ROLLBACK
How can I persist the results that usp_Log saves to a table without rolling them back along with the changes that take place elsewhere in the transaction?
It seems to me that ideally usp_Log would somehow not enlist itself into the transaction that may be rolled back.
I'm looking for a solution that can be implemented in the most reliable way, with the least coding or work possible, and with the least impact on the performance of the script being profiled.
EDIT
The script that is being profiled is extremely time-consuming - taking from an hour to several days - and I need to be able to see intermediate profiling results before the transaction completes or is rolled back. I cannot afford to wait for the end of the batch before being able to view the logs.
You can use a table variable for this. Table variables, like normal variables, are not affected by ROLLBACK. You would need to insert your performance log data into a table variable, then insert it into a normal table at the end of the procedure, after all COMMIT and ROLLBACK statements.
It might sound a bit overkill (given the purpose), but you can create a CLR stored procedure which will take over the progress logging, and open a separate connection inside it for writing log data.
Normally, it is recommended to use context connection within CLR objects whenever possible, as it simplifies many things. In your particular case however, you wish to disentangle from the context (especially from the current transaction), so regular connection is a way to go.
Caveat emptor: if you never dabbled with CLR programming within SQL Server before, you may find the learning curve a bit too steep. That, and the amount of server reconfiguration (both the SQL Server instance and the underlying OS) required to make it work might also seem to be prohibitively expensive, and not worth the hassle. Still, I would consider it a viable approach.
So, as Roger mentions above, SQLCLR is one option. However, since SQLCLR is not permitted, you are out of luck.
In SQL Server 2017 there is another option and that is to use the SQL Server extensibility framework and the support for Python.
You can use this to have Python code which calls back into your SQL Server instance and executes the usp_log procedure.
Another, rather obscure, option is to bind other sessions to the long-running transaction for monitoring.
At the beginning of the transaction call sp_getbindtoken and display the bind token.
Then in another session call sp_bindsession, and you can examine the intermediate state of the transaction.
Or you can read the logs with (NOLOCK).
Or you can use RAISERROR WITH LOG to send debug messages to the client and mirror them to the SQL Log.
Or you can use custom user-configurable trace events, and monitor them in SQL Trace or XEvents.
Or you can use a Loopback linked server configured to not propagate the transaction.
I would like to run a database procedure after a successful EIM job run to collect information and record historical changes.
How can I call this database procedure automatically without manual intervention.
BR
Hani
Depends on the solution approach you take. If all has to be handeled within Sieber, the a workflow that creates the job, monitors it result and then proceeds with the second step seems to me to be feasible. An alternative would be to use a CI system like Jenkins/Automic to handle the orchestration part.
we can create a SQLServer deployment script with TFS&SSDT, but is there a way to create a rollback script, so that we can roll back the deployment?
Thank's
As SSDT (and similar products) all work by comparing the schema in the project against a live database to bring the database in sync with the model, there's not a direct way to create a rollback script. There are also considerations regarding data changed/added/removed through pre or post-deploy scripts.
That being said, there are a handful of options.
Take a snapshot each time you do a release. You can use that snapshot from the prior release to do another compare for rollback purposes.
Maintain a prior version elsewhere - perhaps do a schema compare from your production system against your local machine. You can use that to compare against production and do a rollback.
Generate a dacpac of the existing system prior to release (use SQLPackage or SSDT to do that). You can use that to deploy that version of the schema back to the database if something goes wrong.
Take a database snapshot prior to release. Best case scenario, you don't need it and can drop the snapshot. Worst case, you could use that to rollback. Of course, you need to watch out for space and IO as you'll be maintaining that original state elsewhere.
Run your changes through several environments to minimize the need for a rollback. Ideally if you've run this through Development, QA, and Staging/User Acceptance environments, your code and releases should be solid enough to be able to release without any issues.
You'll need to code accordingly for rolling back data changes. That could be a bit trickier as each scenario is different. You'll need to make sure that you write a script that can undo whatever changes were part of your release. If you inserted a row, you'll need a rollback script to delete it. If you updated a bunch of data, you'll either need a backup of that data or some other way to get it back.
Before making any changes to a database project I take a snapshot (a dacpac) which I can compare the modified database project against to generate a release script. Although it's easy enough to swap the source and target to do a reverse schema compare I've discovered it won't let me generate an update script (which would be the rollback script) from the reverse comparison, presumably because the target is a database project.
To get around that problem and generate a rollback script I do the following:
Deploy the modified database project to my (localdb) development database;
Check out a previous version of the database project from source control, from before the changes were made;
Run a schema compare from the previous version of the database project to the (localdb) development database;
Use the schema compare to generate an update script. This update script will be a rollback script.
Although it would be nice to be able to generate a rollback script more directly the four step process above takes less than five minutes.
i have two questions
1.i have two stored procedures. is it possible to commit/rollback another procedure's transaction in my current procedure.
2.i have two webservices two services connected with same database or linked server database. one webservices gotsucceed it transactions. when moving to the second webservice some error got occured. if error occured i have to rollback the previous webservice transactions.? is it possible. if anyone explain related to banking transactions like ATM
is it possible?
how?
explain related to banking sector with little understandable coding.
No, a commit must be issued from the same connection that the begin transaction statement was issued.
In this case you would first need to append the data tables with a "transaction" field or something similar that will uniquely identify each transaction. If the second webservice needed to issue a rollback that touched the work of the first webservice, it would have to call a custom process would then issue deletes looking for the transaction identifier that you have built into the tables. There's no built-in functionality of the db engine to accommodate this out of the box.
What is the equivalent to the following SQL Server statements in DB2?
Begin Transaction
Commit Transaction
Rollback Transaction
The answer is actually a little more complicated than indicated here. True, transactions are ANSI standardized, and DB2 may support them.
DB2 for z/OS can be a very different beast from the other variants (LUW, Linux-Unix-Windows, being the most common). At risk of sliding into a rant, this makes the idea of talking about DB2 almost pointless. You are talking about some specific variant of IBM's database, but what works in one can be completely invalid in another. I will assume that whatever flavor the OP was using was not the z/OS one, since the BEGIN TRANSACTION answer was accepted.
For those of you who stumble across this trying to use transactions with DB2 z/OS, here is the rundown: DB2 for the mainframe does not have explicit transactions. There is no BEGIN TRANSACTION or any other comparable construct. Transactions are begun implicitly (usually referred to as a unit of work in the docs) and committed or rolled back explicitly (usually--many GUI tools, like Toad, have an autocommit feature that can sneak up on you once in a while).
From the 9.1 z/OS SQL reference manual (page 28; available at http://www-01.ibm.com/support/docview.wss?uid=swg27011656#manuals):
"A unit of work is initiated when an application process is initiated. A unit of work
is also initiated when the previous unit of work is ended by something other than
the end of the application process. A unit of work is ended by a commit operation,
a full rollback operation, or the end of an application process. A commit or rollback
operation affects only the database changes made within the unit of work it ends."
The closest thing you get when writing scripts is to manually specify a savepoint.
These look like this:
SAVEPOINT A ON ROLLBACK RETAIN CURSORS;
UPDATE MYTABLE SET MYCOL = 'VAL' WHERE 1;
ROLLBACK WORK TO SAVEPOINT A;
Superficially, these resemble explicit transactions, but they are not. Instead, they really are just points in time within a single implicit transaction. For many purposes, they may suffice, but it is important to be aware of the conceptual differences.
See here for more info. But basically
BEGIN TRANSACTION
COMMIT TRANSACTION
ROLLBACK
If you use an IDE like Intellij Idea (or others) then you don't have the possibility to start explicitely a transaction. In others words you cannot type 'begin transaction' in the console of your IDE.
But you can disable 'Auto-commit' (and reenable it later) and then type 'commit' or "rollback' into the console.
In IDEA there is also a button to 'commit' and a button to 'rollback'.
Have a look to the screen dump attached.