How to determine internal name of table-valued variable in MS SQL Server 2005

StackOverflow https://stackoverflow.com/questions/95842

  •  01-07-2019
  •  | 
  •  

Question

The name of a temporary table such as #t1 can be determined using

select @TableName = [Name]
from tempdb.sys.tables 
where [Object_ID] = object_id('tempDB.dbo.#t1')

How can I find the name of a table valued variable, i.e. one declared by

declare @t2 as table (a int)

the purpose is to be able to get meta-information about the table, using something like

select @Headers = dbo.Concatenate('[' + c.[Name] + ']')  
from  sys.all_columns c
    inner join sys.tables t
        on c.object_id = t.object_id
where t.name = @TableName

although for temp tables you have to look in tempdb.sys.tables instead of sys.tables. where do you look for table valued variables?


I realize now that I can't do what I wanted to do, which is write a generic function for formatting table valued variables into html tables. For starters, in sql server 2005 you can't pass table valued parameters:

http://www.sqlteam.com/article/sql-server-2008-table-valued-parameters

moreover, in sql server 2008, the parameters have to be strongly typed, so you will always know the number and type of columns.

Was it helpful?

Solution

I don't believe you can, as table variables are created in memory not in tempdb.

OTHER TIPS

Table variable metadata is viewable in tempdb.sys.tables too. This is easily verifiable from the below

declare @t2 as table ( [38F055D8-25D9-4AA6-9571-F436FE] int)

SELECT t.name, t.object_id
FROM tempdb.sys.tables t
JOIN tempdb.sys.columns c
ON t.object_id = c.object_id 
WHERE c.name = '38F055D8-25D9-4AA6-9571-F436FE'

Example Results

name                           object_id
------------------------------ -----------
#4DB4832C                      1303675692

But you will notice the object name is auto generated and bears no relation to the variable name.

If you do not have a guaranteed unique column name that you can use to filter on as above and the table variable has at least one row in it you can (from SQL Server 2008 onwards) use %%physloc%% and DBCC PAGE to determine this information. Example below.

DECLARE @t2 AS TABLE ( a INT)

INSERT INTO @t2
VALUES      (1)

DECLARE @DynSQL NVARCHAR(100)

SELECT TOP (1) @DynSQL = 'DBCC PAGE(2,' + CAST(file_id AS VARCHAR) + ',' + 
                                          CAST( page_id AS VARCHAR) +
                                        ',1) WITH TABLERESULTS'
FROM   @t2
       CROSS APPLY sys.fn_PhysLocCracker( %% physloc %% )

DECLARE @DBCCPage TABLE (
  [ParentObject] [VARCHAR](100) NULL,
  [Object]       [VARCHAR](100) NULL,
  [Field]        [VARCHAR](100) NULL,
  [VALUE]        [VARCHAR](100) NULL )

INSERT INTO @DBCCPage
EXEC (@DynSQL)

SELECT VALUE                 AS object_id,
       OBJECT_NAME(VALUE, 2) AS object_name
FROM   @DBCCPage
WHERE  Field = 'Metadata: ObjectId'  

From Books Online:

A table variable behaves like a local variable. It has a well-defined scope, which is the function, stored procedure, or batch in which it is declared.

Given this, there should be no need to look up this value at run-time because you have to know it at design-time.

On the topic of passing arbitrary lists/arrays into a SQL Server 2005 function or sproc,
the least hokey way I know is to use an XML variable. If desired, that XML variable can be a strongly typed XML type that is associated w/ an XML Schema.

Given a list passed into a procedure/function as XML, you can extract that list into a table variable or temp table via "shredding". "To shred" XML means to transform in the opposite direction--from XML to rowset(s). (The FOR XML clause causes a rowset to XML transformation.)

In the user-defined table function

CREATE FUNCTION [dbo].[udtShredXmlInputBondIdList]  
( 
-- Add the parameters for the function here
@xmlInputBondIdList xml
)
RETURNS 
@tblResults TABLE 
(
-- Add the column definitions for the TABLE variable here
    BondId int 
)
AS
BEGIN
-- Should add a schema validation for @xmlInputIssuerIdList here
--Place validation here
-- Fill the table variable with the rows for your result set
INSERT @tblResults
SELECT  
nref.value('.', 'int') as BondId
FROM
@xmlInputBondIdList.nodes('//BondID') as R(nref)
RETURN 
END

if the @xmlInputBondIdList is an XML fragment of the expected structure like that immediately below and is invoked as follows

DECLARE @xmlInputBondIdList xml
SET @xmlInputBondIdList =
'<XmlInputBondIdList>

<BondID>8681</BondID>

<BondID>8680</BondID>

<BondID>8684</BondID>

</XmlInputBondIdList>
'

SELECT * 
FROM [CorporateBond].[dbo].[udtShredXmlInputBondIdList] 
     (@xmlInputBondIdList)

the result will be the rowset

BondId

8681

8680

8684

A couple other examples can be found at http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=678284&SiteID=1

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top