-
Notifications
You must be signed in to change notification settings - Fork 305
Limited SQL Computed column support when using SqlParameter.Structured #3242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi @PK-ByTE, I don't believe SQL Server itself supports computed columns within UDTs. So it wouldn't be possible for us to do anything on the client side to support your request. If you see documentation indicating otherwise, please share it with me! The closest I can see to what you're looking for is a computed columns over a UDT expression, which is already supported. |
Hi @mdaigle , Well I have used this functionality in sql server/sql scripts before and was wondering why the .NET SqlClient lacks the support for this. I will provide an example below; Given that we have the Num1 and Num2 and [Computed] Total available for us in the udttNumsWithCompute udtt.
Then we can execute following script, which will just populate the Num1 and Num2 fields and the Total field will get computed automatically based on values inputted into Num1 and Num2.
And you can actually specify for the insert part which columns we are inserting and specify only the Num1 and Num2.
Hope this helps. |
Gotcha, thanks for the additional info. The difference I see in these new examples is that you're persisting the table-valued type before interacting with it. In the original examples, because you can only pass table-valued types to stored procedures as You can read more about the limitations here: https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql/table-valued-parameters#limitations-of-table-valued-parameters. |
I still think that this is a lack of library support, because if I create the whole sql command manually it executes just fine, but I'm unable to pass the udtt via command parameter to the query inside the command (because of the udtt validation, that requires that all columns are included even though some of them might be computed). This uses the same codebase that I have provided in this issue earlier. Add following into the codebase, these are just some helper methods to create & populate the datatable parameter.
Let me demonstrate the problem; If we create the whole command as plain string, it works.
But if we try to provide the @numsWithCompute values via command parameter it fails.
Even if we try to mimic the udtt with extra total column, it still fails.
Can the library provide support for udtt that have computed column in them defined? |
Your stored procedure works when you first insert data to the table-types UDT. You need to insert first so that the computed column can have a value set when the UDT data is in a writeable state. For example: DECLARE @UdttNums AS [dbo].[udttNumsWithCompute]
INSERT INTO @UdttNums VALUES(1,2)
EXECUTE [dbo].[spTestUdttWithComputed] @UdttNums
GO Returns:
|
Yeah, As I have stated earlier my example works if you write the whole sql script manually, but how come we cannot use the library's functionality;
To make the same thing work? Do I have to create my inhouse string concat logic for udtt's with computed column, that it would generate sql script such as in your or mine example? I was hoping that library would support atleast this kind of functionality; |
Thanks for bearing with me. The issue I'm trying to highlight is that the behavior you're looking for in the API can't be one-to-one with the underlying SQL (I think we're in agreement on this). To make this type of API possible, we would need to send additional commands or rewrite your commands under the hood, both of which are atypical behavior. We try to avoid layering behavior on top of SQL because it makes it hard to anticipate how the driver will behave. That said, I understand where you're coming from and agree that it seems more ergonomic for the API to work in the way you suggested. Let me give it a bit more thought to see if I have any ideas. |
Describe the bug
When using udtt's with SqlParameter.Structured the passing of values into the underlying udtt works only if the udtt lacks any computed columns.
Like so;
But if we add any computed column into the udtt the passing of values into the underlying udtt fails on first computed column and library does not provide any means to skip computed columns or mitigate this issues atleast none that I know of (Tried multiple approaches). One of them listed below like so;
The issue came up when we tried to create an udtt that would calculate hash value based on the value fields in the udtt and store it in the udtt as varbinary field, thus would allow us to use the calculated hash value to determine if some data has changed when compared to the data in the db table.
To reproduce
Program.cs
TestAppSimple.cs
sql - udttNumsWithCompute
sql - udttNumsWithoutCompute
sql - spTestUdttWithComputed
sql - spTestUdttWithoutComputed
Expected behavior
The library should provide a way to configure the functionality of SqlParameter.Structured so that it would skip computed columns and let the server resolve the value in the udtt, once the rest of the fields are populated that the computed column depends upon.
Further technical details
Microsoft.Data.SqlClient version: 6.0.1
.NET target: .NET 8, .NET 9, .NET 10
SQL Server version: SQL Server 2022 (16.0.1135.2)
Operating system: Microsoft Windows 11 Business (10.0.22631)
The text was updated successfully, but these errors were encountered: