简体   繁体   English

使用Delphi创建新的ODBC用户DSN

[英]creating a new ODBC user DSN with Delphi

AI am trying to make a new entry in User DSN, in ODBC Data Source Administrator with the following code: 我正在尝试使用以下代码在ODBC数据源管理器中在用户DSN中创建一个新条目:

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;

but the SqlConfigDataSource part does not do the job, and also the error that is returned is not undarstandable at all. 但是SqlConfigDataSource部分不能完成这项工作,并且返回的错误也不是无法解决的。 It is not a number, nor description for the error. 它不是数字,也不是错误的描述。 Can anyone help me where i make the mistake? 任何人都可以在我犯错的地方帮助我吗? Thanks 谢谢

Probably your error or even set of errors is in incorrect translation of ODBC headers, which then may be used for non-Unicode or Unicode Delphi version. 可能是您的错误甚至错误集都是ODBC标头的错误翻译,然后可能会用于非Unicode或Unicode Delphi版本。 For example: 例如:

  • for Unicode Delphi you rather need to use XxxW (UTF16) functions from ODBCCP32.DLL , than Xxx (ANSI) functions; 对于Unicode德尔福你最好使用XxxW (UTF-16)功能从ODBCCP32.DLL ,比Xxx (ANSI)的功能;
  • for non-Unicode Delphi rather Xxx functions. 用于非Unicode Delphi而非Xxx功能。 And then wideChars should be defined as array[..] of Char ; 然后将wideChars定义为array[..] of Char ;
  • SqlConfigDataSource may be defined as XxxW with PAnsiChar; SqlConfigDataSource可以用PAnsiChar定义为XxxW ;
  • etc. 等等

I wanted to show you the idea, because without full sources I can only speculate. 我想向你展示这个想法,因为没有完整的资料我只能推测。 Then you have suspicious call StringToWideChar(strAttributes, wideChars, 12); 然后你有可疑的调用StringToWideChar(strAttributes, wideChars, 12); . strAttributes value is much more long than 12 characters. strAttributes值远远超过12个字符。

The following code works well in Delphi XE2: 以下代码在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;

The answer is right but i have to make a note. 答案是对的,但我必须做一个说明。

If you don't set the testserver with the port, windows marks "ODBC SQL SERVER DRIVER DBNETLIB 'Invalid Connection'" It creates the driver and in connects but everytime it sends this error if you don't set the test server like: 如果没有使用端口设置testserver,则Windows会标记“ODBC SQL SERVER DRIVER DBNETLIB'无效连接'”它会创建驱动程序并在连接中,但如果您没有将测试服务器设置为以下,则每次发送此错误时:

'testserver,port' 'TESTSERVER,端口'

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

That would make a better answer because it would avoid sendidng this error. 那样会有更好的答案,因为它可以避免发送此错误。

for Delphi7 http://www.delphigroups.info/2/0b/29040.html 对于Delphi7 http://www.delphigroups.info/2/0b/29040.html

  function SQLConfigDataSource( 
      hwndParent: HWND; 
      fRequest: WORD; 
      lpszDriver: LPCSTR; 
      lpszAttributes: LPCSTR): BOOL; stdcall; external 'ODBCCP32.DLL'; 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM