| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2713 人关注过本帖
标题:关于DELETE - SQL 命令的问题
只看楼主 加入收藏
panpende
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:4
帖 子:528
专家分:963
注 册:2009-4-27
结帖率:90.91%
收藏
已结贴  问题点数:20 回复次数:18 
关于DELETE - SQL 命令的问题
如同在UPDATE - SQL 命令中遇到的问题一样,在DELETE - SQL 命令中同样遇到。
SET TALK OFF
SET SAFETY OFF
SET CENTURY ON
SET EXACT ON
SET DATE YMD
SET SYSMENU OFF
CLEAR ALL
CLOSE DATABASES
CD D:\BDS
CREATE DBF L1 (A1 C(10), A2 C(10),A3 N(2)) &&建立表
FOR X=1 TO 8
Y=STR(X,1)
APPEND BLANK
REPLACE A1 WITH 'SJA'+Y,A2 WITH 'SJB'+Y,A3 WITH X
ENDFOR
COPY TO L2 FOR A3<6
INDEX ON A3 TAG A1
SELECT 0
USE L2
DELETE FOR A3=3
PACK
INDEX ON A3 TAG A1
SELECT L1
SET RELATION TO A3 INTO L2
DELETE FROM L1 WHERE L1.A3=L2.A3
*DELETE FOR L1.A3=L2.A3
BROWSE
RETURN

程序段是想在L1表中,删除L2表有的记录,关键字段是A3。但是上述程序只能删除第一条记录。采用 DELETE FOR L1.A3=L2.A3 是能达到目的的。为什么?

搜索更多相关主题的帖子: 问题 
2012-02-07 14:17
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:10 
經過前面程序的測試,我覺得原因應該是這樣:SQL指令是先把查詢結果複製到內存中一個臨時表的,原因是後面允許很複雜的查詢動作,不可能在原表中完成,所以它必須把全部符合要求數據歸集起來生成一張臨時表,再對這個表進行實際動作。在你的命令中,WHERE L1.A3=L2.A3,是一個查詢表達式,因為它不是常數,所以馬上運算為WHERE L1.A3="1"(因為UPDATE L1指定L1是動作表,所以L1的字段是變量,非L1的表達式取運算結果求解),把這個數據集合提取出來後,才執行SET更新動作。

要解決這個問題,WHERE條件中不能那樣寫,要是一個可變的函數才行。

授人以渔,不授人以鱼。
2012-02-07 15:04
lygcw9603
Rank: 5Rank: 5
等 级:职业侠客
威 望:1
帖 子:233
专家分:357
注 册:2006-8-27
收藏
得分:0 
回复 楼主 panpende
在L1表中删除L2表中A1还是A2
2012-02-07 15:05
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
SQL指令的操作辦法,是把L1和L2合併成一張表(用L1.A3=L2.A3條件把記錄對應橫拼起來),再做動作。兩張表合併的結果,重複的字段名有標識分離,按新形成的字段名操作。

授人以渔,不授人以鱼。
2012-02-07 15:23
panpende
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:4
帖 子:528
专家分:963
注 册:2009-4-27
收藏
得分:0 
lygcw9603老师,我很抱歉。我过于简单的表述,产生疑问。我的题意是以A3字段为关键字段,在L1中删除和L2.A3数据相同的记录。以例题来说就是在L1表中,删除A3=1,2,4,5 这4个记录,因为在L2中都有。
2012-02-07 15:29
panpende
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:4
帖 子:528
专家分:963
注 册:2009-4-27
收藏
得分:0 
TonyDeng老师对SQL指令的介绍,使我进一步了解SQL指令认识。请老师们继续指教。
2012-02-07 15:37
lygcw9603
Rank: 5Rank: 5
等 级:职业侠客
威 望:1
帖 子:233
专家分:357
注 册:2006-8-27
收藏
得分:4 
以下是引用panpende在2012-2-7 15:29:42的发言:

lygcw9603老师,我很抱歉。我过于简单的表述,产生疑问。我的题意是以A3字段为关键字段,在L1中删除和L2.A3数据相同的记录。以例题来说就是在L1表中,删除A3=1,2,4,5 这4个记录,因为在L2中都有。
把UPDATE贴子的内容稍改一下即可使用
2012-02-07 15:40
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
前一個程序,用如下方法可以實現目的(此時其實無需SET RELATION),這個也一樣。

SET TALK OFF
 SET SAFETY OFF
 SET CENTURY ON
SET EXACT ON
 SET DATE YMD
SET SYSMENU OFF
 CLEAR ALL
 CLOSE DATABASES
* CD D:\BDS
 CREATE DBF L1 (A1 C(10), A2 C(10),A3 N(2)) &&建立表
 FOR X=1 TO 8
 Y=STR(X,1)
 APPEND BLANK
 REPLACE A1 WITH 'SJA'+Y,A2 WITH 'SJB'+Y,A3 WITH X
 ENDFOR
 LIST
COPY TO L2 FOR A3<6
 INDEX ON A3 TAG A1
 SELECT 0
 USE L2
 DELETE FOR A3=3
 PACK
 LIST
 WAIT
 INDEX ON A3 TAG A1
 SELECT L1
 SET RELATION TO A3 INTO L2
 *UPDATE L1 SET L1.A1=L2.A2 from L2 WHERE L1.A3=L2.A3 &&此命令在9.0可以,8.0出错
 UPDATE L1 SET A1 = "u" + L2.A2 WHERE Condition(L1.A3)
* SELECT L1        && by Tony
* REPLACE ALL L1.A1 WITH "U"+L2.A2 FOR L1.A3=L2.A3  &&此命令在更改关联方法后也不能达到预想的目的
 BROWSE
 RETURN
 
 FUNCTION Condition(tValue)
     SELECT L2
     SEEK tValue
     RETURN FOUND()
 ENDFUNC

授人以渔,不授人以鱼。
2012-02-07 15:43
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
那個函數,等價於SEEK(L1.A3, "L2"),所以SQL指令可以寫成UPDATE L1 SET A1 = "u" + L2.A2 WHERE SEEK(L1.A3, "L2"),你試試。
寫成函數,是為了應付更複雜的條件,但SQL命令仍然很清晰,不至於一大段指令導致命令行無限長。

[ 本帖最后由 TonyDeng 于 2012-2-7 15:51 编辑 ]

授人以渔,不授人以鱼。
2012-02-07 15:49
panpende
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:4
帖 子:528
专家分:963
注 册:2009-4-27
收藏
得分:0 
谢谢TonyDeng老师,8楼9楼的程序语句达到预想的效果。问题的关键在于 WHERE SEEK(L1.A3, "L2") 字句。
但是我在某些程序段中使用WHERE ...=... .AND. ...=...,还是能够达到目的的。是不是还是稳定性问题呢?
2012-02-07 16:24
快速回复:关于DELETE - SQL 命令的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019669 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved