Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Erro 'Deve declarar a variável escalar' ao passar um parâmetro com valor de tabela para uma instrução SQL parametrizada


Primeiras coisas primeiro:não tenho ideia de onde você está obtendo o tableName e columnName , mas se eles forem fornecidos pelo usuário, isso estará aberto à injeção de SQL. No mínimo, use QUOTENAME() para garantir que nenhum código real seja injetado.

Em segundo lugar, você não está realmente usando o TVP. O código que você tem está apenas dizendo IN (@IDTable) que não é como você usa um TVP.

Um TVP é apenas uma variável de tabela e deve ser usado como qualquer outra tabela:
protected virtual void DoDeleteRecords(List<Guid> ids)
{   
    if (ids.Count == 0)
        return;
    DataTable tvp = new DataTable();
    tvp.Columns.Add("Id", typeof(Guid));

    foreach (Guid id in ids)
        tvp.Rows.Add(id);

    const string sql = @"
DELETE FROM table
WHERE idColumnName IN (SELECT * FROM @IDTable);
";

    using(SqlConnection connection = new SqlConnection(CoreSettings.ConnectionString))
    using(SqlCommand command = new SqlCommand(sql, connection))
    {
        command.Parameters.Add(
            new SqlParameter("@IDTable", SqlDbType.Structured)
        {
            Value = tvp,
            Direction = ParameterDirection.Input,
            TypeName = "dbo.IDList"
        });

        connection.Open();
        command.ExecuteNonQuery();
    }
}