Reputation: 258
I'm newish to SQL server 2012, and I'm trying to create a stored procedure that should:
But I need to use CTEs for performance and other reasons (please don't get hung up on that, I have to, just take my word).
The CTE query works fine if it's by itself in a Stored Procedure, but I can't get the SP to work with two clauses.
I get an error when trying to create the procedure, complaining that I should use a semicolon before the CTE. If I add the semicolon, SQL Server complains about it too. It's driving me insane, please help!
Table where I want to delete/insert:
CREATE MYTABLE ( APPUSER NVARCHAR(15), DATA NVARCHAR(100) )
Simplified stored procedure (no semicolon):
CREATE PROCEDURE P1 ( @SOMEUSER NVARCHAR(15), @TYPE INTEGER) AS
BEGIN
DELETE FROM MYTABLE WHERE ( APPUSER=@SOMEUSER )
WITH CTE AS (
SELECT DATA
FROM SOURCETABLE
WHERE ( TYPE = @TYPE )
)
INSERT INTO MYTABLE
SELECT
@SOMEUSER,
DATA
FROM CTE
END
Error message without semicolon:
[Error Code: 319, SQL State: S1000] Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.
Please note that even though that's a simplified version of the actual query, the error is exactly the same. I did try the above code, without any luck :(
Stored procedure with semicolon (same query as above, showing only the semicolon for brevity):
(...)
BEGIN
DELETE FROM MYTABLE WHERE ( APPUSER=@SOMEUSER ); /* Semicolon */
WITH CTE AS (
(...)
Error with semicolon:
[Error Code: 102, SQL State: 42000] Incorrect syntax near ')'.
I tried enclosing the DELETE clause in it's own transaction, that didn't work either, always get one of the two errors.
Any pointers will be very appreciated, thanks!!!
Upvotes: 3
Views: 62606
Reputation: 11893
For complete clarity of the points raised by others, this excerpt form the MSDN documentation on CTE's in SQL Server is an essential note for usage of CTE's:
•When a CTE is used in a statement that is part of a batch, the statement before it must be followed by a semicolon.
As also noted, it is best practice to either:
I prefer the first, but I have seen competent developers who prefer the second.
Upvotes: 1
Reputation: 45096
You have something strange going on because the following works for me:
CREATE PROCEDURE P1 ( @SOMEUSER NVARCHAR(15), @TYPE INTEGER) AS
BEGIN
DELETE FROM [Table_1] WHERE ( [lname]=@SOMEUSER );
WITH CTE AS (
SELECT [fname], [lname]
FROM [Table_1]
WHERE ( [ID] = @TYPE )
)
INSERT INTO [Table_1]
SELECT top 1
@SOMEUSER,
[lname],
@TYPE
FROM CTE
END
Check your environment
A CTE is just syntax - it does not help performance
Upvotes: 4
Reputation: 296
You need to put a ';' before 'With' keyword, your code look like this
CREATE PROCEDURE P1 ( @SOMEUSER NVARCHAR(15), @TYPE INTEGER) AS
BEGIN
DELETE FROM MYTABLE WHERE ( APPUSER=@SOMEUSER )
;WITH CTE AS (
SELECT DATA
FROM SOURCETABLE
WHERE ( TYPE = @TYPE )
)
INSERT INTO MYTABLE
SELECT
@SOMEUSER,
DATA
FROM CTE
END
As a thumb rule for CTE, always start with a semicolon if you have any executable statement above your CTE.
Upvotes: 11