在JDBC中传递table参数给SQL server stored procedure

SQL Server JDBC驱动不支持直接传递Table参数给stored procedure

我的做法是先创建一个临时表,将需要插入的数据先插入到临时表里面,然后把这个临时表作为参数,传送给stored procedure。使用了Preparestatement来避免SQL注入问题。

先创建User Defined Table
  1. CREATE TYPE UserIdList AS TABLE(
  2. userId uniqueidentifier NOT NULL
  3. );

再创建存储过程:
  1. CREATE PROC insertIntoExamArrange
  2. @subjectId uniqueidentifier,
  3. @startTime datetime2(0),
  4. @duration time(7),
  5. @site nvarchar(255),
  6. @examName nvarchar(255),
  7. @studentIdList dbo.UserIdList READONLY,
  8. @supervisorIdList dbo.UserIdList READONLY
  9. AS
  10. BEGIN
  11. DECLARE @op TABLE (
  12. colGuid uniqueidentifier
  13. );
  14. DECLARE @examId uniqueidentifier;
  15. BEGIN TRAN
  16. INSERT INTO dbo.ExamArrange
  17. (subjectId,startTime,duration,site,examName)
  18. OUTPUT inserted.examId
  19. INTO @op
  20. VALUES(@subjectId, @startTime, @duration, @site, @examName);
  21. SELECT TOP 1
  22. @examId = colGuid
  23. FROM @op;
  24. INSERT INTO dbo.Exam_Student_Relationship
  25. (examId,studentId)
  26. SELECT @examId, userId
  27. FROM @studentIdList;
  28. INSERT INTO dbo.Exam_Supervisor_Relationship
  29. (examId,supervisorId)
  30. SELECT @examId, userId
  31. FROM @supervisorIdList;
  32. COMMIT
  33. END

根据下面的SQL语句,生成相应的Java代码
  1. DECLARE @studentList UserIdList;
  2. INSERT INTO @studentList
  3. VALUES('38C6D0B1-948D-412F-80BA-5BADDD7ABF53'),
  4. ('A3E7AAFF-3C0A-4B27-B92E-15DC5FA479BA');
  5. DECLARE @supervisorList UserIdList;
  6. INSERT INTO @supervisorList
  7. VALUES
  8. ('DE6E2A5B-05D9-484A-B225-C8C7265A816B'),
  9. ('2EEBE00E-117D-4382-9828-93C7F6922F75');
  10. EXEC dbo.insertIntoExamArrange
  11. 'D5C544C2-9983-4805-8599-44DDE095289D','2015-12-18 18:16:30','1:50:33',
  12. '测试楼','编译原理临时考试',@studentList,@supervisorList;

下面是对应上面SQL语句的java代码
  1. public void insertExamArrange(ExamArrange arr, List<User> supervisors,
  2. List<User> students) throws SQLException {
  3. StringBuilder query = new StringBuilder();
  4. if (students.size() > 0) {
  5. query.append(" DECLARE @studentList UserIdList; "
  6. + " INSERT INTO @studentList VALUES(?) ");
  7. for (int i = 0; i < students.size() - 1; ++i) {
  8. query.append(" ,(?) ");
  9. }
  10. query.append(" ; ");
  11. }else{
  12. assert students.size()==0;
  13. query.append(" DECLARE @studentList UserIdList; ");
  14. }
  15. if (supervisors.size() > 0) {
  16. query.append(" DECLARE @supervisorList UserIdList; "
  17. + " INSERT INTO @supervisorList VALUES(?) ");
  18. for (int i = 0; i < supervisors.size() - 1; ++i) {
  19. query.append(" ,(?) ");
  20. }
  21. query.append(" ; ");
  22. }else{
  23. assert supervisors.size()==0;
  24. query.append(" DECLARE @supervisorList UserIdList; ");
  25. }
  26. query.append(" EXEC dbo.insertIntoExamArrange "+
  27. " ?,?,?,?,?,@studentList,@supervisorList; ");
  28. try(PreparedStatement pre = getConnection().prepareStatement(query.toString())){
  29. int preIndex = 1;
  30. for(int i=0;i<students.size();++i){
  31. pre.setString(preIndex, students.get(i).getUserId());
  32. ++preIndex;
  33. }
  34. for(int i=0;i<supervisors.size();++i){
  35. pre.setString(preIndex, supervisors.get(i).getUserId());
  36. ++preIndex;
  37. }
  38. pre.setString(preIndex,arr.getSubjectId());
  39. ++preIndex;
  40. pre.setTimestamp(preIndex, arr.getStartTime());
  41. ++preIndex;
  42. pre.setTime(preIndex, arr.getDuration());
  43. ++preIndex;
  44. pre.setString(preIndex, arr.getSite());
  45. ++preIndex;
  46. pre.setString(preIndex, arr.getExamName());
  47. ++preIndex;
  48. pre.execute();
  49. }
  50. }






posted @ 2015-12-27 19:22  cmicat  阅读(475)  评论(0编辑  收藏  举报