undo changes to a stored procedure - sql

I altered a stored procedure and unknowingly overwrote some changes that were made to it by another developer. Is there a way to undo the changes and get the old script back?
Unfortunately I do not have a backup of that database, so that option is ruled out.

The answer is YES, you can get it back, but it's not easy. All databases log every change made to it. You need to:
Shutdown the server (or at least put it into read-only mode)
Take a full back up of the server
Get a copy of all the db log files going back to before when the accident happened
Restore the back up onto another server
Using db admin tools, roll back through the log files until you "undo" the accident
Examine the restored code in the stored proc and code it back into your current version
And most importantly: GET YOUR STORED PROCEDURE CODE UNDER SOURCE CONTROL
Many people don't grok this concept: You can only make changes to a database; you can't roll back the stored proc version like you can with application code by replacing files with their previous versions. To "roll back", you must make more changes that drop/define your stored proc.
Note to nitpickers: By "roll back" I do not mean "transaction roll back". I mean you've made your changes and decide once the server is back up that the change is no good.

"Is there a way to undo the changes and get the old script back?"
Short answer: Nope.
:-(

In addition to the sound advice to either use a backup or recover from source control (and if you're doing neither of those things, you need to start), you could also consider getting SSMS Tools Pack from #MladenPrajdic. His Management Studio add-in allows you to keep a running history of all the queries you've worked on or executed, so it is very easy to go back in time and see previous versions. While that doesn't help you if someone else worked on the last known good version, if your entire team is using it, anyone can go back and see any version that was executed. You can dictate where it is saved (to your own file system, a network share, or a database), and fine-tune how often auto-save kicks in. Really priceless functionality, especially if you're lazy about backups and/or source control (though again, I stress, you should be doing these things before you touch your production server again).

You could look through the cached execution plans and try to find the one where your colleague made his changes and run the relevant parts again.
EDIT
Although Bohemian looks to have a good answer if you've got the changes in the TL, this is what I'm talking about. Review the SQL text for the plan.
SELECT cached.*,
sqltext.*
FROM sys.dm_exec_cached_plans cached
CROSS APPLY sys.dm_exec_sql_text (cached.plan_handle) AS sqltext
But as squillman points out, there is no execution plan for DDL.

You won't be able to get it back from the database side of things. Your options at this point are pretty much limited to 1) recover from backup, 2) go to source control or 3) hope that someone else has a copy still up in an editor somewhere or saved to a file.
If neither of these are an option for you, then here's the obligatory "you should take regular backups and use source control"....

I'm way late to the game on this but I did this same thing this morning and found I had forgot to save my script at some point in the past and needed to recover it. (It will be in source control after I get done fixing this!!!)
Some people mentioned restoring from a backup but no one really mentioned how easy this is if you have a back up. Moreover, you aren't locked into rolling back the production database. I think this is key and assuming you have a back up I would say this is a much better alternative to what has been voted up to the best answer.
All you have to do is take your back up and restore it to a new database. Pull out the sp you are looking for and voila, you've recovered the missing code.
Don't forget to drop the newly created database after you've recovered the missing file.

I had the same problem, and I don't have the confidence to go restoring from log files to another server. I was pretty distraught until I realised the solution was very simple...
Press Ctrl-Z over and over until I had undone my changes and the run the ALTER PROCEDURE again.
Admittedly I was pretty lucky that I still had it there to revert to but it really is the easiest fix. Probably a bit late now though.

If you have scripted the stored procedure out from management studio object explorer this will work.
Before expand and collapse the object explorer just scroll and point to the stored procedure you have opened. Script the stored procedure as create or alter to then you can get the previous version of the proc since the object explorer doesn't refreshed yet. This is always my life saver.

Related

Can I undo the last few transaction, or revert to yesterday in MariaDB?

I have an SQL file containing several commands, when I need to make a correction to my application database that the application can't yet do, I use DBVis to select and execute the command I need (e.g. to delete an incorrect entry). Problem is, the button to run the whole page is right next to the button to run a selected command. So I just dropped and re-created my table, losing all my data. Is there a way to undo this?
I'm looking to either 'undo' each command until I get back to the right place, or revert back to yesterday, where I know everything was correct.
Thanks!
Yes, you can if...
your administration tool did set autocommit=OFF by default, you can
just execute a ROLLBACK (or just shutdown your administration tool)
If latter doesn't work, check if your binary log was enabled, and restore with mysqlbin log tool
If none of the above mentioned solution works, use your (probably not existent) backup for restoring

SQLServer 2012 Installed copy showing problems:

My problem is like this: I had a copy of SqlServer 2012 installed on my machine. It's been there for over 3 years without any glitches at all. Just 4-5 days ago, a problem sprouted up. When I started Management Studio it told me that
msdb got corrupted so it cannot be opened.
The complete message is something like this:
Cannot display policy health state at the server level, becuase the user doesn't have permission. Permission to the database msdb is required for this feature to work correctly.
So what could be wrong here? What sudden changes/anomalies could have crept in that has made this unstable? Someone told me it could be due to a wide range of possibilities. The reason could be anything. Even some nuget packages affect the database. Initially I though this could have been an issue with login, permissions etc. So I tried to run as administrator also. No, it did not cure this problem. If you try to create a new database it simply tells me, that I can't do it. The message is something like this:
An exception occurred while executing a T-SQL statement or batch.[Microsoft.SqlServer.ConnectionInfo]. Database msdb cannot be opened. It has been marked as SUSPECT by recovery. [Microsoft Sql Server, Error:926]
How do I recover from this? Can you provide me some guidance? Or a clue where precisely to look for the hints of problem? All my work is stalled. Any kind of assistance in recovering my ailing sqlserver installation will be humbly received.
So, I'm requesting you all to show me the way.
Thanks in anticipation.
I fixed mine with Solution C from the following website. my MSDB was corrupt and not loading so I stopped the services and replaced it with the files from the template in the SQL Server directory.
https://www.mssqltips.com/sqlservertip/3191/how-to-recover-a-suspect-msdb-database-in-sql-server/
"The templates are saved in "C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Binn\Templates" (the path varies by version and install choices, this is the default for SQL Server 2012). By shutting down the instance and replacing the bad MSDB data (msdbdata.mdf) and transaction log (msdblog.ldf) files with the template files I was able to restart the instance without error!" (just incase the website link doesn't work I have quoted it here).
Fissh
If your MSDB is corrupted, restore from your most recent backup. That's the safest thing to do and that's why we have backups to begin with.
If you do not have a backup of MSDB, you have a couple of options.
Recreate it. Detailed instructions here: https://msdn.microsoft.com/en-us/library/dd207003(v=sql.110).aspx#CreateMSDB. This is the best way to ensure you get a clean, functional MSDB and is the fastest way to get up and running again. IMPORTANT: Doing this means you lose all jobs, backup history, etc... that is stored in MSDB. Remember to recreate all maintenance jobs after you're done else you're just waiting for the next thing to fall over (e.g. transaction log backups no longer run, tlogs grow till you run out of disk space - now you can't run any queries that will commit transactions).
DBCC CHECKDB WITH Repair_allow_data_loss is another option which you'll probably find if you google/bing the issue. This might work but it is not recommended. The problem is you don't really know what will be lost. It works by deleting what it can't read then fix the links to get the database physically functional again. Once that's done, you'll have to go back and figure out what remains and is still functional. That is tedious and error prone. Besides, if you're gonna do this very thorough manual check to ensure all your jobs are intact, you're better off just re-creating them on a new, clean MSDB.

Migration script methods/procedure

Looking for some suggestions on my data/schema migration. Here is what I plan to do.
using sql 2008
Back up current databases
Restore as "_old" (to be used for data transfer later)
run my scripting changes to the target DB's
then, Run my data scripts transferrring data from the "_old" db's to the now new database.
verify everything is working (websites, applications, etc..)
delete the "_old" databases
run back up on new "changed" databases.
This is my first migration and I want some guidance if I am missing anything or if there is a better way to do this.
Thanks for the help..
You must be very perfect for your step 4. and make sure you do it through transactions. You should keep in mind the each and every step of failure and target that.
And regarding step 6. do not delete your _old. Keep it in a safe place for future use if required.
I practised the migration I did on a development stack a number of times so that I could be sure how long it would take and work out any problems with the scripts.
Verify how long you have to do the migration with how long it takes. Is there an adequate margin of error?
It would be a good idea to get some users or other staff to verify that the new application is 'working'. You are not the best person to test your own work.
I would not delete the _old database just to be sure. I have found issues with the migration months afterwards that required the old data to resolve.
Automate as much possible by using master scripts that call other scripts.
A worst case scenario assumes your scripts will fail during the migration. Build logging and progress points into your scripts so you might be able to restart mid process.
Take some performance measurements of the old database so you can show how the new database is, hopefully, improved

iOS Rolling out app updates. Keeping user data intact when DB update required

I have just done a quick search and nothing too relevant came up so here goes.
I have released the first version of an app. I have made a few changes to the SQLite db since then, in the next release I will need to update the DB structure but retain the user's data.
What's the best approach for this? I'm currently thinking that on app update I will never replace the user's (documents folder, not in bundle) database file but rather alter its structure using SQL queries.
This would involve tracking changes made to the database since the previous release. Script all these changes into SQL queries and run these to bring the DB to the latest revision. I will also need to keep a field in the database to track the version number (keep in line with app version for simplicity).
Unless there are specific hooks, delegate methods that are fired at first run after an update I will put calls for this logic into the very beginning of the appDelegate, before anything else is run.
While doing this I will display "Updating app" or something to the user.
Next thing, what happens if there is an error somewhere along the line and the update fails. The DB will be out of date and the app won't function properly as it expects a newer version?
Should I take it upon myself to just delete the user's DB file and replace it with the new version from the app bundle. OR, should I just test, test, test until everything is solid on my side and if an error occurs on the user's side it's something else, in which case I can't do anything about it only discard the data.
Any ideas on this would be greatly appreciated. :)
Thanks!
First of all, the approach you are considering is the correct one. This is known as database migration. Whenever you modify the database on your end, you should collect the appropriate ALTER TABLE... etc. methods into a migration script.
Then the next release of your app should run this code once (as you described) to migrate all the user's data.
As for handling errors, that's a tough one. I would be very weary of discarding the user's data. Better would be to display an error message and perhaps let the user contact you with a bug report. Then you can release an update to your app which hopefully can do the migration with no problems. But ideally you test the process well enough that there shouldn't be any problems like this. Of course it all depends on the complexity of the migration process.

Replace/Rename the Online Database

I have got a database of ms-sql server 2005 named mydb, which is being accessed by 7 applications from different location.
i have created its copy named mydbNew and tuned it by applying primary keys, indexes and changing queries in stored procedure.
now i wants to replace old db "mydb" from new db "mydbnew"
please tell me what is the best approach to do it. i though to do changes in web.config but all those application accessing it are not accessible to me, cant go for it.
please provide me experts opinion, so that i can do replace database in minimum time without affecting other db and all its application.
my meaning of saying replace old db by new db is that i wants to rename old db "mydb" to "mydbold" and then wants to remname my new db "mydbnew" to "mydb"
thanks
Your plan will work but it does carry a high risk, especially since I'm assuming this is a system that has users actively changing data, which means your copy won't have the same level of updated content in it unless you do a cut right before go-live. Your best bet is to migrate your changes carefully into the live system during a low traffic / maintenance period and extensively test it once your done. Prior to doing this, or the method you mentioned previously, backup everything.
All of the changes you described above can be made to an online database without the need to actually bring it down. However, some of those activities will change the way in which the data is affected by certain actions (changes to stored procs), that means that during the transition the behaviour of the system or systems may be unpredicatable and therefore you should either complete this update at a low point in day to day operations or take it down for a maintenance window.
Sql Server comes with a function to make a script file out of you database, you can also do this manually but clicking on the object you want to script and selecting the Script -> CREATE option. Depending on the amount of changes you have to make it may be worthwhile to script your whole new database (By clicking on the new database and selecting Tasks -> Generate Scripts... and selecting the items needed).
If you want to just script out the new things you need to add individually then you simply click on the object you want to script, select the Script <object> as -> then select DROP and CREATE to if you want to kill the original version (like replacing a stored proc) or select CREATE to if your adding new stuff.
Once you have all the things you want to add/update as a script your then ready to execute that against the new database. This would be the part where you backup everything. Once your happy everything is backed up and the system is in maintenance or a low traqffic period, you execute the script. There may be a few problems when you do this, you will need to fix these as quickly as possible (usually mostly just 'already exisits' errors, thats why drop and create scripts are good) and if anything goes really wrong restore your backups and try again (after figuring out what happened and how to fix it).
Make no mistake if you have a lot of changes to make this could be a long process, or it could take mere minutes, you just need to adapt if things go wrong and be sure to cover yourself with backups/extensive prayer. Good Luck!