2013-07-16 49 views
3

我有一個現有的存儲過程可以生成員工ID。員工編號的格式爲EPXXXX,EP則爲4個數字值。我希望縮短存儲過程。自動增加MSSQL中的字母數字ID

enter image description here

以上表格(tblEmployee)給出。以下是用新員工編號插入新員工的存儲過程。這個過程是我必須得到最後一個員工ID,得到最後4位數字(這是數字),將其轉換爲整數,加1以增加,檢查數字是否小於10,100或1000或等於/更大比1000,添加前綴插入新的記錄到表中。

create procedure NewEmployee 

@EmployeeName VARCHAR(50) 

AS 
BEGIN 

    SET NOCOUNT ON 

    DECLARE @lastEmpID as VARCHAR(6) 
    SET @lastEmpID = 
    (
     SELECT TOP 1 Employee_ID 
     FROM tblEmployee 
     ORDER BY Employee_ID DESC 
    ) 

    DECLARE @empID as VARCHAR(4) 
    SET @empID = 
    (
     SELECT RIGHT(@lastEmpID, 4) 
    ) 

    DECLARE @numEmpID as INT 
    @numEmpID = 
    (
     SELECT CONVERT(INT, @empID) + 1 
    ) 

    DECLARE @NewEmployeeID as VARCHAR(6) 
    IF @numEmp < 10 
     SET @NewEmployee = SELECT 'EP000' + CONVERT(@EmpID) 
    IF @numEmp < 100 
     SET @NewEmployee = SELECT 'EP00' + CONVERT(@EmpID) 
    IF @numEmp < 1000 
     SET @NewEmployee = SELECT 'EP0' + CONVERT(@EmpID) 
    IF @numEmp >= 1000 
     SET @NewEmployee = SELECT 'EP' + CONVERT(@EmpID) 

    INSERT INTO tblEmployee(Employee_ID, Name) 
    VALUES (@NewEmployeeID, @EmployeeName) 

END 
+1

這將是容易得多本身(可能是'IDENTITY'列)在列的數字部分存儲,然後有一個產生計算列這個格式化的值。在這種情況下,無論您是否有專欄來存儲前綴或只是將其硬編碼爲「EP」,都是一個設計決策。 –

回答

1

嘗試這一個 -

CREATE PROCEDURE dbo.NewEmployee 

    @EmployeeName VARCHAR(50) 

AS BEGIN 

SET NOCOUNT ON; 

    INSERT INTO dbo.tblEmployee(Employee_ID, Name) 
    SELECT 
      'EP' + RIGHT('0000' + CAST(Employee_ID + 1 AS VARCHAR(4)), 4) 
      , @EmployeeName 
    FROM (
      SELECT TOP 1 Employee_ID = CAST(RIGHT(Employee_ID, 4) AS INT) 
      FROM dbo.tblEmployee 
      ORDER BY Employee_ID DESC 
    ) t 

END 
+0

它生成一個錯誤:「將varchar值'EP0004'轉換爲數據類型int時轉換失敗。」 – nigel

+0

請嘗試更新的答案。 – Devart

+0

它的工作,謝謝:) – nigel

1

我不認爲你需要一個Stored Procedure,嘗試使用Ranking Functions

select 
'EP'+RIGHT('000000'+ CAST(ROW_NUMBER() OVER (ORDER BY Name) AS VARCHAR(6)), 4) 
    AS [emp_code] 
, 
Name 
FROM emp1 WITH(NOLOCK) 

SQL Fiddle

編輯

select 
'EP'+RIGHT('000000'+ CAST((ROW_NUMBER() OVER (ORDER BY Name)+10) AS VARCHAR(6)), 4) 
    AS [emp_code]          --^Add the last Emp no. 
, 
Name 
FROM emp1 WITH(NOLOCK) 

SQL Fiddle

+0

嘗試過,但不增加新員工ID – nigel

+0

檢查小提琴。 – Luv

+0

它正在工作,但是表中存在的記錄是什麼,我需要爲員工放置順序ID,而不是名稱。 – nigel

2

我不建議在你目前有什麼,但是,我會做這種方式。這是我在我的應用程序中實現的方式。我會給你哪個。希望你喜歡這個。對於您可能擁有的所有交易,這完全是動態的和有效的。

我已經持有的文檔號爲表:

CREATE TABLE INV_DOC_FORMAT(
    DOC_CODE VARCHAR(10), 
    DOC_NAME VARCHAR(100), 
    PREFIX VARCHAR(10), 
    SUFFIX VARCHAR(10), 
    [LENGTH] INT, 
    [CURRENT] INT 
) 

將舉行的數據,如:

INSERT INTO INV_DOC_FORMAT(DOC_CODE,DOC_NAME,PREFIX,SUFFIX,[LENGTH],[CURRENT]) 
VALUES('01','INV_UNIT','U','',5,0) 

INSERT INTO INV_DOC_FORMAT(DOC_CODE,DOC_NAME,PREFIX,SUFFIX,[LENGTH],[CURRENT]) 
VALUES('02','INV_UNIT_GROUP','UG','',5,0) 

而且,我有一個函數或過程,但是,我這裏有一個函數可以生成文檔編號。

CREATE FUNCTION GET_DOC_FORMAT(@DOC_CODE VARCHAR(100))RETURNS VARCHAR(100) 
AS 
BEGIN 
    DECLARE @PRE VARCHAR(10) 
    DECLARE @SUF VARCHAR(10) 
    DECLARE @LENTH INT 
    DECLARE @CURRENT INT 
    DECLARE @FORMAT VARCHAR(100) 
    DECLARE @REPEAT VARCHAR(10) 
    IF NOT EXISTS(SELECT DOC_CODE FROM INV_DOC_FORMAT WHERE [email protected]_CODE) 
     RETURN '' 

    SELECT @PRE= PREFIX FROM INV_DOC_FORMAT WHERE [email protected]_CODE 
    SELECT @SUF= SUFFIX FROM INV_DOC_FORMAT WHERE [email protected]_CODE 
    SELECT @LENTH= [LENGTH] FROM INV_DOC_FORMAT WHERE [email protected]_CODE 
    SELECT @CURRENT= [CURRENT] FROM INV_DOC_FORMAT WHERE [email protected]_CODE 
    SET @REPEAT=REPLICATE('0',(@LENTH-LEN(CONVERT(VARCHAR, @CURRENT)))) 
    SET @[email protected] + @REPEAT +CONVERT(VARCHAR, @CURRENT+1) + @SUF 
    RETURN @FORMAT 
END 

可以使用的功能等:

INSERT INTO  INV_UNIT(UNIT_CODE,UNIT_NAME,UNIT_ALIAS,APPROVED,APPROVED_USER_ID,APPROVED_DATE) 
      VALUES(DBO.GET_DOC_FORMAT('01'),@Unit_Name,@Unit_Alias,@APPROVED,@APPROVED_USER_ID,@APPROVED_DATE) 

--After Transaction Successfully complete, You can 

UPDATE INV_DOC_FORMAT SET [CURRENT]=[CURRENT]+1 WHERE DOC_CODE='01' 

或者,你可以創建一個單一的程序這將獨自處理所有的事情太多。

希望你得到的方式......

因此, 看你的路,你這是一個錯誤。 你得到 SET @lastEmpID = ( SELECT TOP 1的Employee_ID FROM tblEmployee ORDER BY的Employee_ID DESC )

末員工ID,然後你操縱ID的其餘部分。這將創建或重新使用先前生成的ID,但現在已刪除。 假設EMP0010在那裏。經過一天EMP被刪除。所以,當你下一次再次創建一個Employeee時,你會得到與之前僱傭的人相同的Emp ID,但是不會再有更多的退出。我不認爲這是一個好主意。

,取而代之的是:

DECLARE @NewEmployeeID as VARCHAR(6) 
    IF @numEmp < 10 
     SET @NewEmployee = SELECT 'EP000' + CONVERT(@EmpID) 
    IF @numEmp < 100 
     SET @NewEmployee = SELECT 'EP00' + CONVERT(@EmpID) 
    IF @numEmp < 1000 
     SET @NewEmployee = SELECT 'EP0' + CONVERT(@EmpID) 
    IF @numEmp >= 1000 
     SET @NewEmployee = SELECT 'EP' + CONVERT(@EmpID) 

您用來重複一個零。您將使用SQL的複製函數()。像上面的例子一樣。

SET @REPEAT=REPLICATE('0',(@LENTH-LEN(CONVERT(VARCHAR, @CURRENT)))) 
+0

該表已存在,我無權修改該結構。仍然感謝您的回覆,這對未來的使用可能有用。 – nigel

+1

您正在創建一個完整的過程,這將產生一個單一交易的ID!這聽起來不錯嗎?爲什麼你沒有一個過程可以爲您的應用程序中的所有交易生成一個ID?如果是這樣,現在,你可以在那裏建議你的老大。不要你!我認爲你必須。你是這樣做的,如果你有200種類型的交易,如員工,代理,供應商,客戶...什麼,你會創建單個過程foreach生成一個ID?最好你有一個可以管理alllll的程序。建議你的老師。 –

0

當然,接受的答案工作正常,但它不工作,如果我們有以前的值numm。所以如下修改它,希望這將幫助其他人也

CREATE PROCEDURE dbo.NewEmployee 

@EmployeeName VARCHAR(50) 
AS BEGIN 
SET NOCOUNT ON; 

INSERT INTO dbo.tblEmployee(Employee_ID, Name) 
SELECT 
     'EP' + RIGHT('0000' + CAST(Employee_ID + 1 AS VARCHAR(4)), 4) 
     , @EmployeeName 
FROM (
     SELECT TOP 1 Employee_ID = CAST(RIGHT(Employee_ID, 4) AS INT) 
     FROM dbo.tblEmployee 
     ORDER BY Employee_ID DESC 
) t 
END