テーブルにアクセスするために、SQL CLR テーブル値 UDF を作成できます。TV-UDF は動的スキーマをサポートしていないため、スキーマに関連付ける必要があります。(私のサンプルには ID と Title 列が含まれています - 必要に応じて変更してください)
これが完了したら、次のクエリを実行できるはずです。
SELECT * FROM dbo.FromMyTable('table1')
その文字列にもマルチパート名を含めることができます。
SELECT * FROM dbo.FromMyTable('otherdb..table1')
そのテーブルから ID,Title 列を返します。
SQL CLR を有効にし、TRUSTWORTHY オプションをオンにする必要があります。
sp_configure 'clr enabled',1
go
reconfigure
go
alter database mydatabase set trustworthy on
C# SQL プロジェクトを作成し、新しい UDF ファイルを追加して、これをそこに貼り付けます。プロジェクト プロパティ、データベース、アクセス許可レベルを外部に設定します。ビルド、デプロイ。VisualStudio なしで実行できます。必要な場合はお知らせください。
using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Collections;
using System.Data.SqlClient;
[assembly: CLSCompliant(true)]
namespace FromMyTable
{
public static partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read, IsDeterministic = true, SystemDataAccess = SystemDataAccessKind.Read, IsPrecise = true, FillRowMethodName = "FillRow",
TableDefinition = "id int, title nvarchar(1024)")]
public static IEnumerable FromMyTable(SqlString tableName)
{
return new FromMyTable(tableName.Value);
}
public static void FillRow(object row, out SqlInt32 id, out SqlString title)
{
MyTableSchema v = (MyTableSchema)row;
id = new SqlInt32(v.id);
title = new SqlString(v.title);
}
}
public class MyTableSchema
{
public int id;
public string title;
public MyTableSchema(int id, string title) { this.id = id; this.title = title; }
}
internal class FromMyTable : IEnumerable
{
string tableName;
public FromMyTable(string tableName)
{
this.tableName = tableName;
}
public IEnumerator GetEnumerator()
{
return new FromMyTableEnum(tableName);
}
}
internal class FromMyTableEnum : IEnumerator
{
SqlConnection cn;
SqlCommand cmd;
SqlDataReader rdr;
string tableName;
public FromMyTableEnum(string tableName)
{
this.tableName = tableName;
Reset();
}
public MyTableSchema Current
{
get { return new MyTableSchema((int)rdr["id"], (string)rdr["title"]); }
}
object IEnumerator.Current
{
get { return Current; }
}
public bool MoveNext()
{
bool b = rdr.Read();
if (!b) { rdr.Dispose(); cmd.Dispose(); cn.Dispose(); rdr = null; cmd = null; cn = null; }
return b;
}
public void Reset()
{
// note: cannot use a context connection here because it will be closed
// in between calls to the enumerator.
if (cn == null) { cn = new SqlConnection("server=localhost;database=mydatabase;Integrated Security=true;"); cn.Open(); }
if (cmd == null) cmd = new SqlCommand("select id, title FROM " + tableName, cn);
if (rdr != null) rdr.Dispose();
rdr = cmd.ExecuteReader();
}
}
}