2012-11-18 89 views
2

JobID如下所示:ALC-YYYYMMDD-001。前三個是公司的首字母縮寫,最後三個是遞增的數字,每天重置並增加一天的增量,因爲在一天內增加了最多999個工作;這是我試圖與之合作的最後三個。添加'1'返回「BLOB」

我想獲得一個前插入觸發器來查找當天的最大JobID,並添加一個,所以我可以讓觸發器派生出正確的JobID。對於第一份工作,它當然會返回null。所以這是我迄今爲止所擁有的。

通過以下我可以得到'000'的結果。

set @maxjobID = 
(select SUBSTRING(
    (Select MAX(
    SUBSTRING((Select JobID FROM jobs WHERE SUBSTRING(JobID,5,8)=date_format(curdate(), '%Y%m%d')),4,12) 
      ) 
),14,3) 
); 

select lpad((select ifnull(@maxjobID,0)),3,'0') 

但我真的需要添加一個保持前導零以增加當天的第一個和後續工作。我的問題是儘快添加'1'我得到'BLOB'的回報。那就是:

select lpad((select ifnull(@maxjobID,0)+1),3,'0') 

返回「BLOB」

我需要它返回「001」這樣我就可以連接具有CO聲母和當前日期這一結果。

+0

這些表是MyISAM,如果有幫助。 – Damon

回答

0

所以,我發現了一個有效的查詢(到目前爲止)。

Declare maxjobID VARCHAR(16); 
Declare jobincrement SMALLINT; 
SET maxjobID = 
(Select MAX(
    ifnull(SUBSTRING(
     (Select JobID FROM jobs WHERE SUBSTRING(JobID,5,8)=date_format(curdate(), '%Y%m%d')), 
      5, 
      12),0) 
     ) 
    ); 

if maxjobID=0 
then set jobincrement=1; 
else set jobincrement=(select substring(maxjobID,10,3))+1; 
end if; 

Set NEW.JobID=concat 
(New.AssignedCompany,'-',date_format(curdate(), '%Y%m%d'),'-',(select lpad(jobincrement,3,'0'))); 

感謝您的回覆!尤其是用於指出MyISAM中auto_increment功能的eggyal。

1

儘量鑄造VARCHAR回INTEGER

SELECT lpad(SELECT (COALESCE(@maxjobID,0, CAST(@maxjobID AS SIGNED)) + 1),3,'0') 
+0

仍然在這一個上獲得「BLOB」的返回。在發佈之前,我嘗試過使用CAST和CONVERT,但無濟於事。 – Damon

0

如果你使用MyISAM存儲引擎,你可以用AUTO_INCREMENT實現的正是這種,沒有denormalising您的數據轉換成分隔字符串:

對於MyISAM表格,您可以在多列索引的輔助列上指定AUTO_INCREMENT。在這種情況下,AUTO_INCREMENT列的生成值計算爲MAX(auto_increment_column) + 1 WHERE prefix=given-prefix。當您想要將數據放入有序組時,這非常有用。

你的情況:

  1. 規範化架構:

    ALTER TABLE jobs 
        ADD initials CHAR(3)    NOT NULL FIRST, 
        ADD date  DATE     NOT NULL AFTER initials, 
        ADD seq  SMALLINT(3) UNSIGNED NOT NULL AFTER date, 
    ; 
    
  2. 規範化現有數據:

    UPDATE jobs SET 
        initials = SUBSTRING_INDEX(JobID, '-', 1), 
        date  = STR_TO_DATE(SUBSTRING(JobID, 5, 8), '%Y%m%d'), 
        seq  = SUBSTRING_INDEX(JobID, '-', -1) 
    ; 
    
  3. 搭建AUTO_INCREMENT

    ALTER TABLE jobs 
        DROP PRIMARY KEY, 
        DROP JobID, 
        MODIFY seq SMALLINT(3) UNSIGNED NOT NULL AUTO_INCREMENT, 
        ADD PRIMARY KEY(initials, date, seq) 
    ; 
    

然後,您可以重新創建JobID根據需要對SELECT(甚至創造一個view從這樣的查詢):

SELECT CONCAT_WS(
     '-', 
     initials, 
     DATE_FORMAT(date, '%Y%m%d'), 
     LPAD(seq, 3, '0') 
     ) AS JobID, 
     -- etc. 

如果你使用的是InnoDB,而你可以」以這種方式生成序列號我仍然建議像上面那樣對數據進行規範化。

+0

正如你所提到的那樣,我與正常化的想法作鬥爭。根據我的理解,儘管這會使JobID成爲一個複合主鍵,而這本身不是問題。問題在於JobID在其他幾張表格中用於顧客,工作項目,發票和發票項目,並且將來可能會有更多的表格,並且與這些表格中的另一列結合形成一個複合PK。這是一個很大的看法,但是將JobID分開會在其他表中增加不必要的複雜性,這些表中有許多使用JobID來自動化數據輸入的觸發器。 – Damon

+0

此外,使用自動遞增意味着我們必須有一種每日重置的方法,因爲自動遞增不會在未被告知的情況下進行重置,即使在這種情況下,它也不會忘記未強制關閉的位置。我們自動增加了另一個「daily_increment」表,並從中得到最後三個表,然後每天截斷表,但那是依靠一個預定的事件進行截斷,在關閉和意外停電時不能證明是可靠的。可以解決的問題,但我認爲消除預定的事件會一起證明是更強大。 – Damon

+0

@ user1707562:不,我上面的答案*的全部要點是MySQL會自動*每天旋轉'seq'的自動增量。如上所述的規範化仍然可以在不破壞FK的情況下實現(您只有複合FK),所以我不確定在這種情況下「複雜性」是什麼。 – eggyal