Call stored procedure with user-defined table type as parameter; error: column name or number of supplied values does not match table definition

Call stored procedure with user-defined table type as parameter; error: column name or number of supplied values does not match table definition

我尝试了几种方法来完成这项工作,但在调用 ExecuteReader 时出现相同的错误:

Column name or number of supplied values does not match table definition

看起来 table 类型的列名称未与数据 table 列名称映射,但不确定原因。以下是 .net 和 SQL 代码,它适用于其他编写博客和制作视频的人,我从中获得了这段代码,但不幸的是,它对我不起作用。如果您发现任何错误或我遗漏了什么,请回复。

谢谢。

.网络代码:

var dt = new DataTable();
dt.Columns.Add(new DataColumn("DataColumnName",typeof(string)));
       
foreach(var item in request.ControlValues)
{
    var dataRow = dt.NewRow();
    dataRow["DataColumnName"] = item.DataColumnName;                        
    dt.Rows.Add(dataRow);
}

SqlConnection conn = new SqlConnection(ConnectionString);

SqlCommand cmd = new SqlCommand("[dbo].[GetQuoteSearchData]", conn);
cmd.CommandType = CommandType.StoredProcedure;

SqlParameter cob = cmd.Parameters.AddWithValue("@cob", request.Cob);
cob.SqlDbType = SqlDbType.VarChar;
cob.Direction = ParameterDirection.Input;

SqlParameter function = cmd.Parameters.AddWithValue("@function", request.Function);
function.SqlDbType = SqlDbType.VarChar;
function.Direction = ParameterDirection.Input;

SqlParameter searchColumnName = cmd.Parameters.AddWithValue("@searchColumnName", Helper.GetControlSearchColumnName(request.SearchType));
searchColumnName.SqlDbType = SqlDbType.VarChar;
searchColumnName.Direction = ParameterDirection.Input;

SqlParameter controlValues = cmd.Parameters.AddWithValue("@controlValues", dt);
controlValues.Direction = ParameterDirection.Input;
controlValues.SqlDbType = SqlDbType.Structured;
controlValues.TypeName = "[dbo].[ControlValuesTable]";

conn.Open();

SqlDataReader reader = cmd.ExecuteReader();

SQL 服务器/存储过程代码:

CREATE PROCEDURE [dbo].[GetQuoteSearchData]
    @cob nvarchar(50),
    @function nvarchar(50),
    @searchColumnName nvarchar(50),
    @controlValues as [dbo].[ControlValuesTable] READONLY
AS
BEGIN
END

用户自定义table类型:

CREATE TYPE dbo.ControlValuesTable AS 
    TABLE
    (
        DataColumnName varchar(100) 
    );
GO

这是您的代码的简化版本(已更改,因此它可以 运行 独立):

        string ConnectionString = "cs"; // set your connection string here

        var dt = new DataTable();
        dt.Columns.Add(new DataColumn("DataColumnName", typeof(string)));

        var dataRow = dt.NewRow();
        dataRow["DataColumnName"] = "col1";
        dt.Rows.Add(dataRow);

        using (SqlConnection conn = new SqlConnection(ConnectionString))
        {
            SqlCommand cmd = new SqlCommand("[dbo].[GetQuoteSearchData]", conn);
            cmd.CommandType = CommandType.StoredProcedure;

            SqlParameter cob = cmd.Parameters.AddWithValue("@cob", "aa");
            cob.SqlDbType = SqlDbType.VarChar;
            cob.Direction = ParameterDirection.Input;

            SqlParameter function = cmd.Parameters.AddWithValue("@function", "bb");
            function.SqlDbType = SqlDbType.VarChar;
            function.Direction = ParameterDirection.Input;

            SqlParameter searchColumnName = cmd.Parameters.AddWithValue("@searchColumnName", "cc");
            searchColumnName.SqlDbType = SqlDbType.VarChar;
            searchColumnName.Direction = ParameterDirection.Input;

            SqlParameter controlValues = cmd.Parameters.AddWithValue("@controlValues", dt);
            controlValues.Direction = ParameterDirection.Input;
            controlValues.SqlDbType = SqlDbType.Structured;
            controlValues.TypeName = "[dbo].[ControlValuesTable]";

            conn.Open();

            SqlDataReader reader = cmd.ExecuteReader();

            conn.Close();
        }

我还在你的存储过程的正文中添加了一行,因为你发布的存储过程会给出如下错误:

Incorrect syntax near 'END'.

没有它。

drop proc [dbo].[GetQuoteSearchData]
GO
drop type dbo.ControlValuesTable
GO
CREATE TYPE dbo.ControlValuesTable AS 
    TABLE
    (
        DataColumnName varchar(100) 
    );
GO

CREATE PROCEDURE [dbo].[GetQuoteSearchData]
    @cob nvarchar(50),
    @function nvarchar(50),
    @searchColumnName nvarchar(50),
    @controlValues as [dbo].[ControlValuesTable] READONLY
AS
BEGIN
 select * from @controlValues
END
GO

这 运行 在我的系统上没问题。 如果您仍然无法让它工作,请执行 sql 探查器跟踪以捕获发送到 Sqlserver 的原始 sql 请求,并尝试在 SSMS 中重播该请求。
例如请求跟踪应该类似于:

declare @p4 dbo.ControlValuesTable
insert into @p4 values(N'col1')

exec [dbo].[GetQuoteSearchData] @cob='aa',@function='bb',@searchColumnName='cc',@controlValues=@p4

在 SSMS 中重播时 returns 一行。

作为旁注,我认为您也应该能够删除这一行:

controlValues.TypeName = "[dbo].[ControlValuesTable]";  

因为当 CommandType = CommandType.StoredProcedure.

时不需要