数据库字段变化问题(100分)

  • 主题发起人 主题发起人 hnzgw
  • 开始时间 开始时间
H

hnzgw

Unregistered / Unconfirmed
GUEST, unregistred user!
提出问题:
A表
序号,标识,类型
1 f1 char
2 f2 char
3 f3 char
. . .
. . .
. . .
n fn char

表B中的字段是根据表A中的记录来建立的如
xh f1 f2,f3....fn
1 10 20 30
2 50 40 25
3 6 42 64
问题是我如果在表A中删除某一条记录时,表A中的记录要从f1,f2,f3....fn重新进行排列
一次,那表B中的字段也要从f1,f2,f3....fn排列一次,重要的是表B中每一个字段已经有
记录了,记录要和字段一一对应,怎样写代码,各种高手,帮帮忙,给个答案,我愿献出
全部的分数,这个问题困扰我半个月了,因为这个问题在做动态工资系统时十分有用!!
 
太模糊了,原代码发过来看看,我给你调
 
我写的已经很清楚了,就是两个表,表A和表B,表A的记录是表B的字段,当表A的记录改变时,表
B的字段也要改动,问题是表B中有记录.
 
各位高手,是否还用不明白的
 
如果是SQL SERVER的话,很好办,用触发器吧!
 
用触发器
 
触发器不可以的——触发器中变化表是不允许修改的(有可能是死循环)!

你这个表结构是不可取得:一个很重要的原因,一个表中的字段数是有限制的(Oracle中最
多可以有254列,其他不清楚),这样的表结构会限制应用程序的扩展性。

所以建议修改表结构。

你非要这么做也可以:在程序中删除某一字段后,将这个字段后面的字段依次改名即可。
 
我用的数据库是SQLSERVER,其表A中的记录一般不会很多,最多也不会超过50个,所以说表B中的
字段也不会很多了,高手们再想想,怎么做,给点代码吧,这个问题做动态工资时很实用
 
>>触发器不可以的——触发器中变化表是不允许修改的(有可能是死循环)!
如果是MS SQL SERVER 2K 则是可以的,前提是设置为触发器调用不递归,这是缺省值。
 
触发器确实不可以。
我的解决办法是再加一个表,其中记录了表A中行同表B中列(即字段)的关系,这样的话,
应该可以了。
 
好办,根据表A建立动态sql语句,用sp_executeSQL系统存储过程执行即可

查sp_executeSQL的在线帮助,相信你会有收获
 
既然几位兄弟都说触发器不行,那我就用触发器给你解决这个问题。

设表A有‘序号’、‘标识’、‘类型’字段
设B表有‘序号’及根据A表记录动态生成的字段,代码如下。
在SQL SERVER2K下调试通过。

解决问题(用触发器):

--删除触发器
CREATE TRIGGER [OnDeleteToAlterTableB] ON [dbo].[A]
FOR DELETE
AS
DECLARE @BS VARCHAR(50)
SELECT @BS=标识 FROM DELETED

BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
EXEC(' ALTER TABLE dbo.B DROP COLUMN ' + @BS)
COMMIT


--更新触发器
CREATE TRIGGER [OnUpdateBS] ON [dbo].[A]
FOR UPDATE
AS
DECLARE @BS VARCHAR(50) , @BS_OLD VARCHAR(50)
IF UPDATE(标识)
BEGIN
SELECT @BS_OLD=标识 FROM DELETED
SELECT @BS=标识 FROM INSERTED
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
SET @BS_OLD = 'dbo.B.' + @BS_OLD
EXECUTE sp_rename @BS_OLD, N'Tmp_field2', 'COLUMN'

EXECUTE sp_rename N'dbo.B.Tmp_field2', @BS, 'COLUMN'
COMMIT
END


--插入触发器
CREATE TRIGGER [OnInsert] ON [dbo].[A]
FOR INSERT
AS
DECLARE @BS VARCHAR(50) , @LX VARCHAR(50)
SELECT @BS=标识, @LX=类型 FROM INSERTED

BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
EXEC(' ALTER TABLE dbo.B ADD ' + @BS +' '+@LX +' '+' NULL')
COMMIT
 
多人接受答案了。
 
你的b表是随A表记录的变化而动态生成的。
你只有先创建一个临时表,把数据放入 ,然后把b表中的字段删除,再把临时表的数据插入b表中,
我最近做的,一定行的。如果你用的SQL SEVER数据库,可以删除空表的一个字段,如果是ORACAL数据库,就不能删除一个字段,必须删除表。
 
后退
顶部