我是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
自动递增?请检查语法。我的语法有很多问题。
非常感谢你!
答案 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会将它们视为大写。只需确保您的表已使用小写列名称定义。