我有一个用 C# 编写为字符串的查询,我试图在 T-sql 数据库(不是存储过程)上调用它。我必须传入的参数之一是 GUID 列表。我正在尝试使用 table-valued parameter为了这。鉴于查询的那部分需要动态表名,存储过程被认为对于调试来说有些笨拙。查询的最后部分将表上的 ID 连接到我传入的 Guid 列表。
在我的命令中添加参数
var ListOfIDs = new DataTable();
ListOfIDs.Columns.Add("ID", typeof (Guid));
selectedIDs.ForEach(x=> ListOfIDs.Rows.Add(x));
cmd.Parameters.Add(new SqlParameter("@ListOfIDs", SqlDbType.Udt)
{
Value = ListOfIDs, UdtTypeName = "ListOfGuids"
});
我的 table
CREATE TYPE [dbo].[ListOfGuids] AS TABLE(
[ID] [uniqueidentifier] NULL
)
当我运行这条线时:
var reader = cmd.ExecuteReader();
我得到错误:
Specified type is not registered on the target server.System.Data.DataTable, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
我无法找到我需要做什么才能让它正常工作。
最佳答案
您应该使用 SqlDbType.Structured
。 .Udt
不是表值参数或表类型,它是 CLR 用户定义类型 IIRC。 TVP/表值参数是别名类型,而不是用户定义的类型。您也不需要告诉它 .UdtTypeName
因为,这再次与 TVP 无关,并且您的代码不应该以任何形式提及 Udt
或表格。
如果您的程序如下所示:
CREATE PROCEDURE dbo.MyProcedure
@ListOfGUIDs dbo.ListOfGuids READONLY
AS
BEGIN
...
END
那么你的 C# 代码可以是:
SqlCommand cmd = new SqlCommand("dbo.MyProcedure", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter tvparam = cmd.Parameters.AddWithValue("@ListOfGUIDs", ListOfIDs);
tvparam.SqlDbType = SqlDbType.Structured;
或者,如果您只有一个语句,例如 SELECT * FROM @ListOfGUIDs
,那么:
SqlCommand cmd = new SqlCommand("SELECT * FROM @ListOfGUIDs", conn);
cmd.CommandType = CommandType.Text;
SqlParameter tvparam = cmd.Parameters.AddWithValue("@ListOfGUIDs", ListOfIDs);
tvparam.SqlDbType = SqlDbType.Structured;
关于c# - T-SQL 表类型,指定类型未注册,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19368054/