一万光年外  
免费OA软件网 http://www.freeoasoft.com 专注于平台架构设计及OA软件开发
公告
  • 昵称:一万光年外
    园龄:6年5个月
    粉丝:5
    关注:1
日历
<2009年2月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
1234567
统计
  • 随笔 - 22
  • 文章 - 0
  • 评论 - 229
  • 引用 - 4

导航

搜索

 

常用链接

最新随笔

随笔分类(25)

随笔档案(22)

相册

友情链接

积分与排名

  • 积分 - 36973
  • 排名 - 2901

最新评论

阅读排行榜

评论排行榜

推荐排行榜

 

话说程序设计,首先要选择一门语言,语言又分低中高之分,高级语言容易学习,入门门槛低,我们就学习高级语言吧,常见的高级语言有VB,Delphi,C#,JAVA等,首先你得先选择一门语言。”百晓生摇头晃脑道。

 

姚鑫辰:“听过C#,我就选C#吧!”

 

百晓生:“OK!那我们就开始学习C#吧!C#是百分之百面向对象的语言,就先说说面向对象的基本知识吧,话说面向对象…此处省略八万九千四百字”

 

学习中,请稍候…

 

N天以后,百晓生道:”徒儿啊,C#的基本知识为师讲得差不多了,你可有疑问?”

 

姚鑫辰:“差不多明白了!”

 

百晓生:“那好,那我就考一考你,假设我们要做一个业务管理系统,这个系统80%的功能是数据的增删改查,那应该怎么样设计这个系统的数据处理部分呢?”

 

姚鑫辰:“这个我知道,按师傅说的高复用的原则,我们应该设计一个基类窗体,在上面放一个工具栏,再添加增加、修改、删除等按钮,然后分别实现对应的功能,当然,为了增加系统的扩展性,我们可以把一些实现方法设为虚拟的,这样子类如果有不同之处,就不用重写基本的相同功能,只需在不同之处重载虚拟方法就行了。“吞了下口水,邀功似问道:“师傅,我回答得怎么样?”

 

百晓生:“不错不错,刚学不久就能够考虑到系统扩展性的问题,果然姿质不凡。作为考试可以给你满分,不过在基类窗口中直接拖放控件的方法却不太好,因为不符合界面与业务分离的原则。”

 

姚鑫辰:“界面与业务分离?我听师傅说过,就是业务逻辑与界面分开的意思吧,好像还有人从这里面衍生出了MVC的概念?”

 

百晓生:“不错!因为如果界面与业务绑得太紧不利于扩展及维护,所以在实际开发中,最好把每个按钮抽象为一个Action,每个Action包括文本,图像及动作等相关属性,然后基类根据预定义的Action集合自动生成工具栏,如果子类的工具栏有不一样,只要重载Action集合就行了,这样就达到了界面与业务分离,徒儿记住:面向对象的本质就是抽象,要学会抽象!抽象!!再抽象!!!“

 

(注:关于Action抽象的问题,很久以前有写过一篇文章说过我的这个想法,如有兴趣,请看Action设计模式的.Net实现)

 

姚鑫辰点了点头,郑重地说道:“徒儿受教了!”

 

百晓生:“下面再出个简单的题目考考你的应变能力,我们写的程序要支持TAB键,是通过设置TABINDEX来实现切换顺序的,但我不想每次都去设置控件的TABINDEX,因为太麻烦,其实我只想按行且从左到右顺序切换就行了,用什么方法可以实现不用设置每个控件的TABINDEX而自动顺序切换呢?”

 

姚鑫辰想了想,说道:“首先,肯定是要设计一个基类,然后在基类实现对控件的TABINDEX排序的算法,子类再从基类继承也就能够自动进行排序了,至于算法…”

 

顿了一顿,继续想道:“有了,要求是按行从左到右排序,也就是说Y值小的优先,X值小的也优先,而Y又优先于X,也就是说Y的权重大于X的权重,那我设置TABINDEX等于Y*权重+X不就行了吧,只要权重大于X值的最大值就行了!这样即得如下代码:”

 

protected void SortTabIndex(Control parent)

{

     if (parent == null) return;

 
     foreach (Control ctrl in parent.Controls)

     {

          ctrl.TabIndex = ctrl.Top * 10000 + ctrl.Left;

 
          //再递归设置

          if (ctrl is ContainerControl) this.SortTabIndex(ctrl);

      }

}

 

百晓生颔道道:“很好很好!看来基本的编程知识你掌握得差不多了,下面我们说说数据库吧!话说数据库…此处省略五万七千八百字”

 

学习中,请稍候…

 

N天以后,百晓生道:”徒儿啊,数据库的基本知识为师讲得差不多了,你可有疑问?”

 

姚鑫辰:“差不多明白了!”

 

百晓生:“那好,那我就考一考你,我有一个费用表,表名叫欠交费用,其字段结构如下:

 

编号            int             主键(自增)

客户编号        int             客户编码(外键,对应客户表主键)

费用项目        varchar(50)   费用项目

应交时间        datetime        应交费用的时间(精确到日)

欠费            numeric(18, 2)  欠交费用

 

要求写一个自动冲抵的存储过程,对某一客户的交款金额按应交时间从早到晚自动进行冲抵,只到费用冲完为止。“

 

姚鑫辰:“这个简单啊,写两层游标,一条一条的循不就行了!“

 

百晓生:“错是没错,但用游标的效率不高!”提醒道:“你再想想看不用游标能不能实现?“

 

“不用游标,那这个问题可不是一般的难啊!容我仔细想想…“

 

姚鑫辰仔细想道:“不用游标,又要按序的冲,我怎么知道交的钱能冲到哪笔费用,有没有把那笔费用冲干净呢,其实,只要知道了可冲抵到哪笔费用及冲抵那笔费用的冲抵情况,那就好办了!有了!”突然跳了起来,写道:

 

create procedure sp_冲抵

(

    @客户编号 int,

    @冲抵金额 numeric(18, 2)

)

as

begin

 
           declare @temp table(编号 int identity(1, 1), 费用项目 varchar(20), 应交时间 datetime, 欠费 numeric(18, 2))

        declare @Id int --定义编号,用以记录最后冲抵的位置

           insert into @temp(费用项目, 应交时间, 欠费) --先写进临时表,并按顺序自动编号

           select 费用项目, 应交时间, 欠费

                from 欠交费用

        where 客户编号 = @客户编号

 

        order by 应交时间

  
           --以下语句可得出最后的冲抵位置及欠额

    select @冲抵金额 = case

                when @冲抵金额 <= 0 then @冲抵金额

                else @冲抵金额 - isnull(欠费, 0)

        end,

        @Id = case

            when @冲抵金额 <= 0 and @Id is null then 编号

            else @Id

        end

    from @temp

   

    --下面这句就可以查出实际冲抵金额了,可根据实际需求改为冲抵记录

    select case

            when @冲抵金额 >= 0 or 编号 <> @Id then 欠费

            else 欠费 + @冲抵金额

        end as 实冲金额

    from @temp

    where @Id is null or 编号 <= @Id

   

end

 

姚鑫辰笑道:“如果要考虑并发冲突的问题,可以设置事务隔离级别,师傅,这个怎么样?”

 

百晓生:“不错不错!”眼里满是欣慰,颔首道:“那我再说一个简单的题目考考你的应变能力吧,一个消息表,有个字段叫已阅人,是由姓名加分号拼接而成,没有已阅人时为空,如果张三已阅,则值为[张三],如张三和李四已阅,则为[张三;李四],现在的问题是,写一条查询语句,把所有张三阅读过的消息找出来!”百晓生道。

 

姚鑫辰想道:“所有张三阅读过的消息?名字可以叫张三,也可以叫张三毛,也可以叫王张三,李张三”,自言自语道:“不过这个问题却难不倒我,只要已阅人字段先加上分号,再对比已阅人列表中是否存在[;张三;]就行了,不过因不能利用索引,效率不会高,但和这个问题可没有关系!”

 

接着笑道:“师傅,你看这样怎么样:select * from 消息 where charindex(‘;张三;’, ‘;’ + 已阅人 + ‘;’) > 0。”

 

百晓生叹道:“都说找好师傅难,岂不知找好徒儿更难啊,想我百晓生纵模江湖三十载,就只有一个徒儿找上门来,可喜的是此徒儿不负我望,我百晓生后继有人矣!”

 

姚鑫辰嘀咕:“原来我是师傅的唯一徒弟啊!”

 

一顿,百晓生决然道:“你我师徒缘分已尽,你走吧!”

 

虽然早意识到有这么一天,姚鑫辰仍是伤心地道,“师傅,你不要徒儿了吗?”

 

“天下无不散之宴席,雏鹰需展翅才能高飞!别婆婆妈妈的,像个男子汉,做出一番事业给我看看,方不负为我百晓生之徒弟!“百晓生顿足道。

 

“那我走了,那我真走了!“,姚鑫辰走至门口,忍不住回头,瞬时感觉百晓生苍老许多,心中百感交集,扑通一声跪了下来,呜咽道:”师傅,请受徒儿一拜!“

 

然后头也不回,走了出去!

 

“臭小子,说走就走!“百晓生擦了把眼泪,道:”哪个狗屁程序员,我可是NPC啊,还让我流眼泪!“

 

“师傅!“百晓生看到姚鑫辰又进来了,心中一喜。作势道:“臭小子,走就走了,还回来做什么,不爽快,不像个男人!“

 

“我只是想问问下一步我要怎么办?“姚鑫辰委屈道。

 

“去死吧你,我可是NPC,上面只让我教你学习和回答一些技术方面的问题,其它的我什么都不知道!“百晓生吼道。

 

 

 

作者: 一万光年外 欢迎交流

邮箱:   freeoasoft@126.com

Blog:   http://www.cnblogs.com/yaozy/

主页:   http://www.freeoasoft.com

posted on 2009-02-09 19:17 一万光年外 阅读(1615) 评论(14) 编辑 收藏
评论:
  • #1楼  啊啊啊啊啊啊 啊[未注册用户] Posted @ 2009-02-09 20:43
    顶啊啊  回复 引用   

  • #2楼  o﹎箜絔┌↘       Posted @ 2009-02-09 21:27
    正好要用到最后那条SQL语句,在此谢过了呵呵。  回复 引用 查看   

  • #3楼  Allen Zhang       Posted @ 2009-02-09 21:45
    晕啊,那个冲抵的例子笨得还有点看不懂,呵呵.  回复 引用 查看   

  • #4楼  李胜攀       Posted @ 2009-02-10 09:20
    @Allen Zhang
    我也没看明白。。。
     回复 引用 查看   

  • #5楼  海影       Posted @ 2009-02-10 09:30
    那个冲抵的例子也没看懂- -  回复 引用 查看   

  • #6楼  子曰       Posted @ 2009-02-10 10:33
    冲抵的例子作者有没讲清楚,有2点意见指出下。
    1.order by 应交时间 这个是否改成 order by 编号更好
    因为你前面说明 应交费用的时间(精确到日) ,所以是不是以编号更好点
    2.你后面都说道要用事务来提交。那么你这个存储过程是否少来update

     回复 引用 查看   

  • #7楼  韦恩卑鄙       Posted @ 2009-02-10 11:03
    太深刻了

    我没搞清楚 为什么不用

    where ‘;’ + 已阅人 + ‘;’ like '%;张三;%'
     回复 引用 查看   

  • #8楼[楼主]  一万光年外       Posted @ 2009-02-10 14:38
    @子曰
    不好意思,那个编号可能会乱,有点问题,现已更正为临时表重新编号 时间精确到日仅是顺便一提,没什么用,我去掉吧 至于事务,仅是提一提,实际运用请自行处理
     回复 引用 查看   

  • #9楼[楼主]  一万光年外       Posted @ 2009-02-10 14:46
    @Allen Zhang
    @李胜攀
    @海影
    这里的细节可能没说得太准确,因为没有调试是直接手写的,不过我主要是要体现一种算法,具体我说明一下:

    假设我要冲抵的数据记录是这样的(已排好序)

    编号 费用项目 金额
    1 A 100
    2 A 200
    3 B 100

    我如果现在客户交320块,那我最后的冲抵效果是1,2已交清,3交了20,还有80没交

    如果不用游标,那第一步是先得到我冲到哪一笔,如3,然后是得到最后一笔还有多少未交,如80

    最后我们的查询条件为一个小于3的,交款等于欠费,等于3的那一条,交款为100-80,这样就得到了最后的效果,我想说的意思就是这样,可能有些误差,见谅!

    因排序可能会错乱,现已改成临时表,请查看
     回复 引用 查看   

  • #10楼[楼主]  一万光年外       Posted @ 2009-02-10 14:53
    @韦恩卑鄙
    效果一样的,不过我不知道性能有没有左异,不过我那么写纯粹是习惯问题。
     回复 引用 查看   

  • #11楼  韦恩卑鄙       Posted @ 2009-02-11 11:13
    鼓掌 like 那么写是我的习惯 我也不知道性能如何  回复 引用 查看   

  • #12楼  风疑       Posted @ 2009-02-16 16:20
    额,冲抵的那个基本上搞清楚了,感觉游标可能我会更明白点。
    另:游标效率会差么?
     回复 引用 查看   

  • #13楼[楼主]  一万光年外       Posted @ 2009-02-16 19:23
    @风疑
    游标效率一般来说是比较差的,特别是嵌套几层的。 不过这篇文章中例子的本意是想说明一个问题: 解决一个问题往往可以从不同的角度来理解!有时很复杂的东西,换个角度可能会变得很简单!
     回复 引用 查看   

  • #14楼  风疑       Posted @ 2009-02-17 11:19
    额..我还是目光短浅啊,没看到本质  回复 引用 查看   

 
Copyright © 一万光年外 Powered by: 博客园 模板提供:沪江博客
免费OA软件网 http://www.freeoasoft.com 专注于平台架构设计及OA软件开发