Saltar al contenido

Cómo pasar un parámetro de valor de tabla

Luego de mucho luchar ya hallamos el arreglo de este apuro que agunos usuarios de este espacio han presentado. Si deseas aportar alguna información no dejes de dejar tu información.

Solución:

El siguiente ejemplo ilustra el uso de un DataTable o un IEnumerable:

Código SQL

CREATE TABLE dbo.PageView
(
    PageViewID BIGINT NOT NULL CONSTRAINT pkPageView PRIMARY KEY CLUSTERED,
    PageViewCount BIGINT NOT NULL
);
CREATE TYPE dbo.PageViewTableType AS TABLE
(
    PageViewID BIGINT NOT NULL
);
CREATE PROCEDURE dbo.procMergePageView
    @Display dbo.PageViewTableType READONLY
AS
BEGIN
    MERGE INTO dbo.PageView AS T
    USING @Display AS S
    ON T.PageViewID = S.PageViewID
    WHEN MATCHED THEN UPDATE SET T.PageViewCount = T.PageViewCount + 1
    WHEN NOT MATCHED THEN INSERT VALUES(S.PageViewID, 1);
END

Código C#

private static void ExecuteProcedure(bool useDataTable, string connectionString, IEnumerable ids) 
    using (SqlConnection connection = new SqlConnection(connectionString)) 
        connection.Open();
        using (SqlCommand command = connection.CreateCommand()) 
            command.CommandText = "dbo.procMergePageView";
            command.CommandType = CommandType.StoredProcedure;

            SqlParameter parameter;
            if (useDataTable) 
                parameter = command.Parameters.AddWithValue("@Display", CreateDataTable(ids));
            
            else 
                parameter = command.Parameters.AddWithValue("@Display", CreateSqlDataRecords(ids));
            
            parameter.SqlDbType = SqlDbType.Structured;
            parameter.TypeName = "dbo.PageViewTableType";

            command.ExecuteNonQuery();
        
    


private static DataTable CreateDataTable(IEnumerable ids) 
    DataTable table = new DataTable();
    table.Columns.Add("ID", typeof(long));
    foreach (long id in ids) 
        table.Rows.Add(id);
    
    return table;


private static IEnumerable CreateSqlDataRecords(IEnumerable ids) 
    SqlMetaData[] metaData = new SqlMetaData[1];
    metaData[0] = new SqlMetaData("ID", SqlDbType.BigInt);
    SqlDataRecord record = new SqlDataRecord(metaData);
    foreach (long id in ids) 
        record.SetInt64(0, id);
        yield return record;
    

Puede pasar el parámetro como un DataTable, IEnumerableo DbDataReader.

Agregar una nueva respuesta con enlaces actualizados.

De acuerdo con la documentación (docs.microsoft.com), puede usar uno de los siguientes tipos de parámetros:

SqlClient admite el llenado de parámetros con valores de tabla de objetos DataTable, DbDataReader o IEnumerable SqlDataRecord. Debe especificar un nombre de tipo para el parámetro con valores de tabla mediante la propiedad TypeName de SqlParameter. El TypeName debe coincidir con el nombre de un tipo compatible creado previamente en el servidor.

No incluido en los documentos pero importante para aplicaciones de alto rendimiento, una muestra usando IEnumerable (.NET Core 3.1, asíncrono):

  using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(30));
  using SqlConnection connection = this.GetConnection();
  await connection.OpenAsync(timeout.Token);

  using SqlCommand command = connection.CreateCommand();
  command.CommandType = CommandType.StoredProcedure;
  command.CommandText = "Mycommand";

  IEnumerable records = // ...

  SqlParameter parameter = command.Parameters.Add("@MyObjects", SqlDbType.Structured);
  parameter.TypeName = "MyCustomTableType";
  parameter.Value = records;

  await command.ExecuteNonQueryAsync(timeout.Token);

Ejemplo usando un Tabla de datos:

  // Create a DataTable with the modified rows.  
  DataTable addedCategories = CategoriesDataTable.GetChanges(DataRowState.Added);  

  // Configure the SqlCommand and SqlParameter.  
  SqlCommand insertCommand = new SqlCommand("usp_InsertCategories", connection);  
  insertCommand.CommandType = CommandType.StoredProcedure;  
  SqlParameter tvpParam = insertCommand.Parameters.AddWithValue("@tvpNewCategories", addedCategories);  
  tvpParam.SqlDbType = SqlDbType.Structured;  

  // Execute the command.  
  insertCommand.ExecuteNonQuery(); 

Ejemplo usando DbDataReader:

 // Assumes connection is an open SqlConnection.  
 // Retrieve data from Oracle.  
 OracleCommand selectCommand = new OracleCommand(  
     "Select CategoryID, CategoryName FROM Categories;",  
     oracleConnection);  
 OracleDataReader oracleReader = selectCommand.ExecuteReader(  
     CommandBehavior.CloseConnection);  

  // Configure the SqlCommand and table-valued parameter.  
  SqlCommand insertCommand = new SqlCommand(  
      "usp_InsertCategories", connection);  
  insertCommand.CommandType = CommandType.StoredProcedure;  
  SqlParameter tvpParam =  
      insertCommand.Parameters.AddWithValue(  
      "@tvpNewCategories", oracleReader);  
  tvpParam.SqlDbType = SqlDbType.Structured;  

  // Execute the command.  
  insertCommand.ExecuteNonQuery(); 

Sección de Reseñas y Valoraciones

Si te animas, tienes la opción de dejar una división acerca de qué te ha impresionado de esta crónica.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *