How to get the scripts of all the user defined data types through a single query.
Asked
Active
Viewed 5,337 times
4
-
Have you tried something? At least googling it and trying some query before asking here? – Yaroslav Oct 06 '12 at 12:46
3 Answers
6
Try this:
SET NOCOUNT ON
SELECT 'USE ' + QUOTENAME(DB_NAME(), '[') + '
GO';
SELECT '
IF EXISTS (SELECT * FROM sys.types st JOIN sys.schemas ss ON st.schema_id = ss.schema_id WHERE st.name = N''' + st.[name] + ''' AND ss.name = N''' + ss.[name] + ''')
DROP TYPE ' + QUOTENAME(ss.name, '[') + '.' + QUOTENAME(st.name, '[') + '
GO
CREATE TYPE ' + QUOTENAME(ss.name, '[') + '.' + QUOTENAME(st.name, '[') + ' FROM ' +
QUOTENAME(bs.[name], '[') +
CASE bs.[name]
WHEN 'char' THEN (CASE ISNULL(st.max_length, 0) WHEN 0 THEN '' WHEN -1 THEN '(MAX)' ELSE '(' + convert(varchar(10), st.max_length) + ')' END)
WHEN 'nchar' THEN (CASE ISNULL(st.max_length, 0) WHEN 0 THEN '' WHEN -1 THEN '(MAX)' ELSE '(' + convert(varchar(10), st.max_length/2) + ')' END)
WHEN 'varchar' THEN (CASE ISNULL(st.max_length, 0) WHEN 0 THEN '' WHEN -1 THEN '(MAX)' ELSE '(' + convert(varchar(10), st.max_length) + ')' END)
WHEN 'nvarchar' THEN (CASE ISNULL(st.max_length, 0) WHEN 0 THEN '' WHEN -1 THEN '(MAX)' ELSE '(' + convert(varchar(10), st.max_length/2) + ')' END)
WHEN 'numeric' THEN (CASE ISNULL(st.[precision], 0) WHEN 0 THEN '' ELSE '(' + convert(varchar(10), st.[precision]) + ', ' + convert(varchar(10), st.[scale]) + ')' END)
WHEN 'decimal' THEN (CASE ISNULL(st.[precision], 0) WHEN 0 THEN '' ELSE '(' + convert(varchar(10), st.[precision]) + ', ' + convert(varchar(10), st.[scale]) + ')' END)
WHEN 'varbinary' THEN (CASE st.max_length WHEN -1 THEN '(max)' ELSE '(' + convert(varchar(10), st.max_length) + ')' END)
ELSE ''
END +
'
GO
'
FROM sys.types st
INNER JOIN sys.schemas ss ON st.[schema_id] = ss.[schema_id]
INNER JOIN sys.types bs ON bs.[user_type_id] = st.[system_type_id]
WHERE st.[is_user_defined] = 1 -- exclude system types
ORDER BY st.[name], ss.[name]
Disclaimer: I am not the author of this script. Just that I have it in my personal library. Unfortunately authors name is not there in it.

vmvadivel
- 1,041
- 5
- 7
-
1It's just what I looking for!!! Thanks a lot for sharing, and thanks to the author :) – NFRiaCowboy Jul 19 '16 at 15:38
1
Here's a script that is actually working.
Creates a script for all user-defined scalar & table-types (not tested with CLR-types):
-- http://www.sqlines.com/sql-server-to-oracle/create_type
SELECT
sch.name AS UDT_SCHEMA_NAME
,userDefinedTypes.name AS UDT_TYPE_NAME
,
N'IF NOT EXISTS (SELECT * FROM sys.types st JOIN sys.schemas ss ON st.schema_id = ss.schema_id WHERE st.name = N''' + REPLACE(userDefinedTypes.name, '''', '''''') + N''' AND ss.name = N''' + REPLACE(sch.name, '''', '''''') + N''') '
+ NCHAR(13) + NCHAR(10)
+
CASE WHEN userDefinedTypeProperties.IsTableType = 1
THEN N'CREATE TYPE ' + QUOTENAME(sch.name) + '.' + QUOTENAME(userDefinedTypes.name) + ' AS TABLE (
' + tAllColumns.column_definition + N'
); '
ELSE
+ N'CREATE TYPE ' + QUOTENAME(sch.name) + '.' + QUOTENAME(userDefinedTypes.name)
+ N' FROM '
+ tBaseTypeComputation.baseTypeName
+ CASE WHEN userDefinedTypeProperties.is_nullable = 0 THEN N' NOT NULL' ELSE N'' END
+ N'; '
END AS SqlCreateUdt
FROM sys.types AS userDefinedTypes
INNER JOIN sys.schemas AS sch
ON sch.schema_id = userDefinedTypes.schema_id
LEFT JOIN sys.table_types AS userDefinedTableTypes
ON userDefinedTableTypes.user_type_id = userDefinedTypes.user_type_id
LEFT JOIN sys.types AS systemType
ON systemType.system_type_id = userDefinedTypes.system_type_id
AND systemType.is_user_defined = 0
OUTER APPLY
(
SELECT
userDefinedTypes.is_nullable
,userDefinedTypes.precision AS NUMERIC_PRECISION
,userDefinedTypes.scale AS NUMERIC_SCALE
,userDefinedTypes.max_length AS CHARACTER_MAXIMUM_LENGTH
,CASE WHEN userDefinedTableTypes.user_type_id IS NULL THEN 0 ELSE 1 END AS IsTableType
,CONVERT(smallint,
CASE -- datetime/smalldatetime
WHEN userDefinedTypes.system_type_id IN (40, 41, 42, 43, 58, 61) THEN ODBCSCALE(userDefinedTypes.system_type_id, userDefinedTypes.scale)
END
) AS DATETIME_PRECISION
) AS userDefinedTypeProperties
OUTER APPLY
(
SELECT
systemType.name
+
CASE
WHEN systemType.name IN ('char', 'varchar', 'nchar', 'nvarchar', 'binary', 'varbinary')
THEN N'('
+
CASE WHEN userDefinedTypeProperties.CHARACTER_MAXIMUM_LENGTH = -1 THEN 'MAX'
ELSE CONVERT
(
varchar(4)
,userDefinedTypeProperties.CHARACTER_MAXIMUM_LENGTH
)
END
+ N')'
WHEN systemType.name IN ('decimal', 'numeric')
THEN N'(' + CONVERT(varchar(4), userDefinedTypeProperties.NUMERIC_PRECISION) + N', ' + CONVERT(varchar(4), userDefinedTypeProperties.NUMERIC_SCALE) + N')'
WHEN systemType.name IN ('time', 'datetime2', 'datetimeoffset')
THEN N'(' + CAST(userDefinedTypeProperties.DATETIME_PRECISION AS national character varying(36)) + N')'
ELSE N''
END AS baseTypeName
) AS tBaseTypeComputation
OUTER APPLY
(
SELECT
(
SELECT
-- ,clmns.is_nullable
-- ,tComputedProperties.ORDINAL_POSITION
-- ,tComputedProperties.COLUMN_DEFAULT
CASE WHEN tComputedProperties.ORDINAL_POSITION = 1 THEN N' ' ELSE N',' END
+ QUOTENAME(clmns.name)
+ N' '
+ tComputedProperties.DATA_TYPE
+
CASE
WHEN tComputedProperties.DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'binary', 'varbinary')
THEN N'('
+
CASE WHEN tComputedProperties.CHARACTER_MAXIMUM_LENGTH = -1 THEN 'MAX'
ELSE CONVERT
(
varchar(4)
,tComputedProperties.CHARACTER_MAXIMUM_LENGTH
)
END
+ N')'
WHEN tComputedProperties.DATA_TYPE IN ('decimal', 'numeric')
THEN N'(' + CONVERT(varchar(4), tComputedProperties.NUMERIC_PRECISION) + N', ' + CONVERT(varchar(4), tComputedProperties.NUMERIC_SCALE) + N')'
WHEN tComputedProperties.DATA_TYPE IN ('time', 'datetime2', 'datetimeoffset')
THEN N'(' + CAST(tComputedProperties.DATETIME_PRECISION AS national character varying(36)) + N')'
ELSE N''
END
+ CASE WHEN tComputedProperties.is_nullable = 0 THEN N' NOT NULL' ELSE N'' END
+ NCHAR(13) + NCHAR(10)
AS [text()]
FROM sys.columns AS clmns
INNER JOIN sys.types AS t ON t.system_type_id = clmns.system_type_id
LEFT JOIN sys.types ut ON ut.user_type_id = clmns.user_type_id
OUTER APPLY
(
SELECT
33 As bb
,COLUMNPROPERTY(clmns.object_id, clmns.name, 'ordinal') AS ORDINAL_POSITION
,COLUMNPROPERTY(clmns.object_id, clmns.name, 'charmaxlen') AS CHARACTER_MAXIMUM_LENGTH
,COLUMNPROPERTY(clmns.object_id, clmns.name, 'octetmaxlen') AS CHARACTER_OCTET_LENGTH
,CONVERT(nvarchar(4000), OBJECT_DEFINITION(clmns.default_object_id)) AS COLUMN_DEFAULT
,clmns.is_nullable
,t.name AS DATA_TYPE
,CONVERT(tinyint,
CASE -- int/decimal/numeric/real/float/money
WHEN clmns.system_type_id IN (48, 52, 56, 59, 60, 62, 106, 108, 122, 127) THEN clmns.precision
END
) AS NUMERIC_PRECISION
,CONVERT(int,
CASE -- datetime/smalldatetime
WHEN clmns.system_type_id IN (40, 41, 42, 43, 58, 61) THEN NULL
ELSE ODBCSCALE(clmns.system_type_id, clmns.scale)
END
) AS NUMERIC_SCALE
,CONVERT(smallint,
CASE -- datetime/smalldatetime
WHEN clmns.system_type_id IN (40, 41, 42, 43, 58, 61) THEN ODBCSCALE(clmns.system_type_id, clmns.scale)
END
) AS DATETIME_PRECISION
) AS tComputedProperties
WHERE clmns.object_id = userDefinedTableTypes.type_table_object_id
ORDER BY tComputedProperties.ORDINAL_POSITION
FOR XML PATH(''), TYPE
).value('.', 'nvarchar(MAX)') AS column_definition
) AS tAllColumns
WHERE userDefinedTypes.is_user_defined = 1

Stefan Steiger
- 78,642
- 66
- 377
- 442
-
This works well but does not handle unique constraints in table types. For example `create type dbo.mytype as table (x int unique clustered (x))` The SQL text returned will not include the unique constraint. – Ed Avis May 10 '21 at 12:41
-
(You can get the object id from `sys.table_types.type_table_object_id` then look up in `sys.indexes` and `sys.index_columns`, but it would need another big `for xml` section.) – Ed Avis May 10 '21 at 13:37
0
In addition to what vmvadivel said (that works like a charm!!) This is a script to do it for you, just dump that code in there and name the sql file getTypesSelect.sql and this will work:
@echo off
cls
set /p SName=Server Name :
set /p UName=User Name :
set /p Pwd=Password :
set /p DbName=Database Name :
set /p choice=ARE YOU SURE TO EXECUTE SCRIPTS in %DbName% (y/n) ?
if '%choice%'=='y' goto begin
goto end
:begin
if exist addUserDefinedTypes.sql del addUserDefinedTypes.sql
@echo on
SQLCMD -S %SName% -d %DbName% -U %UName% -i "getTypesSelect.sql" -o addUserDefinedTypes.txt -P %Pwd%
rename addUserDefinedTypes.txt addUserDefinedTypes.sql
@notepad addUserDefinedTypes.sql
:end
Remove the following line from the sql query above if you plan to run on a different database (which you probably will)
SELECT 'USE ' + QUOTENAME(DB_NAME(), '[') + '
GO';

Hub3rt
- 113
- 1
- 10