| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1446 人关注过本帖
标题:SELECT — SQL 的使用心得
只看楼主 加入收藏
铁狐狸
Rank: 1
等 级:新手上路
帖 子:19
专家分:1
注 册:2014-4-14
结帖率:100%
收藏
 问题点数:0 回复次数:10 
SELECT — SQL 的使用心得
SELECT —SQL命令的一般格式:
SELECT [ALL | DISTINCT] [TOP nExpr [PERCENT]] [Alias.] Select_Item
[[AS] Column_Name] [, [Alias.] Select_Item [[AS] Column_Name] ...]
FROM [FORCE] [DatabaseName!] Table [[AS] Local_Alias]
[ [INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER] JOIN DatabaseName!] Table [[AS] Local_Alias] [ON JoinCondition ...]
[[INTO Destination] | [TO FILE FileName [ADDITIVE] | TO PRINTER [PROMPT] | TO SCREEN]]
[PREFERENCE PreferenceName] [NOCONSOLE] [PLAIN] [NOWAIT]
[WHERE JoinCondition [AND JoinCondition ...] [AND | OR FilterCondition [AND | OR FilterCondition ...]]]
[Group By GroupColumn [, GroupColumn ...]] [HAVING FilterCondition] [UNION [ALL] SELECTCommand]
[Order By Order_Item [ASC | DESC] [, Order_Item [ASC | DESC] ...]]

下面谈几点SELECT —SQL的使用技巧。
1.    查询检索数据。这是SELECT —SQL的主要用法,因为其WHERE子句可以几乎任意组合条件,在程序中用的最多的不是查询界面,而是用来进行数据比对和判别。比如有些表字段不允许有相同重复数据录入,一般想到的是在表中建立主索引或候选索引,这个办法的最大隐患是需要将表单和表数据绑定,这对表文件是不安全的,以前讲过,最好不要对数据表直接“编辑”,确需绑定的,必须设定为只读,防备用户误操作而修改数据。其次,一旦录入数据出现重复,数据库报错可能使得整条记录作废,程序的易用性降低。解决的办法是在录入表单的相应字段的编辑框的Valid方法中使用SELECT —SQL进行判别验证,一旦检索到重复,及时提醒用户,这比“一错全错”要好得多。SELECT —SQL进行检索不需要切换工作区,无需所检索的表是否打开,也无需所检索的字段是否建立索引,还不改变工作区记录指针位置,如果一个字段不满足,或一个表的数据不满足,SELECT —SQL可以做到多字段、多表检索,这要比在表中设置主索引或候选索引要好得多。鉴于此,强烈建议各位狐友不要在数据库中建立字段级规则或记录级规则,同时,在数据库存储过程中也要慎用常量,那些做法只会使程序的适应性和易用性降低。因为程序升级比较容易,而要在将来修改用户的数据库,风险就太大了,不要为了眼前编程省点劲,而为自己将来设下绊索。
2.    建立临时表。SELECT —SQL的INTO Cursor子句 可以将检索到的数据存放到指定的临时表中,当关闭这个临时表后,将被自动删除。其实,这个临时表的字段结构是不限于检索源表的,可以任意构造,看下面的程序:
create table cname free (姓名 c(10))
select 姓名,;
       space(2) as 性别, ;
       000 as 年龄 ;
       From cname into cursor cperson
    上面程序中SELECT —SQL在表cname的基础上,增加了2个字段,一个是“性别”,字符型,另一个是“年龄”,数值型。space(2)和000称为占位符,其作用就是规定新构造字段的属性及宽度,space(2)表示性别字段是字符型,宽度为2字符,000表示年龄字段为数值型,三位整数,如果是00000.00则表示字段宽度为8,5位整数,2位小数。如果在上面的SELECT —SQL的后面加上READWRITE子句,这个临时表还可以执行写操作,不然临时表只能是只读的。
    实际应用中,数据库中各种表的结构会有很大的不同,但SELECT —SQL很多连接操作要求连接的两表字段属性及宽度一致,我们可以先将其中的一个表重构一个结构相同的临时表,再进行连接操作。SELECT —SQL的这个功能,已经超出了数据检索的意义了,实现了数据重构和重组,学会了数据重构和重组,就可以改变我们组织数据的思维,也会大大改变我们程序的结构,这就是SELECT —SQL是VFP的精髓之所在。数据库只需要那些动态的基本数据,其他的完全可以用SELECT —SQL实现汇总、合并、连接。本菜鸟在一个企业库存管理模块中,就只用一个“年初库存结存表”和一个“本年入出库明细表”,通过几个SELECT —SQL命令,就轻松实现了年度内任意期间的期初数据、本期入库数据、本期出库数据、期末结存数据的统计查询。
3.    替代求和、求最大、求最小等命令和函数。由于SELECT —SQL不需要切换工作区,也不改变记录指针位置,使用SELECT —SQL替代SUM命令及MAX()和MIN()函数进行求和、求最大、求最小要方便得多。
4.    同表建立一对多关系。一对多关系在数据库里是异表间建立的,利用SELECT —SQL完全可以实现同表建立一对多关系。实现的原理是,先用SELECT —SQL建立一个临时表,在命令中使用DISTINCT子句剔除重复记录,使其成为“一”方,源表自然就是“多”方。
以上是本菜鸟的一点心得,本菜鸟在学习SELECT —SQL的过程中,已然感到其高深莫测,还是没有完全掌握其精髓,苦于找不到好的学习资料,冀望自己先献献丑,好引来高手们雨点般的砖头。
献丑了。
2014-09-26 13:23
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:335
帖 子:9848
专家分:27241
注 册:2012-2-5
收藏
得分:0 
好的学习资料,就是多看多练。前提是要具有VFP基础的基础。
简单一句:走出去,请进来。

坚守VFP最后的阵地
2014-09-26 13:35
tlliqi
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:204
帖 子:15453
专家分:65956
注 册:2006-4-27
收藏
得分:0 
来看总结 是的 用好sql
2014-09-26 13:41
tlliqi
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:204
帖 子:15453
专家分:65956
注 册:2006-4-27
收藏
得分:0 
楼主能给举些例示说明更直观
2014-09-26 21:15
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11857
专家分:43421
注 册:2006-5-13
收藏
得分:0 
SQL命令的确是VFP的一大亮点,用好SQL命令,可以达到事半功倍的效果。

活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2014-09-27 06:57
windrain110
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2014-10-3
收藏
得分:0 
VFP用到今天,就是因为数据管理直观,加上sql,数据统计分析更加神奇了
2014-10-03 21:12
panpende
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:4
帖 子:528
专家分:963
注 册:2009-4-27
收藏
得分:0 
SQL命令也有不方便的时候。
2014-10-04 09:03
taifu945
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:80
帖 子:1545
专家分:3298
注 册:2012-7-6
收藏
得分:0 
以下是引用panpende在2014-10-4 09:03:08的发言:

SQL命令也有不方便的时候。

比如,有些SQL命令不直接支持对象值引用,需要事先弄个变量来存一下对象值,再把这个变量值代入命令使用。
2014-10-04 20:27
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
SQL到底是什么性质的东西,一直都没人答。html/css也有标准,ie和firefox都支持,但任谁都知道,不同的浏览器支持这些东西有各自的实现方式(亦即它们是用自己内部的机制对外表达出同样的行为而已),用这些“语言”的人其实是不知道程序的真正机制的(换言之习惯用这种东西的人实际上不懂编程),何况不同的浏览器还千方百计设计出独特的扩展以图优胜别人,结果web业界编程实际上没有统一的标准,不同浏览器之间不兼容和行为不一致的烦恼,困扰相关人员很多年了。所谓的SQL,也是一样。

SQL的效率是由实现决定的,即由具体软件本身的算法效率决定,不是这个“语言”有多高效。万变不离其宗,不熟悉该软件(VFP或SQL Server、MySQL等)的底层实现方式,只能盲目使用SQL查询,最明显的代价是无端增大机器负荷。


[ 本帖最后由 TonyDeng 于 2014-10-5 19:55 编辑 ]

授人以渔,不授人以鱼。
2014-10-05 12:24
kyleyuan
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2014-10-14
收藏
得分:0 
PUBLIC oMyObject
oMyObject = CREATEOBJECT("frmImage")
oMyObject.SHOW

DEFINE CLASS frmImage as Form
    caption="SQL Server中 Image字段处理示例"
    nHand=0
    autocenter=.t.
   
   
    ADD OBJECT command1 as commandbutton with;
        top =7,;
        left=10,;
        height=25,;
        width=84,;
        caption="生成SQL数据表",;
        name="btnCreateTable"

     ADD OBJECT command2 AS commandbutton WITH ;
        Top = 7, ;
        Left = 100, ;
        Height = 25, ;
        Width = 84, ;
        Caption = "上传文件", ;
        Name = "btnUp"


    ADD OBJECT command3 AS commandbutton WITH ;
        Top = 7, ;
        Left = 200, ;
        Height = 25, ;
        Width = 84, ;
        Caption = "下载文件", ;
        Name = "btnDown"
        
    PROCEDURE init
        SET SAFETY OFF
        this.nHand=SQLSTRINGCONNECT("Driver=SQL Server;Server=200.200.200.200;Uid=kyle;Pwd=513031;database=wise_order")
    ENDPROC
    PROCEDURE unload
        SQLDISCONNECT(this.nHand)
        this.nHand=0
    ENDPROC
   
    PROCEDURE CreateTable
        LOCAL cSql
        TEXT TO csql NOSHOW TEXTMERGE
        IF NOT exists(select * from sysobjects where name='myImage')
        CREATE TABLE myImage(
        fileStream image null,
        id int IDENTITY(1,1) not null,
        primary key (id)
        )
        ENDTEXT
        IF !thisform.execsql(cSql)
            MESSAGEBOX("生成数据表失败",0+64,"系统提示")
        ELSE
            MESSAGEBOX("成功创建表myImage",0+64,"系统提示")
        ENDIF
    ENDPROC
   
    FUNCTION execsql
        LPARAMETERS cCommand
        IF EMPTY(cCommand)
            RETURN
        ENDIF
        nResult=SQLEXEC(this.nHand,cCommand)
        IF nResult<=0
            RETURN .f.
        ELSE
            RETURN .t.
        ENDIF
   
    ENDFUNC
   
    PROCEDURE btnCreateTable.click
        thisform.CreateTable()
    ENDPROC
   
    PROCEDURE btnDown.click
        thisform.downLoadFile
    ENDPROC
    &&下载文件
    PROCEDURE downLoadFile
        LOCAL cSql
        cSql="select top 1 fileStream  from myImage order by id desc"
        
        =SQLEXEC(thisform.nhand,cSql,"tempcursor")
        SELECT ("tempcursor")
        cValue=FIELD(1)
        cFieldStream=CAST(&cValue as W)
        cFile=PUTFILE("文件另存为...")
        IF EMPTY(cFile)
            CANCEL
            RETURN
        ENDIF
        CREATE CURSOR t1(id int,filechar blob)
        APPEND BLANK
        replace filechar WITH cFieldStream
        COPY MEMO filechar  TO (cFile)
        USE IN t1
    ENDPROC
   
   
    PROCEDURE btnUp.click
        thisform.Uploadfile
    ENDPROC
    PROCEDURE Uploadfile
        cFile=GETFILE()
*!*            create cursor t1 (id int, fff blob)
*!*               append blank
*!*               append memo fff from (cFile)
   
        cFileName=ALLTRIM(JUSTFNAME(cFile))
        cfileValue=CAST(filetostr(cFile) as W)
        cCommand="Insert into myimage (fileStream) values(?cfileValue)"
        =MESSAGEBOX(SQLEXEC(this.nhand,cCommand))
         = AERROR(aErrorArray)  && 最近发生错误的数据
           CLEAR
           MESSAGEBOX( aErrorArray(2),0+64,"系统提示")
    ENDPROC
endDEFINE
2014-10-14 20:18
快速回复:SELECT — SQL 的使用心得
数据加载中...
 
   



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

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