使用 ADO.NET 传递表值参数

Posted

技术标签:

【中文标题】使用 ADO.NET 传递表值参数【英文标题】:Pass table valued parameter using ADO.NET 【发布时间】:2012-05-11 16:20:45 【问题描述】:

如何使用 ADO.NET 将表值参数传递给存储过程?

【问题讨论】:

【参考方案1】:

    在 SQL Server 中创建类型

    CREATE TYPE [dbo].[MyDataType] As Table
    (
        ID INT,
        Name NVARCHAR(50)
    )
    

    创建程序

    CREATE PROCEDURE [dbo].[MyProcedure]
    (
        @myData As [dbo].[MyDataType] Readonly
    )
    AS
    
    BEGIN
        SELECT * FROM @myData
    END
    

    在 C# 中创建数据表

    DataTable myDataTable = new DataTable("MyDataType");
    myDataTable.Columns.Add("Name", typeof(string));
    myDataTable.Columns.Add("Id", typeof(Int32));
    myDataTable.Rows.Add("XYZ", 1);
    myDataTable.Rows.Add("ABC", 2);
    

    创建 SQL 参数

    SqlParameter parameter = new SqlParameter();
    parameter.ParameterName = "@myData";
    parameter.SqlDbType = System.Data.SqlDbType.Structured;
    parameter.Value = myDataTable;
    command.Parameters.Add(parameter); 
    

【讨论】:

这仅适用于 Sql Server 2008 我的意思是这仅适用于 Sql server 2008 及更高版本,因此它也可以在 2012 年使用。 注意,我相信您在步骤 3 中创建的 DataTable 中的列必须与您在步骤 1 中的表类型中定义的列顺序相匹配。您只是传入一个数据网格,然后 SQL Server 按位置读取它。事实上,你在 .NET 中给它的实际列名只是为了你自己的利益的一个字符串——它可以不同,因为 SQL 不会使用它。 在 C# 中创建的 DataTable 可以在实体框架 LINQ 查询中使用吗? @KyleMit 你是对的 - 列顺序必须匹配。 xlink 到相关的 SO 问题:***.com/questions/40628276/…【参考方案2】:

我试过这个并收到异常:

表类型参数“@MyDataType”必须具有有效的类型名称。

我必须设置 SqlParameter 的“TypeName”属性:

parameter.TypeName = "MyDataType";

【讨论】:

添加 db 模式作为表名的一部分为我做了:DataTable myDataTable = new DataTable("dbo.MyDataType");【参考方案3】:

此问题与How to pass table value parameters to stored procedure from .net code 重复。请参阅该问题以获取说明使用 DataTableIEnumerable<SqlDataRecord> 的示例。

【讨论】:

【参考方案4】:

对于多语种,有点晚了:

a) tsql 上的其他地方

--- create a vector data type
CREATE TYPE [dbo].[ItemList] AS TABLE([Item] [varchar](255) NULL)

b)

Dim Invoices As New DataTable("dbo.ItemList") 'table name is irrelevant
Invoices.Columns.Add("Invoice", GetType(String))
...
        With .SqlCommand.Parameters
            .Clear()
            .Add(New Data.SqlClient.SqlParameter() With 
                        .SqlDbType = Data.SqlDbType.Structured,
                        .Direction = Data.ParameterDirection.Input,
                        .ParameterName = "@Invoices",
                        .TypeName = "dbo.ItemList",
                        .Value = Invoices)
        End With
...
   ' using  store procedure
   .CommandText = "SELECT * FROM dbo.rpt(@invoices) "
   ' or direct reference is a select
   .CommandText = "SELECT * FROM dbo.invoicedata" +
        "where ((select count(*) from @invoices) = 0 or "+
             "InvoiceNumber in (select distinct * from @Invoices)) 

【讨论】:

【参考方案5】:

你可以用 Exec 作为前缀

using( SqlConnection con = new SqlConnection( "Server=.;database=employee;user=sa;password=12345" ) )
    
        SqlCommand cmd = new SqlCommand( " exec ('drop table '+@tab)" , con );
        cmd.Parameters.AddWithValue( "@tab" ,"Employee" );
        con.Open( );
        cmd.ExecuteNonQuery( );
    

【讨论】:

以上是关于使用 ADO.NET 传递表值参数的主要内容,如果未能解决你的问题,请参考以下文章

SSIS Passing Parameters to an ADO .NET Source query;向ado.net数据源传递参数。

如何在 ADO.NET 源 SSIS 中传递参数

如何将自定义子查询传递给 ADO.NET 中的 SQL 命令?

使用 ADO.NET 的 PostgreSQL 参数化插入

将动态表传递给 SSIS 中的 ADO.NET 目标

如何在 ASP.NET Core MVC 中使用 ADO.NET 向存储过程添加参数?