2012-03-04 11 views
5

AI estoy tratando de hacer una nueva entrada en el DSN de usuario, en Administrador de orígenes de datos ODBC con el siguiente código:crear un nuevo DSN de usuario ODBC con Delphi

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; 

pero la parte SqlConfigDataSource no hace el trabajo, y también el error que se devuelve no es imposible de entender en absoluto. No es un número, ni una descripción del error. ¿Alguien puede ayudarme donde cometo el error? Gracias

Respuesta

7

Probablemente su error o incluso un conjunto de errores es en la traducción incorrecta de encabezados ODBC, que luego se pueden utilizar para la versión no Unicode o Unicode Delphi. Por ejemplo:

  • para Unicode Delphi en lugar necesidad de utilizar XxxW funciones (UTF16) de ODBCCP32.DLL, que Xxx funciones (ANSI);
  • para funciones no Delicode Delphi más bien Xxx. Y luego wideChars se debe definir como array[..] of Char;
  • SqlConfigDataSource se puede definir como XxxW con PAnsiChar;
  • etc.

quería mostrarle la idea, ya que sin el código fuente completo sólo puedo especular. Entonces tiene una llamada sospechosa StringToWideChar(strAttributes, wideChars, 12);. El valor de strAttributes es mucho más largo que 12 caracteres.

El siguiente código funciona bien en 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; 
+0

gracias, eso funcionó – dzibul

-1

La respuesta es correcta, pero tengo que hacer una nota.

Si no se establece la testserver con el puerto, las marcas de ventanas "ODBC SQL SERVER DRIVER DBNETLIB 'de conexión no válido'" Se crea el conductor y en Conexiones pero cada vez que se envía este error si no se establece el servidor de pruebas como:

'testserver, puerto'

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

que haría una mejor respuesta, ya que evitaría sendidng este error.

Cuestiones relacionadas