存储过程的并发问题

时间:2012-02-20 10:11:32

标签: oracle plsql

我需要帮助。我有以下存储过程但我有并发问题。任何人都可以告诉我如何修改存储过程以避免重复键错误,因为两个用户一次进行相同的选择?主键是字段IDSOLICITUD和表OS SOLIC,这是数字,我想在每次访问它时将一个计数器插入到该表中并将该值返回给调用应用程序。表的结构我无法改变,我不能放一个自动编号。

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;

谢谢。

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:0)

根据无法使用自动增量进行编辑

以下假设您正在使用MySQL,对于Oracle,请参阅其他答案

看到你无法将它改为AutoIncrement,你似乎不得不求助于使用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;