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

Community
  • 1
  • 1
openkava
  • 45
  • 2
  • 9
  • 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 ) – openkava Sep 09 '16 at 05:54

1 Answers1

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>
Shnugo
  • 66,100
  • 9
  • 53
  • 114
  • Thanks ,further more ,I want get the table column name in the result html ,like `
    id username department
    1 tom finance
    2 mark business
    ` ,so when I pass a table variable(or xml ) to function ,it return like this .
    – openkava Sep 13 '16 at 07:12
  • @openkava, see my update. Please upvote and accept, if this solves your issue, thx! – Shnugo Sep 13 '16 at 07:58
  • @openkava, one more update, I'm not so familiar with `html` and improved the table's structure... – Shnugo Sep 13 '16 at 08:09