How To Match UDT T-SQL AND C# CLR Types?
Unsure if this question makes sense but I'm new to CLR/UDT and just finished following through this example here:
https://docs.microsoft.com/en-us/sql/relational-databases/clr-integration/database-objects/getting-started-with-clr-integration?view=sql-server-2017
What I want to achieve right now is pretty similar. I've tried adding in a string parameter without fail, but when adding a C# object is where the issue begins.
This is my C# Main:
[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;
}
And this is the C# Person class:
public class Person
{
public string firstName;
public string lastName;
public Person(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
}
I'm able to successfully create the assembly, but it's the procedure where I get stuck. I want to do something like:
CREATE PROCEDURE helloname
(
@person (@firstname nchar(300), @lastname nchar(300))
@result nchar(300) OUTPUT
)
AS EXTERNAL NAME helloworld.HelloWorldProc.HelloName
But after some research apparently the best way to go about objects is through UDTs. I have followed another example and created both a Person table and a PersonType as below in T-SQL:
CREATE TABLE Person
(
FirstName nvarchar(50),
LastName nvarchar(50)
)
Go
CREATE TYPE PersonType AS TABLE
(
FirstName nvarchar(50),
LastName nvarchar(50)
)
Go
The error occurs here:
CREATE PROCEDURE helloname
(
@personType PersonType,
@result nchar(300) OUTPUT
)
AS EXTERNAL NAME helloworld.HelloWorldProc.HelloName
On attempted execution it says "CREATE PROCEDURE for "helloname" failed because T-SQL and CLR types for parameter "@personType" do not match."
How do I get "PersonType" to equal the C# Class "Person" for this to work properly? Let me know if I'm going about this the completely wrong way/if there's a simpler solution. Ideally I will be passing in a List with multiple variable types inside Person. Thanks in advance.
c# sql sql-server clr sqlclr
add a comment |
Unsure if this question makes sense but I'm new to CLR/UDT and just finished following through this example here:
https://docs.microsoft.com/en-us/sql/relational-databases/clr-integration/database-objects/getting-started-with-clr-integration?view=sql-server-2017
What I want to achieve right now is pretty similar. I've tried adding in a string parameter without fail, but when adding a C# object is where the issue begins.
This is my C# Main:
[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;
}
And this is the C# Person class:
public class Person
{
public string firstName;
public string lastName;
public Person(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
}
I'm able to successfully create the assembly, but it's the procedure where I get stuck. I want to do something like:
CREATE PROCEDURE helloname
(
@person (@firstname nchar(300), @lastname nchar(300))
@result nchar(300) OUTPUT
)
AS EXTERNAL NAME helloworld.HelloWorldProc.HelloName
But after some research apparently the best way to go about objects is through UDTs. I have followed another example and created both a Person table and a PersonType as below in T-SQL:
CREATE TABLE Person
(
FirstName nvarchar(50),
LastName nvarchar(50)
)
Go
CREATE TYPE PersonType AS TABLE
(
FirstName nvarchar(50),
LastName nvarchar(50)
)
Go
The error occurs here:
CREATE PROCEDURE helloname
(
@personType PersonType,
@result nchar(300) OUTPUT
)
AS EXTERNAL NAME helloworld.HelloWorldProc.HelloName
On attempted execution it says "CREATE PROCEDURE for "helloname" failed because T-SQL and CLR types for parameter "@personType" do not match."
How do I get "PersonType" to equal the C# Class "Person" for this to work properly? Let me know if I'm going about this the completely wrong way/if there's a simpler solution. Ideally I will be passing in a List with multiple variable types inside Person. Thanks in advance.
c# sql sql-server clr sqlclr
add a comment |
Unsure if this question makes sense but I'm new to CLR/UDT and just finished following through this example here:
https://docs.microsoft.com/en-us/sql/relational-databases/clr-integration/database-objects/getting-started-with-clr-integration?view=sql-server-2017
What I want to achieve right now is pretty similar. I've tried adding in a string parameter without fail, but when adding a C# object is where the issue begins.
This is my C# Main:
[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;
}
And this is the C# Person class:
public class Person
{
public string firstName;
public string lastName;
public Person(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
}
I'm able to successfully create the assembly, but it's the procedure where I get stuck. I want to do something like:
CREATE PROCEDURE helloname
(
@person (@firstname nchar(300), @lastname nchar(300))
@result nchar(300) OUTPUT
)
AS EXTERNAL NAME helloworld.HelloWorldProc.HelloName
But after some research apparently the best way to go about objects is through UDTs. I have followed another example and created both a Person table and a PersonType as below in T-SQL:
CREATE TABLE Person
(
FirstName nvarchar(50),
LastName nvarchar(50)
)
Go
CREATE TYPE PersonType AS TABLE
(
FirstName nvarchar(50),
LastName nvarchar(50)
)
Go
The error occurs here:
CREATE PROCEDURE helloname
(
@personType PersonType,
@result nchar(300) OUTPUT
)
AS EXTERNAL NAME helloworld.HelloWorldProc.HelloName
On attempted execution it says "CREATE PROCEDURE for "helloname" failed because T-SQL and CLR types for parameter "@personType" do not match."
How do I get "PersonType" to equal the C# Class "Person" for this to work properly? Let me know if I'm going about this the completely wrong way/if there's a simpler solution. Ideally I will be passing in a List with multiple variable types inside Person. Thanks in advance.
c# sql sql-server clr sqlclr
Unsure if this question makes sense but I'm new to CLR/UDT and just finished following through this example here:
https://docs.microsoft.com/en-us/sql/relational-databases/clr-integration/database-objects/getting-started-with-clr-integration?view=sql-server-2017
What I want to achieve right now is pretty similar. I've tried adding in a string parameter without fail, but when adding a C# object is where the issue begins.
This is my C# Main:
[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;
}
And this is the C# Person class:
public class Person
{
public string firstName;
public string lastName;
public Person(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
}
I'm able to successfully create the assembly, but it's the procedure where I get stuck. I want to do something like:
CREATE PROCEDURE helloname
(
@person (@firstname nchar(300), @lastname nchar(300))
@result nchar(300) OUTPUT
)
AS EXTERNAL NAME helloworld.HelloWorldProc.HelloName
But after some research apparently the best way to go about objects is through UDTs. I have followed another example and created both a Person table and a PersonType as below in T-SQL:
CREATE TABLE Person
(
FirstName nvarchar(50),
LastName nvarchar(50)
)
Go
CREATE TYPE PersonType AS TABLE
(
FirstName nvarchar(50),
LastName nvarchar(50)
)
Go
The error occurs here:
CREATE PROCEDURE helloname
(
@personType PersonType,
@result nchar(300) OUTPUT
)
AS EXTERNAL NAME helloworld.HelloWorldProc.HelloName
On attempted execution it says "CREATE PROCEDURE for "helloname" failed because T-SQL and CLR types for parameter "@personType" do not match."
How do I get "PersonType" to equal the C# Class "Person" for this to work properly? Let me know if I'm going about this the completely wrong way/if there's a simpler solution. Ideally I will be passing in a List with multiple variable types inside Person. Thanks in advance.
c# sql sql-server clr sqlclr
c# sql sql-server clr sqlclr
edited Nov 20 '18 at 20:39
Mike Brunner
686
686
asked Nov 20 '18 at 20:33
WenWen
394
394
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
I think you have misunderstood the concept of User-Defined Types. These are not the same thing as User-Defined Data Types (mapping a random name to an actual T-SQL datatype) or User-Defined Table Types (predefined table schemas used for creating table variables, typically used as Table-Valued Parameters).
Try this for a better intro: CLR User-Defined Types
Let me know if I'm going about this the completely wrong way/if there's a simpler solution. Ideally I will be passing in a List with multiple variable types inside Person.
If the Stored Procedure was going to be a T-SQL stored proc, then the best way to do this would be to use a User-Defined Table Type / TVP (i.e. CREATE TYPE PersonType AS TABLE...
). But since SQLCLR does not accept TVP's, you can do either:
- construct the list of complex "objects" as an XML document, which is easily parsed in .NET. Use
SqlXml
as the .NET input parameter type. - create a Local Temporary Table (i.e. starting with a single
#
), populate it, and then read from it in the SQLCLR stored procedure usingContext Connection = true
as the connection string. I'm not sure under what conditions this option would be better / easier than simply passing in an XML document, but it is still an option.
Other notes:
- You don't need the
param:
part of theSqlFacet
attribute. - Use
SqlString
as the incoming datatype instead ofstring
. Get the .NET string viaParamName.Value
property. Check ifNULL
viaParamName.IsNull
property. - Parameters cannot be expressed as combinations of parameters. Meaning,
@person (@firstname nchar(300), @lastname nchar(300))
is not valid syntax under any condition.
For more info on working with SQLCLR in general, please visit: SQLCLR Info
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53401082%2fhow-to-match-udt-t-sql-and-c-sharp-clr-types%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I think you have misunderstood the concept of User-Defined Types. These are not the same thing as User-Defined Data Types (mapping a random name to an actual T-SQL datatype) or User-Defined Table Types (predefined table schemas used for creating table variables, typically used as Table-Valued Parameters).
Try this for a better intro: CLR User-Defined Types
Let me know if I'm going about this the completely wrong way/if there's a simpler solution. Ideally I will be passing in a List with multiple variable types inside Person.
If the Stored Procedure was going to be a T-SQL stored proc, then the best way to do this would be to use a User-Defined Table Type / TVP (i.e. CREATE TYPE PersonType AS TABLE...
). But since SQLCLR does not accept TVP's, you can do either:
- construct the list of complex "objects" as an XML document, which is easily parsed in .NET. Use
SqlXml
as the .NET input parameter type. - create a Local Temporary Table (i.e. starting with a single
#
), populate it, and then read from it in the SQLCLR stored procedure usingContext Connection = true
as the connection string. I'm not sure under what conditions this option would be better / easier than simply passing in an XML document, but it is still an option.
Other notes:
- You don't need the
param:
part of theSqlFacet
attribute. - Use
SqlString
as the incoming datatype instead ofstring
. Get the .NET string viaParamName.Value
property. Check ifNULL
viaParamName.IsNull
property. - Parameters cannot be expressed as combinations of parameters. Meaning,
@person (@firstname nchar(300), @lastname nchar(300))
is not valid syntax under any condition.
For more info on working with SQLCLR in general, please visit: SQLCLR Info
add a comment |
I think you have misunderstood the concept of User-Defined Types. These are not the same thing as User-Defined Data Types (mapping a random name to an actual T-SQL datatype) or User-Defined Table Types (predefined table schemas used for creating table variables, typically used as Table-Valued Parameters).
Try this for a better intro: CLR User-Defined Types
Let me know if I'm going about this the completely wrong way/if there's a simpler solution. Ideally I will be passing in a List with multiple variable types inside Person.
If the Stored Procedure was going to be a T-SQL stored proc, then the best way to do this would be to use a User-Defined Table Type / TVP (i.e. CREATE TYPE PersonType AS TABLE...
). But since SQLCLR does not accept TVP's, you can do either:
- construct the list of complex "objects" as an XML document, which is easily parsed in .NET. Use
SqlXml
as the .NET input parameter type. - create a Local Temporary Table (i.e. starting with a single
#
), populate it, and then read from it in the SQLCLR stored procedure usingContext Connection = true
as the connection string. I'm not sure under what conditions this option would be better / easier than simply passing in an XML document, but it is still an option.
Other notes:
- You don't need the
param:
part of theSqlFacet
attribute. - Use
SqlString
as the incoming datatype instead ofstring
. Get the .NET string viaParamName.Value
property. Check ifNULL
viaParamName.IsNull
property. - Parameters cannot be expressed as combinations of parameters. Meaning,
@person (@firstname nchar(300), @lastname nchar(300))
is not valid syntax under any condition.
For more info on working with SQLCLR in general, please visit: SQLCLR Info
add a comment |
I think you have misunderstood the concept of User-Defined Types. These are not the same thing as User-Defined Data Types (mapping a random name to an actual T-SQL datatype) or User-Defined Table Types (predefined table schemas used for creating table variables, typically used as Table-Valued Parameters).
Try this for a better intro: CLR User-Defined Types
Let me know if I'm going about this the completely wrong way/if there's a simpler solution. Ideally I will be passing in a List with multiple variable types inside Person.
If the Stored Procedure was going to be a T-SQL stored proc, then the best way to do this would be to use a User-Defined Table Type / TVP (i.e. CREATE TYPE PersonType AS TABLE...
). But since SQLCLR does not accept TVP's, you can do either:
- construct the list of complex "objects" as an XML document, which is easily parsed in .NET. Use
SqlXml
as the .NET input parameter type. - create a Local Temporary Table (i.e. starting with a single
#
), populate it, and then read from it in the SQLCLR stored procedure usingContext Connection = true
as the connection string. I'm not sure under what conditions this option would be better / easier than simply passing in an XML document, but it is still an option.
Other notes:
- You don't need the
param:
part of theSqlFacet
attribute. - Use
SqlString
as the incoming datatype instead ofstring
. Get the .NET string viaParamName.Value
property. Check ifNULL
viaParamName.IsNull
property. - Parameters cannot be expressed as combinations of parameters. Meaning,
@person (@firstname nchar(300), @lastname nchar(300))
is not valid syntax under any condition.
For more info on working with SQLCLR in general, please visit: SQLCLR Info
I think you have misunderstood the concept of User-Defined Types. These are not the same thing as User-Defined Data Types (mapping a random name to an actual T-SQL datatype) or User-Defined Table Types (predefined table schemas used for creating table variables, typically used as Table-Valued Parameters).
Try this for a better intro: CLR User-Defined Types
Let me know if I'm going about this the completely wrong way/if there's a simpler solution. Ideally I will be passing in a List with multiple variable types inside Person.
If the Stored Procedure was going to be a T-SQL stored proc, then the best way to do this would be to use a User-Defined Table Type / TVP (i.e. CREATE TYPE PersonType AS TABLE...
). But since SQLCLR does not accept TVP's, you can do either:
- construct the list of complex "objects" as an XML document, which is easily parsed in .NET. Use
SqlXml
as the .NET input parameter type. - create a Local Temporary Table (i.e. starting with a single
#
), populate it, and then read from it in the SQLCLR stored procedure usingContext Connection = true
as the connection string. I'm not sure under what conditions this option would be better / easier than simply passing in an XML document, but it is still an option.
Other notes:
- You don't need the
param:
part of theSqlFacet
attribute. - Use
SqlString
as the incoming datatype instead ofstring
. Get the .NET string viaParamName.Value
property. Check ifNULL
viaParamName.IsNull
property. - Parameters cannot be expressed as combinations of parameters. Meaning,
@person (@firstname nchar(300), @lastname nchar(300))
is not valid syntax under any condition.
For more info on working with SQLCLR in general, please visit: SQLCLR Info
edited Nov 20 '18 at 21:35
answered Nov 20 '18 at 21:30
Solomon RutzkySolomon Rutzky
32.6k477116
32.6k477116
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53401082%2fhow-to-match-udt-t-sql-and-c-sharp-clr-types%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown