以下是我在線與網友對話(很感謝他,有在線的网友與我聯繫 MSN : [email protected])
程序人生 說:
我看了你的问题,如果用户1输入kh003而用户2输入kh004,如果用户1不存盘的话,那不是会少一个编号kh003这样可以吗?
我 說:
這樣可以
程序人生 說:
那为什么这样呢:
我 說:
對,這樣的話,用戶1可能放棄
我 說:
也可能存檔
程序人生 說:
如果放弃的话kh003是不是在下次还要用到还是永远不要了
我 說:
我們的目的是讓用戶感覺他要增加的號碼,沒有重復
我 說:
所以說我們可以補空號功能
我 說:
可以補,也可以不補
程序人生 說:
我想要达到这个功能的话,一定要用到两个表,因为一个表的话可能有一点难
我 說:
我們一開始就是兩個表
我 說:
wait
程序人生 說:
你说的两个表是什么意思?
我 說:
有一張臨時表,存放我們取用的編號(用戶還沒有存檔的編號)
程序人生 說:
这样可以啊,在每新增一条资料时,用一个查询select id from table1 union select id from table2
我 說:
這樣是沒有問題,可是取到了KH003,若還沒有存檔,那另為一用戶怎麼知道KH003已經被人使用了呢
程序人生 說:
你的这个号是系统给出还是用户自已输入?
我 說:
我們採用手工或者自動都可以
程序人生 說:
我看了你的问题,如果用户1输入kh003而用户2输入kh004,如果用户1不存盘的话,那不是会少一个编号kh003这样可以吗?
我 說:
這樣可以
程序人生 說:
那为什么这样呢:
我 說:
對,這樣的話,用戶1可能放棄
我 說:
也可能存檔
程序人生 說:
如果放弃的话kh003是不是在下次还要用到还是永远不要了
我 說:
我們的目的是讓用戶感覺他要增加的號碼,沒有重復
我 說:
所以說我們可以補空號功能
我 說:
可以補,也可以不補
程序人生 說:
我想要达到这个功能的话,一定要用到两个表,因为一个表的话可能有一点难
我 說:
我們一開始就是兩個表
我 說:
wait
程序人生 說:
你说的两个表是什么意思?
我 說:
有一張臨時表,存放我們取用的編號(用戶還沒有存檔的編號)
程序人生 說:
这样可以啊,在每新增一条资料时,用一个查询select id from table1 union select id from table2
我 說:
這樣是沒有問題,可是取到了KH003,若還沒有存檔,那另為一用戶怎麼知道KH003已經被人使用了呢
程序人生 說:
你的这个号是系统给出还是用户自已输入?
我 說:
我們採用手工或者自動都可以
太夸张了吧?我看见GUID就晕:)
你講的做法是存在的;
To fermium(列御寇) :
用人工編號的當初想法是:很個性化,也是方便用戶;
自動編號主要是程序一體化,也有規格化,eg:打銷貨單,用戶可設置YYMMDD9999 or YYYYMMDD9999 or MMDDYY9999 or WANGMMDDYY999多種格式;
另外兩位朋友提到GUID,不知能否詳細講一下呢?
其實現在對於人工編號:我們就是在退出編號欄位時如何知道編號是否重復(考慮其他用戶已經占用還沒有存檔的編號)
自動取用編號:關鍵在於取時,不能取相同的編號(也是要考慮其他用戶已經占用還沒有存檔的編號);
另外還有一個難點我可能沒有表述清楚:
那就是可能有多個程序(不是同一系統)都用此一張資料表,它們都有取用編號的情況;
如何做到唯一--GUID 要确保一个名字是唯一的,仅有两个方法: 1。通过一些准政府组织来登记名字; 2。使用一个特别的算法来产生唯一的数字,这些数字可被认为在世界范围内是唯一的 第一个方法与网络上的域名管理一样。它的问题是你必须付$50来登记一个新的名字,而且要令登记生效,你要等几个星期。 第二个方法对于开发者更为方便。如果你可以发明一个算法,每次人们调用它都可以产生一个可被认为是唯一的名字,那么这个问题就解决了。事实上,这个问题已经被开放软件基金会提到(Open Software Foundation,OSF)。OSF有一个算法,可将一个网络地址、时间(100纳秒递增)和一个计数器结合,得到一个128位的唯一数字。 2的128次方是一个非常大的数字。通过它,你可以识别由宇宙开始到现在的每个100纳秒--而且还会剩下39位。OSF将它称为UUID,意思是Universally Unique Identifier,在COM的命名标准上,微软使用同样的算法。在COM中微软将它重命名为Globally Unique Identifier。 GUID的记录通常采用16进制。不过这没有关系,一个典型的GUID类似为: "50709330-F93A-11D0-BCE4-204C4F4F5020" 由于在C++中并没有标准的128位数据类型。,因此我们使用一个结构体来表示。虽然GUID的结构体包含有4个不同的字段,不过你可能从来不会操作它的成员。该结构体通常都作为一个整体使用。typedef struct _GUID
{
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
} GUID;
GUID的普通读音是“gwid”,与“squid”的发音类似。一些人也读为“goo-wid”。 GUID通过一个称为GUIDGEN的程序产生。在GUIDGEN中,你只要按下一个按钮就可以产生一个新的GUID。你可以认为你产生的每个GUID都是唯一的,不管你产生了多少个,或者世界上有多少人产生它。这个认定可以成立是基于以下的原因:Internet上的所有机器都有一个唯一的地址。因此,你的机器最好是处在网络上。不过,即使你没有网络地址,GUIDGEN也将会产生一个,但是这样就会令唯一性的机率降低。
不過如何應用在我們的程序中呢?
GUID的解释:自动编号和标识符列
对任何表都可创建包含系统所生成序号值的一个标识符列,该序号值唯一标识表中的一行。例如,当在表中插入行时,标识符列可自动为应用程序产生唯一的客户收据号码。标识符列在其所定义的表中包含的数值通常是唯一的。这意味着在包含标识符列的其它表中可使用与之相同的数值进行标识。但是,由于标识符值通常是在一个独立表的上下文中使用而不与其它表中的标识符列发生关联,所以通常不会发生问题。可在每个表上创建一个全局唯一标识符列,而该列中包含对世界上所有网络计算机均不重复的值。当必须对来自多个数据库系统的相似数据进行合并时(例如,在包含位于世界各地分公司的数据的客户帐单系统中),包含全局唯一值的列很有用。当数据汇集到中心进行合并和制作报表时,使用全局唯一值可防止不同国家/地区的客户拥有相同的帐单号或客户 ID。
我用的方法是在表里把编号的字段设置成关键字字段(Key)
如果是单据这样的编号
我直接用"[XXXX]YYYYMMDDNNMMSS[XXX]"这样的编码方式
//单据头 + 年月日时分秒 + 本地流水号
我現在這里要做的是防止用戶取了相同的編號,假如a用戶 用了編號kh001(還沒有存檔),這時候b用戶再輸入kh001(在退出edit時,我就要給他提示,有人正在使用此編號);---------這種情況是用戶人工自己選擇編號的問題
另外一個是:我們系統自動給它取編號(用戶可定義格式,如yyyymmdd99999),這個時候我們如何保證系統取用的編號是沒有重復的,另外要考慮到有人占用編號的情況
如果只是僅僅取一個唯一編號,沒有甚麼難的,關鍵在於用戶同時操作,有可能是多系統,還要考慮有人占用的編號,對同一資料表並發的操作
编号当然可以个性化,但数据的存储要个性化就会有问题
如何做到編號個性化,唯一性
你只有用编程序去解决它,我们曾经遇到过这样的问题,我们增加了一个字段,标示是否有用户正在操作它从而避免编号重复的情况.
取消己发出的单据, 言该序号是否可以重用呢?
>>>>>>>>>>>>>
其實你講的這個意思應該是個是否補空號,程序中有控制,也可以補也可以不補;
你說用兩個序號不知如何處理?我覺得很難做到,單據編號的唯一性;
>>>>>>>>>>>>>
我們程序里現在的要求是如何知道有人正在占用編號(已經退出編號edit,還沒有存檔的編號,可能是我們程序自動生成,也可能是用戶自己輸入);占用的編號是否和我現在的編號重復;如果是自動生成編號,如何保證我們取用的編號是唯一的(要考慮到占用的編號)
取消己发出的单据, 言该序号是否可以重用呢?
>>>>>>>>>>>>>
其實你講的這個意思應該是個是否補空號,程序中有控制,也可以補也可以不補;
你說用兩個序號不知如何處理?我覺得很難做到,單據編號的唯一性;
>>>>>>>>>>>>>
我們程序里現在的要求是如何知道有人正在占用編號(已經退出編號edit,還沒有存檔的編號,可能是我們程序自動生成,也可能是用戶自己輸入);占用的編號是否和我現在的編號重復;如果是自動生成編號,如何保證我們取用的編號是唯一的(要考慮到占用的編號)
編號有其自己的格式,用戶可自己定義
eg: yymmdd9999 or user1YYMMDD9999
我們要實現的也是
首先搜索有没有中间空闲的编号(也就是楼上有些朋友说的某个用户发单了后又取消的那种情况),如果有,就拿来用,没有就新生成一个
其中的麻煩是:若有多個用戶同時取用編號時,你是如何處理的?
后存的一个会返回错误,在程序中可以利用该错误信息来重新生成一个编号,
>>>>
這樣用戶一開始的那個編號就改變了,用戶這時候他不能接受,因為他一開始輸入的是一個編號,而存檔時又改變了;
所以我不知如何是好?
3,現在有兩種做法:(我個人認為都比較麻煩,做起來比較煩,不方便)
A:加一張資料表(Table_NO),專門存放我們取用的編號(占用的編號/還沒有存檔),
新增(更新)操作(退出編號欄位):
手工取用編號:要到兩張資料表中去尋找是否有存在的編號
若有(提示編號已用);否則再存給Table-NO,pass
自動取用編號:要到兩張資料表中去尋找最大的編號,然後加1,再存給Table-NO
一旦有存檔動作:我們要把Table-NO中的相應編號刪除
若有放棄動作:同樣要Table-NO中的相應編號刪除
B:另一種做法是在Table_Cust加一字段(suse),用來標誌是否真正存檔;
也是就是若一用戶取用編號后,我們要做一個假存檔的動作;若沒有真正的存檔,我們
再做刪除的動作;
4.此兩做法,都不是太好:
A.的做法只要修改一個地方,就是新增(更新)操作時,但是同時會存在對Table_NO的並
發控制問題,對於這個問題,我們現在採用對資料表加鎖的方法,但是這也是存在問題,
鎖的時間長短問題,是否能解開鎖的問題,真的比較頭痛;有時會沒辦法控制;
B.的做法就是基於這一點,我們又提出來的新方法,這種方法任何關聯的地方都要修改,
就是那個地方有Table_Cust資料表就要修改,它同時要面對的也是有並發控制,還有死
機的問題
>>>>>>>>>
其實我是比較傾向於A做法;我也講了這個做法存在的問題(也是我們程序在客戶那邊行很長時間出現的問題),
還有>>
2,數據庫類型為Paradox,Infomix,SQL Server,Postgre SQL;
因為不同的數據庫關係,在用A方法時,確實是有問題多多,主要是系統不穩定
>>>也由於這些問題,想讓csdn上的高手出招;再次謝謝各位!
我先让A,B用户取得的编号都为F003,当A用户写入数据后,B用户接着写入数据,
但是B用户写入时检查F003 的存在,如果存在,则自动增1为F004,然后再重复检查F004 的存在 ,直到取得的编号不存在(不重复)。如果需要再返回新的编号给用户。
这样如果可以的话,就不要考虑跳号的问题,也不会存在空号。
有更好的方法请记得告诉我。
????這樣肯定不行;你要記住:用戶在欄位輸入的編號,在這個時候你就要去校驗是否有重號(還有別的用戶正在輸入資料,還沒有存檔);
因為用戶發現如果這個時候校驗正確,你就應該把這個編號存入資料表中(這也是對的)