47
IF @SQL IS NOT NULL
BEGIN
    BEGIN TRY 
        EXEC sp_executesql @SQL
        PRINT 'SUCCESS: ' + @SQL
    END TRY 
    BEGIN CATCH
        SET @ErrorMessage = 
                    N'Error dropping constraint' + @CRLF
                    + 'Table ' + @TableName + @CRLF
                    + 'Script: ' + @SQL + @CRLF
                    + 'Error message: ' + ERROR_MESSAGE() + @CRLF
        THROW  50100, @ErrorMessage, 1;
    END CATCH
END

When the CATCH executes, I get the following error:

Msg 102, Level 15, State 1, Line 257
Incorrect syntax near 'THROW'.

Replacing THROW with PRINT @ErrorMessage works.

Replacing @ErrorMessage variable with a literal string works.

According to the docs, however, THROW is supposed to be able to take a variable. Not sure what to make of this.

Metaphor
  • 6,157
  • 10
  • 54
  • 77

3 Answers3

72

From MSDN:

The statement before the THROW statement must be followed by the semicolon (;) statement terminator.

Sam Axe
  • 33,313
  • 9
  • 55
  • 89
6

From the Documentation on THROW, Remarks:

The statement before the THROW statement must be followed by the semicolon (;) statement terminator.

It's a good habit to always end your statements with a semi-colon.

TT.
  • 15,774
  • 6
  • 47
  • 88
  • 6
    "It's a good habit to always end your statements with a semi-colon." Sure, but it's really weird to have to terminate `begin` with a semicolon, given `if @@rowcount = 0 begin throw ###, '', # end` – Tim Sparkles Feb 25 '17 at 00:38
  • @Timbo `BEGIN` isn't a statement. `BEGIN`and `END` are control-of-flow language keywords. – TT. Feb 25 '17 at 07:37
  • 2
    Which is why I find it strange that the build wants `begin` to be terminated with a semicolon. – Tim Sparkles Feb 26 '17 at 09:07
  • @Timbo Indeed that is strange. Nothing's perfect I guess ;) – TT. Feb 26 '17 at 10:15
  • 1
    agree with @Timbo, I prefer writing ;THROW when throw is on a new line – maets Jan 30 '19 at 08:04
6

I just hit the same error but for a completely different reason. The machine I'm using is slightly old but has SSMS 2012 (the version that THROW was introduced). However the actual SQL server is 10.5 (which is 2008 R2; see https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-compatibility-level) and so the command is not valid.

Hopefully there won't be too many instances of ten year old setups out there but double check if you get this and you're sure your syntax is correct!

d219
  • 2,707
  • 5
  • 31
  • 36
  • Just a note that forgetting the semicolon and using it after a parameterless procedure call will pass parsing (in versions before 2012), and instead throw the error 8146 at runtime with the message "Procedure `ParameterlessProcedure` has no parameters and arguments were supplied." – Elaskanator Oct 29 '18 at 18:58