請教各位大大關於編號問題 |
尚未結案
|
skycap
一般會員 發表:10 回覆:14 積分:4 註冊:2002-11-07 發送簡訊給我 |
請教各位大大:
我為程式新手,設計資料庫用的是MS SQL ,程式軟體為Delphi6,
為了編流水號,寫了一組程式;又為了此流水號,左思右想的只好再資料庫中先建一個
欄位adno作識別使其編號1,2,3,4,5,6......
程式再利用這個欄位編流水號.(其中編號 0的function及一些程式片斷及概念是請教另一位大大的)
程式如下: (我是先以資料表已有多筆資料要編編號的情況下撰寫,一筆一筆的去更新) function FullZero(I1:string;I2:integer): string;
begin
while length(I1) < I2 do
I1:='0' I1;
Result:=I1;
end; procedure TForm1.Button1Click(Sender: TObject);
var
MAXNUM:STRING;
adno:integer;
begin
esdm1.DataModule2.ESQ1.Close;
esdm1.DataModule2.ESQ1.SQL.Clear;
esdm1.DataModule2.ESQ1.SQL.Add('select ad,ESP_NO from esp where ESP_NO is null');
esdm1.DataModule2.ESQ1.Open;
try
while not esdm1.DataModule2.ESQ1.Eof do
begin
MAXNUM:='ES' FullZero((esdm1.DataModule2.ESQ1.FieldByName('ad').AsString),11);
adno:=(esdm1.DataModule2.ESQ1.FieldByName('ad')).AsInteger;
esdm1.DataModule2.ESQ2.Close;
esdm1.DataModule2.ESQ2.SQL.Clear;
esdm1.DataModule2.ESQ2.SQL.Add('update esp set ESP_NO=:MAXNUM where ad=:adno');
esdm1.DataModule2.ESQ2.Params[0].AsString :=MAXNUM;
esdm1.DataModule2.ESQ2.Params[1].AsInteger :=adno;
esdm1.DataModule2.ESQ2.ExecSQL;
esdm1.DataModule2.ESQ1.Next;
end;
finally
esdm1.DataModule2.ESQ1.Close;
esdm1.DataModule2.ESQ2.Close;
end;
end;
end. 請教各位高手,若以此情況,1.是否有較佳的撰寫方式?
2.若一次只需更新一筆又該如何撰寫較佳呢?
3.更新完是否有元件或資料要free的情況?
4.若要以日期為一個區段去編號,(如此編號才不會有不足問題)
ex:98020100001(19980201,varchar 8)
98020100002
98020100003
98020300001
98020300002
.
.
程式又該如何寫才好呢? 抱歉一下子提了這麼多問題,但我已測試修改程式約一個星期,仍未有較好效果...
希望您們不吝指導......
多謝各位前輩!!!
|
dinokuo
初階會員 發表:3 回覆:29 積分:31 註冊:2002-09-11 發送簡訊給我 |
|
asupeduer
初階會員 發表:36 回覆:49 積分:27 註冊:2002-11-08 發送簡訊給我 |
以前我做自動編號也都是寫在前端,但是後來發現時在是太麻煩了,
後來我就把自動編號寫到後端資料庫的Trigger上,讓資料在Insert的時候.
自動抓取資料來建立自動編號
以下是我寫的兩個自動編號的範例:
不過我寫Trigger都是用巢狀觸發程序的寫法,因為你如果不用
Cursor寫的話,會造成如果一次插入多筆資料會無法判斷Inserted的
邏輯資料表中你選取的是哪一列資料,不信的話可以試試看 1.客戶資料表的自動編號,出來的編號是
P11000001-0211(P自然人會員,1男性,1000001,流水號,-0211西元2002.11月) CREATE TRIGGER [Customer_AssignNumber] ON dbo.Customer
After Insert
AS Print '資料表Orders巢狀觸發程序Auto_assign_number(自動編號)'
Declare CursL Cursor For Select PorC,Sexs,NumIdnt,EnterDate From Inserted
Declare @PorC bit,
@Sexs bit ,
@NumIdnt int,
@EnterDate datetime,
@Month char(2),
@NSexs char(1),
@NPorC char(1)
Open CursL Fetch Next From CursL Into @PorC,@Sexs,@NumIdnt,@EnterDate While @@Fetch_Status = 0
BEGIN--While迴圈
--判斷月份是否為雙位數,
IF (Datepart (month,(@EnterDate)) < 10)
Begin
SET @Month='0' Cast(Datepart (Month,(@EnterDate)) as char(1))--單月份改為雙碼
End
ELSE
Begin
SET @Month=Cast(Datepart (Month,(@EnterDate)) as char(2))--雙月份
End
--判斷公司或法人
IF @PorC=0
Begin
SET @NPorC='P'---------自然人
End
ELSE
Begin
SET @NPorC='C'---------法人
End
--判斷性別
IF @Sexs=1
Begin
SET @NSexs='1'---------男生
End
ELSE
Begin
SET @NSexs='2'---------女生
End --開始重新編號
Update Customer
Set Customer_Number=@NPorC @NSexs Cast(@NumIdnt as nvarchar(6)) Cast(Right(Datepart (Year,@EnterDate),2) as char(2)) @Month
Where NumIdnt=@NumIdnt
--下一筆
Fetch Next From CursL Into @PorC,@Sexs,@NumIdnt,@EnterDate
End--While迴圈
Close CursL
Deallocate CursL 2.訂單資料表的自動編號,編出來的是
P10000010211(P訂單種類,1000001流水號,0211日期) CREATE TRIGGER [Auto_assign_number] ON dbo.Orders
After Insert
AS
Print '資料表Orders巢狀觸發程序Auto_assign_number(自動編號)'
Declare CursK Cursor For Select Serial_Number,OrderDate,Products_Kind From Inserted
Declare @Serial_Number Bigint,
@OrderDate DateTime ,
@Products_Kind tinyint,
@Month char(2),
@BOP char(1)
Open CursK Fetch Next From CursK Into @Serial_Number,@OrderDate,@Products_Kind While @@Fetch_Status = 0
BEGIN--While迴圈
--判斷月份是否為雙位數,
IF (Datepart (month,(@OrderDate)) < 10)
Begin
SET @Month='0' Cast(Datepart (Month,(@OrderDate)) as char(1))
End
ELSE
Begin
SET @Month=Cast(Datepart (Month,(@OrderDate)) as char(2))
End
--判斷作品或期刊
IF @Products_Kind=1
Begin
SET @BOP='B'----------------------------------------------
End
ELSE IF @Products_Kind=2
Begin
SET @BOP='I'----------------------------------------------
End
ELSE IF @Products_Kind=3
Begin
SET @BOP='T'----------------------------------------------
End
ELSE IF @Products_Kind=4
Begin
SET @BOP='P'----------------------------------------------
End
ELSE IF @Products_Kind=5
Begin
SET @BOP='H'----------------------------------------------
End
ELSE IF @Products_Kind=6
Begin
SET @BOP='O'----------------------------------------------
End
ELSE
Begin
SET @BOP='S'----------------------------------------------
End
--開始重新編號
Update Orders
Set Order_ID=@BOP Cast(@Serial_Number as nvarchar(9)) '-' Cast(Right(Datepart (Year,@OrderDate),2) as char(2)) @Month
Where Serial_Number=@Serial_Number
--下一筆
Fetch Next From CursK Into @Serial_Number,@OrderDate,@Products_Kind
End--While迴圈
Close CursK
Deallocate CursK 試試看吧,也可以實做更複雜的編號方式喔,且寫在後端的好處是不用
考慮前端,用ap也形,網頁的也行,反正有資料近來,資料庫就彙編好碼給你,
另外與設的主索引(要編號的欄位),記得採用預設值為Rand(),這樣才不會造成
無法插入資料,或者多人使用時,會造成同一豪秒鐘有多人插入資料,資料庫會造
成錯誤而無法Insert 如果寫的不錯就給我個分數吧 楊政憲
------
//------------------------------------------------ 我常在想,寫程式跟爬格子到底有什麼不同呢??????????? //------------------------------------------------ |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |