在CLR下运行代码时,它将作为SQL服务帐户运行,该帐户无权访问我需要的资源。我不知道使用凭据进行大量编程。如何切换凭据以使用其他帐户?
CLR代码在SQL服务帐户下运行。我们不想授予该帐户权限,而是使用另一个帐户来提供对CLR功能所需的外部资源(主要是文件)的访问。您如何在处理期间切换帐户,然后再还原?
请注意,该类用于表值函数,因此SQL将使用foreach(IEnumerator)方法读取每一行,在此期间文件需要保持打开状态。因此,我每次从文件中读取一行并切换回凭证还是只是为了打开文件时都需要切换凭证吗?
最后,如果我切换凭据,我只是在为我的线程或整个SQL更改它吗?显然,我不想做后者。我需要一些类似于SQL模拟的功能,仅用于执行我的CLR函数时,返回到SQL时可以还原。
示例CLR加载文本文件。我们需要在打开文件,读取文件和关闭文件之前更改凭据。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.SqlServer.Server;
// TextLine and TextFile load text files with indexed lines
public class TextLine
// contains a line of text from a file
{
int _lineIndex;
string _data;
public TextLine(int iIndex, string cData)
{
_lineIndex = iIndex;
_data = cData;
}
public int LineIndex
{
get { return _lineIndex; }
set { _lineIndex = value; }
}
public string Data
{
get { return _data; }
set { _data = value; }
}
}
public class TextFile : IEnumerable, IEnumerator
{
private int _index = -1;
private string _data; // the content of the last line read
private StreamReader _reader = null;
public TextFile(string filename)
{
_reader = new StreamReader(filename);
}
IEnumerator IEnumerable.GetEnumerator()
{
return this;
}
public object Current
{
get
{
return new TextLine(_index, _data);
}
}
public bool MoveNext()
{
_data = _reader.ReadLine();
if (_data != null)
{
_index++;
return true;
}
else
{
_reader.Close();
return false;
}
}
public void Reset()
{
_index = -1;
}
}
public partial class UserDefinedFunctions
{
[SqlFunction(
Name = "ReadTextFile",
FillRowMethodName = "ReadTextFile_FillRow",
TableDefinition = "LineIndex INT, Data NVARCHAR(4000)")]
public static IEnumerable ReadTextFile(SqlString cFilename) // this returns an object that has inherited IEnumerable
{
TextFile oFile = null;
try
{
oFile = new TextFile((string)cFilename);
return oFile;
}
finally
{
oFile.Reset();
}
}
public static void ReadTextFile_FillRow(object row, out SqlInt32 LineIndex, out SqlString Data)
{
TextLine oLine;
oLine = (TextLine)row;
LineIndex = (SqlInt32)oLine.LineIndex;
Data = (SqlString)oLine.Data;
}
}
我只需要CLR代码即可在指定的AD帐户(而不是SQL Service帐户)下运行。