5

我有一个存储过程,它接受用户定义的表类型,并且用户定义数据类型中所有列的默认值设置为 null。现在我将一个包含较少列的数据表从 c# 代码传递给存储过程,期望剩余列的值将设置为空。

但我收到此错误:尝试传递具有 21 列的表值参数,其中相应的用户定义表类型需要 77 列。这是代码

  SqlConnection conn = new SqlConnection("server=****; database=***;integrated security=SSPI");
  DataSet dataset=new DataSet();
  conn.Open();
  SqlCommand cmd = new SqlCommand("Insert");      
  cmd.CommandType = CommandType.StoredProcedure;
  cmd.Connection = conn;
  SqlParameter para = new SqlParameter();
  para.ParameterName = "@TableVar";
  para.SqlDbType = SqlDbType.Structured;
  //SqlParameter para=cmd.Parameters.AddWithValue("@TableVar",table);
  para.Value = table;
  cmd.Parameters.Add(para);
  cmd.ExecuteNonQuery();
4

2 回答 2

2

您可以使用 SqlDataAdapter 创建与表类型架构匹配的 DataTable:

DataTable table = new DataTable();

// Declare a variable of the desired table type to produce a result set with it's schema.
SqlDataAdapter adapter = new SqlDataAdapter("DECLARE @tableType dbo.UserDefindTableType 
                                             SELECT * FROM @tableType", ConnectionString);

// Sets the DataTable schema to match dbo.UserDefindTableType .
adapter.FillSchema(table, SchemaType.Source);

然后,您可以使用所有默认列值创建 DataRows 并设置您知道的列:

DataRow row = table.NewRow();

// Set know columns...
row["ColumnName"] = new object();

// or check column exists, is expected type etc first
if (table.Columns.Contains("ColumnName") 
    && table.Columns["ColumnName"].DataType == typeof(string)) {
    row["ColumnName"] = "String";
}

table.Rows.Add(row);
于 2015-06-11T01:41:55.023 回答
1

我遇到了同样的问题,我正在研究的解决方案是运行额外的 SQL 查询来获取列定义,然后用缺失的列填充 DataTable,这是表上列定义的 SQL 语句类型:

select c.name, t.name as type, c.max_length as length from sys.table_types tt
inner join sys.columns c on c.object_id = tt.type_table_object_id
inner join sys.types t on t.system_type_id = c.system_type_id
where tt.name = @tabletypename
order by c.column_id

SqlDbType如果您希望解决方案适用于所有表值参数定义,则C# 代码将更加混乱,因为您必须将返回类型(即 VARCHAR、INT 等)解析为枚举。

如果您没有本地文件系统的写入权限,我会认为 Microsoft 在 SQL Server 引擎中可以更好地解决此类问题,作为导入 CSV 文件的下一个最佳方法,但我想要一个单一的 UDTT 来满足每次我处理新的文件格式时,所有 CSV 文件都不必创建新的表类型。反正..吐槽。

于 2015-06-11T00:37:20.800 回答