Reputation: 121
I have a need to create a user table type. My preference is to use a single SQL statement. Ignoring the bells and whistles that can be attributed to such create statement I first derived the logic to generate the create statement for a single column table with the statement:
select 'create type ' + tt.name + ' as TABLE (' + c.name + ' ' + t.name +
case
when t.name in ('varchar','char','nvarchar','nchar','binary','varbinary') then
'(' +
case
when c.max_length = -1 then 'MAX'
else convert(varchar, c.max_length)
end + ')'
when t.name in ('numeric','decimal') then
'(' + convert(varchar, c.precision) + ',' + convert(varchar, c.scale) + ')'
else ''
end + ')'
from sys.table_types tt
join sys.columns c
on tt.type_table_object_id = c.object_id
join sys.types t
on c.system_type_id = t.system_type_id and
c.user_type_id = t.user_type_id
This is limited in scope in terms of the data types, etc but sufficient for now. What I am trying to figure out is out to expand this such that the statement that creates the table column definitions is in some sort of inner loop to handle 1 to n columns. It seems as though it should be possible, but I have not been able to work out the logic.
Upvotes: 3
Views: 810
Reputation: 138960
You can use the for xml path
string concatenation trick.
select 'create type ' + tt.name + ' as TABLE (' +
stuff((select ', '+c.name + ' ' + t.name +
case when t.name in ('varchar','char','nvarchar','nchar','binary','varbinary')
then '(' + case when c.max_length = -1
then 'MAX'
else convert(varchar, c.max_length)
end + ')'
when t.name in ('numeric','decimal')
then '(' + convert(varchar, c.precision) + ',' + convert(varchar, c.scale) + ')'
else ''
end
from sys.columns c
inner join sys.types t
on c.system_type_id = t.system_type_id and
c.user_type_id = t.user_type_id
where c.object_id = tt.type_table_object_id
for xml path(''), type
).value('.', 'varchar(max)'), 1, 2, '')+ ')'
from sys.table_types tt
Upvotes: 2