关于表中有标识列的插入问题

烤火的鱼 2013-04-26 07:03:38
我有两个表(当前表,历史表),除历史表多一个自增长的标识列(假如名称为ID)以外,其他结构完全一样,假如从F1到Fn,我需要经常将当前表中的数据插入到历史表中,如果没有标识列,通常这么写:
insert into 历史表 select @x as id,* from 当前表
因为有标识列,这么写肯定不行,通常的做法是:
insert into 历史表(f1,f2,....fn) select * from 当前表
但这样写太麻烦,尤其是如果表结构变了(两个表同时会改变,比如增加一列),上面的f1到fn的列名要重新写一遍,非常不方便,有没有简单的办法,比如(当然,下面的方法是不行的,我只是想表达一下我偷懒的想法):
insert into 历史表
select auto,* from 当前表 where....
也就是说,无论两个表结构怎么变,我根本不需要去动存储过程
...全文
141 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
烤火的鱼 2013-04-29
  • 打赏
  • 举报
回复
无论如何,至少我们的处理思路是一样的,我其实做的是一个GPS数据接收,收到一条定位信息后,更新当前记录(一个车牌号就一条当前记录,便于客户端更新当前状态),同时,将这条记录写到历史库中,便于查询历史轨迹,说白了,相当于下面几句话: update 当前记录 set GPS信息=XXX WHERE 车牌号=XXX IF @@ROWCOUNT=0 INSERT INTO 当前记录 (GPS信息,车牌号) values.... insert into 历史记录 select * from 当前记录 where 车牌号=XXXX 因为历史记录很多,用ID做主键便于插入相关附加信息,同时,并发量很大,因此,用标识列而不是手工计算ID
daiyueqiang2045 2013-04-27
  • 打赏
  • 举报
回复
如果这个两个表结构除了标识列不存在之外,其他全部相同。 使用*,我感觉没有任何问题,这个我是用过的,数据量500W而,现在运行正常。 只是当时没有考虑使用增量式更新数据,发现更新速度慢。所以如果下一次设计的时候,建议使用增量式 不用动态拼接SQL语句,也不用显示的列出表的列,个人愚见。
烤火的鱼 2013-04-27
  • 打赏
  • 举报
回复
我也是通过上面的思路通过手工写到存储过程里面实现的,而且也不用考虑字段的先后顺序了,只不过觉得该方法笨了点,以为有更合理的方式,我的代码如下: --定义当前表/历史表表名 DECLARE @tbCur NVARCHAR(50),@tbHistory NVARCHAR(50) SELECT @tbCur='testcur',@tbHistory='testHis' --查询当前表的字段名 DECLARE @FieldList NVARCHAR(MAX) SELECT @FieldList='' SELECT @FieldList=@FieldList+B.NAME+',' FROM sysobjects A,syscolumns B WHERE A.id=b.id AND A.name=@tbCur AND A.TYPE='U' IF LEN(@FieldList)=0 RETURN --去掉最后一个逗号 SELECT @FieldList=LEFT(@FieldList,LEN(@FieldList)-1) --动态创建插入用的Sql语句 DECLARE @strSql NVARCHAR(MAX) SELECT @strSql='INSERT INTO '+@tbHistory+'('+@FieldList+') select '+@FieldList+' FROM '+@tbCur EXECUTE(@strSql)
daiyueqiang2045 2013-04-26
  • 打赏
  • 举报
回复
insert into 历史表 select auto,* from 当前表 where.... 这个思路我感觉可以,我现在使用的就是这个思路。可以插入数据 但重要的是你的数据量是不是很大,如果数据量大的话,建议增量式插入当前表。
發糞塗牆 2013-04-26
  • 打赏
  • 举报
回复
这个是动态显式列名,这样你就不用担心表结构的更新
DECLARE @s NVARCHAR(4000)
SET @s = ''
SELECT  @s = @s + ',' + QUOTENAME(name)
FROM    syscolumns
WHERE   id = OBJECT_ID('表名')
        AND name NOT IN ( '不希望显式的列' )
SET @s = STUFF(@s, 1, 1, '')
EXEC('select '+@s+' from 表名  ')
烤火的鱼 2013-04-26
  • 打赏
  • 举报
回复
肯定是一致的,这是前提
daiyueqiang2045 2013-04-26
  • 打赏
  • 举报
回复
如果那么写的话,列设计顺序一定要一样,否则插入的列会出现问题。 我之前做的程序中,就出现了问题。因为表中添加字段的在顺序上不对应,使用*要注意这个

22,210

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧