Eu tenho um procedimento armazenado (SS2k8) com alguns parâmetros com valor de tabela que às vezes serão nulos ou vazios. Eu vi este post do StackOverflow que diz que TVPs nulos/vazios devem simplesmente ser omitidos da lista de parâmetros de chamada. Meu problema é que não consigo descobrir como verificar vazio ou nulo dentro do procedimento armazenado, pois "IF (@tvp IS NULL)" falha na criação do procedimento com a mensagem 'Deve declarar a variável escalar "@tvp"'. Eu tenho que fazer um SELECT COUNT(*) no TVP e checar por zero?
Trecho do código:
CREATE PROCEDURE [foo] (@tvp [TvpType] READONLY) AS
IF (@tvp IS NOT NULL) -- doesn't work
BEGIN
-- lots of expensive processing
END
ELSE
BEGIN
-- a little bit of cheap processing
END
...
Uma mesa não pode ser
NULL
, nem um TVP. Como verificar se uma tabela está vazia? Você certamente não dizIF Sales.SalesOrderHeader IS NULL
. :-)O parâmetro com valor de tabela não será nulo. Trate-o mais como uma mesa e @aaraon Bertrand me venceu. Então, sim, verifique se há linhas.
Solução alternativa 1:
bit
parâmetros:Como uma solução alternativa, garanto que cada parâmetro opcional com valor de tabela tem um parâmetro "ignorar" associado com um valor padrão de,
0
portanto, é opt-in, por exemplo... claro, se o seu procedimento for destrutivo (por exemplo, você usa
MERGE
comWHEN NOT MATCHED BY SOURCE THEN DELETE
), então você pode torná-lo seguro por padrão, tornando os@ignore...
parâmetros padrão em1
vez de0
.Solução alternativa 2: outro parâmetro com valor de tabela que lista parâmetros ignoráveis:
Outra opção, especialmente se você tiver muitos parâmetros com valor de tabela, é usar outro TVP que armazene uma lista de nomes de parâmetros válidos ou ignoráveis, por exemplo
Solução alternativa 3: use
#temporary
tabelasEXECUTE
instrução em umTRY/CATCH
bloco para garantir que o#temporaryTable
será descartado.FINALLY
bloco, então o código resultante requer a duplicação daDROP TABLE
instrução .