создание нового DSN пользователя ODBC с помощью Delphi

AI пытаюсь сделать новую запись в user DSN, в ODBC Data Source Administrator со следующим кодом:

procedure TForm1.FormCreate(Sender: TObject);
var strAttributes: string;
    wideChars   : array[0..1000] of WideChar;
     pfErrorCode: DWORD;
     errMsg: PChar;

begin
 strAttributes := 'DSN=' + 'example_DSN' + Chr(0);
    strAttributes := strAttributes + 'DESCRIPTION=' + 'description' + Chr(0);
    strAttributes := strAttributes + 'SERVER=' + 'testserver' + Chr(0);
    strAttributes := strAttributes + 'DATABASE=' + 'somedatabase' + Chr(0);

  StringToWideChar(strAttributes, wideChars, 12);
  if not SqlConfigDataSource(0, ODBC_ADD_DSN, 'SQL Server', wideChars) then
  begin
    errMsg := AllocMem(SQL_MAX_MESSAGE_LENGTH);
    SQLInstallerError(1, @pfErrorCode, errMsg, SQL_MAX_MESSAGE_LENGTH, nil);
    MessageBox(0, errMsg, PChar('Add System DSN Error #' + IntToStr(pfErrorCode)), 0);
    FreeMem(errMsg);
  end;
end;

но функции sqlconfigdatasource часть не выполнять работу, а также ошибку, которая возвращается не undarstandable на всех. Это не число и не описание ошибки. Может ли кто-нибудь помочь мне, когда я совершаю ошибку? Спасибо

2 ответов


вероятно, ваша ошибка или даже набор ошибок заключается в неправильном переводе заголовков ODBC, которые затем могут быть использованы для не-Unicode или Unicode Delphi версии. Например:

  • для Unicode Delphi вам скорее нужно использовать XxxW (UTF16) функции от ODBCCP32.DLL, чем Xxx (ANSI) функции;
  • для не-Unicode Delphi скорее Xxx функции. А потом ... --5--> должно быть определено как array[..] of Char;
  • SqlConfigDataSource можно определить как XxxW С PAnsiChar;
  • etc.

Я хотел показать вам идею, потому что без полных источников я могу только предполагать. Тогда у вас подозрительный звонок StringToWideChar(strAttributes, wideChars, 12);. значение strAttributes намного длиннее 12 символов.

следующий код хорошо работает в Delphi XE2:

type
  SQLHWnd = LongWord;
  SQLChar = Char;
  PSQLChar = ^SQLChar;
  SQLBOOL = WordBool;
  UDword = LongInt;
  PUDword = ^UDword;
  SQLSmallint = Smallint;
  SQLReturn = SQLSmallint;

const
  SQL_MAX_MESSAGE_LENGTH = 4096;

  ODBC_ADD_DSN     = 1;         // Add data source
  ODBC_CONFIG_DSN  = 2;         // Configure (edit) data source
  ODBC_REMOVE_DSN  = 3;         // Remove data source

  ODBC_ADD_SYS_DSN    = 4;          // add a system DSN
  ODBC_CONFIG_SYS_DSN   = 5;        // Configure a system DSN
  ODBC_REMOVE_SYS_DSN   = 6;        // remove a system DSN
  ODBC_REMOVE_DEFAULT_DSN   = 7;    // remove the default DSN

function SQLConfigDataSource (
    hwndParent:     SQLHWnd;
    fRequest:       WORD;
    lpszDriver:     PChar;
    lpszAttributes: PChar
  ): SQLBOOL; {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};
  external 'odbccp32.dll' name 'SQLConfigDataSourceW';

function SQLInstallerError (
    iError:           WORD;
    pfErrorCode:      PUDword;
    lpszErrorMsg:     PChar;
    cbErrorMsgMax:    WORD;
    pcbErrorMsg:      PWORD
  ): SQLReturn; {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};
  external 'odbccp32.dll' name 'SQLInstallerErrorW';

procedure TForm616.Button1Click(Sender: TObject);
var
  strAttributes: string;
  pfErrorCode: UDword;
  errMsg: PChar;
begin
  strAttributes := 'DSN=' + 'example_DSN' + Chr(0);
  strAttributes := strAttributes + 'DESCRIPTION=' + 'description' + Chr(0);
  strAttributes := strAttributes + 'SERVER=' + 'testserver' + Chr(0);
  strAttributes := strAttributes + 'DATABASE=' + 'somedatabase' + Chr(0);
  if not SqlConfigDataSource(0, ODBC_ADD_DSN, 'SQL Server', PChar(strAttributes)) then begin
    errMsg := AllocMem(SQL_MAX_MESSAGE_LENGTH);
    SQLInstallerError(1, @pfErrorCode, errMsg, SQL_MAX_MESSAGE_LENGTH, nil);
    MessageBox(0, errMsg, PChar('Add System DSN Error #' + IntToStr(pfErrorCode)), 0);
    FreeMem(errMsg);
  end;
end;

ответ правильный, но я должен сделать примечание.

Если вы не устанавливаете testserver с портом, Windows отмечает "Драйвер ODBC для SQL-сервера DBNETLIB 'неверный'связи" Он создает драйвер и подключается, но каждый раз отправляет эту ошибку, если вы не установите тестовый сервер, например:

'testserver, port'

strAttributes := strAttributes + 'SERVER=' + 'testserver,port' + Chr(0);

Это сделало бы лучший ответ, потому что это позволило бы избежать sendidng этой ошибки.