TSQL Functions used in stored procedure force column to readonly

Go To StackoverFlow.com

5

The Set Up: Loading a DataReader into a DataTable. Attempting to alter a column in the DataTable after load.

The Problem: ReadOnlyException triggered when attempting to alter a column.

The Conditions:

  • When a function (udf or system) is applied to an aliased column in the stored procedure, the column becomes ReadOnly.
  • The error is not triggered if the column is simply aliased with no function applied.
  • The error is not triggered if the select is moved to a table-function, then the proc selects from that function.
  • The error (obviously) doesn't occur when setting the column property to ReadOnly in C#.

The Question: Is there any way to alter a procedure so that an aliased column with a function applied is not ReadOnly? I am looking for an alternate to changing the C# or creating a function to do what the proc already does.

The C#:

var dt = new DataTable();
using( var sqlDR = objDocsFBO.GetActiveDocsMerged(KeyID) )
{
    dt.Load(sqlDR);
}
foreach( DataRow dr in dt.Rows )
{
    //Testing Alias Alone - Pass
    dr["DocumentPathAlias"] = "file:///" + Server.UrlEncode(dr["DocumentPathAlias"].ToString()).Replace("+", "%20");
    //Testing Function Applied - Fail
    //dr["DocumentPath"] = "file:///" + Server.UrlEncode(dr["DocumentPath"].ToString()).Replace("+", "%20");
}

The SQL:

GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[usp_ActiveDocs_RetrieveMerged]
@KeyID INT
AS 
BEGIN
--Testing Select From Function
--SELECT * FROM dbo.ufn_ActiveDocs_RetrieveMerged(@KeyID) --Pass
SELECT AD.ADMergeLogID
, AD.TemplateName
, CONVERT(NVARCHAR(10), AD.InitiatedOn, 101) [CreatedOn]
, (SELECT fn.UserName FROM dbo.ufn_User_GetFullName(AD.InitiatedBy) fn) [CreatedBy]
, AD.DocumentName
, AD.DocumentPath [DocumentPathAlias] --Pass
--, REPLACE(AD.DocumentPath, '\\', '\') [DocumentPath] --Fail
--, dbo.udf_VerifyPath(AD.DocumentPath) [DocumentPath] --Fail
FROM dbo.ActiveDocsMergeLog AD
WHERE AD.DocumentPath != 'DocumentPath not found.'
AND AD.KeyID = @KeyID
END
2012-04-05 15:40
by Bear In Hat
What would it update? As the column is simply the result of a function, what would the code write to - Joshua Drake 2012-04-05 16:05
The stored procedure is only running a SELECT. Where is the need for the column to be read/write - Aaron Bertrand 2012-04-05 16:44
@JoshuaDrake Once the results of the query are in the DataTable, the columns have their values, and the code doesn't care about where those came from. It does respect any properties of the column though. The issue isn't directly with the column being written to (which it can when setting ReadOnly = false). I'm guessing SQL applies the default of ReadOnly on a computed column whether the column is in a table, view, procedure, or function. I was hoping for a setting to override this - Bear In Hat 2012-04-05 18:07
@AaronBertrand I'm attempting to alter the column value in C# - Bear In Hat 2012-04-05 18:08
I thought that you had noted that when it was in a table it did not encounter a problem, can you further explain your statement: The error is not triggered if the select is moved to a table-function - Joshua Drake 2012-04-05 18:13
@JoshuaDrake I meant to say a user defined table-valued function. I'll edit the post, thanks for catching that - Bear In Hat 2012-04-05 18:24


1

If you place the query into a temp table it will override any table schema properties SQL sets.

2012-04-06 12:02
by Pearce Grinnell
I was unable to edit my post yesterday, but this is the same conclusion i came too. Thanks - Bear In Hat 2012-04-06 12:04
Ads