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
, IEnumerable
o 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
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.