You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Some keywords written right next to the transaction control statement are treated as transaction name and some as a separate command/next statement. This may lead to significant misunderstanding of what the code will actually do.
Statements:
BEGIN TRAN
SAVE TRAN
COMMIT TRAN
ROLLBACK TRAN
Examples of keywords/statements treated as valid identifier for transaction name:
THROW
RECEIVE
SEND
Steps to Reproduce:
If you write BEGIN TRAN THROW - here THROW will be treated as a valid transaction name. However in BEGIN TRAN CONTINUE the CONTINUE will be treated as a separate command. BEGIN/COMMIT/ROLLBACK behave similarly - they can take modern keywords/commands as a valid tran name but "ignore" "oldschool" keywords/commands and treat them as a separate statement even if no statement terminator is present between them. SAVE TRAN unlikely mentioned statements requires transaction name to be provided and if the next word is parsed as an invalid tran identifier candidate the parsing fails with syntax error.
in all lines not marked with comment the last word is treated as a separate statement. SAVE TRAN requires third word in statement and in all lines except marked with comment parser would say that syntax is broken:
The most ambiguous case to me is this one:
BEGIN TRY
BEGIN TRAN
SELECT 1 / 0
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
THROW -- "Divide by zero" error will not be rethrown here
-- new error will be generated:
-- Cannot roll back THROW. No transaction or savepoint of that name was found
END CATCH
On ROLLBACK TRAN docs page it is said that transaction name must be a valid identifier, identifier is valid if it does not match any of reserved words and THROW is not listed there. On THROW docs page it is said that preceding statement must end with semicolon. Thus ROLLBACK TRAN THROW in the example above behaves expectedly speaking of the docs. But it is an error so easy to make and you need so much to remember to avoid it while coding.
It would be great if
all one-word statements were included into reserved keywords (especially THROW); maybe in future compatibility levels
SSDT/DacFx would show at least a warning in such cases and recommend to put semicolon before THROW or choose another identifier for transaction name
As a workaround I'm developing another rule for our custom linter which would detect such suspicious cases.
(DacFx/SqlPackage/SSMS/Azure Data Studio)
The text was updated successfully, but these errors were encountered:
thanks @IVNSTN! we moved this over to the ScriptDOM repo so its closer to where the fix needs to go in - once fixed in ScriptDOM it'll get picked up by DacFx and then into SSDT.
Some keywords written right next to the transaction control statement are treated as transaction name and some as a separate command/next statement. This may lead to significant misunderstanding of what the code will actually do.
Statements:
Examples of keywords/statements treated as valid identifier for transaction name:
Steps to Reproduce:
If you write
BEGIN TRAN THROW
- hereTHROW
will be treated as a valid transaction name. However inBEGIN TRAN CONTINUE
theCONTINUE
will be treated as a separate command. BEGIN/COMMIT/ROLLBACK behave similarly - they can take modern keywords/commands as a valid tran name but "ignore" "oldschool" keywords/commands and treat them as a separate statement even if no statement terminator is present between them.SAVE TRAN
unlikely mentioned statements requires transaction name to be provided and if the next word is parsed as an invalid tran identifier candidate the parsing fails with syntax error.Examples of ambiguity:
in all lines not marked with comment the last word is treated as a separate statement.
![image](https://private-user-images.githubusercontent.com/13050317/304683469-e5b34088-d6d5-43bc-bcd7-2a7546dca521.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkzMDQ2NjgsIm5iZiI6MTczOTMwNDM2OCwicGF0aCI6Ii8xMzA1MDMxNy8zMDQ2ODM0NjktZTViMzQwODgtZDZkNS00M2JjLWJjZDctMmE3NTQ2ZGNhNTIxLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjExVDIwMDYwOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTc0YmNkZTQ0OGEwN2M3ZGQyMzM0ZjQ2NTVkYzYxYTA4ZWUyMWRkMjcxNzFiMmY3MDg2YjMxZDljYTQ2OTBmNGUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.oVxPXGvRgm0kbZSOs99hUs-rjwNYRZtFeChZCAEqAK4)
SAVE TRAN
requires third word in statement and in all lines except marked with comment parser would say that syntax is broken:The most ambiguous case to me is this one:
On ROLLBACK TRAN docs page it is said that transaction name must be a valid identifier, identifier is valid if it does not match any of reserved words and
THROW
is not listed there. On THROW docs page it is said that preceding statement must end with semicolon. ThusROLLBACK TRAN THROW
in the example above behaves expectedly speaking of the docs. But it is an error so easy to make and you need so much to remember to avoid it while coding.It would be great if
THROW
); maybe in future compatibility levelsTHROW
or choose another identifier for transaction nameAs a workaround I'm developing another rule for our custom linter which would detect such suspicious cases.
(DacFx/SqlPackage/SSMS/Azure Data Studio)
The text was updated successfully, but these errors were encountered: