最近由于项目中有些业务要用到存储过程来写,所以在数据库中添加了一个简单的存储过程,如下:
ALTER PROCEDURE [dbo].[Test_addperson]
@name AS varchar(20) ,
@password AS varchar(20) ,
@age AS int,
@allCount int = 0 output--总数
AS
BEGIN
insert into z_person_test (name,password,age) values (@name,@password,@age)
SET @allCount = @@rowcount
END
这是一个向person表中插入数据的简单存储过程,语法我就不一一介绍了,相信大家肯定都比我牛b!
但是当这段语句在Navicat中运行时,报出下面的错误
必须声明标量“xxxx”,也就是你想输出的数据信息,调试了好久,也找不到错误处在哪里。
最后不得已在项目中添加了Person的实体类和Service和Dao,然后用Junit测试!
下面只写了iml的代码,接口的代码此处就省略了!
PersonServiceImpl.java
@Transactional
@Service(value="personService")
public class PersonServiceImpl implements PersonService{
@Autowired
private PersonDao personDao;
public void add(Person p) throws Exception {
personDao.add(p);
}
}
PersonServiceDaoImpl.java
@Repository(value="personDao")
public class PersonDaoImpl extends SqlSessionDaoSupport implements PersonDao{
public void add(Person p) throws Exception {
getSqlSession().selectOne("person.add", p);
System.out.println("------------"+p.getAllCount()); //此处的allCount变量要在Person实体类中定义,不然取不到存储过程反回的输出数据。
}catch(Exception e){
e.printStackTrace();
throw new Exception(e.getMessage());
}
}
}
Person-mapper.xml
<select id="add" statementType="CALLABLE" parameterType="java.util.HashMap" resultType="person"> <--此处的标签,如果使用存储过程一定要使用select标签 -->
<![CDATA[
{#{allCount,mode=OUT,jdbcType=INTEGER}=call Test_addperson(
#{name,mode=IN,jdbcType=VARCHAR},
#{password,mode=IN,jdbcType=VARCHAR},
#{age,mode=IN,jdbcType=INTEGER},
#{allCount,mode=OUT,jdbcType=INTEGER}
)}
]]>
</select>
然后运行代码,发现存储过程原来是没问题的,添加的反回数据也可以添加成功
@Test
public void Test2(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("conf/spring-*.xml");
PersonService personService = (PersonService) applicationContext.getBean("personService");
Person person = new Person();
person.setAge(19);
person.setName("AAAA");
person.setPassword("BBBB");
try {
personService.add(person);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
从上面可以看出,有些存储过程在某些IDE中提示的错误,并不能完全的代表是存储过程出错了,我们可能是被某些数据库的操作软件坑了!