2

3 つの基本テーブル (テーブルはすべての場所で同じ定義を持っています) に含まれるデータの実際の場所を抽象化するテーブル/ビュー/ストアド プロシージャなど (具体化されたもの、それを X と呼びましょう) にアクセスするプログラムが必要です。

Xがどこか(おそらくテーブル) からサーバー名、カタログ名、およびテーブル名をフェッチし、特定の 3 つの基本テーブルにアクセスするようにします。Xの呼び出し元は、どの特定のテーブルが呼び出されているかを知りません。

SQL Server (2008) でこれを行うにはどうすればよいですか?

4

4 に答える 4

2

関数と同様に、ビューは動的 SQL を使用できません。どこかでメタデータ参照を見つけて、それに応じて調整することはできません。

あなたが望むものに最も近いのはsynonymだと思います。と の 3 つの異なるデータベースがAあるBとしCます。Aビューが参照するテーブルではdbo.fooBそれはdbo.barであり、Cそれはdbo.splungeです。したがって、各データベースで次のようなシノニムを作成できます。

USE A;
GO
CREATE SYNONYM dbo.YourCommonViewName FOR dbo.foo;
GO

USE B;
GO
CREATE SYNONYM dbo.YourCommonViewName FOR dbo.bar;
GO

USE C;
GO
CREATE SYNONYM dbo.YourCommonViewName FOR dbo.splunge;
GO

これは技術的にはビューではありませんが、各データベースで言うことができます...

SELECT <cols> FROM dbo.YourCommonViewName;

...そして、データベース固有のテーブルからデータを返します。


これをストアド プロシージャで行う方がはるかに簡単です。たとえば、サーバー、データベース、およびテーブル名をいくつかのテーブルに保存するとしますdbo.lookup

CREATE TABLE dbo.lookup
(
  id INT PRIMARY KEY,
  [server]   SYSNAME,
  [database] SYSNAME,
  [table]    SYSNAME,
  active BIT NOT NULL DEFAULT (0)
);

-- you may want a constraint or trigger to ensure
-- only one row can be active at any one time.

INSERT dbo.lookup(id, [server], [database], [table])
  SELECT 1,N'serverA',N'databaseA',N'tableA'
  UNION ALL SELECT 2,N'serverB',N'databaseB',N'tableB';

これで、プログラムは次のように言うことができます:

UPDATE dbo.lookup SET active = 1 WHERE ... ?

また、ストアド プロシージャは次のようになります。

CREATE PROCEDURE dbo.whatever
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @sql NVARCHAR(MAX);

  SELECT @sql = N'SELECT <cols> FROM ' + QUOTENAME([server]) 
    + '.' + QUOTENAME([database]) + '.dbo.' + QUOTENAME([table])
    FROM dbo.lookup WHERE active = 1;

  EXEC sp_executesql @sql;
END
GO

私はまだ要点を理解していません.2 人の異なるユーザーが同時にあなたのプログラムを呼び出し、それぞれ別の場所から結果を取得する必要がある場合に、あなたが何をしようとしているのかわかりません.

于 2012-09-23T15:58:44.950 に答える
1
  1. リモートサーバーにSYNONYMを作成します。
  2. UNION ALLを使用して、ビューを作成し、場所を連結します。

「テーブル」と言ったので、UNION ALLの前にテーブルを結合してください。うまくいけば、MSはリモートでJOINを実行します。

于 2012-09-23T16:11:46.973 に答える
1

データベース、サーバー、およびカタログのパラメーターを含むユニオン クエリを使用します。

Select col1, col2, <etc.>, 'table1' as tablename, 'server1' as servername, 'catalog1' as catname from server1.catalog1.table1
Union Select col1, col2, <etc.>, 'table2' as tablename, 'server2' as servername, 'catalog2' as catname from server2.catalog2.table2
Union Select col1, col2, <etc.>, 'table3' as tablename, 'server3' as servername, 'catalog3' as catname from server3.catalog3.table3

次に、3 つの基準に基づいてフィルター処理します。これはおそらく非常に高速ではありませんが、std で動作します。SQL。

于 2012-09-23T16:15:56.973 に答える
1

ビューと関数が動的SQLを使用できないという事実について、アーロンに同意しました。

それでもできることは、clr テーブル値関数を作成することです。その中で、.net コードで遊んで、好きなようにクエリを実行できます。それに応じてデータを構築し、必要なものを出力します。

したがって、次のようにデータをクエリする代わりに

select * from myview

あなたはそれを照会することができます

select * from dbo.clr_mymockupview()
于 2012-09-23T16:02:22.767 に答える