-1

我管理了我的安装程序的 [code] 部分,以便运行一个简单的 sql 脚本(针对现有的 db/table 进行选择)。编译正常,使用正确的密码正确检索 sql 机器和实例,但是无论何时运行安装程序,安装程序都会暂时中止提供消息 " Microsoft OLE DB Provider for SQL Server: Could not find store procedure 'ÿƥS'。当然,这些字符都没有在 sql 脚本 ( SELECT @@SERVERNAME AS SERVERNAME, DB_NAME() AS [DB_NAME], CURRENT_USER AS [CURRENT_USER]) 中定义。

这是[代码]部分:

[Code]
const
  //some constants definition

var
  //some var definition

 var
  Page: TWizardPage;

// Used to generate error code by sql script errors
procedure ExitProcess(exitCode:integer);
  external 'ExitProcess@kernel32.dll stdcall';

// enable/disable child text boxes & functions when text has been entered into Server textbox. Makes no sense to populate child items unless a value exists for server.
Procedure ServerOnChange (Sender: TObject);
begin                            
  //code there
end;

// enable/disable user/pass text boxes depending on selected auth type. A user/pass is only required for SQL Auth
procedure  AuthOnChange (Sender: TObject);
begin
  //code there
end;

// Enable next button once a database name has been entered.
Procedure DatabaseOnChange (Sender: TObject);
//code there
end;

// Retrieve a list of databases accessible on the server with the credentials specified.
// This list is shown in the database dropdown list
procedure RetrieveDatabaseList(Sender: TObject);
var  
  ADOCommand: Variant;
  ADORecordset: Variant;
  ADOConnection: Variant;  
begin
  lstDatabase.Items.Clear;
  try
    // create the ADO connection object
    ADOConnection := CreateOleObject('ADODB.Connection');
    // build a connection string; for more information, search for ADO
    // connection string on the Internet 
    ADOConnection.ConnectionString := 
      'Provider=SQLOLEDB;' +               // provider
      'Data Source=' + txtServer.Text + ';' +   // server name
      'Application Name=' + '{#SetupSetting("AppName")}' + ' DB List;'
    if chkWindowsAuth.Checked then
      ADOConnection.ConnectionString := ADOConnection.ConnectionString +
      'Integrated Security=SSPI;'         // Windows Auth
    else
      ADOConnection.ConnectionString := ADOConnection.ConnectionString +
      'User Id=' + txtUsername.Text + ';' +              // user name
      'Password=' + txtPassword.Text + ';';                   // password
    // open the connection by the assigned ConnectionString
    ADOConnection.Open;
    try
      // create the ADO command object
      ADOCommand := CreateOleObject('ADODB.Command');
      // assign the currently opened connection to ADO command object
      ADOCommand.ActiveConnection := ADOConnection;
      // assign text of a command to be issued against a provider
      ADOCommand.CommandText := 'SELECT name FROM master.dbo.sysdatabases WHERE HAS_DBACCESS(name) = 1 ORDER BY name';
      // this property setting means, that you're going to execute the 
      // CommandText text command; it does the same, like if you would
      // use only adCmdText flag in the Execute statement
      ADOCommand.CommandType := adCmdText;
      // this will execute the command and return dataset
      ADORecordset := ADOCommand.Execute;
      // get values from a dataset using 0 based indexed field access;
      // notice, that you can't directly concatenate constant strings 
      // with Variant data values
      while not ADORecordset.eof do 
      begin
       lstDatabase.Items.Add(ADORecordset.Fields(0));
       ADORecordset.MoveNext;
      end  ;

    finally
      ADOConnection.Close;
    end;
  except
    MsgBox(GetExceptionMessage, mbError, MB_OK);
  end;
end;

// Execute files specified in [files] section (hardcoded) against the user defined server.database
procedure DeploySQL();
var  
  Myscript: AnsiString;    
  ADOCommand: Variant;
  ADOConnection: Variant;  
begin
  // extract script
  ExtractTemporaryFile('script.sql');

  try
    // create the ADO connection object
    ADOConnection := CreateOleObject('ADODB.Connection');
    // build a connection string; for more information, search for ADO
    // connection string on the Internet 
    ADOConnection.ConnectionString := 
      'Provider=SQLOLEDB;' +               // provider
      'Data Source=' + txtServer.Text + ';' +   // server name
      'Initial Catalog=' + lstDatabase.Text + ';' +   // server name
      'Application Name=' + '{#SetupSetting("AppName")}' + ' Execute SQL;' ;     
    if chkWindowsAuth.Checked then
      ADOConnection.ConnectionString := ADOConnection.ConnectionString +
      'Integrated Security=SSPI;'         // Windows Auth
    else
      ADOConnection.ConnectionString := ADOConnection.ConnectionString +
      'User Id=' + txtUsername.Text + ';' +              // user name
      'Password=' + txtPassword.Text + ';';                   // password
    // open the connection by the assigned ConnectionString
    ADOConnection.Open;
    try
      // create the ADO command object
      ADOCommand := CreateOleObject('ADODB.Command');
      // assign the currently opened connection to ADO command object
      ADOCommand.ActiveConnection := ADOConnection;
      // load a script from file into variable. 
      if(LoadStringFromFile(ExpandConstant('{app}\script.sql'), Myscript)) then
      begin
        // assign text of a command to be issued against a provider. Append all 3 because one of the install assembly strings will always be empty.
        ADOCommand.CommandText := Myscript;
        // this will execute the script; the adCmdText flag here means
        // you're going to execute the CommandText text command, while
        // the adExecuteNoRecords flag ensures no data row will be get
        // from a provider, what should improve performance
        ADOCommand.Execute(NULL, NULL, adCmdText or adExecuteNoRecords);
      end
      else
      begin
        MsgBox('Installation files missing.', mbError, MB_OK);
        ExitProcess(7);
      end ;
    finally
      ADOConnection.Close;
    end;
  except
    MsgBox(GetExceptionMessage, mbError, MB_OK);
    ExitProcess(5);
  end;
end;

{ CustomForm_NextkButtonClick }
// try to connect to supplied db. Dont need to catch errors/close conn on error because a failed connection is never opened.
function CustomForm_NextButtonClick(Page: TWizardPage): Boolean;
var  
  ADOConnection: Variant;  
begin
  //try
    // create the ADO connection object
    ADOConnection := CreateOleObject('ADODB.Connection');
    // build a connection string; for more information, search for ADO
    // connection string on the Internet 
    ADOConnection.ConnectionString := 
      'Provider=SQLOLEDB;' +               // provider
      'Data Source=' + txtServer.Text + ';' +   // server name
      'Initial Catalog=' + lstDatabase.Text + ';' +   // server name
      'Application Name=' + '{#SetupSetting("AppName")}' + ' Execute SQL;' ;     
    if chkWindowsAuth.Checked then
      ADOConnection.ConnectionString := ADOConnection.ConnectionString +
      'Integrated Security=SSPI;'         // Windows Auth
    else
      ADOConnection.ConnectionString := ADOConnection.ConnectionString +
      'User Id=' + txtUsername.Text + ';' +              // user name
      'Password=' + txtPassword.Text + ';';                   // password
    // open the connection by the assigned ConnectionString
    ADOConnection.Open;
    Result := True;
end;

{ CustomForm_CreatePage }

function CustomForm_CreatePage(PreviousPageId: Integer): Integer;
begin

  Page := CreateCustomPage(
    PreviousPageId,
    ExpandConstant('{cm:CustomForm_Caption}'),
    ExpandConstant('{cm:CustomForm_Description}')
  );

  { lblServer }
  lblServer := TLabel.Create(Page);
  with lblServer do
  begin
    Parent := Page.Surface;
    Caption := ExpandConstant('{cm:CustomForm_lblServer_Caption0}');
    Left := ScaleX(24);
    Top := ScaleY(32);
    Width := ScaleX(68);
    Height := ScaleY(13);
    Enabled := True;
  end;

  { txtServer }
  txtServer := TEdit.Create(Page);
  with txtServer do
  begin
    Parent := Page.Surface;
    Left := ScaleX(112);
    Top := ScaleY(32);
    Width := ScaleX(273);
    Height := ScaleY(21);
    TabOrder := 1;
    Enabled := True;
    OnChange := @ServerOnChange;
  end;

  { lblAuthType }
  lblAuthType := TLabel.Create(Page);
  with lblAuthType do
  begin
    Parent := Page.Surface;
    Caption := ExpandConstant('{cm:CustomForm_lblAuthType_Caption0}');
    Left := ScaleX(24);
    Top := ScaleY(72);
    Width := ScaleX(87);
    Height := ScaleY(13);
    Enabled := False;
  end;

  { chkWindowsAuth }
  chkWindowsAuth := TRadioButton.Create(Page);
  with chkWindowsAuth do
  begin
    Parent := Page.Surface;
    Caption := ExpandConstant('{cm:CustomForm_chkWindowsAuth_Caption0}');
    Left := ScaleX(32);
    Top := ScaleY(88);
    Width := ScaleX(177);
    Height := ScaleY(17);
    Checked := True;
    TabOrder := 2;
    TabStop := True;
    OnClick := @AuthOnChange;
    Enabled := False;
  end;

  { chkSQLAuth }
  chkSQLAuth := TRadioButton.Create(Page);
  with chkSQLAuth do
  begin
    Parent := Page.Surface;
    Caption := ExpandConstant('{cm:CustomForm_chkSQLAuth_Caption0}');
    Left := ScaleX(32);
    Top := ScaleY(108);
    Width := ScaleX(185);
    Height := ScaleY(17);
    TabOrder := 3;
    OnClick := @AuthOnChange;
    Enabled := False;
  end;

  { lblUser }
  lblUser := TLabel.Create(Page);
  with lblUser do
  begin
    Parent := Page.Surface;
    Caption := ExpandConstant('{cm:CustomForm_lblUser_Caption0}');
    Left := ScaleX(56);
    Top := ScaleY(128);
    Width := ScaleX(58);
    Height := ScaleY(13);
    Enabled := False;
  end;

  { lblPassword }
  lblPassword := TLabel.Create(Page);
  with lblPassword do
  begin
    Parent := Page.Surface;
    Caption := ExpandConstant('{cm:CustomForm_lblPassword_Caption0}');
    Left := ScaleX(56);
    Top := ScaleY(152);
    Width := ScaleX(53);
    Height := ScaleY(13);
    Enabled := False;
  end;

  { txtUsername }
  txtUsername := TEdit.Create(Page);
  with txtUsername do
  begin
    Parent := Page.Surface;
    Left := ScaleX(120);
    Top := ScaleY(128);
    Width := ScaleX(241);
    Height := ScaleY(21);
    Enabled := False;
    TabOrder := 4;
  end;

  { txtPassword }
  txtPassword := TPasswordEdit.Create(Page);
  with txtPassword do
  begin
    Parent := Page.Surface;
    Left := ScaleX(120);
    Top := ScaleY(152);
    Width := ScaleX(241);
    Height := ScaleY(21);
    Enabled := False;
    TabOrder := 5;
  end;

   { lblDatabase }
  lblDatabase := TLabel.Create(Page);
  with lblDatabase do
  begin
    Parent := Page.Surface;
    Caption := ExpandConstant('{cm:CustomForm_lblDatabase_Caption0}');
    Left := ScaleX(56);
    Top := ScaleY(192);
    Width := ScaleX(53);
    Height := ScaleY(13);
    Enabled := False;
  end;

  { lstDatabase }
  lstDatabase := TComboBox.Create(Page);
  with lstDatabase do
  begin
    Parent := Page.Surface;
    Left := ScaleX(120);
    Top := ScaleY(192);
    Width := ScaleX(145);
    Height := ScaleY(21);
    Enabled := False;
    TabOrder := 6;    
    OnDropDown:= @RetrieveDatabaseList;
    OnChange:= @DatabaseOnChange;
  end;

  with Page do
  begin
    OnNextButtonClick := @CustomForm_NextButtonClick;
  end;

  Result := Page.ID;
end;

procedure CurPageChanged(CurPageID: Integer);
begin
// set initial status of next button. Should be disabled when page is first loaded, but should be enabled if user clicked back.
  if CurPageID = Page.ID then
    WizardForm.NextButton.Enabled := bIsNextEnabled;  
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
// The preinstall step seems like the best time to do the actual install. The problem is that this is not a traditional install. Nothing is copied to the users' pc
  if CurStep = ssInstall then
    DeploySQL;  
end;

procedure InitializeWizard();
begin
  bIsNextEnabled := False;
  CustomForm_CreatePage(wpLicense);
end;

任何想法?谢谢

4

1 回答 1

0

我得到了解决方案!if(LoadStringFromFile(ExpandConstant('{app}\script.sql'), Myscript)) 语句中出现问题,因为 sql 文件不是 ANSI 编码的。通过更改编码一切都很好。谢谢大家!

于 2015-11-04T09:43:49.787 回答