セットアップ: DataReader を DataTable にロードします。ロード後に DataTable の列を変更しようとしています。
問題: 列を変更しようとすると、ReadOnlyException がトリガーされます。
状況、契約条項:
- 関数 (udf またはシステム) がストアド プロシージャ内のエイリアス化された列に適用されると、その列は ReadOnly になります。
- 関数が適用されずに列が単純にエイリアス化されている場合、エラーは発生しません。
- 選択がテーブル関数に移動された場合、エラーはトリガーされず、proc はその関数から選択します。
- C# で列プロパティを ReadOnly に設定すると、(明らかに) エラーは発生しません。
質問: 関数が適用されたエイリアス列が読み取り専用にならないようにプロシージャを変更する方法はありますか? C# を変更したり、proc が既に行っていることを行う関数を作成したりする代わりの方法を探しています。
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");
}
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