ti-enxame.com

Vinculando lista vazia ou valor nulo ao parâmetro com valor de tabela em um procedimento armazenado (.net)

Eu criei um procedimento armazenado que usa um parâmetro com valor de tabela que é uma tabela com uma única coluna do tipo int. A idéia é simplesmente passar uma lista de IDs para o procedimento de armazenamento e permitir que o sp trabalhe com os dados. No entanto, no caso em que não há dados para passar, estou encontrando problemas (as coisas funcionam corretamente quando tenho dados). Estou convertendo uma lista em um IEnumerable e vinculando isso ao parâmetro com valor de tabela para sp. Tentei ligar uma lista vazia, o que resultou no erro

System.ArgumentException: não há registros na enumeração SqlDataRecord. Para enviar um parâmetro com valor de tabela sem linhas, use uma referência nula para o valor.

Tentei vincular um valor nulo (que eu achava que era a mensagem acima), mas isso só resultou em uma mensagem de erro diferente

System.NotSupportedException: o valor DBNull para o parâmetro '@MainItemIdList' não é suportado. Os parâmetros com valor de tabela não podem ser DBNull.

Não parece que você pode declarar o parâmetro com valor de tabela como anulável na declaração sp. Qual é o método correto para vincular uma lista vazia ao parâmetro com valor de tabela?

60
Brian Jones

O truque é: não transmita o parâmetro. O valor padrão para um parâmetro com valor de tabela é uma tabela vazia.

É uma pena que a mensagem de exceção seja tão inútil.

83
Daniel Cassidy

Não passar um valor funciona , mas não no caso em que eu tinha vários parâmetros de valor de tabela para passar para o procedimento. Como eu resolvi foi especificar um valor de DEFAULT na minha string de consulta. Por exemplo,

string sqlQuery = "[dbo].[GetOrderData] @QueueId";

if (OrderIdList.Any())
{
    sqlQuery = sqlQuery + ", @OrderIdList";
}
else
{
    sqlQuery = sqlQuery + ", DEFAULT";
}

if (RegionIdList.Any())
{
    sqlQuery = sqlQuery + ", @RegionIdList";
}
else
{
    sqlQuery = sqlQuery + ", DEFAULT";
}

Parabéns para http://www.sommarskog.se/arrays-in-sql-2008.html#Invoking onde encontrei a solução para isso.

3
Anthony

Fiquei um pouco confuso com o que significa a declaração 'não passando o parâmetro'. O que acaba funcionando para o Entity Framework ExecuteSqlCommandAsync () é este:

  new SqlParameter("yourParameterName", SqlDbType.Structured)
  {
      Direction = ParameterDirection.Input,
      TypeName = "yourUdtType",
      Value = null
  };

Isso passará o parâmetro como 'padrão'.

2
Noppey

Recebo o erro ao passar um IEnumerable<int> Vazio, mas funciona bem quando passo um List<int> Vazio.

0
jausel