Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TSQL Functions used in stored procedure force column to readonly

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
like image 624
Bear In Hat Avatar asked Nov 13 '22 07:11

Bear In Hat


1 Answers

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

like image 130
Pearce Grinnell Avatar answered Nov 16 '22 03:11

Pearce Grinnell