Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2008 Forums
 Transact-SQL (2008)
 POP QUIZZ ********* What will this do?

Author  Topic 

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2013-06-07 : 04:49:05
Before you run this -- just think about what you expect to get out of the OUTPUT clause of the DELETE statement...

Then try running it. SURPRISE!

IF OBJECT_ID('tempdb..#foo') IS NOT NULL DROP TABLE #foo
CREATE TABLE #foo (
[bar] CHAR(1)
, [val] INT
)

INSERT #foo ( bar, val )
VALUES ( 'A', 1)
, ( 'A', 2)
, ( 'B', 2)
, ( 'A', 3)

; WITH delCTE AS (
SELECT *
, ROW_NUMBER() OVER (PARTITION BY [bar] ORDER BY [val]) AS [rnk]
FROM #foo
)
DELETE d OUTPUT DELETED.* FROM delCTE AS d WHERE d.[rnk] > 1

SELECT * FROM #foo



Transact Charlie
Msg 3903.. The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.
http://nosqlsolution.blogspot.co.uk/

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2013-06-07 : 04:52:58
And the explanation from SHOW_PLAN:

statement:

WITH delCTE AS ( SELECT * , ROW_NUMBER() OVER (PARTITION BY [bar] ORDER BY [val]) AS [rnk] FROM #foo ) DELETE d OUTPUT DELETED.* FROM delCTE AS d WHERE d.[rnk] > 1


Plan:

|--Sequence Project(DEFINE:([Expr1009]=row_number))
|--Segment
|--Sort(ORDER BY:([tempdb].[dbo].[#foo].[bar] ASC, [tempdb].[dbo].[#foo].[val] ASC))
|--Table Delete(OBJECT:([tempdb].[dbo].[#foo]))
|--Top(ROWCOUNT est 0)
|--Filter(WHERE:([Expr1004]>(1)))
|--Sequence Project(DEFINE:([Expr1004]=row_number))
|--Segment
|--Sort(ORDER BY:([tempdb].[dbo].[#foo].[bar] ASC, [tempdb].[dbo].[#foo].[val] ASC))
|--Table Scan(OBJECT:([tempdb].[dbo].[#foo]))


So the ROW_NUMBER is evaluated twice! once for the CTE before the delete and then again in the OUTPUT clause.

SQL Server -- you still surprise me sometimes!

Transact Charlie
Msg 3903.. The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.
http://nosqlsolution.blogspot.co.uk/
Go to Top of Page

TG
Master Smack Fu Yak Hacker

6065 Posts

Posted - 2013-06-07 : 11:03:16
Good one. I failed the pop-quiz.
But it makes sense. the OUTPUT clause could have contained any (valid) expression and sql would have to evaluate it independently.

Be One with the Optimizer
TG
Go to Top of Page

James K
Master Smack Fu Yak Hacker

3873 Posts

Posted - 2013-06-07 : 11:04:01
This is interesting behavior!

I would think views behave the same way. But then, what about indexed views? Would they behave differently, given that the data is persisted?

Editing: I take back my last question. Indexed views can't have ranking functions in them, so the issue does not arise.
Go to Top of Page

Lamprey
Master Smack Fu Yak Hacker

4614 Posts

Posted - 2013-06-10 : 13:25:57
Nice! :)
Go to Top of Page
   

- Advertisement -