Выберите Количество хранимых процедур с динамическим запросом не работает правильно - PullRequest
1 голос
/ 01 апреля 2019

-Я пытаюсь выполнить хранимую процедуру, которая должна вернуть мне результат Count, но это дает мне следующую ошибку (на португальском):

2019-04-01 10:13:49.215  WARN 7068 --- [io-8080-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 214, SQLState: S0002
2019-04-01 10:13:49.216 ERROR 7068 --- [io-8080-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper   : O procedimento espera o parâmetro '@statement' do tipo 'ntext/nchar/nvarchar'.

-Я не совсем понимаюпотому что единственный параметр, который я установил, - это имя таблицы, которое я передаю в своем коде выполнения репозитория.

-Это моя хранимая процедура:

ALTER PROCEDURE [dbo].[usp_verificarTabelaCadMov] (
    @NomeTabela VARCHAR(20)

)   
AS
BEGIN
    SET NOCOUNT ON;

Declare @Comando Varchar(1000)
Declare @Resultado INT;

Set @Comando = 'SELECT @Resultado = COUNT(*) FROM sysobjects WHERE nome = ' + QUOTENAME(@NomeTabela)

exec sp_executesql @Comando , N'@Resultado INT OUTPUT', @Resultado = @Resultado OUTPUT

SELECT @Resultado

END;

GO

-Это моевыполнение в моем репозитории:

@Query(value = "EXECUTE usp_verificarTabelaCadMov :tabela", nativeQuery = true)
public Integer verificarTabela(@Param("tabela") String tabela);

-В моем контроллере:

                    String tabela = ("M00"+(String.valueOf(Math.round(funcionario.getEmpresa().getCodigo())))+anoInicio+mesAtual);
                    if (eventoEspelhoPontoRepository.verificarTabela(tabela) > 1) {
                        registros.addAll(eventoEspelhoPontoRepository.findAllRegistrosByFuncionarioTableUnica(
                                tabela, dataInicioString, dataFimString, funcionario.getCracha()));
                    }

EDIT1 - я пытаюсь сделать здесь, выбрать ряд таблиц, но иногда некоторые изтаблиц не существует, поэтому я пытаюсь выполнить проверку, если таблица существует, и если она существует, она должна выполнить Select * из этой таблицы, в противном случае ее следует игнорировать.Это единственный способ, который я нашел, чтобы сделать это, если у кого-то есть лучший способ, пожалуйста, помогите мне.

Кстати, это мой выбор, упомянутый выше, я попытался проверить существование таблицы с помощью пункта ЕСЛИ СУЩЕСТВУЕТно это все же работает, я продолжаю получать сообщение об ошибке «НЕ МОЖЕТ ЭКСТРАКТИРОВАТЬ РЕЗУЛЬТАТ УСТАНОВИТЬ» в моей основной программе.

ALTER PROCEDURE [dbo].[usp_listarRegistrosMov]
    --PARÂMETROS
    @NomeTabela VARCHAR(20),
    @DataInicial VARCHAR(20),
    @DataFinal VARCHAR(20),
    @Cracha FLOAT

AS  

IF EXISTS(SELECT name FROM sysobjects WHERE name = @NomeTabela AND xtype = 'U')

BEGIN

Declare @Comando Varchar(1000)

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

Exec(@Comando)

END



GO

РЕДАКТИРОВАТЬ 2: Я пытался использовать OBJECT_ID в том же sp также:

IF OBJECT_ID(@NomeTabela) IS NOT NULL

Но всегда получаю ошибку:

2019-04-01 11:18:03.147  WARN 7068 --- [nio-8080-exec-8] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: null
2019-04-01 11:18:03.148 ERROR 7068 --- [nio-8080-exec-8] o.h.engine.jdbc.spi.SqlExceptionHelper   : The statement did not return a result set.

Ответы [ 2 ]

1 голос
/ 01 апреля 2019

Я бы сделал что-то вроде этого:

ALTER PROCEDURE dbo.usp_verificarTabelaCadMov
(
  @NomeTabela VARCHAR(20)
)
AS
  BEGIN
    SET NOCOUNT ON;

    DECLARE @Comando NVARCHAR(1000);
    DECLARE @Resultado INT;

    SET @Resultado = -1

        -- Or set to NULL depending on how you would like to handle table existence in the application code;
        --SET @Resultado = NULL

    IF OBJECT_ID(QUOTENAME(@NomeTabela), 'U') IS NOT NULL
      BEGIN
        SET @Comando = N'SELECT @Resultado = COUNT(*) FROM ' + QUOTENAME(@NomeTabela);

        EXEC sys.sp_executesql
          @Comando
          , N'@Resultado INT OUTPUT'
          , @Resultado OUTPUT;
      END;

    SELECT @Resultado AS resultado;
  END;

Таким образом, в зависимости от вашего выбора, как обрабатывать существование таблицы, звоните

EXEC dbo.usp_verificarTabelaCadMov @NomeTabela = 'thistabledoesNOTexist';

вернет -1 или NULL (см. Сохраненный комментарий к процессу) и

EXEC dbo.usp_verificarTabelaCadMov @NomeTabela = 'thistableDOESexist';

вернет значение> -1.

0 голосов
/ 01 апреля 2019

Исправлено, мне пришлось:

1 - Измените мою хранимую процедуру следующим образом:

ALTER PROCEDURE dbo.usp_verificarTabelaCadMov
      @NomeTabela VARCHAR(20)
AS
BEGIN
      SET NOCOUNT ON;

      DECLARE @Exists INT

      IF EXISTS(SELECT name
                        FROM sysobjects
                        WHERE name = @NomeTabela)
      BEGIN
            SET @Exists = 1
      END
      ELSE
      BEGIN
            SET @Exists = 0
      END

      RETURN @Exists
END

2 - Измените мой вызов в репозитории на:

@Query(value = "Declare @Exists int "
        + "Exec @Exists = usp_verificarTabelaCadMov :tabela"
        + " Select @Exists", nativeQuery = true)

РЕЗУЛЬТАТ: он проверяет, существует ли таблица.

...