I'm using a PHP database abstraction layer to work with both MySQL and SQL Server. MySQL has a 'release savepoint' statement which SQL Server does not support, and I can't find a comparable statement within T-SQL to use in its stead. Does anybody know of a way around this, or can the lack of functionality be safely ignored?
I'd appreciate any insight!
Cheers
In SQL Server you do not need to do any operation to release a savepoint. Savepoints are 'released' automatically at the final transaction commit or rollback, you don't need to manage them intermediately.
I don't know much about MySQL but it sounds a bit like using
Save Transaction <Name> and Rollback Transaction <Name>
to partially rollback a transaction to a named point. See MSDN
The ANSI standard syntax is SAVEPOINT , ROLLBACK TO SAVEPOINT , and RELEASE SAVEPOINT . Oracle, DB/2, MySQL, Postgres, Sybase, Informix, Interbase, and Firebird all use that same, standard, syntax. SQL Server is the oddball with a different syntax and no "release".
As Remus Rusanu said, though, it's not strictly required, but could help the database manage internal resources better if it knew that the savepoint was no longer necessary (it certainly helps on multigenerational architectures like Oracle, Interbase and Firebird).
Related
I accidentally included the word "data" in a SQL script I wrote and now am not sure what this does. Can someone tell me what the following script would actually do if the Rollback transaction were not set?
Begin Transaction
data
Rollback Transaction
I think "Data" is in the future reserved keyword list in our SQl Server. But I'm not sure if this is why the script runs without error.
Begin Transaction
data
Rollback Transaction
Not sure what happened. The script ran correctly
You are aliasing the transaction as data
Without the rollback you would just have an open transaction called data
according to my knowledge and the keywords for SQL Server, disponible here:
https://learn.microsoft.com/pt-br/sql/t-sql/language-elements/reserved-keywords-transact-sql?view=sql-server-2017
there is no meaning for data word, but it could be an abbreviation for database, or it could just be a bug
I had unfortunately deleted data from database by using following query in SQL Server
exec usp_delete_cascade "someTable", "id='somexyz'"
Can anyone please tell me how to get back my data?
Is this possible?
There are two kinds of transactions - implicit and explicit.
Implicit transaction is used every time you do DML statement (in your case delete). This transaction is not user handled. And it is not true your qry did not run under transaction.
Explicit transaction can be defined by user (with begin transaction). When you do not specify transaction, there are only implicit transactions, which are autocommited when statement success.
There is a few ways how to data recover, but never with 100% success and without work. You have to use some external program as SysTools SQL Recovery, ApexSQL Recover or Veeam. Level of recovery depends on your storage use and your server configuration.
Only one 100% way is prevension (and backups, change tracking etc).
You can try to recover with this tool of ApexSQL, but you would think in backup and measures to avoid this kind of problem.
http://www.apexsql.com/sql_tools_recover.aspx
Obviously is a third party tool and you would pay for using it.
It depends on your server config. But, by default, SQL Server does not starts transaction when executing query. So, if you do not started transaction, or transaction started, but commited, rollback is impossible.
Other ways to restore the data: if your database recovery model is set to full, and you have diff or full backup, youre lucky. If no, data is missing forewer.
Oracle does implicit commits on DDL statements. So you don't have to commit an ALTER statement for instance.
Microsoft SQL requires a commit on DDL statements.
SQL-92 is too old and there is just basic information about transactions and latest SQL Standard Documents cost dollars and I reject to pay for things that should be free (imho).
So I hope someone knows what the standard says and if the standard doesn't clarify this, maybe there is a de-facto standard or a "design recommendation" for DBMS developers.
Thanks a lot.
EDIT:
For clarification: what I want to know is, if a database SHOULD do implicit commits on DDL statements (according to the standard or some kind of de-facto standard / recommendations). I do not want to know, what the actual DBMS do in practise, because I know that already (and it's answered several times here on SO).
Thanks to the link provided by #GolezTrol, I was able to read a draft of the SQL:2003 standard.
In 4.33.4 SQL-statements and transaction states it says, that all SQL Schema statements are transaction initiating.
In 4.33.5 SQL-statement atomicity and statement execution contexts it says, that no atomic SQL statement (and SQL Schema statements are considered atomic) may terminate an SQL transaction.
Finally, in 4.35.6 Effects of statements in an SQL-Transaction it says:
The execution of an SQL-statement within an SQL-transaction has no effect on SQL-data or schemas other than the effect stated in the General Rules for that SQL-statement, in the General Rules for Subclause 11.8, "referential constraint definition", in the General Rules for Subclause 11.39, "trigger definition", and in the General Rules for Subclause 11.50, "SQL-invoked routine"
So it seems that an implicit commit within a DDL statement is not permitted by the standard, because it would terminate a transaction and open a new transaction within an atomic statement. It is argueable, if closing a transaction is considered an "effect" on SQL schema or data (4.35.6) - maybe this note is irrelevant for deciding if a commit is allowed implicitly or not.
And in 4.35.1 General description of SQL-transactions it says:
It is implementation-defined whether or not the execution of an SQL-data statement is permitted to occur within the same SQL-transaction as the execution of an SQL-schema statement. If it does occur, then the effect on any open cursor or deferred constraint is implementation-defined. There may be additional implementation defined restrictions, requirements, and conditions. If any such restrictions, requirements, or conditions are violated, then an implementation-defined exception condition or a completion condition warning with an implementation-defined subclass code is raised.
So what happens, if the implementation does not allow data and schema statements in one transaction? Then you are forced to use a COMMIT before and after a group of schema statements. So that would not explain, why each schema statement should be implicitly surrounded by COMMITs.
In general the pages in the standard read like they always take the existance of transacted SQL schema statements for granted.
So my conclusion is, that the standard way is NOT to have implicit COMMITs within an DDL statement.
If you don't mind and if there are no objections / protests against my interpretation of the standard, I will accept what I've found out within the next few days.
We have a developer connecting to SQL Server using pymssql which uses freetds. His script dynamically generates sql insert queries based on values in a MySQL DB.
The statements are parsed properly and have proper begin transaction/commits in them when you view them in SQL Profiler. The only 'user error message' that comes up a 'changed database context to...' which comes up whenever you issue a USE in SQL. After the batch completes, there is a transaction log event 'rollback' and all the records that were inserted are removed.
We are not using XACT_ABORT_OFF because I haven't seen 'change db context to' be affected by it.
Does anyone have any ideas or experience with this? Thanks!
[edit]:
The code copied out of profiler works fine in SSMS using the same user and there are no triggers.
[2nd edit]:
inside SQL profiler I see a 'TransactionLog' entry with 'rollback' under eventsubtype, however there isn't a TM:Rollback Tran
Perhaps the connection is not being committed or closed correctly. Check the freetds documentation to ensure that you are using the correct usage patterns. Also you might want to check whether its possible to enable autocommit mode on the connection.
So after much searching and triple checking the auto commit setting, we caught that 2 variables were very closely named and it was committing the wrong one. There is a mysql and a pymysql module, but in this case we were using pymssql but it was typed in at pymysql instead. Thanks everyone who commented.
In SQL Server, how can I separate a large number of tsql statement into batches? Should I use the GO statement in stored procedures or functions? Should I use the GO statement in explicit transaction management situation(between BEGIN TRANSACTION and ROLLBACK TRANSACTION or COMMIT TRANSACTION)?
Are there some best practice about this topic?
Great thanks in advance.
GO is not actually a SQL keyword - it's interpreted by SQL Server Management Studio. So you can't use it in stored procedures.
If you're writing a script for SSMS, you can use GO inside a transaction, but be careful about error handling - if an error occurs, the transaction will be rolled back, but only the current batch will be aborted, and then execution will continue to the next batch. See this question.
As for best practises, personally I just use GO only when I have to (for example, when creating multiple stored procedures - each has to have its own batch). The fewer GO statements, the less work to handle errors.