如何先update数据,如不存在再插入! (100分)

  • 主题发起人 主题发起人 yangh
  • 开始时间 开始时间
Y

yangh

Unregistered / Unconfirmed
GUEST, unregistred user!
我用的是Tquery控件!该表userinfo有两个字段,
number numeric,
username char(20),
我从一文本文件逐行读入数据,如果在表中存在从文本中读入电话号码存在则update,
如果电话号码不存在,则insert,如何更新表?
怎样最快,
目前想采取这种方式,不管存不存在,先update,根据sqlcode值,如果失败再insert,
但是再delphi中,如何得到sqlcode??
高手指点!我用的是sybase!
 
讲清楚些!
 
建一个忽略重复值的唯一索引。
 
delphi好像不行
不过你可以先select,然后检查输出值来判断是否存在
 
也可以先 delete 文本中存在的号码,再把文本中的号码全部插入
 
如果是逐行更新就简单了,在每次UPDATE后,用TQuery.RowsAffected来判断更新是否影响到数据表,
如果RowsAffected=0,就INSERT INTO。
 
用batchmove控件可以很容易办到, batchmove有一种数据复制方式叫插入并更新方式
(batAppendUpdate), 可以满足你的要求, 但是一定要设置主键

如果要用SQL , 不是一句SQL能搞定的
但是一定要设置主键, 以判断表中记录是否存在
另外, 可以用ODBC连接文本文件
 
try
// update
except
// insert into
end;
 
各位!我用batchmove时!提示字符集不对cp850,
can not find requested character set in syscharset name=cp850,
但是别的操作都行!
怎样让它好使呢!
 
EASY啦,做法如下:

先设Query的SQL为如下内容:
“SELECT * FROM Telephone
WHERE Number = :Number”
然后在读入电话资料后
where not 电话号码文件.eof do
begin
username := 取得用户名字;
 tele := 取得电话号码;
Query.Close;
Query.Parameters.ParamByName('Number').Value := tele;
 //如果你的Query不是ADOQuery的话,上面那句要做相应改变,这你会吧
 //如果不会就多看看帮助文件,自学是一个很好的进步方法。
Query.Open;
if Query.RecordCount = 0 then
//此处写你的增加记录的代码
else
//此处写你的更新资料的代码,此处要注意的是:如果没有给Number加唯一索引
  //那么可能会找出多条记录,这也得相应地处理一下。
end;
 
大哥!我的表可能有70万条记录,不慢吗》?
 
用存储过程最好,传入参数.
if exists(select .....) then
updata .....
else
insert ....
 
这样啊,有办法啊,也很easy啦:

下面说做法。
1、在数据库建立一表TMP_UserInfo,结构和UserInfo一样(只有两个字段是吧)
2、将文本文件中的数据全部到表TMP_UserInfo。
3、更新UserInfo表,做法如下:
procedure UpdateUserInfo;
begin
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.ADD('UPDATE UserInfo set UserName= (SELECT UserName ');
Query1.SQL.ADD(' FROM TMP_UserInfo WHERE Tele = UserInfo.Tele)');
//注意在加第二行时前面加了个空格。
Query1.SQL.ADD(' WHERE UserInfo.Tele IN(SELECT Tele FROM TMP_UserInfo)');
Query1.ExecSQL;//没有返回结果集,用ExecSQL;
end;

procedure InsertUserInfo;
begin
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.ADD('INSERT INTO UserInfo (UserName, Tele) ');
Query1.SQL.ADD(' SELECT UserName, Tele FROM TMP_UserInfo ');
Query1.SQL.ADD(' WHERE TMP_UserInfo.Tele NO In (SELECT Tele FROM UserInfo)');
Query1.ExecSQL;
end;
清除TMP_UserInfo的内容以准备下次任务。
procedure ClearTMP_UserInfo]
begin
//这部份代码不用给了吧,用SQL语句"DELETE FROM TMP_UserInfo"
end

更新部份的SQL语句:
UPDATE UserInfo set UserName= (SELECT UserName FROM TMP_UserInfo WHERE Tele = UserInfo.Tele)
WHERE UserInfo.Tele IN(SELECT Tele FROM TMP_UserInfo)
插入的SQL语句:
INSERT INTO UserInfo (UserName, Tele)
SELECT UserName, Tele FROM TMP_UserInfo
WHERE TMP_UserInfo.Tele NOT In (SELECT Tele FROM UserInfo)
**注意**
在执行这些SQL语句之前请备份好有用的数据,以免意外。
或者另做两个表测试一下,我这里给出的可能有错误,但思路是对的。
上面的SQL语句在Paradox7上测试通过。
 
to yhaochuan:
我上一次是这么做的,但是慢!集合操作一次更新所有的数据!
是否可以控制每次提交的数量?
 
可以这么做吧。
先设定关键字段(如电话号码),
然后直接把所有记录先Insert,
如果出错的话再进行Update,
不知道是否可以提高速度。(这样就省去了Select花费的时间)
 
你有没有在UserInfor上做主键?比如将电话号码做为主健(Parimary key)
将TMP_UserInfo也用电话号码做主键会不会快些?
你说“我上一次是这么做的,但是慢!”
大概要花多少时间?我想十几秒钟应该够了吧。
你在SYSBASE中建立一存贮过程去做Update,Insert, delete(tmp_userinfo)这三个
动作试试。
 
多人接受答案了。
 
后退
顶部