动态传入“表名,字段名,字段类型,默认值”四个字符串,根据新的字段名称和类型来创表表结构
2008-09-15 13:53
471 查看
CREATE FUNCTION dbo.Split --自定义的拆分函数,用来装传入的字符串分隔成表
(
@ItemList VARCHAR(4000),
@delimiter VARCHAR(10)
)
RETURNS @IDTable TABLE (IndexID INT IDENTITY(1,1),Item VARCHAR(50))
AS
BEGIN
WHILE CHARINDEX(@delimiter, @ItemList)>0
BEGIN
INSERT @IDTable SELECT LEFT(@ItemList,CHARINDEX(@delimiter,@ItemList)-1)
SET @ItemList=STUFF(@ItemList,1,CHARINDEX(@delimiter,@ItemList),'')
END
INSERT @IDTable SELECT @ItemList
RETURN
END
CREATE PROC P_Alter_Table
@tb VARCHAR(100), --表名
@fieldsLists VARCHAR(1000), --字段列表
@fieldsTypeLists VARCHAR(1000), --字段类型列表,需要与字段列表一一对应
@DefaultValue VARCHAR(1000) --新增字段默认值,与字段一一对应
AS
BEGIN
DECLARE @sql VARCHAR(8000)
DECLARE @sql1 VARCHAR(8000),@sql2 VARCHAR(8000),@Sql0 VARCHAR(8000)
IF object_id(@tb,'u') IS NULL --若表不存在
BEGIN
SELECT @sql=ISNULL(@sql + ',','') + '[' + a.Item + '] ' + b.Item +' Default '+CHAR(39)+ c.Item +CHAR(39)
FROM dbo.Split(@fieldsLists,',') a
INNER JOIN
dbo.Split(@fieldsTypeLists,',') b
ON a.IndexID=b.IndexID
INNER JOIN dbo.Split(@DefaultValue,',') C
ON a.IndexId=C.IndexId
EXEC('CREATE TABLE [' + @tb + '](' + @sql + ')')
END
ELSE --若表存在
BEGIN
SELECT @sql1='',@sql2='',@sql0=''
SELECT @sql1=@sql1 + CASE WHEN Field IS NULL THEN '['+name+'],' ELSE '' END,--记录待删除列列表
@Sql0=@Sql0 + CASE WHEN Field IS NULL AND CDEFAULT <> 0 THEN (SELECT [NAME] FROM SYSOBJECTS WHERE ID=CDEFAULT) + ',' ELSE '' END, --记录待删除的默认值
@sql2=@sql2 + CASE WHEN Name IS NULL THEN '['+Field+'] ' + FType + ' Default '+CHAR(39)+ DValue + CHAR(39)+',' ELSE '' END --记录待新增列列表
FROM
(SELECT [NAME],CDEFAULT FROM syscolumns WHERE id=object_id(@tb,'u')) a
FULL OUTER JOIN
(
SELECT b.Item Field,a.Item FType,c.Item DValue FROM
dbo.Split(@fieldsLists,',') b
INNER JOIN dbo.Split(@fieldsTypeLists,',') a
ON a.IndexID=b.IndexID
INNER JOIN dbo.Split(@DefaultValue,',') c
ON a.IndexId=c.IndexId
) b
ON name=Field
SELECT @sql1=STUFF(@sql1,LEN(@sql1),1,''),@sql2=STUFF(@sql2,LEN(@sql2),1,''),@sql0=STUFF(@sql0,LEN(@sql0),1,'')
IF LEN(@sql2)>0
EXEC('ALTER TABLE [' + @tb + '] ADD ' + @sql2) --先加原表中不存在的列
IF LEN(@Sql0)>0
EXEC('ALTER TABLE ['+ @TB+ '] DROP CONSTRAINT '+ @Sql0) --删除表中不需要字段的默认值
IF LEN(@sql1)>0
EXEC('ALTER TABLE [' + @tb + '] DROP COLUMN ' + @sql1) --再删除新传入结构中不需要的列
END
END
Eg:
EXEC P_ALTER_TABLE 'A','A1,A2','INT,VARCHAR(10)','0,T'
SELECT * FROM A
(
@ItemList VARCHAR(4000),
@delimiter VARCHAR(10)
)
RETURNS @IDTable TABLE (IndexID INT IDENTITY(1,1),Item VARCHAR(50))
AS
BEGIN
WHILE CHARINDEX(@delimiter, @ItemList)>0
BEGIN
INSERT @IDTable SELECT LEFT(@ItemList,CHARINDEX(@delimiter,@ItemList)-1)
SET @ItemList=STUFF(@ItemList,1,CHARINDEX(@delimiter,@ItemList),'')
END
INSERT @IDTable SELECT @ItemList
RETURN
END
CREATE PROC P_Alter_Table
@tb VARCHAR(100), --表名
@fieldsLists VARCHAR(1000), --字段列表
@fieldsTypeLists VARCHAR(1000), --字段类型列表,需要与字段列表一一对应
@DefaultValue VARCHAR(1000) --新增字段默认值,与字段一一对应
AS
BEGIN
DECLARE @sql VARCHAR(8000)
DECLARE @sql1 VARCHAR(8000),@sql2 VARCHAR(8000),@Sql0 VARCHAR(8000)
IF object_id(@tb,'u') IS NULL --若表不存在
BEGIN
SELECT @sql=ISNULL(@sql + ',','') + '[' + a.Item + '] ' + b.Item +' Default '+CHAR(39)+ c.Item +CHAR(39)
FROM dbo.Split(@fieldsLists,',') a
INNER JOIN
dbo.Split(@fieldsTypeLists,',') b
ON a.IndexID=b.IndexID
INNER JOIN dbo.Split(@DefaultValue,',') C
ON a.IndexId=C.IndexId
EXEC('CREATE TABLE [' + @tb + '](' + @sql + ')')
END
ELSE --若表存在
BEGIN
SELECT @sql1='',@sql2='',@sql0=''
SELECT @sql1=@sql1 + CASE WHEN Field IS NULL THEN '['+name+'],' ELSE '' END,--记录待删除列列表
@Sql0=@Sql0 + CASE WHEN Field IS NULL AND CDEFAULT <> 0 THEN (SELECT [NAME] FROM SYSOBJECTS WHERE ID=CDEFAULT) + ',' ELSE '' END, --记录待删除的默认值
@sql2=@sql2 + CASE WHEN Name IS NULL THEN '['+Field+'] ' + FType + ' Default '+CHAR(39)+ DValue + CHAR(39)+',' ELSE '' END --记录待新增列列表
FROM
(SELECT [NAME],CDEFAULT FROM syscolumns WHERE id=object_id(@tb,'u')) a
FULL OUTER JOIN
(
SELECT b.Item Field,a.Item FType,c.Item DValue FROM
dbo.Split(@fieldsLists,',') b
INNER JOIN dbo.Split(@fieldsTypeLists,',') a
ON a.IndexID=b.IndexID
INNER JOIN dbo.Split(@DefaultValue,',') c
ON a.IndexId=c.IndexId
) b
ON name=Field
SELECT @sql1=STUFF(@sql1,LEN(@sql1),1,''),@sql2=STUFF(@sql2,LEN(@sql2),1,''),@sql0=STUFF(@sql0,LEN(@sql0),1,'')
IF LEN(@sql2)>0
EXEC('ALTER TABLE [' + @tb + '] ADD ' + @sql2) --先加原表中不存在的列
IF LEN(@Sql0)>0
EXEC('ALTER TABLE ['+ @TB+ '] DROP CONSTRAINT '+ @Sql0) --删除表中不需要字段的默认值
IF LEN(@sql1)>0
EXEC('ALTER TABLE [' + @tb + '] DROP COLUMN ' + @sql1) --再删除新传入结构中不需要的列
END
END
Eg:
EXEC P_ALTER_TABLE 'A','A1,A2','INT,VARCHAR(10)','0,T'
SELECT * FROM A
相关文章推荐
- Java 通过JDBC查询数据库表结构(字段名称,类型,长度等)
- SQL根据字符串类型字段进行排序,可以在取值的时候处理
- oracle,如何查看视图结构,获得视图中的字段名称、字段类型、字段长度等。
- IoC组件Unity再续~根据类型字符串动态生产对象
- oracle,如何查看视图结构,获得视图中的字段名称、字段类型、字段长度等。
- Navicat给字段设置为默认值,字符串类型需要加单引号
- 根据字符串名称动态调用Python的函数和对象方法
- Java 通过JDBC查询数据库表结构(字段名称,类型,长度等)
- Java 通过JDBC查询数据库表结构(字段名称,类型,长度等)
- 输入框动态判断数据库中是否有重复(根据企业名称和企业类型)
- javascript实现根据函数名称字符串动态执行函数的方法示例
- Sqlite 修改表名称、增加字段、查询表结构、修改表结构字段类型
- Mysql 一个字段定义成int类型,查询时传入String,会截取字符串
- 使用Linq时,根据特定的字符串名称,找到对应字段并获取值
- 练习 2017-08-22 通过控制台,获取类名,字段名称,字段类型,根据一个模板文件,自动创建这个类文件,并且为字段提供setter和getter方法
- javascript中根据函数名称字符串,动态执行函数
- 根据表名和字段得到约束名称 创建默认值的sql
- Java 通过JDBC查询数据库表结构(字段名称,类型,长度等)
- MySQL中根据format字符串格式化date类型字段值
- Java 通过JDBC查询数据库表结构(字段名称,类型,长度等)