Sql高手请进!谁能给出最佳代码?100分!!!

nols001 2010-10-12 11:27:32
DataBase:HD1
Table:dbo.AB
Id Uid Value
1 001 1
Tabel:dbo.AC
Id ABid Value
1 1 01
2 1 01

DataBase:HD2
Table:dbo.AB
Id Uid Value
1 001 1
2 009 9
Tabel:dbo.AC
Id ABid Value
1 2 09
2 2 09

Id 自动增长列(主键)
ABid 对应自动编号(AB表中的自动增长列)

HD1、HD2两个结构完全相同的数据库。现将HD2里的数据导入HD1,要求导入Uid字段不重复的条目。
AB和AC表之间唯一的关系就是id对应Uid。没有任何约束或主外键关系。
...全文
170 点赞 收藏 26
写回复
26 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
nols001 2010-10-13
[Quote=引用 16 楼 chuifengde 的回复:]

SQL code

declare @a table(id int,Uid varchar(20),Value int)
DECLARE @b TABLE(ABid INT,VALUE INT)

insert @a select A.* from HD2.dbo.AB A Left Join HD1.dbo.AB B ON A.Uid=B.Uid and B.Uid is NULL

ins……
[/Quote]
不仅是这样...再次导入的话,还会出现另外一种问题,就是ABid不会随Id改变了....
回复
nols001 2010-10-13
[Quote=引用 16 楼 chuifengde 的回复:]

SQL code

declare @a table(id int,Uid varchar(20),Value int)
DECLARE @b TABLE(ABid INT,VALUE INT)

insert @a select A.* from HD2.dbo.AB A Left Join HD1.dbo.AB B ON A.Uid=B.Uid and B.Uid is NULL

ins……
[/Quote]
运行到是成功了,但是....Uid相同的也别导入了~~~
回复
nols001 2010-10-13
[Quote=引用 15 楼 sqlcenter 的回复:]

SQL code
-- 获取HD1.dbo.AB当前标识
declare @curident int
set @curident=ident_current('HD1.dbo.AB')

-- 利用row_number影射新的ABid, 插入AC
;with cte as
(
select newABid = row_number()over(order by Id)+@curiden……
[/Quote]
报错:
消息 4104,级别 16,状态 1,第 6 行
无法绑定由多个部分组成的标识符 "b.ABid"。
消息 4104,级别 16,状态 1,第 6 行
无法绑定由多个部分组成的标识符 "b.Value"。
回复
juge001 2010-10-12
上面的错了,用临时表的办法可行。稍微整理一下,用临时表
[Quote=引用 12 楼 jstoic 的回复:]
SQL code

DECLARE @max INT
SELECT @max = MAX(id) FROM HD1.dbo.AB

INSERT INTO HD1.dbo.AB(Uid,[VALUE])
SELECT a.Uid,a.[VALUE] FROM
HD2.dbo.AB a WHERE
NOT EXISTS
( SELECT * FROM HD1.dbo.AB c W……
[/Quote]
回复
juge001 2010-10-12
[Quote=引用 19 楼 zhangyangziwo 的回复:]
直接将自增列也导过去不就行了
SET IDENTITY_INSERT
[/Quote]

如果程序允许的话,可以用这个办法
回复
zhangyangziwo 2010-10-12
直接将自增列也导过去不就行了
SET IDENTITY_INSERT
回复
SQLCenter 2010-10-12
newABid = row_number()over(order by Id) * ident_incr('HD1.dbo.AB') + @curident
回复
SQLCenter 2010-10-12
identity列的步长都是1吧,如果不是,就要调整影射newABid部分。
回复
chuifengde 2010-10-12

declare @a table(id int,Uid varchar(20),Value int)
DECLARE @b TABLE(ABid INT,VALUE INT)

insert @a select A.* from HD2.dbo.AB A Left Join HD1.dbo.AB B ON A.Uid=B.Uid and B.Uid is NULL

insert HD1.dbo.AB(Uid,Value) select Uid,Value from @a

insert @b SELECT A.ABid,A.Value from HD2.dbo.AC A inner join @a B on A.ABid=B.id

UPDATE C SET ABid=A.id from HD1.dbo.AB A inner join @a B
on A.Uid=B.Uid inner JOIN @b C ON B.id=C.ABid

INSERT HD1.dbo.AC(ABid,Value) SELECT * FROM @b
回复
SQLCenter 2010-10-12
-- 获取HD1.dbo.AB当前标识
declare @curident int
set @curident=ident_current('HD1.dbo.AB')

-- 利用row_number影射新的ABid, 插入AC
;with cte as
(
select newABid = row_number()over(order by Id)+@curident, * from HD2.dbo.AB t where not exists (select 1 from HD1.dbo.AB where Uid=t.Uid)
)
insert HD1.dbo.AC select a.newABid, b.Value from cte a join HD2.dbo.AC on a.Id=b.ABid

-- 插入AB
insert HD1.dbo.AB select Uid, Value from HD2.dbo.AB t
where not exists (select 1 from HD1.dbo.AB where Uid=t.Uid)
order by Id
回复
nols001 2010-10-12
[Quote=引用 11 楼 zsh0809 的回复:]

分两次导入就可以了,参考,没有测试

SQL code
----导入AB
INSERT INTO HD1.dbo.AB
SELECT * FROM HD2.dbo.AB d2
WHERE uid NOT IN (SELECT distinct uid FROM HD1.dbo.AB)

----导入AC
INSERT INTO HD1.dbo.AC
SELECT * FROM HD2.db……
[/Quote]
肯定不行的,导入AC时,ABid肯定要绑定为新的id,因为导入AB时,原来的Id肯定会变成新的。
回复
nols001 2010-10-12
[Quote=引用 12 楼 jstoic 的回复:]

SQL code

DECLARE @max INT
SELECT @max = MAX(id) FROM HD1.dbo.AB

INSERT INTO HD1.dbo.AB(Uid,[VALUE])
SELECT a.Uid,a.[VALUE] FROM
HD2.dbo.AB a WHERE
NOT EXISTS
( SELECT * FROM HD1.dbo.AB c WHERE c.……
[/Quote]
Uid不重复是不可能的......
回复
jstoic 2010-10-12

DECLARE @max INT
SELECT @max = MAX(id) FROM HD1.dbo.AB

INSERT INTO HD1.dbo.AB(Uid,[VALUE])
SELECT a.Uid,a.[VALUE] FROM
HD2.dbo.AB a WHERE
NOT EXISTS
( SELECT * FROM HD1.dbo.AB c WHERE c.Uid = a.Uid)

INSERT INTO HD1.dbo.AC(ABid,[VALUE])
SELECT c.id,b.[VALUE] FROM
HD2.dbo.AB a JOIN HD2.dbo.AC b ON a.id = b.ABid JOIN HD1.dbo.AB c ON a.Uid = c.Uid
WHERE c.id > @max



前提是AB表的Uid都不会重复.如果有重复,又要麻烦点,要建临时表存储插入HD1.dbo.AB时记录HD2.dbo.AB 的主键值
回复
zsh0809 2010-10-12
分两次导入就可以了,参考,没有测试

----导入AB
INSERT INTO HD1.dbo.AB
SELECT * FROM HD2.dbo.AB d2
WHERE uid NOT IN (SELECT distinct uid FROM HD1.dbo.AB)

----导入AC
INSERT INTO HD1.dbo.AC
SELECT * FROM HD2.dbo.AC d2
WHERE ABid NOT IN (SELECT distinct ABid FROM HD1.dbo.AC)
回复
nols001 2010-10-12
[Quote=引用 7 楼 zsh0809 的回复:]

1,这两个DB是否在同一台服务器上?
如果是,前面直接加上DB名称就可以访问,否则,需要建立linkserver等访问方式。

2,要求导入Uid字段不重复的条目
====
这句话中的“不重复”是指HD2中重复的就导入一次,还是HD1中有了这个Uid就不用重复导入了?
[/Quote]
是在同一服务器上,HD1有的Uid就不进行导入。
回复
kevn 2010-10-12
[Quote=引用 5 楼 nols001 的回复:]
问题就是在于导入后的AB.id必须对应AC.ABid,导入AB后id肯定会变,那ABid肯定也得跟着变。
[/Quote]

用@@indentity得到新的自增主键,然后写触发器更改导入后的AC的abid
回复
billpu 2010-10-12
如果是一个实例 可以用database.owner.table的方式直接访问比如
insert into hd1.dbo.ab select id,uid,value from hd2.dbo.ab where uid not in (select uid from hd1.dbo.ab)


回复
zsh0809 2010-10-12
1,这两个DB是否在同一台服务器上?
如果是,前面直接加上DB名称就可以访问,否则,需要建立linkserver等访问方式。

2,要求导入Uid字段不重复的条目
====
这句话中的“不重复”是指HD2中重复的就导入一次,还是HD1中有了这个Uid就不用重复导入了?
回复
kevn 2010-10-12
两个数据库相同表自增ID是不一样的吧

insert into hd1..ab (uid,value) select uid,value from hd2..ab where hd1..ab.uid <>hd2..ab.uid and hd1..ab.value <>hd2..ab.value

回复
nols001 2010-10-12
问题就是在于导入后的AB.id必须对应AC.ABid,导入AB后id肯定会变,那ABid肯定也得跟着变。
回复
加载更多回复
相关推荐
发帖
疑难问题
创建于2007-09-28

2.1w+

社区成员

MS-SQL Server 疑难问题
申请成为版主
帖子事件
创建了帖子
2010-10-12 11:27
社区公告
暂无公告