[ QQ群讨论:1005454 ] 三层由淺到深讨论,欢迎高手指点,新手捧场。 (0分)

  • 主题发起人 主题发起人 aleyn
  • 开始时间 开始时间
2004-05-18 17:03:25 煙灰缸(2282902)
請繼續。
2004-05-18 17:04:28 斜陽(249208513)
一般性的校驗工作都放在客戶部分了,每次客戶端在啟動的時候都對比服務器上相應模塊的版本,如果不一致就先同步客戶端的軟件
2004-05-18 17:05:09 煙灰缸(2282902)
這是升級吧,請繼續。。。
2004-05-18 17:06:20 Jackey(15677613)
所有的數據控件都動態生成: 包括database? 什麼時候free.database. query可以立時free的?
2004-05-18 17:06:23 斜陽(249208513)
客戶端並不是什麼都沒有,因為客戶端的硬盤有的是地方,怎麼說也是在客戶端直接執行東西快些,況且版本也不是總升級,哪有天天改業務邏輯的?所以還是很不錯的
2004-05-18 17:07:08 煙灰缸(2282902)
呵呵,所見略同也。N
2004-05-18 17:08:10 風(68187411)
hi
2004-05-18 17:08:19 煙灰缸(2282902)
答Jackey:規則交回服務層後,服務層轉換數據後,再FREE。
2004-05-18 17:08:33 煙灰缸(2282902)
hi,Gmto come back?
2004-05-18 17:08:40 風(68187411)
hi

2004-05-18 17:09:04 煙灰缸(2282902)
你的事搞定了嗎?
2004-05-18 17:09:05 風(68187411)
好熱鬧
2004-05-18 17:09:23 風(68187411)
沒有,等了好久老板都沒有回來。
2004-05-18 17:09:42 煙灰缸(2282902)
一起聊聊三層吧。
2004-05-18 17:09:51 風(68187411)
好啊,講到哪裡?
2004-05-18 17:10:42 煙灰缸(2282902)
一時也說不清, 該斜陽講了。
2004-05-18 17:11:08 斜陽(249208513)
啊?該我了?我手指頭打字打的都酸了
2004-05-18 17:11:44 煙灰缸(2282902)
呵呵,我從2點多開始,都打得。。。。。。。
2004-05-18 17:12:03 風(68187411)
呵呵,錯過了好多東西。
2004-05-18 17:12:27 煙灰缸(2282902)
Jackey來點提示吧。
2004-05-18 17:12:34 Jackey(15677613)
也就是說。client取發送了Olevariant. 服務層解析OleVaruant.建立生成database, 建立聯結,根據規則運行數據。 完成規則後。返問用戶層需要的數據。free database.
2004-05-18 17:12:47 Jackey(15677613)
錯.client層
2004-05-18 17:13:00 煙灰缸(2282902)
我的正是如此。
2004-05-18 17:13:15 斜陽(249208513)
我先聲明一下,我作三層結構開發的時候還使用Nt4.0呢,當時用Delphi5開發的,現在好久不作三層結構的開發了,要是我說的東西都落伍了,大家可別笑話我啊!N
2004-05-18 17:13:21 風(68187411)
我教過VB三層結構。
2004-05-18 17:14:08 煙灰缸(2282902)
呵呵,思想是一樣,語言沒界定。N
2004-05-18 17:14:08 Jackey(15677613)
to 斜陽:差不多。聽一下煙灰缸的, 他的設計思路很好.
2004-05-18 17:14:12 風(68187411)
是用DCOM.
 

2004-05-18 17:14:39 煙灰缸(2282902)
呵呵,Jackey過獎了。
2004-05-18 17:14:44 Jackey(15677613)
比李維的更成體系。
2004-05-18 17:14:57 風(68187411)
Delphi是用MIDAS
2004-05-18 17:15:05 煙灰缸(2282902)
是啊。
2004-05-18 17:15:38 風(68187411)
原理差不多,只是使用的技術不一樣
2004-05-18 17:15:48 斜陽(249208513)
看到這裡這麼熱鬧,勾起了我好多當時開發時的回憶,就忍不住摻和了一下,是該好好交流交流了,要不然都忘了。
2004-05-18 17:15:56 煙灰缸(2282902)
今天的最後一個問題:
2004-05-18 17:16:00 煙灰缸(2282902)
(3)。中間層規則是動態連接的好還是編譯鏈入好。
2004-05-18 17:16:25 Jackey(15677613)
continue..到哪? 如何創建規則管理層.?(還沒有深入).
2004-05-18 17:16:32 斜陽(249208513)
你指的是什麼規則呢?

2004-05-18 17:16:34 煙灰缸(2282902)
呵呵,斜陽現在在做什麼?
2004-05-18 17:16:55 斜陽(249208513)
認真聽講啊,然後想......
2004-05-18 17:17:17 Jackey(15677613)
M
2004-05-18 17:17:46 煙灰缸(2282902)
建立規則層的問題,我想放在第4課或第5課時講比較合適,大家意思呢?
2004-05-18 17:17:57 煙灰缸(2282902)
規則管理層
2004-05-18 17:17:59 風(68187411)
中間層是商業邏輯層,主要是各種商業對象的組件。
2004-05-18 17:18:11 斜陽(249208513)
我當時作了一個解釋器,用戶可以用腳本語言定義業務流程
2004-05-18 17:18:20 Jackey(15677613)
明白,
2004-05-18 17:18:34 Jackey(15677613)
我認為用腳本好一點。
2004-05-18 17:18:51 煙灰缸(2282902)
我用動態連接庫。
2004-05-18 17:19:09 斜陽(249208513)
一直想作一個Windows風格的定義器,但是沒等實施就離開那個單位了
2004-05-18 17:19:21 風(68187411)
用動態鏈接庫能實現分布式嗎?
2004-05-18 17:19:35 Jackey(15677613)
我現在做的前台都大部分用了腳本,通過數據字典定義前台簡單的規則。
2004-05-18 17:19:43 風(68187411)
aleyn?
2004-05-18 17:19:51 煙灰缸(2282902)
在。
2004-05-18 17:20:05 煙灰缸(2282902)
是可以,我是這樣做的。
2004-05-18 17:20:11 風(68187411)
用動態鏈接庫能實現分布式嗎?是COM組件吧?
2004-05-18 17:20:20 煙灰缸(2282902)
是用到COM。
2004-05-18 17:20:44 煙灰缸(2282902)
基本上用Interface實現。
2004-05-18 17:20:50 風(68187411)
那個應該不稱為動態鏈接庫,叫COM組件。
2004-05-18 17:21:17 煙灰缸(2282902)
因為我是用到COM的思想,但不用COM組件。
2004-05-18 17:21:38 斜陽(249208513)
o
 
2004-05-18 17:21:42 風(68187411)
動態鏈接庫怎麼實現分布式?
2004-05-18 17:21:43 斜陽(249208513)
值得學習
2004-05-18 17:22:04 煙灰缸(2282902)
這個說來長了。。。。
2004-05-18 17:22:12 風(68187411)
原理
2004-05-18 17:23:02 煙灰缸(2282902)
大家有沒有看過劉藝老師的DLL Object輸出的文章?
2004-05-18 17:23:23 風(68187411)
no
2004-05-18 17:23:33 斜陽(249208513)
看了以部分
2004-05-18 17:23:37 煙灰缸(2282902)
我是之後才發覺我的做法原來和他的想法一樣。
2004-05-18 17:23:50 煙灰缸(2282902)
我是之後才發覺我的做法原來和他的想法一樣。
2004-05-18 17:24:03 Jackey(15677613)
在找
2004-05-18 17:24:30 煙灰缸(2282902)
建議大家看一看,很有幫助。
2004-05-18 17:24:57 煙灰缸(2282902)
在他的主頁上有。
2004-05-18 17:25:08 斜陽(249208513)
那你遠程的客戶端又是如何同服務器上的組件交互的呢?比如:如何遠程創建服務器上的租間
2004-05-18 17:25:30 煙灰缸(2282902)
後面的沒明白。
2004-05-18 17:25:46 李逸(57440981)
dll的Object輸出有什麼難的呢
2004-05-18 17:26:09 李逸(57440981)
在Delphi或者BCB中RTTI也是同時可以輸出的
2004-05-18 17:26:10 煙灰缸(2282902)
呵呵,老狼來了?
2004-05-18 17:26:15 風(68187411)
如何調用遠程的DLL?
2004-05-18 17:26:26 李逸(57440981)
我一直在,只是沒有時間和大家溝通
2004-05-18 17:26:31 李逸(57440981)
不知道
2004-05-18 17:26:44 李逸(57440981)
遠程的dll需要宿主程序的
 

2004-05-18 17:26:45 風(68187411)
老狼
2004-05-18 17:26:53 風(68187411)
Yes
2004-05-18 17:27:02 李逸(57440981)
GMTO
2004-05-18 17:27:06 煙灰缸(2282902)
老狼,下一次和大家聊一聊你對VCL的認識,好讓我們見識廣一些。
2004-05-18 17:27:10 李逸(57440981)
Aleyn
2004-05-18 17:27:13 煙灰缸(2282902)
yes.
2004-05-18 17:27:30 斜陽(249208513)
你的業務邏輯不是在服務器上嗎?客戶端要完成一個業務,就必須創建相關的業務對象吧,這些對象應該在服務器上,要不然就不能實現真正意義上的三層。你是如何讓客戶端創建服務器上的業務組件的?
2004-05-18 17:27:37 風(68187411)
dll必須加載到進程裡運行,所有我不明白aleyn是如何用Dll進行分布式的。
2004-05-18 17:27:55 李逸(57440981)
這個在CSDN上有一個VCL揭密的程序,是動態載入bpl,並且使用其中的組件的
2004-05-18 17:27:57 煙灰缸(2282902)
等等,一時看不完。
2004-05-18 17:28:36 風(68187411)
那也實現不了分布式啊。
2004-05-18 17:28:47 煙灰缸(2282902)
TO斜陽:我的規則是在服務器上。
2004-05-18 17:29:12 斜陽(249208513)
那業務組件在哪裡呢?
2004-05-18 17:29:25 煙灰缸(2282902)
建立規則對象由服務層來做。
2004-05-18 17:29:53 風(68187411)
如果不用DCOM,你是如何實現遠程調用呢?
2004-05-18 17:30:02 煙灰缸(2282902)
裝載和更新則規則管理器來做。
2004-05-18 17:30:35 斜陽(249208513)
概念問題要統一一下,你說的規則是什麼?能否說一下或者舉個例子
2004-05-18 17:30:40 煙灰缸(2282902)
由服務層做就可以啦 。
2004-05-18 17:31:05 風(68187411)
MTS
2004-05-18 17:31:12 風(68187411)
用MTS?
2004-05-18 17:32:32 煙灰缸(2282902)
例如:Client傳來數據後,由Server確定包中的規則類型,再動太創建規則,將包轉向規則線程。
2004-05-18 17:33:04 Jackey(15677613)
快下課了,下次什麼時候開課?
2004-05-18 17:33:22 風(68187411)
client 和 server用soket鏈接?
2004-05-18 17:33:44 斜陽(249208513)
你的“規則”的詞性變化的好快
2004-05-18 17:33:45 煙灰缸(2282902)
下次開課明天決定好嗎。
2004-05-18 17:34:25 煙灰缸(2282902)
TO斜陽:有點不明白你的意思。
2004-05-18 17:34:31 Jackey(15677613)
ok.
2004-05-18 17:34:37 煙灰缸(2282902)
TO GMTO,是
2004-05-18 17:35:18 風(68187411)
明明有好的技術,為什麼偏要自己定義一種呢?
2004-05-18 17:35:35 李逸(57440981)
自己定義的好
2004-05-18 17:35:38 風(68187411)
DCOM,和Midas都可以實現分布式,為什麼不用?
2004-05-18 17:35:47 煙灰缸(2282902)
我是用MIDAS啊。
2004-05-18 17:35:49 Jackey(15677613)
不是技術問題。 而是實現問題

2004-05-18 17:36:28 斜陽(249208513)
噢,知道了
2004-05-18 17:36:31 煙灰缸(2282902)
可能是大家對概念沒有統一吧。N
2004-05-18 17:37:09 風(68187411)
我開始明白你的架構了。
2004-05-18 17:37:31 煙灰缸(2282902)
又一個明白了,反而我不明白了。B
2004-05-18 17:37:54 李逸(57440981)
你媽貴姓,呵呵,凱歌玩笑
2004-05-18 17:38:08 風(68187411)
你用Midas,但沒有用到類型庫,而用你自己的Dll,是吧?
2004-05-18 17:38:19 煙灰缸(2282902)
老狼。。。。。。。。。。。。。。。。。。?
2004-05-18 17:38:24 煙灰缸(2282902)
是。
2004-05-18 17:38:36 李逸(57440981)
?
 
2004-05-18 17:38:43 風(68187411)
為什麼不用類型庫?
2004-05-18 17:38:56 煙灰缸(2282902)
因為我用到Interface.
2004-05-18 17:39:28 斜陽(249208513)
我們在討論某個問題的時候首先作的就是先將關鍵的名詞的定義弄清楚,讓每個人都對同一個名詞是一種理解,然後再討論業務。所以習慣了,上來就問什麼是你說的“規則”是什麼
2004-05-18 17:40:34 煙灰缸(2282902)
OK,大家都說一下自己的,“規則”是什麼?
2004-05-18 17:40:46 煙灰缸(2282902)
斜陽,你先來.
2004-05-18 17:40:48 Jackey(15677613)
to 斜陽: 一開始其實有個前提作討論,就是煙灰缸的中間層架構圖.
2004-05-18 17:41:11 煙灰缸(2282902)
可能斜陽沒有看到那個圖。
2004-05-18 17:41:20 風(68187411)
規則不是業務邏輯或者稱商業規則嗎?
2004-05-18 17:41:22 Jackey(15677613)
而規則就是指的業務邏輯
2004-05-18 17:41:28 斜陽(249208513)
抱歉,我來晚了,能否告訴我在哪裡能找到
2004-05-18 17:41:53 煙灰缸(2282902)
http://www.delphibbs.com/keylife/images/g28/Stru.rar
2004-05-18 17:42:24 煙灰缸(2282902)
規則是業務邏輯
2004-05-18 17:42:32 斜陽(249208513)
在服務端,只有一堆堆的對象和對象之間的交互,我理解的規則就是如何讓這些對象協作來完成一個業務
2004-05-18 17:42:48 煙灰缸(2282902)
對,大家都一樣。
2004-05-18 17:42:50 斜陽(249208513)
不知道理解的對還是不對
2004-05-18 17:43:03 Jackey(15677613)
一樣
2004-05-18 17:43:20 煙灰缸(2282902)
但我的做法是,一個規則就只完成“一個”規則。
2004-05-18 17:43:37 斜陽(249208513)
不清楚
 
2004-05-18 17:45:02 煙灰缸(2282902)
下次開課我們談什麼好?
2004-05-18 17:45:25 斜陽(249208513)
看了你的圖,我有點明白了
2004-05-18 17:45:31 煙灰缸(2282902)
還是順著我那個圖下去?
2004-05-18 17:45:47 鶴嘯九天(123618972)
看來我來晚了

2004-05-18 17:46:10 煙灰缸(2282902)
說好了3點,你遲到了。
2004-05-18 17:46:54 Jackey(15677613)
先按這個圖。再延伸。否則又會多出一些二義性的東東.
2004-05-18 17:47:10 煙灰缸(2282902)
也好。
2004-05-18 17:47:37 煙灰缸(2282902)
要不明天3點左右,再來一課?
2004-05-18 17:47:53 Jackey(15677613)
ok. 我快下班了。
2004-05-18 17:47:55 鶴嘯九天(123618972)
3點。。。。。
我在上班。
5。。。。。。5。。。。
聊天記錄裡面怎麼沒有記錄
2004-05-18 17:48:18 Jackey(15677613)
我的記錄怎麼也不全.
2004-05-18 17:48:22 煙灰缸(2282902)
你沒開吧?
2004-05-18 17:48:40 煙灰缸(2282902)
好像要打開才有的。
2004-05-18 17:48:51 斜陽(249208513)
看完了,明白了。很有啟發噢
2004-05-18 17:49:04 煙灰缸(2282902)
謝謝,過獎了。。。
2004-05-18 17:50:18 風(68187411)
這樣文件好管理些。
2004-05-18 17:50:51 煙灰缸(2282902)
明天3點左右,再來一課,大家意下如何?
2004-05-18 17:51:14 斜陽(249208513)
恭候!
2004-05-18 17:51:34 煙灰缸(2282902)
下班了,大家快做決定。
2004-05-18 17:51:43 鶴嘯九天(123618972)
把發言記錄下來
2004-05-18 17:51:52 Jackey(15677613)
o
2004-05-18 17:51:54 鶴嘯九天(123618972)
我肯定來不了
2004-05-18 17:52:10 煙灰缸(2282902)
要上班?
2004-05-18 17:52:33 鶴嘯九天(123618972)
嗯。 開QQ了,一旦發現,¥50
2004-05-18 17:53:01 斜陽(249208513)
越看你的那個圖越覺得服務端好辛苦噢!幹那麼多工作,太便宜客戶端了!N
2004-05-18 17:53:47 煙灰缸(2282902)
這樣啊,那看看那個朋友能不能整理一下記錄,放在大富翁裡了。
2004-05-18 17:53:48 Jackey(15677613)
但是對于BS就有用了。 客戶端不能做太多.
2004-05-18 17:54:06 鶴嘯九天(123618972)
要這樣。
如果寫b/s 程序,前台根本看不見 操作代碼

2004-05-18 17:54:21 斜陽(249208513)
是啊是啊,早幾年看到這個圖我就發了!
2004-05-18 17:55:04 煙灰缸(2282902)
斜陽太看重我了。BTW:我去年就放上去了。
2004-05-18 17:55:09 鶴嘯九天(123618972)
而且, 這樣如果數據庫或業務規測變化了,也好修正
2004-05-18 17:55:16 風(68187411)
早幾年也有分布式,不過現在這種技術開始慢慢淘汰了。現在開始用.net和java.
2004-05-18 17:55:38 Jackey(15677613)
.net 與java只是實現而已
2004-05-18 17:55:48 鶴嘯九天(123618972)
但我們沒有傳Var..,傳ClientDataSEt
2004-05-18 17:56:05 煙灰缸(2282902)
對於中小企業來說,還是Midas比較合適,我的想法。
2004-05-18 17:56:06 風(68187411)
對,原理是一樣的。

2004-05-18 17:56:19 風(68187411)
實現的技術不一樣而以。
2004-05-18 17:56:34 煙灰缸(2282902)
我下班回家了,大家明天見。
2004-05-18 17:56:36 斜陽(249208513)
我在Delphi5剛推出那年給別人作三層結構的東西,差點把我累死
2004-05-18 17:56:39 鶴嘯九天(123618972)
88
2004-05-18 17:56:48 風(68187411)
有誰玩過D8?
2004-05-18 17:57:48 風(68187411)
aleyn?
2004-05-18 17:58:11 風(68187411)
這個結構我發現有點問題啊。
2004-05-18 17:58:29 Jackey(15677613)
怎麼?
2004-05-18 17:58:54 風(68187411)
我看客戶端程序可以直接寫SQL語句訪問數據庫,是吧?
2004-05-18 17:59:34 風(68187411)
如果是這樣就違反三層結構的原則。
2004-05-18 17:59:49 斜陽(249208513)
如果你定義了這個規則,應該沒問題的
2004-05-18 18:00:45 Fly(147564273)
O
2004-05-18 18:00:53 風(68187411)
如果在客戶端能直接寫SQL語句,也就是說他不受控,可以繞過中間層,這樣代碼就不規範,不算三層。
2004-05-18 18:01:39 風(68187411)
三層應該是
界面<-->中間層<-->數據層
不能跨層調用。
2004-05-18 18:02:37 斜陽(249208513)
但是入果你中間層定義了一個RunSQL接口給客戶調用,那你說算不算三層呢?
2004-05-18 18:03:14 風(68187411)
所以通常我的多層應用程序結構應該是。
界面對象<-->商業邏輯對象<-->數據控制對象<-->數據庫
2004-05-18 18:03:34 風(68187411)
不算
2004-05-18 18:03:54 風(68187411)
這個只是物理的三層
2004-05-18 18:04:21 風(68187411)
就算不用分布式,單機也要實現邏輯上的三層。
2004-05-18 18:04:43 風(68187411)
這樣程序才真正的面向對象。這是我們所要求的。
2004-05-18 18:04:59 斜陽(249208513)
那你不定義那個RunSQL不就完事了
2004-05-18 18:05:20 風(68187411)
對,鏈接數據庫應該有數據控制對象來實現。
2004-05-18 18:05:43 風(68187411)
aleyn,死哪兒去啦?
2004-05-18 18:06:06 鶴嘯九天(123618972)
D8 的 ECO 有誰研究過
2004-05-18 18:11:15 斜陽(249208513)
剛剛看了一下這個組的成員的省份,發現南方的居多,東北的好像就我一個,好孤獨啊
2004-05-18 18:11:26 鶴嘯九天(123618972)
有中部的
2004-05-18 18:11:52 風(68187411)
全是中國的。
2004-05-18 18:12:10 斜陽(249208513)
看來北方確實是一個廉價的勞動力市場,培養起步人才的基地啊。唉!可惜我走不了
 
今天討論的內容大概是:
加深昨天的話題,把一些模糊的概念統一一下。
開課時間:大概是下午3時左右開始。
 
unit dmOrderTimeModule;
interface
uses
SysUtils, Variants, Classes, dmBaseModuleImp, hmStrTools, hmSqlTools, hmDateTools, hmTimeTools;
type
TdmOrderTime = class(TBaseDataModule)
private
{ Private declarations }
protected
function ActionList(CmdIndex: integer;
var Data, Msg: OleVariant): WordBool;
override;
function Action1(var Data, Msg: OleVariant): WordBool;
function Action2(var Data, Msg: OleVariant): WordBool;
function Action3(var Data, Msg: OleVariant): WordBool;
function Action4(var Data, Msg: OleVariant): WordBool;
end;

TdmOrderTimeInfo = class(TBaseDataModuleInfo)
public
function GetModuleName: WideString;
override;
stdcall;
function GetVersion: Widestring;
override;
stdcall;
function GetMemo: Widestring;
override;
stdcall;
function GetLastUpdate: WideString;
override;
stdcall;
function GetModuleIndex: Integer;
override;
stdcall;
end;

implementation
uses swModuleIndex;
{ TdmOrderTime }
function TdmOrderTime.ActionList(CmdIndex: integer;
var Data, Msg: OleVariant): WordBool;
begin
case CmdIndex of
1: Result := Action1(Data, Msg);
2: Result := Action2(Data, Msg);
3: Result := Action3(Data, Msg);
4: Result := Action4(Data, Msg);
else
Result := inherited ActionList(CmdIndex, Data, Msg);
end;
end;

function TdmOrderTime.Action1(var Data, Msg: OleVariant): WordBool;
var
s: TStringList;
cnt: integer;
Option: integer;
begin
Self.CheckTranstion;
s := TStringList.Create;
try
Service.begin
Trans;
try
Option := Ole['Option'];
if Option = 1 then
(* 動作1:加入排班*)
begin
Sql.LoadFromStore(2);
//sql.InLines.Assign(SqlStore.SqlGroup[2].Sql);
if Ole['chkWorkTime'] = True then
sql.Params.ParamValue['@mm_WorkKey'] := Ole['edtWorkTime']
else
sql.Params.ParamValue['@mm_WorkKey'] := '@F ot.tw_WorkKey';
sql.Params.ParamValue['@PsnCond'] := '@F ' + Ole['PsnCond'];
sql.Params.ParamValue['@mm_FirstDate'] := Ole['FirstDate'];
sql.Params.ParamValue['@mm_LastDate'] := Ole['LastDate'];
Service.Execute(Sql.SqlLanguage);
Sql.LoadFromStore(3);
//sql.InLines.Assign(SqlStore.SqlGroup[3].Sql);
Service.Execute(Sql.SqlLanguage);
cnt := Service.RecordsAffected;
Service.DropTable('#ordertimetmp');
Service.CommitTrans;
if cnt > 0 then
Msg := format('排班成功,本次共有%d條記錄加入.', [cnt])
else
Msg := '可能已經排過班,本次排班沒有加入任何記錄.';
end;
if Option in [2, 3] then
begin
Sql.LoadFromStore(4);
//sql.InLines.Assign(SqlStore.SqlGroup[4].Sql);
sql.Params.ParamValue['@PsnCond'] := '@F ' + Ole['PsnCond'];
Service.Execute(Sql.SqlLanguage);
if Option = 2 then
(* 動作2:取消排班,但不刪除*)
Sql.LoadFromStore(5)
//sql.InLines.Assign(SqlStore.SqlGroup[5].Sql)
else
(*動作3:刪除排班 *)
Sql.LoadFromStore(6);
//sql.InLines.Assign(SqlStore.SqlGroup[6].Sql);
sql.Params.ParamValue['@mm_FirstDate'] := Ole['FirstDate'];
sql.Params.ParamValue['@mm_LastDate'] := Ole['LastDate'];
Service.Execute(Sql.SqlLanguage);
cnt := Service.RecordsAffected;
Service.DropTable('#Psn');
Service.CommitTrans;
if Option = 2 then
begin
if cnt > 0 then
Msg := format('更新排班成功,本次共有%d條記錄被更新.', [cnt])
else
Msg := '可能未滿足條件,本次操作沒有更新任何記錄.';
end
else
begin
if cnt > 0 then
Msg := format('刪除排班成功,本次共有%d條記錄被刪除.', [cnt])
else
Msg := '可能未滿足條件,本次操作沒有刪除任何記錄.';
end;
end;
if Option = 4 then
(* 動作4:為員工指定班次*)
begin
Sql.LoadFromStore(8);
Service.Execute(Sql.SqlLanguage);
Sql.LoadFromStore(9);
Service.Execute(Sql.SqlLanguage);
cnt := Service.RecordsAffected;
Service.DropTable('#Psn');
Service.CommitTrans;
if cnt > 0 then
Msg := format('指定班次成功,本次共有%d條記錄加入.', [cnt])
else
Msg := '可能未滿足條件,本次操作沒有任何記錄.';
end;
if Option = 5 then
(* 動作4:刪除入職之前的排班和數據*)
begin
Sql.LoadFromStore(10);
//sql.InLines.Assign(SqlStore.SqlGroup[10].Sql);
sql.Params.ParamValue['@PsnCond'] := '@F ' + Ole['PsnCond'];
Service.Execute(Sql.SqlLanguage);
s.Add('以下是被刪除的排班記錄清單:');
Sql.LoadFromStore(11);
//Sql.InLines.Assign(SqlStore.SqlGroup[11].Sql);
Sql.Params.ParamValue['@mm_Table'] := '@F tmcDays1';
Service.Execute(Sql.SqlLanguage);
s.Add(format('打卡記錄 - %d', [Service.RecordsAffected]));
//Sql.LoadFromStore(11);
//Sql.InLines.Assign(SqlStore.SqlGroup[11].Sql);
Sql.Params.ParamValue['@mm_Table'] := '@F tmcDays2';
Service.Execute(Sql.SqlLanguage);
s.Add(format('簽卡記錄 - %d', [Service.RecordsAffected]));
//Sql.InLines.Assign(SqlStore.SqlGroup[11].Sql);
Sql.Params.ParamValue['@mm_Table'] := '@F tmcDays3';
Service.Execute(Sql.SqlLanguage);
s.Add(format('請假記錄 - %d', [Service.RecordsAffected]));
//Sql.InLines.Assign(SqlStore.SqlGroup[11].Sql);
Sql.Params.ParamValue['@mm_Table'] := '@F tmcDays4';
Service.Execute(Sql.SqlLanguage);
//Sql.InLines.Assign(SqlStore.SqlGroup[11].Sql);
Sql.Params.ParamValue['@mm_Table'] := '@F tmcDays4List';
Service.Execute(Sql.SqlLanguage);
s.Add(format('額加記錄 - %d', [Service.RecordsAffected]));
Service.DropTable('#Psn');
Service.CommitTrans;
Msg := s.Text;
end;
if Option = 6 then
(* 動作4:按策略排班*)
begin
Sql.LoadFromStore(4);
//sql.InLines.Assign(SqlStore.SqlGroup[4].Sql);
sql.Params.ParamValue['@PsnCond'] := '@F ' + Ole['PsnCond'];
Service.Execute(Sql.SqlLanguage);
Sql.LoadFromStore(12);
//sql.InLines.Assign(SqlStore.SqlGroup[12].Sql);
sql.Params.ParamValue['@mm_FirstDate'] := Ole['FirstDate'];
sql.Params.ParamValue['@mm_LastDate'] := Ole['LastDate'];
Service.Execute(Sql.SqlLanguage);
Sql.LoadFromStore(13);
//sql.InLines.Assign(SqlStore.SqlGroup[13].Sql);
sql.Params.ParamValue['@mm_FirstDate'] := Ole['FirstDate'];
sql.Params.ParamValue['@mm_LastDate'] := Ole['LastDate'];
sql.Params.ParamValue['@mm_Policy'] := Ole['Policy'];
Service.Execute(Sql.SqlLanguage);
cnt := Service.RecordsAffected;
Service.DropTable('#Psn');
Service.CommitTrans;
if cnt > 0 then
Msg := format('按策略排班,本次共有%d條記錄加入.', [cnt])
else
Msg := '可能未滿足條件,本次操作沒有任何記錄.';
end;
Service.ReceiveDataWithNoData;
Result := True;
except
on E: Exceptiondo
begin
Msg := '排班操作出現錯誤:' + E.Message;
Service.RollbackTrans;
Service.ReceiveDataWithNoData;
Result := False;
end;
end;
finally
s.Free;
end;
end;

function TdmOrderTime.Action2(var Data, Msg: OleVariant): WordBool;
const
tm_time: array[1..6] of string = ('begin
1', 'end1', 'begin
2', 'end2', 'begin
3', 'end3');
var
cmdstr: string;
i: integer;
cnt: integer;
begin
Self.CheckTranstion;
try
Service.begin
Trans;
Sql.LoadFromStore(14);
//Sql.InLines.Assign(SqlStore.SqlGroup[14].Sql);
sql.Params.ParamValue['@PsnCond'] := '@F ' + Ole['PsnCond'];
Service.Execute(Sql.SqlLanguage);
Sql.LoadFromStore(15);
//sql.InLines.Assign(SqlStore.SqlGroup[15].Sql);
sql.Params.ParamValue['@mm_FirstDate'] := Ole['FirstDate'];
sql.Params.ParamValue['@mm_LastDate'] := Ole['LastDate'];
Service.Execute(Sql.SqlLanguage);
Sql.LoadFromStore(16);
//sql.InLines.Assign(SqlStore.SqlGroup[16].Sql);
sql.Params.ParamValue['@mm_FirstDate'] := Ole['FirstDate'];
sql.Params.ParamValue['@mm_LastDate'] := Ole['LastDate'];
Service.Execute(Sql.SqlLanguage);
Cmdstr := '';
for i := 1 to 5do
begin
Sql.LoadFromStore(17);
//Sql.InLines.Assign(SqlStore.SqlGroup[17].Sql);
Sql.Params.ParamValue['@mm_Action1'] := '@F td_' + tm_time;
Sql.Params.ParamValue['@mm_Action2'] := '@F tm_' + tm_time;
if i mod 2 = 1 then
begin
Sql.Params.ParamValue['@mm_BDelay'] := '@F tm_BDelay';
Sql.Params.ParamValue['@mm_EDelay'] := '@F 25';
end
else
begin
sql.Params.ParamValue['@mm_BDelay'] := '@F 25';
Sql.Params.ParamValue['@mm_EDelay'] := '@F tm_EDelay';
end;
CmdStr := CmdStr + Sql.OutLines.Text;
end;
Sql.LoadFromStore(18);
//Sql.InLines.Assign(SqlStore.SqlGroup[18].Sql);
CmdStr := CmdStr + Sql.OutLines.Text;
Sql.LoadFromStore(19);
//Sql.InLines.Assign(SqlStore.SqlGroup[19].Sql);
Sql.Params.ParamValue['@mm_Fields'] := '@F ' + CmdStr;
sql.Params.ParamValue['@mm_FirstDate'] := Ole['FirstDate'];
sql.Params.ParamValue['@mm_LastDate'] := Ole['LastDate'];
Service.Execute(Sql.SqlLanguage);
cnt := Service.RecordsAffected;
Service.DropTable('#Psn');
Service.DropTable('#TS1');
Service.DropTable('#Card');
Service.CommitTrans;
if cnt > 0 then
Msg := format('分析考勤數據成功,共分析了%d條記錄.', [cnt])
else
Msg := '可能未滿足條件,本次操作沒有任何記錄.';
Service.ReceiveDataWithNoData;
Result := True;
except
on E: Exceptiondo
begin
Msg := E.Message;
Result := False;
Service.ReceiveDataWithNoData;
Service.RollbackTrans;
end;
end;
end;

(* 本函數的作用是取得沒有排班的員工數據 *)
function TdmOrderTime.Action3(var Data, Msg: OleVariant): WordBool;
var
s: TStringList;
i: integer;
begin
s := TStringList.Create;
try
Sql.LoadFromStore(7);
Service.Query.LoadSqlAndOpen(Sql.SqlLanguage);
if Service.Query.NotEmpty and (Service.Query.RecordCount > 0) then
begin
s.Add('以下是沒有排班的員工名單:');
for i := 1 to Service.Query.RecordCountdo
begin
s.Add(Service.Query.SV['td_Number'] + ' - ' +
Service.Query.SV['td_Name'] + ' - ' +
Service.Query.SV['td_Card']);
Service.Query.Next;
end;
Service.Query.First;
s.Add(format('共找到%d條記錄', [Service.Query.RecordCount]));
Service.ReceiveDataWithNoData;
Msg := s.Text;
end
else
begin
Service.ReceiveDataWithNoData;
Msg := '沒有找到任何記錄';
end;
Result := True;
finally
s.Free;
end;
end;

function TdmOrderTime.Action4(var Data, Msg: OleVariant): WordBool;
var
Option: integer;
begin
Option := Ole['Option'];
case Option of
1: Sql.LoadFromStore(20);
2: Sql.LoadFromStore(0);
end;
Service.Query.LoadSql(Sql.SqlLanguage);
Service.ReceiveDataWithDefault;
Result := True;
end;

{ TdmOrderTimeInfo }
function TdmOrderTimeInfo.GetLastUpdate: WideString;
begin
Result := '2003-10-20';
end;

function TdmOrderTimeInfo.GetMemo: Widestring;
begin
Result := '';
end;

function TdmOrderTimeInfo.GetModuleIndex: Integer;
begin
Result := dmOrderTime;
end;

function TdmOrderTimeInfo.GetModuleName: WideString;
begin
Result := 'OrderTime Module';
end;

function TdmOrderTimeInfo.GetVersion: Widestring;
begin
Result := '1.0.0.3';
end;

end.
 

2004-05-19 14:55:25 烟灰缸(2282902)
重讲一下,今天讨论的内容大概是:
加深昨天的话题,把一些模糊的概念统一一下。
开课时间:现在开始。
2004-05-19 14:57:25 烟灰缸(2282902)
好,开始,大家先打开PDF。
2004-05-19 14:59:19 烟灰缸(2282902)
昨天有讲到一点,客户端执行RunSQL,算不算违反三层规则,大家说一下。
2004-05-19 14:59:30 llyygg(13029886)

2004-05-19 14:59:54 烟灰缸(2282902)
为何,投票看一下好了。
2004-05-19 15:00:15 烟灰缸(2282902)
我先一个 p
2004-05-19 15:00:16 风云雨(6614897)
算,但好像又很难避免
2004-05-19 15:00:39 烟灰缸(2282902)
算的 o,不算的 p
2004-05-19 15:00:52 Jackey(15677613)
不算。 p
2004-05-19 15:00:57 风云雨(6614897)
o
2004-05-19 15:01:25 斜阳(249208513)
我觉得不算,如果客户端确实有这个需要的话
2004-05-19 15:01:42 烟灰缸(2282902)
好象没有昨天那么多人出来说话了。。。。 B
2004-05-19 15:01:52 llyygg(13029886)
o
2004-05-19 15:01:52 黑夜(13633497)

2004-05-19 15:02:38 Jackey(15677613)
RunSQL其实是用户自定义了规则.而此规则还是在中间层运行。
2004-05-19 15:02:45 斜阳(249208513)
提供什么接口取决于需求,不能为了三层而三层
2004-05-19 15:03:03 烟灰缸(2282902)
我觉得,比如有一些高级的查询,SQL语句在CLIENT生成比在SERVER生成要快很多,而且效卒要好一点。
2004-05-19 15:03:45 llyygg(13029886)
为什么Client生成会比Server快?
2004-05-19 15:03:46 烟灰缸(2282902)
主要一点是,用户不能自己更改SQL语句就可以了。
2004-05-19 15:04:27 烟灰缸(2282902)
因为是动态生成查询语句,查询条件来自用户自己。
2004-05-19 15:04:38 llyygg(13029886)
不能更改那客户端还要SQL干什么?不理解.
2004-05-19 15:04:43 幽燕游侠(1142610)
其实,将SQL放在中间层
主要是考虑到维护方便
必要的时候只修改升级中间层,
而不用重新发布客户端
2004-05-19 15:05:08 烟灰缸(2282902)
如果有写过高级动太查询的朋友,应该会理解这一句。
2004-05-19 15:05:12 Jackey(15677613)
to llyygg: 中间层服务器也要占用资源。
2004-05-19 15:05:23 斜阳(249208513)
比如有一种情况,我作了这个软件,我现在要通过客户端调试一些信息,必须直接向数据库中请求信息,而我只能在客户端工作,那我就要为我提供一个RunSQL的接口来完成我的要求
2004-05-19 15:05:57 幽燕游侠(1142610)
这样的SQL也可以写在中间层饿
2004-05-19 15:06:59 风云雨(6614897)
三层其中一个优点不是比两层安全吗?但如果sql写在客户端,还有什么安全可言?
2004-05-19 15:07:06 llyygg(13029886)
to:斜阳:是啊,其实就是个后门.
2004-05-19 15:07:06 烟灰缸(2282902)
最好的一点是,客户端只生成SQL的WHERE后面的语句或Order by ,Group by 等,不要直接生成整个SQL。
2004-05-19 15:07:07 黑夜(13633497)
这种是意外的,而且只是为我们维护人员服务
可以开例吗?
2004-05-19 15:07:45 斜阳(249208513)
不能算后门,如果我在用客户端,那我就是用户,只不过这个用户特殊了点而已啊。
2004-05-19 15:08:20 llyygg(13029886)
只生成SQL的where后面的语句也很难维护啊,Server端很难解析啊(为了安全的话)
2004-05-19 15:08:52 烟灰缸(2282902)
我的做法是,SQL主句不在客户端生成,也很少在服务层生成,只在“服务器”的SQL管理器中生成。
2004-05-19 15:09:16 风云雨(6614897)
如果是做web的应用,我想大家就不会想到把sql写在Client端了吧
2004-05-19 15:09:33 斜阳(249208513)
其实在这种情况下,中间层只起到了一个存储-转发的功能
2004-05-19 15:09:59 烟灰缸(2282902)
大家看看那个PDF。
2004-05-19 15:09:59 llyygg(13029886)
to:(斜阳)其实我现在的做法和你一样的,不过我自己觉得就是一个后门.
2004-05-19 15:10:28 llyygg(13029886)
打开了
2004-05-19 15:10:57 烟灰缸(2282902)
这个后门应该只让程序员,用户不能用到。
2004-05-19 15:11:16 斜阳(249208513)
是就是吧,反正你得承认,如果没有这个中间层,你根本就本能执行你的 SQL 语句
2004-05-19 15:11:34 llyygg(13029886)
是的,这个模块客户是没有的.
2004-05-19 15:11:54 烟灰缸(2282902)
我不明白你的意思。
2004-05-19 15:12:09 风云雨(6614897)
所以我觉得用delphi做三层很别扭,其实做两层的更好,三层不过是卖点而已
2004-05-19 15:12:18 llyygg(13029886)
我说的是后门哪个模块
2004-05-19 15:12:36 斜阳(249208513)
是不能,不是本能 N
2004-05-19 15:12:56 烟灰缸(2282902)
重申:SQL主句在SERVER生成,后句的条件可以由用户生成。
2004-05-19 15:13:21 Jackey(15677613)
关于runsql,其实这个问题可以skip了。 见仁见智.
2004-05-19 15:13:33 斜阳(249208513)
OK
2004-05-19 15:13:39 风云雨(6614897)
这样两端程序耦合度不是很高了吗?
2004-05-19 15:13:40 黑夜(13633497)
那这样子跟传参数到中间层去由中间层生成sql语句有什么区别呢?
2004-05-19 15:14:39 烟灰缸(2282902)
也一样的,只是跟据要求不同而不同而已。

2004-05-19 15:13:53 烟灰缸(2282902)
好,继续我们的另一个话题。
2004-05-19 15:15:40 斜阳(249208513)
其实我觉得客户端就应该干客户端该干的事情,你要请求一个查询,没必要非要提交一个SQL语句的Where子句,这只是一种方法,客户端完全可以把需要请求的数据的条件按照其它的容易解析的方式传给服务器
2004-05-19 15:16:28 烟灰缸(2282902)
谁还记得昨天还有个什么问题没统一意见?
2004-05-19 15:16:44 llyygg(13029886)
是的,但不能是一个SQL语句,可以是一个可以生成SQL语句的文件.
2004-05-19 15:16:55 Jackey(15677613)
关于规则。应该统一了.
2004-05-19 15:17:35 烟灰缸(2282902)
请大家看看PDF,右下角就是我所谓的“规则”,看看和大家是不是一样的。
2004-05-19 15:17:36 斜阳(249208513)
再哪里合成SQL语句不重要,重要的是你的中间层可以负担更多的客户端,中间层维系着业务规则,当业务规则有变动的时候,你不需要一个一个客户端去跑,去给他们升级软件。我觉得这才是重要的
2004-05-19 15:18:16 llyygg(13029886)
客户端不可能永远不修改吧,客户端做一个自动升级就行了.
2004-05-19 15:18:43 烟灰缸(2282902)
这个问题下一步再深入一些来谈好不好。要不的话又要扯得太远了。
2004-05-19 15:19:10 烟灰缸(2282902)
请大家看看PDF,右下角就是我所谓的"规则",看看和大家是不是一样的。
2004-05-19 15:19:28 烟灰缸(2282902)
每一种规则都是一个DLL。
2004-05-19 15:19:44 Jackey(15677613)
明确一下。
2004-05-19 15:20:16 烟灰缸(2282902)
是你明确了,还是要我明确?
2004-05-19 15:20:36 llyygg(13029886)
我做的比较简单,用COM+做的,每个组建客户端都可以连接,不是通过Action来由服务器调用.
2004-05-19 15:21:11 Jackey(15677613)
比如。erp中进销存,. 出货? 出货的不同类别,你是如何做的
2004-05-19 15:21:59 Jackey(15677613)
是将进销存定义一个dll,还是一个进货类,还是再进一步明细的。
2004-05-19 15:23:10 烟灰缸(2282902)
我的做法是,将进销存中的“进”做成DLL,然后
2004-05-19 15:24:05 烟灰缸(2282902)
“进”中的每种单的类型就是Action,类型中再细化的就是Option了。
2004-05-19 15:25:02 llyygg(13029886)
将数据转换成类我觉得很复杂,不知道谁做过.
我现在的都是传递记录.就是定义成一个COM+组建.然后由客户端远程调用.
Jackey是如何做的?
2004-05-19 15:25:25 Jackey(15677613)
也就是说借料. 一般入仓. 检收。等都是作不同的option.
2004-05-19 15:25:50 斜阳(249208513)
还是一个粒度问题,分的越细,越容易被重用,但是太细了就会使使结构变的复杂
2004-05-19 15:25:54 烟灰缸(2282902)
是Action.
2004-05-19 15:27:02 烟灰缸(2282902)
借料里的不同,例如:借主料和借办公用品是不同的,这就是Option.
2004-05-19 15:28:06 烟灰缸(2282902)
喝点水再继续。。。。。。。
2004-05-19 15:28:45 Jackey(15677613)
to llyygg: 但是对于记录你是操作的。
2004-05-19 15:29:23 llyygg(13029886)
但是对于记录你是操作的?不明白-_-!
2004-05-19 15:30:04 烟灰缸(2282902)
好象又要扯得太远了。
2004-05-19 15:31:19 斜阳(249208513)
我觉得在讨论的过程中应该有一个主持人吧,把握住全局
2004-05-19 15:31:34 Jackey(15677613)
比如:入仓。 对应于入仓你有enquire。add update dele. post...
2004-05-19 15:31:45 烟灰缸(2282902)
http://www.delphibbs.com/delphibbs/DispQ.asp?LID=2614850
2004-05-19 15:31:58 llyygg(13029886)
先确定一个主题,然后烟灰缸先说一下,然后大家问问题,然后讨论...如何,一开始就讨论的话很难避免
2004-05-19 15:32:05 烟灰缸(2282902)
大家打开那帖子,看最后的。
2004-05-19 15:32:46 烟灰缸(2282902)
type
TdmOrderTime = class(TBaseDataModule)
private
{ Private declarations }
protected
function ActionList(CmdIndex: integer;
var Data, Msg: OleVariant): WordBool;
override;
function Action1(var Data, Msg: OleVariant): WordBool;
function Action2(var Data, Msg: OleVariant): WordBool;
function Action3(var Data, Msg: OleVariant): WordBool;
function Action4(var Da
2004-05-19 15:33:11 llyygg(13029886)
to:Jackey,在Dsp的BeforeUpdateRecord里面写对应的规则.
2004-05-19 15:33:30 烟灰缸(2282902)
我不在那理写规则的。
2004-05-19 15:33:54 llyygg(13029886)
为什么,很方便啊.
2004-05-19 15:34:13 烟灰缸(2282902)
不方便模块化管理。
2004-05-19 15:34:38 烟灰缸(2282902)
我的做法的明细分工。
2004-05-19 15:34:46 Jackey(15677613)
对看烟灰缸的思路往下走。 回头再解释
2004-05-19 15:35:28 烟灰缸(2282902)
大家先看看最后一个回复的前一段,类定义那里。
2004-05-19 15:37:19 烟灰缸(2282902)
看了前段了吗?
2004-05-19 15:38:21 Jackey(15677613)
ok
2004-05-19 15:41:08 烟灰缸(2282902)
function ActionList(CmdIndex: integer;
var Data, Msg: OleVariant): WordBool;
override;
这个函数相当于车间中的主管
2004-05-19 15:42:20 烟灰缸(2282902)
服务层传来包后,由它分配给“本部门”员工去做。
2004-05-19 15:42:29 烟灰缸(2282902)
数据包。
2004-05-19 15:43:09 烟灰缸(2282902)
CmdIndex就是Client中的Ole.Action
2004-05-19 15:43:27 烟灰缸(2282902)
Data有几层意思,迟一点说。
2004-05-19 15:43:44 烟灰缸(2282902)
Msg是指返回客户端的信息。
2004-05-19 15:45:19 烟灰缸(2282902)
按照“办公室管理”的思路,比较好思考一些。
2004-05-19 15:45:40 文(4184443)
什么叫“办公室管理”?
2004-05-19 15:49:23 烟灰缸(2282902)
比如:你是采购部的,你要报销采购的产品,你会如何做?
2004-05-19 15:49:57 文(4184443)
拿发票找领导签字啊!然后再到财务部领钱啊!
2004-05-19 15:49:59 黑夜(13633497)
拿发票去财务部门
2004-05-19 15:50:52 烟灰缸(2282902)
我们都知道, 报销都是支付证明单是不是?

2004-05-19 15:52:19 烟灰缸(2282902)
你填了支付证明单(Client 指定Action)后,
2004-05-19 15:53:33 烟灰缸(2282902)
你要拿到财务室去,你为什么要拿到 尔怚h,这就是“规则”。
2004-05-19 15:54:36 烟灰缸(2282902)
就是这个“规则”让你到人财务室,你肯定不会直接拿给出纳,
2004-05-19 15:56:06 烟灰缸(2282902)
肯定要先有人给你签字,再给会计,这个过程可以说是"ActionList"
2004-05-19 15:56:37 烟灰缸(2282902)
不知有没有说错。。。。
2004-05-19 15:58:55 Jackey(15677613)
是不是可以这样说: 对于财务室,是一个中间层服务器,你提交数据(支付单)。 财务室根据它找相应的action(报销的规则处理)。
2004-05-19 15:59:23 烟灰缸(2282902)
会计算完(Action)后,转至出纳(DataIO),再由出纳决定是给钱(Data)给你,还是和你说“没钱”(Msg)
2004-05-19 15:59:32 烟灰缸(2282902)
是。
2004-05-19 16:00:01 烟灰缸(2282902)
但愿我的比喻不会太复杂。。。。。
2004-05-19 16:00:04 Jackey(15677613)
ok. continue.
2004-05-19 16:01:03 烟灰缸(2282902)
下面是什么,好象忘了,哪个兄弟提醒一下。
2004-05-19 16:02:18 烟灰缸(2282902)
function TdmOrderTime.Action1(var Data, Msg: OleVariant): WordBool;

2004-05-19 16:02:36 烟灰缸(2282902)
大家看看帖子中这一段的实现部分。
2004-05-19 16:04:13 烟灰缸(2282902)
只看Opton=1部分就可以了。
2004-05-19 16:07:10 风云雨(6614897)
ole是什么来的?
2004-05-19 16:07:37 烟灰缸(2282902)
OLE是数据转换类。
2004-05-19 16:11:03 烟灰缸(2282902)
有一点要说的是,SQL语句我从不放在程序里,而是让SQL管理器来管理。
2004-05-19 16:11:54 烟灰缸(2282902)
我来说好了。OLE的作用是将Client中的数据和参数转成OleVariant.
2004-05-19 16:12:01 llyygg(13029886)
怎么做的?SQL管理器就是Sql这个类吗?
2004-05-19 16:12:03 烟灰缸(2282902)
不是。
2004-05-19 16:12:27 烟灰缸(2282902)
Sql这个类只作读取作用。
2004-05-19 16:12:29 文(4184443)
那是。。。?
2004-05-19 16:12:37 风(68187411)
对了,说到SQL,如果像你那种结构就不能算是三层结构了。
客户端怎么允许写SQL语句呢?
2004-05-19 16:15:12 wind(9186029)
to:烟灰缸
请教你的SQL管理器是放在哪一层?
2004-05-19 16:18:31 烟灰缸(2282902)
数据转换类看昨天的,sql管理器要第5,6课才讲,现在讲Action1好不好。
2004-05-19 16:20:33 烟灰缸(2282902)
Sql.LoadFromStore(2);
if Ole['chkWorkTime'] = True then
sql.Params.ParamValue['@mm_WorkKey'] := Ole['edtWorkTime']
else
sql.Params.ParamValue['@mm_WorkKey'] := '@F ot.tw_WorkKey';
sql.Params.ParamValue['@PsnCond'] := '@F ' + Ole['PsnCond'];

2004-05-19 16:20:42 烟灰缸(2282902)
sql.Params.ParamValue['@mm_FirstDate'] := Ole['FirstDate'];
sql.Params.ParamValue['@mm_LastDate'] := Ole['LastDate'];
Service.Execute(Sql.SqlLanguage);

2004-05-19 16:20:58 烟灰缸(2282902)
我按这一段来讲好不?
2004-05-19 16:24:24 烟灰缸(2282902)
还是继续。
Sql.LoadFromStore(2);

2004-05-19 16:25:38 烟灰缸(2282902)
本意是,从SQL管理中装载本Module的第二条语句。
2004-05-19 16:26:27 Jackey(15677613)
本Module的第二条语句。 ?
是定义在Module中?

2004-05-19 16:26:40 Jackey(15677613)
ini? other?
2004-05-19 16:27:13 烟灰缸(2282902)
不是,SQL语句实际上是存在DATABASE中。
2004-05-19 16:27:41 烟灰缸(2282902)
只是由Sql这个类统一管理读取而已。
2004-05-19 16:27:58 烟灰缸(2282902)
sql.Params.ParamValue['@mm_WorkKey'] := Ole['@mm_WorkTime']

2004-05-19 16:28:07 Jackey(15677613)
sql是此规则此action的主要部分。 而所有的sql写在一个表中?
2004-05-19 16:28:54 风云雨(6614897)
这样做有什么好处呢?
2004-05-19 16:29:03 烟灰缸(2282902)
Sql不是单个Action的主要部分,是所有Action读取SQL语句的通道。
2004-05-19 16:29:07 llyygg(13029886)
改SQL不用改程序
2004-05-19 16:29:12 烟灰缸(2282902)

2004-05-19 16:29:45 llyygg(13029886)
但改了SQL的参数,好像还是要改程序?
2004-05-19 16:30:04 Jackey(15677613)
题外: 我的所有sql也都是在一个表中,但是你是用什么加密此数据?
2004-05-19 16:30:09 风云雨(6614897)
就是了
2004-05-19 16:31:01 烟灰缸(2282902)
哪一个加密方法都可以。
2004-05-19 16:31:11 风云雨(6614897)
应该很少机会只修改sql语句就能满足的吧?
2004-05-19 16:31:21 烟灰缸(2282902)
又忘了到哪里了。。。。。。
2004-05-19 16:31:29 Jackey(15677613)
param....

2004-05-19 16:31:43 烟灰缸(2282902)
对。继续。。。
2004-05-19 16:31:56 烟灰缸(2282902)
sql.Params.ParamValue['@mm_WorkKey'] := Ole['@mm_WorkTime']

2004-05-19 16:32:47 烟灰缸(2282902)
当SQL需要Param时,它可以在OLE中找(OLE中的参数是Client传来的)。
2004-05-19 16:33:37 烟灰缸(2282902)
sql.Params.ParamValue['@PsnCond'] := '@F ' + Ole['PsnCond'];

2004-05-19 16:33:56 烟灰缸(2282902)
这里的实际上就不是参数这么简单了。
2004-05-19 16:34:45 烟灰缸(2282902)
随然说可以把它当成Param来看待,
2004-05-19 16:35:41 烟灰缸(2282902)
但实际上它是Client中的高级查询生成器生成的(大部分指Where后面的)。
2004-05-19 16:36:15 午秋(345816)
提,提,提个小建议,别见怪呀,能不能讲讲系统的,一味讲语法细节不是教育手法呀!!!!
2004-05-19 16:36:46 烟灰缸(2282902)
加个'@F ' 是让Sql知道它是Func而不普通Param.
2004-05-19 16:37:13 烟灰缸(2282902)
好像不是在讲语法吧。。。。象吗?
2004-05-19 16:37:15 wind(9186029)
如果是多条件查询,而且条件数不一定呢?
2004-05-19 16:37:44 烟灰缸(2282902)
Sql只当它是一个。
2004-05-19 16:38:25 烟灰缸(2282902)
Service.Execute(Sql.SqlLanguage);

2004-05-19 16:39:38 烟灰缸(2282902)
是指,通知服务层执行Sql“解释”后的语句。因为,规则层不能直接执行语句。
2004-05-19 16:40:41 Jackey(15677613)
在以此作例子讲架构。
2004-05-19 16:40:46 烟灰缸(2282902)
对。
2004-05-19 16:41:03 烟灰缸(2282902)
没有例子,讲不成架构了。
2004-05-19 16:41:31 Jackey(15677613)
wait: sqllanguage就是在sql管理器中生成的实际sql?
2004-05-19 16:41:40 烟灰缸(2282902)
是。
2004-05-19 16:42:41 Jackey(15677613)
如何知是哪个账套的?
2004-05-19 16:43:04 烟灰缸(2282902)
因为,我们在写SQL语句时,总会有一些Comment或其它的Params SET,如果让ADO直接执行的话,可能会出错,而且会加长QueryString.
2004-05-19 16:44:11 烟灰缸(2282902)
老弟,你还是忙你的“指纹技术”好了,好久不玩Midas,可能你都忘 了。
2004-05-19 16:45:02 烟灰缸(2282902)
继续,继续,哪里了?。。。。。
2004-05-19 16:45:05 午秋(345816)
这句话实在,说起来我有一年没碰Delphi了....
2004-05-19 16:45:22 Jackey(15677613)
Execute(Sql.SqlLanguage);

2004-05-19 16:45:57 烟灰缸(2282902)
对,执行完后,数据暂时还是服务层,
2004-05-19 16:46:11 烟灰缸(2282902)
对,执行完后,数据暂时还在服务层,
2004-05-19 16:47:57 烟灰缸(2282902)
所以,就会出现几中可能:
1,无须返回DATA:Service.ReceiveDataWithNoData;
2,要返回DATA:Service.ReceiveDataWithDefault;
3,
2004-05-19 16:48:52 烟灰缸(2282902)
数据由服务层返回Client,规则不谋这个职。
2004-05-19 16:50:12 烟灰缸(2282902)
因为,还要考泸都DLL中返回数据比较麻烦,第二,对应“办公室管理”规则。
2004-05-19 16:50:55 烟灰缸(2282902)
数据返回的技术要点到第8,9课时讲。
2004-05-19 16:52:58 Jackey(15677613)
sql.运行时, 按你的架构, 要动态创建数据联结。如何知是哪个数据联结(账套)
2004-05-19 16:53:51 烟灰缸(2282902)
在服务层创建线程后,用户Login时,就可是确定。
2004-05-19 16:54:54 烟灰缸(2282902)
当你是一个账套一个DATABASE里,比较适知此方法。
2004-05-19 16:55:53 烟灰缸(2282902)
还有不明白的吗?
2004-05-19 16:56:51 文(4184443)
全部都不明白啊!你们说的太高深了!什么线程都来了!
2004-05-19 16:57:06 烟灰缸(2282902)
K
2004-05-19 16:57:23 Jackey(15677613)
O
2004-05-19 16:57:28 文(4184443)
我晕!
不好意思,我是菜鸟!
2004-05-19 16:57:50 思想恐龙(男)(41867801)
是啊!线面我听说过,线程没听说过的。
2004-05-19 16:57:53 烟灰缸(2282902)
没关系,大不了再来过。
2004-05-19 16:58:04 烟灰缸(2282902)
什么是线面?
2004-05-19 16:58:23 文(4184443)
什么线面啊,是面线吧!
2004-05-19 16:58:31 烟灰缸(2282902)
N
2004-05-19 16:58:33 思想恐龙(男)(41867801)
一种像线一样的面!
2004-05-19 16:58:33 文(4184443)
吃面条啊!
2004-05-19 16:58:37 wind(9186029)
我来得晚能不能看看
SQL.LoadFromStore(2) 具体如何实现?

2004-05-19 16:58:47 风云雨(6614897)
还不是很明白你的思路,能否给个完整的例子代码看看(包括客户端服务器)?
hophychow@163.com
2004-05-19 16:59:18 Jackey(15677613)
可能到第8.9课才讲。。。 O
2004-05-19 16:59:30 文(4184443)
好,期待中。。。。
2004-05-19 16:59:31 烟灰缸(2282902)
有些思路可能要在后面讲了,倒回来看时才明白。。。。
2004-05-19 17:00:27 烟灰缸(2282902)
TO风云雨,完整的Source给不了,因为我签了合约了。
2004-05-19 17:01:18 烟灰缸(2282902)
有些技术要点我会直接放在一个地方让大家下载。
2004-05-19 17:01:20 风云雨(6614897)
不一定要商业上的源码,可以是一个小小的demo
2004-05-19 17:01:39 烟灰缸(2282902)
Demo可能没有,都几年前的事了。。。。。。
2004-05-19 17:03:32 烟灰缸(2282902)
可能到了第6课时,我就会放一些Source在另一个网站上,但只留一个星期。
2004-05-19 17:04:02 烟灰缸(2282902)
又忘了到哪里了、、。。。。。。

2004-05-19 17:11:23 烟灰缸(2282902)
我倒回查一下先。
2004-05-19 17:11:59 烟灰缸(2282902)
1,无须返回DATA:Service.ReceiveDataWithNoData;
2,要返回DATA:Service.ReceiveDataWithDefault;

2004-05-19 17:13:05 烟灰缸(2282902)
如果Action是属于Command型的,它无须返回DATA,所以通知服务层Service.ReceiveDataWithNoData;

2004-05-19 17:14:08 烟灰缸(2282902)
如果Action是要返回DATA,而且数据就在服务层的缓冲里,所以就Service.ReceiveDataWithDefault;

2004-05-19 17:14:34 烟灰缸(2282902)
还有3和4看来要明天讲了。。。。
2004-05-19 17:14:53 烟灰缸(2282902)
今天先不管3和4
2004-05-19 17:15:31 wind(9186029)
辛苦了,给烟灰缸倒茶~~
2004-05-19 17:15:43 烟灰缸(2282902)
if cnt > 0 then
Msg := format('分析考勤数据成功,共分析了%d条记录.', [cnt])
else
Msg := '可能未满足条件,本次操作没有任何记录.';

2004-05-19 17:15:57 Jackey(15677613)
点烟 t
2004-05-19 17:16:06 烟灰缸(2282902)
这一段比较简单,只是返回信息而已。
2004-05-19 17:16:14 烟灰缸(2282902)
{
2004-05-19 17:16:24 wind(9186029)
羊腿一跟,站着吃
2004-05-19 17:16:33 烟灰缸(2282902)
on E: Exceptiondo
begin
Msg := E.Message;
Result := False;
Service.ReceiveDataWithNoData;
Service.RollbackTrans;
end;

2004-05-19 17:17:18 烟灰缸(2282902)
这一段只是Exception捕捉, 碍藀^给服务层和Client.
2004-05-19 17:19:12 烟灰缸(2282902)
等我忙完这几天,我整理出一个更接近我现在做的架构图出来给大家。

2004-05-19 17:20:10 烟灰缸(2282902)
明天要讲的,大概和服务层有关。
2004-05-19 17:20:10 wind(9186029)
期待ing~~
 
下一次开课讨论时间大概是:星期一下午3点。
会议主持:烟灰缸(Aleyn)
讨论内容:
1)。如何在DLL中活用Interface(上一课没讨论完)。
2)。如何定制事务层Interface
3)。如何定制规则层Interface
 
別貼QQ記彔好不?
貼之前你征求過發言人的意見不?
如果沒有你就侵權了.吼吼
 
对不起,以后不再在这里QQ记录了.
另:三层原程序已经上传!
 
[:D][:D]已加入!!
 

Similar threads

I
回复
0
查看
620
import
I
I
回复
0
查看
634
import
I
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部