Doc*_*ley 3 c# sql t-sql sql-server user-defined-types
我有一个在C#中写为字符串的查询,我试图在T-sql数据库(而不是存储过程)上调用.我必须传递的参数之一是GUID列表.我正在尝试使用表值参数.鉴于查询的一部分需要动态表名称,因此调试存储过程有点笨拙.查询的最后一部分将表上的ID连接到我传入的Guids列表中.
将参数添加到我的命令中
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"
});
Run Code Online (Sandbox Code Playgroud)
我的桌子
CREATE TYPE [dbo].[ListOfGuids] AS TABLE(
[ID] [uniqueidentifier] NULL
)
Run Code Online (Sandbox Code Playgroud)
当我运行这条线时:
var reader = cmd.ExecuteReader();
Run Code Online (Sandbox Code Playgroud)
我收到错误:
指定的类型未在目标服务器上注册.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
Run Code Online (Sandbox Code Playgroud)
然后你的C#代码可以是:
SqlCommand cmd = new SqlCommand("dbo.MyProcedure", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter tvparam = cmd.Parameters.AddWithValue("@ListOfGUIDs", ListOfIDs);
tvparam.SqlDbType = SqlDbType.Structured;
Run Code Online (Sandbox Code Playgroud)
或者,如果您只是声明,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;
Run Code Online (Sandbox Code Playgroud)