运行期更改表结构绝对不可取,用户自定义字段实际上实现起来相当容易。例如:产品表设计如下: Product id int primary key, type int, title varchar(100), -- 一些公用属性,如title, price price float但是mp3和book会有完全不同的属性,比如mp3有容量,book有作者,如果要动态存储属性,可以再定义Property表: Property id int primary key, product_id int foreign key, name varchar(100), -- 属性名称 type int, -- 属性类型:int, float, String? value varchar(100), -- 属性值这样你在查询某一Product时再查询其关联的全部Property就得到完整属性
如果在运行时定义结构,那么可解决的办法是使用动态sql,比如我们定义一个可变的列,我们变可以控制其字段名和类型等,例如 USE master GO--define variable DECLARE @column varchar(30) DECLARE @sql nvarchar(max)--set column name SET @column=N'name varchar(30)'--set create table SET @sql = N'USE tempdb IF OBJECT_ID(''tempdb..#temp'') IS NOT NULL DROP TABLE #temp CREATE TABLE #temp(ID int primary key , '+@column+') exec sp_help #temp' --view table structure --execute sql EXEC sp_executesql @sql
然后用户一应用那调用过程在库中生成相应真实的表,并把生成的表名关联给用户所有调用的地方用动态SQL
不过,确实不提倡
创建一个网页文件,文件名为 test.htm,代码为:<html>
<head>
<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>向表中增添新列</title>
</head>
<body>
<form method="POST" action="addcolumn.asp">
<p>你将要对表tb1增加一个新列:</p>
<p>输入你要新增加列的列名:<input type="text" name="newcol" size="20"></p>
<p>输入你要修改表的数据类型:<input type="text" name="datatype" size="20"></p>
<p><input type="submit" value="提交" name="B1"></p>
</form>
</body>
</html>再创建一个ASP网页,代码为:<%
dim myConn,addstr
set myConn = Server.CreateObject("ADODB.Connection")
myConn.ConnectionString= "driver={SQL Server};server=myservername;uid=sa;pwd=mypassword;database=mydatabase"
myConn.openaddstr="alter table tb1 add " & request.form("newcol") & " " & request.form("datatype")
myConn.execute(addstr)myConn.close
set myConn=nothing
%><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>增加成功</title>
</head><body>
你向数据库表 tb1 中插入了一列,请向该列中添加适当的数据。
</body></html>
这样,用户就可以通过网页向你的数据库插入新列了.
上面ASP的VBScript中的服务器名/用户名/密码必须真实有效.
别,千万别让用户改你的表结构,表结构的修改设计人员的事情,表结构的使用是开发人员的事情。
数据的使用才是用户的事情。
这些关系千万要搞清楚。至于你说的动态数据问题,可以通过记录来实现,有很多方法,有一个简单的你可以参考:
http://topic.csdn.net/u/20080322/15/428e23e4-7cc7-466d-88c6-9700f1d4a6bf.html
例如:webConfig里的东西你存储到表里。2,一对多关系 ,一张表包含另外一个表的主键作为外键。
例如:手机.品牌id=2, 这里的2是[品牌名称表]的id字段为2的纪录,品牌名称是"Nokia"。一个手机只能有一个品牌。3,多对多,需要2张表,有一个包含两个外键的关系表。
例如: 手机1即属于"智能" 又属于"滑盖"组的, 一个组包含多个手机,一个手机可以属于多个组。4,树型结构,常见的两钟:父ID设计和001002编码设计。
例如:手机的经销商分为 省/市/县5,“多态”结构和多对多略有不同,如果需求中某表字段多少类型有非常大的不确定性,可以采用3个表来完成:一个[主表](ID),
一个[属性名称表](属性ID.属性名称),
一个[属性值表],包括3个字段:
属性值(属性Value varchar(500))
主表ID
属性ID这样可以作到最小冗余度。
(和常见的多对多关系不同的是:值统一用varchar来存储,因为这类型的值一般不会用来计算)。比如:手机型号有几千种,除了共同属性外还有不同属性有几百个,属性名和值类型都不一样,有的手机有这属性,有的没有。
对于这样的“多态”,我们就采用上面的设计结构。
其效果相当于:某奇怪手机.属性集合["某某奇怪属性名"]="某某奇怪值";
某变态手机.属性集合["某某变态属性名"]="某某变态值";这样的属性本身有无是不确定的,值类型也不确定,根本无法用字段来表示的。
恩,SAP的一些产品的数据库我也比较了解,的确可以用户自定义表和自定义字段。
主要方便实施时灵活,和二次开发使用。
Product
id int primary key,
type int,
title varchar(100), -- 一些公用属性,如title, price
price float但是mp3和book会有完全不同的属性,比如mp3有容量,book有作者,如果要动态存储属性,可以再定义Property表:
Property
id int primary key,
product_id int foreign key,
name varchar(100), -- 属性名称
type int, -- 属性类型:int, float, String?
value varchar(100), -- 属性值这样你在查询某一Product时再查询其关联的全部Property就得到完整属性
USE master
GO--define variable
DECLARE @column varchar(30)
DECLARE @sql nvarchar(max)--set column name
SET @column=N'name varchar(30)'--set create table
SET @sql = N'USE tempdb
IF OBJECT_ID(''tempdb..#temp'') IS NOT NULL
DROP TABLE #temp
CREATE TABLE #temp(ID int primary key ,
'+@column+')
exec sp_help #temp' --view table structure
--execute sql
EXEC sp_executesql @sql
1,用户有自定义字段的需求是很正常的,绝对不算是无理取闹.
2,让用户可以修改数据库结构的做法是很不可取的,这样做可能会对数据库产生灾难性的影响.解决方案有很多种,我推荐一种简单的做法.
自定义字段单独作为一张表存在,表中有一列作为外键关联到需要自定义字段的表中.在查询数据时一并查询是否有关联的自定义字段,如果有作为一个列显示.
这个方法是bug管理系统Mantis关于自定义字段的解决方法,个人认为比较好.
一个[属性名称表](属性ID.属性名称),
一个[属性值表],包括3个字段:
属性值(属性Value varchar(500))
主表ID
属性ID
如果是ERP或者相关的系统,还要设计一个字段定义这个表A是哪个模块的.这样方便分类.否则会乱套的.
2.写几个公共函数,在每个Form或者页面加载的时候,判断是否需要将该自定义的列显示出来,在SUID(Select,Update,Insert,Delete)的语句中,需要判断是否有自定义的列,然后产生相应的SUID修改语句.如果是存储过程来完成SUID的操作话,还要稍微麻烦一点点.因为具体的代码和设计文档已经找不到,很早以前设计过的了,凭记忆写来来的.
总的来说,如果是开发产品的话,这种花哨的功能少些比较好,我记得当时我们这个开发出来,有Customer在用,但是不多,当然,功能非常好,但是,与其花大量的时间来开发这样一个功能,不如多在产品的稳定性,数据的正确性,操作易用性等等方面下功夫,这样更好.单纯以功能大而全来做竞争的产品,经验好像都做的不长的!
-------------
你说的对啊
用的时候把表定义xml+数据xml生成xml用xpath操作就可以了。
我的问题是关于报表的.
设计一个通用报表的接口,数据源(要在报表中显示的)中的表结构是未知的,比如:A数据库里的a表有4行4列,B数据库里的b表8行6列,但可以在程序中生成相应的报表。小弟是一点思路都没有。