根据Jiten的答案,简化了部分逻辑,考虑了identity
列(使用sys.
表格而不是SCHEMEA
)
CREATE PROCEDURE [dbo].[usp_DefineTypeFromTable]
@TableNames NVARCHAR(500)
AS
BEGIN
DECLARE @TableName NVARCHAR(100)
DECLARE @strSQL NVARCHAR(max)
DECLARE @strSQLCol NVARCHAR(1000)
DECLARE @ColName NVARCHAR(100)
DECLARE @ColDataTaype NVARCHAR(50)
DECLARE @ColDefault NVARCHAR(50)
DECLARE @ColIsNulable NVARCHAR(50)
DECLARE @ColFirst NVARCHAR(50)
DECLARE @ColSecond NVARCHAR(50)
DECLARE @ColID NVARCHAR(50)
DECLARE @ColCompute NVARCHAR(50)
IF LEN(@TableNames) > 0 SET @TableNames = @TableNames + ','
WHILE LEN(@TableNames) > 0
BEGIN
SELECT @TableName = TRIM(LEFT(@TableNames, CHARINDEX(',', @TableNames) - 1))
DECLARE schemaCur CURSOR FOR
SELECT
c.name as column_name,
t.name as [type_name],
c.is_nullable,
convert(nvarchar(4000), object_definition(ColumnProperty(c.object_id, c.name, 'default'))) as column_default,
CASE
WHEN c.collation_name IS NOT NULL THEN c.max_length
WHEN t.name like 'datetime%' THEN c.scale
WHEN c.scale = 0 THEN NULL
ELSE c.precision
END as firstValue,
CASE
WHEN (c.scale = 0 or t.name like 'datetime%') THEN NULL
ELSE c.scale
END as secondValue,
c.is_identity, -- would be best to know seed,increment
c.is_computed -- should really look up col definition. `convert(nvarchar(4000), object_definition(ColumnProperty(c.object_id, c.name, 'computed')))` as computed ?
FROM sys.columns as c join
sys.all_objects as o
on c.object_id=o.object_id join
sys.types as t
on c.user_type_id=t.user_type_id
WHERE
o.type in ('U','V','TF','IF','TT') and --'S' to include built-in tables/types
o.name = @TableName
ORDER BY o.name, c.column_id
OPEN schemaCur
SELECT @strSQL=''
FETCH NEXT FROM schemaCur
INTO @ColName,@ColDataTaype,@ColIsNulable,@ColDefault,@ColFirst,@ColSecond,@ColID,@ColCompute
WHILE @@FETCH_STATUS = 0 BEGIN
-- SELECT @strSQLCol=''
SELECT @strSQLCol= '['+@ColName+'] '+'[' + @ColDataTaype +'] '
IF @ColSecond is NULL
BEGIN
IF @ColFirst is not NULL SELECT @strSQLCol += '(' + @ColFirst + ') '
END
ELSE SELECT @strSQLCol += '(' + @ColFirst +',' +@ColSecond + ') '
IF @ColID>0 SELECT @strSQLCol += ' IDENTITY(1,1)'
IF @ColIsNulable>0 SELECT @strSQLCol += 'NULL'
ELSE SELECT @strSQLCol += ' NOT NULL'
IF @ColDefault IS NOT NULL SELECT @strSQLCol += ' DEFAULT(' +@ColDefault + '),'
ELSE SELECT @strSQLCol += ','
SELECT @strSQL += @strSQLCol
--print @strSQL
FETCH NEXT FROM schemaCur
INTO @ColName,@ColDataTaype,@ColIsNulable,@ColDefault,@ColFirst,@ColSecond,@ColID,@ColCompute
END
CLOSE schemaCur
DEALLOCATE schemaCur
SELECT @strSQL=left(@strSQL, len(@strSQL)-1)
IF EXISTS (SELECT * FROM sys.types WHERE IS_TABLE_TYPE = 1 AND name = 'tt_' +@TableName)
BEGIN
EXEC('DROP TYPE tt_' +@TableName )
END
SELECT @strSQL = 'CREATE TYPE tt_' + @TableName + ' AS TABLE (' + @strSQL + ')'
-- print @strSQL
EXEC (@strSQL)
SELECT @TableNames = SUBSTRING(@TableNames, CHARINDEX(',', @TableNames) + 1, LEN(@TableNames))
END
END