2012-02-20 119 views
0

我需要幫助。我有以下存儲過程但我有併發問題。任何人都可以告訴我如何修改存儲過程以避免重複鍵錯誤,因爲兩個用戶同時進行相同的選擇?主鍵是字段IDSOLICITUD和表os os,它是數字型的,我想在每次訪問它時將計數器插入此表中並將該值返回給調用應用程序。表格的結構我不能改變,我不能放一個自動編號。存儲過程的併發問題

CREATE procedure PRC_SOLIC(FECHA IN DATE, IDTRAMITE IN VARCHAR2, ESTADO IN NUMBER, ESTADO_FECHA IN DATE, MENSAJE_ERROR IN VARCHAR2, CPROVIN IN NUMBER, CMUNICI IN NUMBER, NHABITA IN NUMBER, NDOMICI IN NUMBER, REFORIGEN IN VARCHAR2,OPERACION_TIPO IN VARCHAR2, OPERACION_CODIGO IN NUMBER, USUARIO IN VARCHAR2, FINALIDAD IN VARCHAR2, RESULTADO IN VARCHAR2,NUM OUT NUMBER) is 

    v_Numero NUMBER; 

    CURSOR c_Solic is SELECT MAX(IDSOLICITUD)+1 FROM SOLIC; 

BEGIN 
    OPEN c_Solic; 
    FETCH c_Solic INTO v_Numero; 

    IF (v_Numero is NULL) THEN 
    v_Numero := 1; 
    END IF; 

    INSERT INTO SOLIC VALUES (v_Numero, FECHA, IDTRAMITE, ESTADO, ESTADO_FECHA, MENSAJE_ERROR, CPROVIN, CMUNICI, NHABITA, 
    NDOMICI, REFORIGEN, OPERACION_TIPO, OPERACION_CODIGO, USUARIO, FINALIDAD, RESULTADO);  

    NUM := v_Numero; 

    close c_Solic; 


END PRC_SOLIC; 

謝謝。基於暫時無法使用自動遞增

回答

0

編輯

下面假設你正在使用MySQL,甲骨文請參閱其他答案

看到,因爲你不能改變它是一個自動增加你似乎不得不求助於使用顯式鎖定表LOCK TABLES

http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html

這給

CREATE procedure PRC_SOLIC(FECHA IN DATE, IDTRAMITE IN VARCHAR2, ESTADO IN NUMBER, ESTADO_FECHA IN DATE, MENSAJE_ERROR IN VARCHAR2, CPROVIN IN NUMBER, CMUNICI IN NUMBER, NHABITA IN NUMBER, NDOMICI IN NUMBER, REFORIGEN IN VARCHAR2,OPERACION_TIPO IN VARCHAR2, OPERACION_CODIGO IN NUMBER, USUARIO IN VARCHAR2, FINALIDAD IN VARCHAR2, RESULTADO IN VARCHAR2,NUM OUT NUMBER) is 

BEGIN 
    // Declare the variable which will hold the "AI" field 
    DECLARE thisSolicID INT UNSIGNED DEFAULT 0; 
    // Lock the table for writing 
    LOCK TABLES SOLIC WRITE; 
    // Get the "AI" value 
    SELECT COALESCE(MAX(IDSOLICITUD),0)+1 INTO thisSolicID FROM FROM SOLIC; 
    // Insert it 
    INSERT INTO SOLIC VALUES (thisSolicID, FECHA, IDTRAMITE, ESTADO, ESTADO_FECHA, MENSAJE_ERROR, CPROVIN, CMUNICI, NHABITA, NDOMICI, REFORIGEN, OPERACION_TIPO, OPERACION_CODIGO, USUARIO, FINALIDAD, RESULTADO);  
    // Unlock the table 
    UNLOCK TABLES; 
END PRC_SOLIC; 
+0

非常感謝您的快速反應,但是場IDSOLICITID不是自動遞增。這只是一個數字,我不能改變表格的結構 – user1220719 2012-02-20 10:39:56

+0

謝謝您的評論。現在我測試它。非常感謝你。 – user1220719 2012-02-20 10:59:16

1

你的標籤很混亂,是Oracle還是MySQL?如果Oracle然後考慮使用序列來處理這類事情。見Managing Sequences。然後,您可以創建一個序列,例如:

CREATE SEQUENCE IDSOLICITUD_SEQ 
START WITH 1 
INCREMENT BY 1; 

然後在你的代碼:

CURSOR c_Solic is SELECT IDSOLICITUD_SEQ.NEXTVAL FROM SYS.DUAL; 
+0

非常感謝您的回覆。它是PL/SQL。這個存儲過程是從web服務調用的。 – user1220719 2012-02-20 10:52:49

+1

如果你使用11g,你可以直接從PL/SQL調用'IDSOLICITUD_SEQ.NEXTVAL',不需要使用遊標。 – 2012-02-21 13:24:52