1

xml is a type in sqlserver, now I want to pass a table variable to procedure, but you must define the table as type (use "create type"). So I think I can use xml as a variable to pass into the procedure as parameters.

declare @tv  table
(
  id int, 
  username varchar(50),
  department varchar(50) 
  
)
insert into @tv values(1,'tom','finance'),(2,'mark','business');

declare @xml xml;
set @xml  =(select * from @tv for xml  path('row') ,type )
select @xml  ;

I want to use table like @tv as parameter, pass it to procedure, and get the result like this:

<table>
<tr><td>1</td><td>tom</td><td>finance</td></tr>
<tr><td>2</td><td>mark</td><td>business</td></tr>
</table>

I know it can be done by this:

select id as td ,username as td , department as td from @tv for xml raw('tr'),elements

but I want it dynamic, because I don't know the column name when it pass as parameters.

UPDATE (taken from OP's comment)

further more ,I want get the table column name in the result html ,like

<table> <tr> <td>id</td> <td>username</td> <td>department</td> </tr> <tr> <td>1</td> <td>tom</td> <td>finance</td> </tr> <tr> <td>2</td> <td>mark</td> <td>business</td> </tr> </table>

,so when I pass a table variable(or xml ) to function ,it return like this

1
  • If I pass xml variable to procedure parameters , how can it be query like table . or insert into table variable ,so I can query such as ( select * from @xml ) Commented Sep 9, 2016 at 5:54

1 Answer 1

2

You find a much enhanced version of this answer here.

old answer:

because I don't know the column name when it pass as parameters

This makes it impossible, to call something like SELECT * FROM... You might think about dynamic SQL, but there is a great alternative: FLWOR

declare @tv  table
(
  id int, 
  username varchar(50),
  department varchar(50) 

)
insert into @tv values(1,'tom','finance'),(2,'mark','business');

SELECT
(
    SELECT *
    FROM @tv 
    FOR XML PATH('tr'),TYPE
).query('for $tr in /tr
         return <tr>
           {
             for $td in $tr/*
             return <td>{$td/text()}</td>
           }
                </tr>')
FOR XML PATH('table')

The .query() will run through your XML and re-create it as demanded.

The result:

<table>
  <tr>
    <td>1</td>
    <td>tom</td>
    <td>finance</td>
  </tr>
  <tr>
    <td>2</td>
    <td>mark</td>
    <td>business</td>
  </tr>
</table>

##UPDATE ##This is a solution with a FUNCTION on XML-base using FLWOR

It will transform any SELECT into a XHTML table: The call is as easy as this:

SELECT dbo.CreateHTMLTable((SELECT TOP 5 * FROM sys.objects FOR XML RAW,ELEMENTS XSINIL));

That's the code

CREATE FUNCTION dbo.CreateHTMLTable(@SelectForXmlRawElementsXsinil XML)
RETURNS XML
AS
BEGIN

RETURN
(
    SELECT  
    @SelectForXmlRawElementsXsinil.query('let $first:=/row[1]
                return 
                <tr> 
                {
                for $th in $first/*
                return <td>{local-name($th)}</td>
                }
                </tr>') AS thead
    ,@SelectForXmlRawElementsXsinil.query('for $tr in /row
                 return 
                 <tr>
                 {
                 for $td in $tr/*
                 return <td>{string($td)}</td>
                 }
                 </tr>') AS tbody
    FOR XML PATH('table'),TYPE
);
END
GO

--a mock-up-table with data

declare @tv  table
(
  id int, 
  username varchar(50),
  department varchar(50) 
)
--NULL value in row=2!!!
insert into @tv values(1,'tom','finance'),(2,NULL,'business');

--That's the way you use it

SELECT dbo.CreateHTMLTable((SELECT * FROM @tv FOR XML RAW,ELEMENTS XSINIL));

--Clean-Up

DROP FUNCTION dbo.CreateHTMLTable;

returns be aware of the NULL value in last row!

<table>
  <thead>
    <tr>
      <td>id</td>
      <td>username</td>
      <td>department</td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>tom</td>
      <td>finance</td>
    </tr>
    <tr>
      <td>2</td>
      <td />
      <td>business</td>
    </tr>
  </tbody>
</table>

##UPDATE Possible Enhancements

  • You can control the layout easily via CSS
  • You might pass in class names for table, thead, tbody... for better CSS-control
  • One could pass in a one-row-footer with aggregated values as second parameter and append it as <tfoot>
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks ,further more ,I want get the table column name in the result html ,like <table> <tr> <td>id</td> <td>username</td> <td>department</td> </tr> <tr> <td>1</td> <td>tom</td> <td>finance</td> </tr> <tr> <td>2</td> <td>mark</td> <td>business</td> </tr> </table> ,so when I pass a table variable(or xml ) to function ,it return like this .
@openkava, see my update. Please upvote and accept, if this solves your issue, thx!
@openkava, one more update, I'm not so familiar with html and improved the table's structure...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.