web-dev-qa-db-ja.com

スクリプトを作成するときに、SMOの転送がリンクサーバーにログインしようとするのはなぜですか?

このコードサンプルを検討してください。

            var sourceDatabaseConnectionString = "Data Source=MyServer;Initial Catalog=MyDatabase;User Id=MyLogin;Password=MyPassword";
            var serverConnection = new ServerConnection
            {
                ConnectionString = sourceDatabaseConnectionString
            };

            var server = new Server(serverConnection);
            var builder = new SqlConnectionStringBuilder(sourceDatabaseConnectionString);
            var database = server.Databases[builder.InitialCatalog];
            var transfer = new Transfer(database);

            // setting transfer options
            transfer.CopyAllObjects = true;
            transfer.CopyAllSynonyms = true;
            transfer.CopyData = false;

            transfer.Options.WithDependencies = true;
            transfer.Options.DriAll = true;
            transfer.Options.Triggers = true;
            transfer.Options.Indexes = true;
            transfer.Options.SchemaQualifyForeignKeysReferences = true;
            transfer.Options.ExtendedProperties = true;
            transfer.Options.IncludeDatabaseRoleMemberships = true;
            transfer.Options.Permissions = true;
            transfer.PreserveDbo = true;

            // scripting database
            var script = transfer.ScriptTransfer();

既存のデータベースから空白を取得しようとします。

このデータベースの一部のオブジェクトは、リンクサーバーにあるオブジェクトに依存しています。このコードがそのようなオブジェクトのスクリプトを作成しようとすると、ScriptTransferは「ユーザー 'MyLogin'のログインに失敗しました」で失敗します。

ログ分析によると、MyLoginがいいねしたサーバーにログインしようとするとエラーが発生します。しかし、これの必要性は何ですか?結局のところ、私はMyDatabaseCREATE ...スクリプトの束を取得したいだけで、リンクされたサーバーからデータを読み取りたくありません。

私のSQLServerとSMOのバージョンは2012SP1です。

1
Dennis

ログインしているSQLServerからのみデータを取得できます。テーブル定義、ストアドプロシージャなどのメタデータもデータです。

したがって、リンクサーバーを介したログインは成功する必要があります。これは、他のサーバーへのログイン権限を付与することで実行できます。または、リンクサーバーのセキュリティは、必要な権限を持つ特定のログインを介して行うことができます。

ただし、データベースのメタデータに対する権限を取得する意味するものではありませんデータベース内のデータに対する権限が必要であること。例えば:

USE DBName;
GRANT VIEW DEFINITION ON DATABASE::DBName TO [YourDomain\YourLogin]

これにより、ユーザーデータにアクセスしなくても、データベースから定義をスクリプト化できます。 (ただし、必要に応じて個別に付与することもできます。)

編集:SQL Serverは、リンクサーバー全体での遅延名前解決をサポートしていません。したがって、リモートテーブルへの参照を解決できないため、スクリプトが失敗していると確信しています。

もちろん、ストアドプロシージャが暗号化されていない場合、テキストはローカルサーバーのsys.sql_modulesに格納されます。そこからテキストを抽出できます。

 SELECT definition FROM DBName.sys.sql_modules 
 WHERE object_id = object_id(N'DBName.Schema.ObjectName');
1
RLF