Writing a SQL Server database object, I was faced with the problem of to serialize some data to XML and to get the count of rows being serialized.
I wrote something like this using a CTE:
-- Way III
begin
declare @TmpUno as table (
uno int, dos varchar(max)
)
declare @RC int
declare @XmlSerializedData xml
insert into @TmpUno (uno, dos)
values (1, 'uno'), (2, 'dos')
-- Way III :
-- * Serialization data is stored in a local variable
-- * Rows count is stored in a local variable
;with c1 as
(
select uno, dos
from @TmpUno
)
select
@XmlSerializedData = (select * from c1 for xml path('row')),
@RC = (select count(1) from @TmpUno)
-- But is this the optimal way?
select 'Way III:' as way,
@XmlSerializedData as [@XmlSerializedData],
@RC as [@RC]
end
For a small table and low number of requests, that would be enough to solve the problem, but consider now to evaluate if this is this the optimal way. Execution plan look like this
Showing that, in effect two table scans are performed (circled blue)
For optimization, my question: ¿Is there a way to serialize and to count the rows being serialized, and store both results (the xml, and the rouwcount) into script local variables using only one statement, or performing only one table scan?
3条答案
按热度按时间jljoyd4f1#
Simply use @@rowcount. eg
This will send an XML stream to the client followed by a single-row single-column resultset.
zbq4xfa02#
Don't use
@@ROWCOUNT
if you are storing the data in a variable, or if you are using the,TYPE
clause. It won't work, you will just get1
.Instead, you could count the nodes inside the XML
A more efficient version is to assign each XML node a row-number, then just select the last node's number.
You could even modify this second option to get the row-number in the XML just once, and not within any
<row>
node.db<>fiddle
3bygqnnd3#
For the top level
FOR XML
statement rows get output to a top levelXML SELECT
operator and@@ROWCOUNT
is set accordingly.When you assign it to a variable they get collapsed down to 1 by the UDX operator and
@@ROWCOUNT
doesn't return what you need.I can't think of any sensible possibility to get these rows counted along the way in the yellow highlighted portion of the plan and surface this up without altering the XML.
A non sensible method is below though for "fun" (depends on elevated permissions and brittle execution plan details as well as lightweight query profiling infastructure being enabled)
A way that technically works but which I do not recommend!