Вы можете создать UDF с табличным значением SQL CLR для доступа к таблицам. Вы должны связать его со схемой, потому что TV-UDF не поддерживают динамическую схему. (Мой образец включает в себя идентификатор и столбец заголовка - измените для ваших нужд)
Как только вы это сделаете, вы сможете выполнить следующий запрос:
SELECT * FROM dbo.FromMyTable('table1')
Вы также можете включить составное имя в эту строку.
SELECT * FROM dbo.FromMyTable('otherdb..table1')
чтобы вернуть ID, столбцы заголовков из этой таблицы.
Скорее всего, вам потребуется включить 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();
}
}
}