2013-10-02 2 views
1

데이터베이스를 설치하는 설치 프로그램이 있습니다. 데이터베이스는 일부 로그인과 함께 생성됩니다. 로그인을 만들려면 SqlString 요소에서 master 데이터베이스를 사용하고 있습니다. master 데이터베이스에 대한 액세스 권한은 SQL Server에 대한 권한이 매우 높은 사용자에게만 부여됩니다. 마스터 데이터베이스 용으로 지정된 SQL 문자열을 권한 부족으로 실행할 수 없기 때문에 설치가 중단되는 경우가 많습니다.SqlString으로 편집 한 문자열의 결과를 내보낼 수 있습니까?

SqlString 요소를 실행할 수 없을 때 설치의 SQL 부분을 건너 뛰도록 설치 프로그램을 편집하고 싶습니다. 설치가 완료되면 사용자가 SQL 문을 직접 실행할 수 있기를 원합니다. 설치 관리자가 취한 모든 SQL 작업은 SqlString 요소에 저장됩니다. SqlString 요소에는 설치 중에 바뀌는 많은 속성이 들어 있습니다. 모든 편집 된 SqlString 요소의 내용을 사용자 디렉토리에 저장된 하나의 SQL 파일로 추출하려고합니다.

sqlextension이 속성을 대체 한 후 발생하는 사용자 지정 작업을 작성해야합니다. 그런 다음 변경된 문자열에 액세스해야합니다. 내가 이것을 할 수있는 방법이 있습니까?

예 SqlString 요소 : 나는 SqlStrings 실패 후가하고자하는 SQL 파일의

<sql:SqlDatabase Id="MasterDB" Server="[SQLSERVER_SERVER]" Instance="[SQLSERVER_INSTANCENAME]" Database="master" /> 

<sql:SqlString 
     SqlDb="MasterDB" 
     Id="CreateNetworkServiceAccount" 
     ExecuteOnInstall="yes" 
     ContinueOnError="no" 
     SQL="IF NOT EXISTS (SELECT * FROM sys.server_principals WHERE name = N'{[WIX_ACCOUNT_NETWORKSERVICE]}') 
     CREATE LOGIN [\[]{[WIX_ACCOUNT_NETWORKSERVICE]}[\]] FROM WINDOWS WITH DEFAULT_DATABASE=[\[]master[\]]" 
     Sequence="101"/> 

예 :

USE master; 
IF NOT EXISTS (SELECT * FROM sys.server_principals WHERE name = N'NT AUTHORITY\Network Service') 
CREATE LOGIN [NT AUTHORITY\Network Service] FROM WINDOWS WITH DEFAULT_DATABASE=[master] 

답변

0

나는 오히려 이상한 솔루션이 문제를 해결했다. CustomAction을 작성하여 SqlString 테이블에서 String 요소를 추출한 다음 세션에 저장된 적절한 Properties로 서식이 지정된 필드를 바꿉니다. 세션 변수에 액세스하려면 CustomAction을 immediate으로 실행해야합니다. 나는 InstallFinalize 전에 PersonalFolder 속성에 대한 액세스 권한을 부여하기 전에 일정을 잡았습니다. 이 속성을 사용하여 사용자 Documents 디렉터리의 SqlScript 테이블에있는 항목으로 생성 된 Sql 스크립트를 저장할 수 있습니다. 설치시 다른 데이터베이스를 고려하기 위해 SqlDatabase 테이블에 조회를 포함 시켰습니다.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Deployment.WindowsInstaller; 
using System.IO; 
using System.Text.RegularExpressions; 

namespace SaveSqlStrings 
{ 
    public class CustomActions 
    { 
     [CustomAction] 
     public static ActionResult SaveSqlStrings(Session session) 
     { 
      StringBuilder sqlStrings = new StringBuilder(); 
      Database db = session.Database; 
      View view = db.OpenView("SELECT * FROM `SqlString`"); 
      IList<string> SqlStringElements = db.ExecuteStringQuery("SELECT `String` FROM `SqlString`"); 
      Regex bracketedProperties = new Regex(@"\[(\b[A-Z_]*\b)\]"); 
      Regex formattedProperties = new Regex(@"{\[(\b[A-Z_]*\b)\]}"); 
      Regex openeningSquareBrackets = new Regex(@"\[\\\[\]"); 
      Regex closingSquareBrackets = new Regex(@"\[\\\]\]"); 
      string sqlDb_ = ""; 
      string sqlString = ""; 
      string Database = ""; 
      foreach (string dbString in SqlStringElements) 
      { 
       sqlDb_ = (string)db.ExecuteScalar("SELECT `SqlDb_` FROM `SqlString` WHERE `String` ='{0}'",dbString); 
       sqlString = (string)db.ExecuteScalar("SELECT `SQL` FROM `SqlString` WHERE `String` ='{0}'",dbString); 
       view.Close(); 
       view = db.OpenView("SELECT * FROM `SqlDatabase`"); 
       Database = (string)db.ExecuteScalar("SELECT `Database` from `SqlDatabase` WHERE `SqlDb`='{0}'", sqlDb_); 
       if(bracketedProperties.IsMatch(Database)) 
       { 
        Database = bracketedProperties.Match(Database).Groups[1].Value; 
        Database = session[Database]; 
       } 
       if (openeningSquareBrackets.IsMatch(sqlString)) 
        sqlString = openeningSquareBrackets.Replace(sqlString, "["); 
       if (closingSquareBrackets.IsMatch(sqlString)) 
        sqlString = closingSquareBrackets.Replace(sqlString, "]"); 
       if(formattedProperties.IsMatch(sqlString)) 
       { 
        string propertyName = formattedProperties.Match(sqlString).Groups[1].Value; 
        string propertyValue = session[propertyName]; 
        sqlString = formattedProperties.Replace(sqlString, propertyValue); 
       } 
       sqlStrings.AppendLine(String.Format("use {0}",Database)); 
       sqlStrings.AppendLine(sqlString); 
      } 
      string home = session["PersonalFolder"]; 
      string sqlPath = string.Concat(home, @"Script.sql"); 
      try 
      { 
       File.WriteAllText(sqlPath, sqlStrings.ToString()); 
      } 
      catch (Exception ex) 
      { 
       session["FailedTowrite"] = sqlPath; 
      } 
      view.Close(); 
      db.Close(); 
      return ActionResult.Success; 
     } 
    } 
} 
: 여기

은에서 CustomAction에 코드입니다