• 在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. }






  • 相关阅读:
    ls-remote -h -t git://github.com/adobe-webplatform/eve.git
    vue学习(四)登陆、注册、首页模板页区分
    Asp.Net Api+Swagger控制器注释
    vue学习(三)完善模板页(bootstrap+AdminLTE)
    vue学习(二)模板页配置(bootstrap)
    vue学习(一)项目搭建
    react-native当使用antd-mobile出现View config not found for name div
    部署上次的Hapi到Windows+Docker,WindowsDocker
    Hapi+MySql项目实战自动化文档生成(四)
    Android DialogFragment 遇到 java.lang.IllegalStateException: Fragment already added: 的解决方法
  • 原文地址:https://www.cnblogs.com/cmicat/p/5080647.html
Copyright © 2020-2023  润新知