【问题标题】:Stored Procedure doesn't bring results存储过程不带来结果
【发布时间】:2019-08-19 16:46:42
【问题描述】:
  • 我的存储过程没有带来应有的结果

  • 所有参数都设置好,比如我的表名(根据年/月变化)。

  • 当我在 Management Studio 上手动执行查询时,结果会出现,但是当我在 Controller 上调用该过程时,结果却没有。

  • PS:直接执行的代码是其他日期的,但是在IDE中执行的带有通知日期的代码应该也带来了结果,我试过不同的日期,问题似乎出在存储过程查询。


存储过程代码:

ALTER PROCEDURE [dbo].[usp_listarRegistrosMov]
    --PARÂMETROS
    @NomeTabela VARCHAR(20),
    @DataInicial VARCHAR(20),
    @DataFinal VARCHAR(20),
    @Cracha FLOAT
AS
BEGIN
  Declare @Comando Varchar(1000)

  Set @Comando = 'SELECT * FROM ' + @NomeTabela + ' WHERE mov_data BETWEEN ' + @DataInicial + ' AND ' + @DataFinal + ' AND mov_cracha = ' + CAST(@Cracha AS VARCHAR(20))

  Exec(@Comando)
END
GO

控制器代码:

    public void consultar() {
        LocalDate dataInicio = dataInicial.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate dataFim = dataFinal.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        String mesInicio = String.valueOf(dataInicio.getMonthValue());
        String mesFim = String.valueOf(dataFim.getMonthValue());
        String anoInicio = (String.valueOf(dataInicio.getYear())).substring(2,4);
        String anoFim = (String.valueOf(dataFim.getYear())).substring(2,4);
        String empresaString = String.valueOf(Math.round(funcionario.getEmpresa().getCodigo()));
        long mesesDiferencaGlob = ChronoUnit.MONTHS.between(dataInicio, dataFim) + 1;

        if (dataInicio.isAfter(dataFim)) {
            Messages.addGlobalError("Informe uma data inicial posterior à data final");
            return;
        }

        if (dataInicio.getMonthValue() != dataFim.getMonthValue()) {
            if (dataInicio.getYear() == dataFim.getYear()) {
                do {
                    System.out.println(mesesDiferencaGlob);
                    String tabela = ("M00"+(String.valueOf(Math.round(funcionario.getEmpresa().getCodigo())))+anoInicio+"0"+mesInicio);
                    System.out.println(tabela);
                    DateTimeFormatter formatadorInicio = DateTimeFormatter.ofPattern("dd/MM/yyyy");
                    String dataInicioString = dataInicio.format(formatadorInicio);
                    String dataFimString = dataFim.format(formatadorInicio);
                    System.out.println(dataInicioString + dataFimString);
                    setRegistrosTemp(eventoEspelhoPontoRepository.findAllRegistrosByFuncionarioTableUnica(tabela, dataInicioString, dataFimString, funcionario.getCracha()));
                    for (EventoEspelhoPonto item : registrosTemp) {
                        registros.add(item);                        
                    }
                    int mesInicioInt = Integer.parseInt(mesInicio) + 1;
                    mesInicio = Integer.toString(mesInicioInt);
                    mesesDiferencaGlob--;
                } while (mesesDiferencaGlob != 0);      
            }   
        }
}

存储库代码:

@Query(value = "EXECUTE usp_listarRegistrosMov :tabela, :dataInicial, :dataFinal, :cracha", nativeQuery = true)
List<EventoEspelhoPonto> findAllRegistrosByFuncionarioTableUnica(@Param("tabela") String tabela,
                                                                 @Param("dataInicial") String dataInicial,
                                                                 @Param("dataFinal") String dataFinal,
                                                                 @Param("cracha") Double cracha);

【问题讨论】:

  • 如果将存储库更改为与过程相同的参数名称会发生​​什么情况(例如:NomeTabela 而不是tabela
  • 我看到您有一个 FLOAT 类型的参数 Cracha,您可以与之进行精确比较。在过程中将此浮点数转换为字符串值。但字符串表示至少在 3 个方面可能有点棘手: 精确错误会使精确比较不可靠。限制为 20 个字符可能还不够。小数点可以根据设置在点和逗号之间变化。尽量避免与已转换为字符串的浮点值进行精确比较。
  • @TabAlleman 它什么都没有改变,我有另一个程序在其他存储库中执行 ALTER 程序,名称完全相同并且运行良好,我几乎 100% 确定这与存储过程中的 SELECT 方法有关,我读到它与“输出”值有关,不确定...
  • @Morten Cracha 上的 Float 类型它是一个数据库错误,它应该是整数......所以所有 Cracha 总是 .0,我测试的这个数字是 25.0,转换为字符串 = 25. 奇怪的是我还有另一个与 cracha 相关的存储过程,但它是一个 UPDATE 存储过程,我创建了它并且它工作正常,这个 SELECT 让我觉得我错过了一些东西,因为另一个我已经完成了

标签: java sql sql-server spring stored-procedures


【解决方案1】:

在您的存储过程中,因为您在动态 sql 字符串中使用日期字符串,所以您需要在它们周围添加 2 个单引号,以便执行的字符串将它们括在单引号中。

换句话说,改变这个:

Set @Comando = 'SELECT * FROM ' + @NomeTabela + 
               ' WHERE mov_data BETWEEN ' + @DataInicial + ' AND ' + @DataFinal + ' AND mov_cracha = ' + CAST(@Cracha AS VARCHAR(20))

到这里:

Set @Comando = 'SELECT * FROM ' + @NomeTabela + 
               ' WHERE mov_data BETWEEN ''' + @DataInicial + ''' AND ''' + @DataFinal + ''' AND mov_cracha = ' + CAST(@Cracha AS VARCHAR(20))

我不保证这是您唯一的问题,因为我不会说 java,但这绝对是您的存储过程中的问题。

【讨论】:

  • 感谢您的建议!在这种情况下,我作为 DATE、DATETIME 或 STRING 工作会更好吗?我现在正在修 sp
  • 既然你使用的是动态sql,那么你最好还是坚持STRING参数,因为你在构建动态字符串的时候无论如何都要将它们转换成字符串。
  • 确实,它似乎解决了我最初的报价问题,谢谢!但是我的前端空行,也许与连接有关?打算在 EDIT 1 上张贴一张照片,也许你能帮助我?
  • 我会看看,但我怀疑我不会有多大帮助,因为我不懂 java。
  • 好吧,我调试了选择,它做得很好,由于两个不同的月份,重复了两次,通常每个表都给我带来了一个对象..但表中没有信息已经出现了,我去看看
猜你喜欢
  • 2016-06-12
  • 2021-03-22
  • 2014-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-04
  • 1970-01-01
相关资源
最近更新 更多