2013-12-10 87 views
1

我正在使用Smo編寫數據庫的用戶及其角色。這裏是我正在做它:Smo Scripter使用「語法錯誤」腳本編寫用戶腳本

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' 

但是,如果你嘗試和對數據庫運行該腳本,你會得到:

「Msg 102,Level 15,State 1,Line 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 

腳本完美的作品。有沒有辦法要麼:

  • 運行腳本是沒有得到「不正確的語法」或
  • 讓編劇產生的方式,可運行 這個腳本?
+0

存儲過程調用不屬於第一個命令在批處理需要通過'EXEC'之前。你可以在每次調用sys.sp_addrolememeber之前添加'EXEC',或者像你在這裏顯示的那樣使用'GO'將每個命令放到它自己的批處理中。 –

+0

有沒有使用Smo庫生成的方法? – saml

+0

@saml user.AddToRole(「db_datareader」);等等... – yuriy

回答

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