如何在oracle 10g数据库中插入并返回使用存储过程生成的ID

时间:2016-04-14 04:33:09

标签: oracle stored-procedures

我是oracle的sql开发人员(因为我们已经研究过mysql)以及编程方面的新手。我在本网站上搜索了我的问题的答案,但我真的无法理解所提供的解决方案。

我想要的是返回从java插入对象后生成的ID到数据库中。我正在使用mybatis和oracle 10g数据库。我已经创建了表格及其列。

这是我的mapper代码

<insert id="addUser" parameterType="User" statementType="CALLABLE"> { CALL addUserSP( #{user.surname, javaType=String, jdbcType=VARCHAR, mode=IN}, #{user.firstName, javaType=String, jdbcType=VARCHAR, mode=IN}, #{userId, javaType=Integer, jdbcType=NUMBER, mode=OUT} )} </insert>

这是我的存储过程(我已经创建了一个名为&#39; CREATEUSER&#39;的程序包)

PROCEDURE ADDUSERSP
( surname IN VARCHAR2, 
  firstName IN VARCHAR2,
  userId OUT NUMBER
) AS

BEGIN

INSERT INTO users("surname", "first_name")
VALUES (surname, firstName);
RETURNING user_id INTO userId;

END ADDUSERSP;

根据我在这里找到的内容,似乎我需要创建一个触发器(?)和序列(?),以便在我向表中添加新数据时使user_id自动递增。但是,我不知道该怎么做。

以下是我的问题: 我的存储过程是对的吗?代码是否不完整?我的意思是,我没有在映射器中声明包,我已经看到它需要(?),类似于{ CALL [CreateUser].[addUserSP]( blah blah...。我应该编写序列和触发器还是有一种简单的方法可以使主键user_id自动递增?请检查语法。我的语法有很多问题。

非常感谢你!

1 个答案:

答案 0 :(得分:1)

要在Oracle中模拟MySQL AUTO_INCREMENT,该模式(如您所见)确实使用了SEQUENCE对象和BEFORE INSERT触发器。

作为演示,对于序列对象来说是这样的:

CREATE SEQUENCE myseq START WITH 1 INCREMENT BY 1 ;

以前插入触发器的类似内容:

CREATE TRIGGER users_bi
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
   IF :NEW.id IS NULL THEN
      SELECT myseq.NEXTVAL INTO :NEW.id FROM DUAL;
   END IF;
END

就程序而言,我并不是包装SQL INSERT语句的额外PL / SQL块的忠实粉丝。

在RETURNING之前看起来你有一个额外的分号。该子句是INSERT语句的一部分,而不是单独的语句。

需要注意的一个重要问题是PL / SQL块中的SQL语句可以引用列和PL / SQL变量。当变量与列具有相同的名称时,您可能会遇到您不期望的行为。

通常,PL / SQL作者使用变量的命名约定来降低名称冲突的可能性。我们经常看到名称为v_surname的变量。 (就个人而言,我使用略有不同的约定,但是变量名称&#34;看起来像&#34;变量名称,而不是列引用。而且我没有按照我用于变量的模式命名列。)

标识符周围的双引号是可以接受的,但这确实使标识符区分大小写。如果标识符不用双引号括起来,Oracle会将它们视为大写。只需确保您的表已使用小写列名称定义。