由于LocalAdmin登录,SMO.Transfer失败,但仅适用于某些数据库

时间:2016-12-30 19:16:40

标签: sql-server smo

我正在尝试将SQL Server数据库复制到同一服务器上的新数据库中,而不传输数据(也就是说,我正在尝试构建一个相同的空数据库)。

以下代码在我专门为测试构建的示例数据库上正常工作。但是当应用于实际目标数据库时,它在.TransferData()调用(执行几秒钟后)时失败,错误为System.Data.SqlClient.SqlException : 'LocalAdmin' is not a valid login or you do not have permission.我正在开发和测试程序的帐户可用于记录进入有问题的SQL Server实例并执行数据库创建,以及在源数据库和目标数据库中创建对象。

失败后,targetDb 中指定的数据库实际上已经创建了,但它没有表或其他结构。

有人能告诉我如何修复以下代码,以便能够成功复制我的数据库结构吗?

/* Ref: Microsoft.SqlServer.ConnectionInfo.dll
        Microsoft.SqlServer.Management.Sdk.Sfc.dll
        Microsoft.SqlServer.Smo.dll
        Microsoft.SqlServer.SmoExtended.dll
        Microsoft.SqlServer.SqlEnum.dll */

using Microsoft.SqlServer.Management.Smo;
using System;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            CopyEmptyDatabase(@"server_name\instance_name", "sourceDb_name", "targetDb_name");
        }

        public static void CopyEmptyDatabase(string instance, string sourceDb, string targetDb)
        {
            var server = new Server(instance);

            var transferAgent = new Transfer(server.Databases[sourceDb]);

            transferAgent.CopyAllObjects = true;
            transferAgent.DropDestinationObjectsFirst = true;
            transferAgent.CopySchema = true;
            transferAgent.CopyData = false;

            // Transfer requires the target DB to exist
            var target = new Database(server, targetDb);
            target.Create();

            transferAgent.DestinationServer = instance;
            transferAgent.DestinationDatabase = targetDb;
            transferAgent.DestinationLoginSecure = true;
            transferAgent.Options.IncludeIfNotExists = true;

            try
            {
                transferAgent.TransferData();
            }
            catch (Exception exc)
            {
                Debug.Print(exc.Message);
                throw;
            }

        }
    }
}

2 个答案:

答案 0 :(得分:1)

尝试从SQL工具创建一个新数据库,看看是否可以删除新创建的数据库中的sprocs。如果您不是dbo,则可能无法删除它们。请注意,其中的对象是从model db ...复制的,因此它在开始时不会完全为空。您的组织可能还在model添加了内容...因此您需要对此进行调查。

修改

另一种测试此理论的方法......只需删除显示transferAgent.DropDestinationObjectsFirst = true;

的行

答案 1 :(得分:0)

  • 登录问题可能与查询运行的服务帐户有关。例如,复制默认使用SQL Server代理帐户读入文件共享。这也与尝试登录目标数据库的帐户有关。
  • 绝不写明文密码。
  • 确保SUSER_ID与逻辑相同,两个相同但纯文本的登录/用户将彼此不同。

当它已经可用时,尽量不要重新发明轮子。除非这是一个应用程序(听起来有风险),利用您已拥有的工具将节省时间,创建稳定的.sql文件,并帮助控制对任何PROD环境的更改。

作为一般规则,如果我在PROD服务器的原理图级别上更改了任何内容,我会在实现之前保存脚本或先前的原理图。你永远不知道什么时候能挽救你的生命。

  1. 使用SSMS并选择GENERATE SCRIPTS Generate ScriptsObject Explorer中,右键单击目标数据库。在标签Tasks下,选择Generate Scripts...

    • 默认情况下,设置设置为重新创建所有主要(tablesschemasStored Procedures等)对象,但这不包括某些无形设置,例如数据。
  2. 设置位置 Set Scripting Options 设置脚本的位置,例如每个人都可以找到的共享文件夹。

    • 如果您可以避免使用Unicode脚本,请使用ANSI设置,因为任何大型.sql文件都需要SQLCMD才能执行。
    • 或者,您可以将对象拆分为自己的文件,以允许版本控制
  3. 使用高级设置 Set the environment 您可以设置脚本的版本级别(可以追溯到SQL Server 2005)和数据库引擎的类型。
    • 您将指定登录对象级权限所有者,甚至可以选择包含统计信息如果您的测试与您的PROD环境相同,则直方图。一般来说,让Optimizer处理这个。
    • 可能不包含其他对象,例如Triggers,因此请务必浏览您所在环境的列表。
  4. 享受您的新.sql脚本! Enjoy!!! 这就是全部!
  5.   

    最好的部分是使用本地SSMS客户端来创建和您   拥有任何SQL Server版本都能够使用的合法.sql文件   读取。