【问题标题】:Smo Scripter scripting user script with "Incorrect Syntax"Smo Scripter 使用“不正确的语法”编写用户脚本
【发布时间】:2013-12-10 23:02:07
【问题描述】:

我正在使用 Smo 为数据库的用户及其角色编写脚本。这是我的做法:

var scripter = new Scripter(server)
{
    Options = new ScriptingOptions()
    {
        IncludeIfNotExists = true,
        IncludeDatabaseRoleMemberships = true,
        // lots of other options here
    }
};

foreach (User smoObject in database.Users)
{
    var sc = scripter.Script(new Urn[] { smoObject.Urn });
    // write to file here
}

结果是这样的:

/****** Object:  User [myuser]    Script Date: 12/10/2013 5:00:57 PM ******/
IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N'myuser')
CREATE USER [myuser] WITHOUT LOGIN WITH DEFAULT_SCHEMA=[dbo]
sys.sp_addrolemember @rolename = N'r_execprocs', @membername = N'myuser'
sys.sp_addrolemember @rolename = N'db_owner', @membername = N'myuser'
sys.sp_addrolemember @rolename = N'db_datareader', @membername = N'myuser'
sys.sp_addrolemember @rolename = N'db_datawriter', @membername = N'myuser'

但是,如果您尝试对数据库运行此脚本,您会得到:

“消息 102,级别 15,状态 1,第 4 行 'sys' 附近的语法不正确。”

但是,如果我手动将脚本更改为:

/****** Object:  User [myuser]    Script Date: 12/10/2013 5:00:57 PM ******/
IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N'myuser')
CREATE USER [myuser] WITHOUT LOGIN WITH DEFAULT_SCHEMA=[dbo]
GO
sys.sp_addrolemember @rolename = N'r_execprocs', @membername = N'myuser'
GO
sys.sp_addrolemember @rolename = N'db_owner', @membername = N'myuser'
GO
sys.sp_addrolemember @rolename = N'db_datareader', @membername = N'myuser'
GO
sys.sp_addrolemember @rolename = N'db_datawriter', @membername = N'myuser'
GO

脚本完美运行。有没有办法:

  • 按原样运行脚本而不会出现“语法错误”或
  • 让脚本编写者以可运行的方式生成此脚本 ?

【问题讨论】:

  • 不是批处理中第一个命令的存储过程调用需要在前面加上EXEC。您可以在每次调用sys.sp_addrolememeber 之前添加EXEC,或者使用GO 将每个命令放入自己的批处理中,就像您在此处显示的那样。
  • 有没有办法使用 Smo 库生成它?
  • @saml user.AddToRole("db_datareader");等等……

标签: c# sql smo


【解决方案1】:

嗯,想通了。脚本编写者可以做两件事的任意组合:

  • 将脚本输出到内存中的StringCollection
  • 将脚本输出到scripter.Options.FileName确定的文件中

当为字符串集合编写脚本时,由于某种原因,它不会在 sp 调用之间编写批处理终止符 GO,但在编写文件时会这样做。所以我把上面的代码改成这样:

var scripter = new Scripter(server)
{
    Options = new ScriptingOptions()
    {
        IncludeIfNotExists = true,
        IncludeDatabaseRoleMemberships = true,

        //ADDED THIS OPTION
        FileName = Path.Combine(path, "Script.sql"),

        // lots of other options here
    }
};

foreach (User smoObject in database.Users)
{
    var sc = scripter.Script(new Urn[] { smoObject.Urn });
    // no need to write to file anymore since scripter automatically does it
}

结果是:

/****** Object:  User [myuser]    Script Date: 12/10/2013 5:00:57 PM ******/
IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N'myuser')
CREATE USER [myuser] WITHOUT LOGIN WITH DEFAULT_SCHEMA=[dbo]
GO
sys.sp_addrolemember @rolename = N'r_execprocs', @membername = N'myuser'
GO
sys.sp_addrolemember @rolename = N'db_owner', @membername = N'myuser'
GO
sys.sp_addrolemember @rolename = N'db_datareader', @membername = N'myuser'
GO
sys.sp_addrolemember @rolename = N'db_datawriter', @membername = N'myuser'
GO

【讨论】:

    猜你喜欢
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多