不确定这个问题是否有意义,但是我是CLR / UDT的新手,并在此处通过以下示例完成了操作: https://docs.microsoft.com/en-us/sql/relational-databases/clr-integration/database-objects/getting-started-with-clr-integration?view=sql-server-2017
我现在想要实现的目标非常相似。我尝试添加一个字符串参数没有失败,但是添加C#对象是问题开始的地方。
这是我的C#Main:
receive
这是C#Person类:
[Microsoft.SqlServer.Server.SqlProcedure]
public static void HelloName(Person person, [param: SqlFacet(MaxSize=-1)]out string result)
{
SqlContext.Pipe.Send("Hello world!" + Environment.NewLine);
result = "Hello, " + person.firstName + " " + person.lastName;
}
我能够成功创建程序集,但这是卡住的过程。我想做类似的事情:
public class Person
{
public string firstName;
public string lastName;
public Person(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
}
但经过一些研究,显然最好的方法是通过UDT。我遵循了另一个示例,并在T-SQL中创建了一个Person表和一个PersonType:
CREATE PROCEDURE helloname
(
@person (@firstname nchar(300), @lastname nchar(300))
@result nchar(300) OUTPUT
)
AS EXTERNAL NAME helloworld.HelloWorldProc.HelloName
错误发生在这里:
CREATE TABLE Person
(
FirstName nvarchar(50),
LastName nvarchar(50)
)
Go
CREATE TYPE PersonType AS TABLE
(
FirstName nvarchar(50),
LastName nvarchar(50)
)
Go
在尝试执行时,它说“为“ helloname”创建过程失败,因为参数“ @personType”的T-SQL和CLR类型不匹配。”
如何使“ PersonType”等于C#类“ Person”以使其正常工作?让我知道我是否要以完全错误的方式进行操作/是否有更简单的解决方案。理想情况下,我将在Person内部传递具有多个变量类型的List。提前致谢。
答案 0 :(得分:0)
我认为您误解了用户定义类型的概念。这些与用户定义的数据类型(将随机名称映射到实际的T-SQL数据类型)或用户定义的表类型(用于创建表变量的预定义表模式,通常用作表值参数)不同。
尝试以下方法以获得更好的介绍:CLR User-Defined Types
让我知道我是否要以完全错误的方式进行操作/是否有更简单的解决方案。理想情况下,我将在Person内部传递具有多个变量类型的List。
如果存储过程将是T-SQL存储过程,那么最好的方法是使用用户定义的表类型/ TVP(即CREATE TYPE PersonType AS TABLE...
)。但是,由于SQLCLR不接受TVP,因此您可以执行以下任一操作:
SqlXml
用作.NET输入参数类型。#
开始),填充它,然后使用Context Connection = true
作为连接字符串在SQLCLR存储过程中从中读取它。我不确定在什么条件下该选项会比简单地传递XML文档更好/更容易,但是它仍然是一个选项。其他说明:
param:
属性的SqlFacet
部分。SqlString
作为传入数据类型,而不是string
。通过ParamName.Value
属性获取.NET字符串。通过NULL
属性检查ParamName.IsNull
。@person (@firstname nchar(300), @lastname nchar(300))
在任何情况下都不是有效的语法。有关一般使用SQLCLR的更多信息,请访问:SQLCLR Info