【问题标题】:alternate way to execute stored proc using simplejdbccall使用 simplejdbccall 执行存储过程的替代方法
【发布时间】:2020-03-08 11:10:18
【问题描述】:

无法在使用 SimpleJdbcCall 执行存储过程时捕获可读的 sql。我执行的 SQL Server 分析器将显示一个冗长的 SQL,因为该值不在参数旁边,所以不可读。 有没有其他方法可以执行存储过程,最好使用 spring-jdbc 创建类似于下面预期下所示的可读 sql?

我尝试使用 useInParameterNames 和/或 withoutProcedureColumnMetaDataAccess 和/或 not-declaring-input-parameters 构建 SimpleJdbcCall,但没有得到肯定的结果

我的 DAO

SimpleJdbcCall call = new SimpleJdbcCall(dataSource)
            .withProcedureName("UpdateSomethingProc");
 final SqlParameterSource in = new MapSqlParameterSource()
                .addValue(parm1, null)
                .addValue(parm2, null)
                .addValue(parm3, null)
                .addValue(parm4, "1")
                .addValue(parm5, "987654321")
...
                .addValue(parm21, null);
                .addValue(parm22, null);
call.execute(in);

存储过程定义

CREATE      PROCEDURE [dbo].[UpdateSomethingProc] 
@parm1  varchar(16) = NULL,
@parm2  integer     = NULL,
@parm3  varchar(16) = NULL,
@parm4  char(3) ,
@parm5  char(18),
@parm6  T_DBID,
@parm7  char(3) ,
@parm8  char(1) ,
@parm9  char(4) ,
@parm10 smallint    = 0,
@parm11 char(4)     = NULL,
@parm12 char(4)     = NULL,
@parm13 smallint    = NULL,
@parm14 smallint    = NULL,
@parm15 smallint    = NULL,
@parm16 smallint    = NULL,
@parm17 smallint    = NULL,
@parm18 char(4)    = NULL,  
@parm19 char(4)    = NULL,  
@parm20 char(4)     = NULL,
@parm21 smallint    = 0,        
@parm22 smallint    = 0 

预期: 使用 C++ 的旧应用程序最终会在 SQL Server Profiler 中遵循 SQL,因为它显示了参数名称和相应的值,因此更具可读性。

exec dbo.UpdateSomethingProc @param1='0x9',@parm2='1',@parm3='987654321',@parm4='ABC',@parm5='000',@parm6='1',@parm7='505B',@parm8='0',@parm9='999',@parm10='',@parm11='0',@parm12='0',@parm13='0',@parm14='0',@parm15='0',@parm16='2019/11/11 23:54:35',@parm17='HUB',@parm18='0'

实际: 使用 Spring Boot 的新应用程序最终会在 SQL Server Profiler 中使用以下 SQL。正如您所注意到的,很难读取哪个参数具有哪个值。特别是在故障排除时。

exec sp_executesql N'EXEC dbo.UpdateSomethingProc @P0, @P1, @P2, @P3, @P4, @P5, @P6, @P7, @P8, @P9, @P10, @P11, @P12, @P13, @P14, @P15, @P16, @P17, @P18, @P19, @P20, @P21  ',N'@P0 nvarchar(4000),@P1 int,@P2 nvarchar(4000),@P3 nvarchar(4000),@P4 nvarchar(4000),@P5 nvarchar(4000),@P6 nvarchar(4000),@P7 nvarchar(4000),@P8 nvarchar(4000),@P9 smallint,@P10 nvarchar(4000),@P11 nvarchar(4000),@P12 smallint,@P13 smallint,@P14 smallint,@P15 smallint,@P16 smallint,@P17 nvarchar(4000),@P18 nvarchar(4000),@P19 nvarchar(4000),@P20 smallint,@P21 smallint',NULL,NULL,NULL,N'1',N'987654321',N'ABC',N'000',N'2',N'505B',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,N'2019-11-12T00:14:29.859Z',NULL,NULL,NULL,NULL

【问题讨论】:

  • 我不明白这里的问题。您是在问如何使分析器提供不同的输出?
  • @SeanLange,用问题更新了帖子。感谢您的回复。

标签: java spring-jdbc simplejdbccall


【解决方案1】:

这是几乎所有 ORM 调用存储过程(或任何其他参数化 sql 语句)的方式。它将确保值被显式传递并且不受 sql 注入等影响。

我对 JDBC 不熟悉,但它看起来有“准备好的语句”的概念。如果 sql 的格式对您来说特别重要,我会使用准备好的语句.... 伪代码:

query = connection.preparedStatment('exec sp_MyProc @param1=?, @param2=?');

query.supplyValue(1, value1);
query.supplyValue(2, value2);

query.execute

请记住,这将导致与您已经看到的语句类似的语句,但您可以稍微控制它的详细程度。

【讨论】:

  • 这将是我最后的手段,除非我可以使用 SimpleJdbcCall 本身进行一些调整
  • 老实说,虽然查看原始输出有点痛苦,但它也是 ORM 执行此操作的“正确”方式……您不必非常看通常,除非您发现自己只是在不断地调试该过程,即使那样它也只是位置匹配。
  • 换句话说,JDBC 没有真正的理由提供更好看输出,因为更好看代码是 JDBC 本身给你的,它是数据库和数据库之间的抽象层你的代码。
猜你喜欢
  • 1970-01-01
  • 2019-06-25
  • 2017-04-04
  • 1970-01-01
  • 2017-09-15
  • 2023-04-04
  • 2020-10-08
  • 1970-01-01
相关资源
最近更新 更多