不使用(Table-Valued-Parameter)类型将集合作为SQL参数添加到SqlCommand

时间:2018-12-10 13:35:06

标签: c# sql-server .net-core system.data

我正在尝试在SQL查询中使用表作为参数,但是如果不使用现有类型的名称(表值参数),就无法使表起作用。

在MSSQL中,我可以这样做:

declare @mytable table (column1 int, column2 nvarchar(10))
insert into @mytable select 1, "test" UNION ALL select 2, "test2" UNION ALL [...]

select * from sometable inner join @mytable on sometable.id = @mytable.column1

要在C#中完成此操作,我可以(大致)执行以下操作:

SqlCommand cmd ...
var p = cmd.CreateParameter();
p.TypeName = "MyType";                  // <-- I dont't want to do this
p.SqlDbType = SqlDbType.Structured;
p.Value = myDataTable;
p.ParameterName = "table";
cmd.Parameters.Add(p);
cmd.CommandText = "select * from sometable inner join @mytable on ... ";

为此,我必须在数据库中创建类型“ MyType”:CREATE TYPE [MyType] AS TABLE (...);

我的问题是,即使在MSSQL中,我也可以内联完成表的类型,但我需要显式指定表的类型。其次,我需要为每种可能的集合类型在数据库中明确定义类型。

有什么方法可以将集合作为参数添加到SQL命令中,而无需在数据库中声明其类型并将该类型用作参数的类型名称?

1 个答案:

答案 0 :(得分:0)

我最终使用了Json(由@DanGuzman提出),对其进行了测试,并且在相对简单的大约500个项目的数据集(我的用例)中,它的表现要好得多。

C#中的简单实现示例:

var col = new object[] { new { Column1 = "Test", Column2 = 1 }, new { Column1 = "2nd row", Column2 = 2 }, ... };
IDbDataParameter p = command.CreateParameter();
p.DbType = DbType.String;
p.ParameterName = "mytable";
p.Value = JsonConvert.SerializeObject(col); // NewtonSoft 
command.Parameters.Add(p);
command.CommandText = "SELECT * FROM OPENJSON(@mytable) WITH (Column1 nvarchar(max), Column2 int)";

参考