PDA

Ver la Versión Completa : Obtener ado connectionstring


mblascog
30-05-2014, 09:31:50
Buenas,
He creado una aplicación que accede a una base de datos Access vía ODBC.
He creado un DSN de usuario, y he cargado en la propiedad ConnectionString la cadena de connexión:

Provider=MSDASQL.1;Persist Security Info=False;Extended Properties="DSN=Iris;DBQ=C:\OMH\Habitatge_Iris.mdb;DriverId=25;FIL=MS Access;MaxBufferSize=2048;PageTimeout=5;UID=admin;"


Ahora que ya he acabo el programa y funciona en mi pc, lo quiero instalar en el servidor de la empresa. Al igual, creo el DSN de usuario en el servidor, y en ConnectionString cambio la ruta de la base de datos. Creía que así funcionaría, pero da el siguiente error:

[Microsoft][Controlador ODBC Microsoft Access]'desconocido' no es una ruta de acceso válida. Asegúrese de que la ruta está escrita correctamente y que está conectado al servidor donde se encuentra el archivo

La ruta es correcta, seguro. Es una unidad de red.
He buscado si existe alguna función que a partir del nombre de DSN de usuario te devuelva la cadena de conexión, pero no he encontrado nada.

Alguien puede guiarme un poco.
Gracias.

ecfisa
30-05-2014, 13:33:36
Hola mblascog.

Intenta de este modo:

...
implementation

uses Registry;

function IsWOW64: Boolean;
type
LPFN_ISWOW64PROCESS = function(hProcess: THandle; var Wow64Process: BOOL): BOOL; stdcall;
var
fnIsWow64Process: LPFN_ISWOW64PROCESS;
bIsWOW64: BOOL;
begin
Result:= False;
fnIsWow64Process:= LPFN_ISWOW64PROCESS(GetProcAddress(GetModuleHandle('kernel32'), 'IsWow64Process'));
if Assigned(fnIsWow64Process) then
begin
bIsWow64:= False;
if fnIsWow64Process(GetCurrentProcess(), bIsWOW64) then
Result:= bIsWOW64;
end;
end;

function GetConnectStrFromDSN(const DSNStr: string): string;
const
KEY_WOW64_64KEY = $0100;
begin
Result:= '';
with TRegistry.Create(KEY_READ + KEY_WOW64_64KEY * Integer(IsWOW64)) do
try
RootKey:= HKEY_LOCAL_MACHINE;
if OpenKey('\SOFTWARE\ODBC\ODBC.INI', False) then
begin
Result:= ReadString(DSNStr);
CloseKey;
end;
finally
Free;
end;
end;


Ej. llamada:

procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(GetConnectStrFromDSN('Iris'));
end;


Saludos :)

mblascog
30-05-2014, 16:33:44
Buenas Ecfisa,
Gracias por tu código. Lo he probado y me devuelve un string en blanco.
He mirado en el Registro si existía la clave y la he encontrado en HKEY_CURRENT_USER en lugar de HKEY_LOCAL_MACHINE. Lo he cambiado, pero me sigue devolviendo el string en blanco.
Puede tener algo que ver en 32 o 64 bits?

Gracias por tu ayuda.

ecfisa
30-05-2014, 17:01:41
Hola mblascog.
Buenas Ecfisa,
Gracias por tu código. Lo he probado y me devuelve un string en blanco.
He mirado en el Registro si existía la clave y la he encontrado en HKEY_CURRENT_USER en lugar de HKEY_LOCAL_MACHINE. Lo he cambiado, pero me sigue devolviendo el string en blanco.
Puede tener algo que ver en 32 o 64 bits?

Es lo mas probable ya que si el SO es de 64 bits hay registros afectados por WOW64 (entre los que figura el que tratamos).

Si todo transcurre en un entorno de 32 bits el código quedaría de este modo:

function GetConnectStrFromDSN(const DSNStr: string): string;
begin
Result:= '';
with TRegistry.Create(KEY_READ) do
try
RootKey:= HKEY_LOCAL_MACHINE;
if OpenKey('\SOFTWARE\ODBC\ODBC.INI', False) then
begin
Result:= ReadString(DSNStr);
CloseKey;
end;
finally
Free;
end;


Saludos :)

mblascog
30-05-2014, 18:56:59
Gracias Daniel,
Pero me sigue devolviendo una cadena en blanco.
Quizás me estoy complicando la vida. La cadena de ConnectionString la consigo a partir de la propiedad ConnectionString del componente TQuery. Al hacer click me aparece la pantalla para construir la cadena, seleccionas el origen de datos (DSN de usuario) y te la genera.
Hay alguna manera de conseguir, como sea, esta cadena en Windows Server 2003, es que no me importa ponerla a mano y dejo de complicarme la vida?.

Muchas gracias por tu ayuda.

ecfisa
30-05-2014, 19:49:38
Hola mblascog.

No sé si entendí lo último que comentas pero si solo se trata de obtener la ruta de la cadena que previamente se generó en el query, creo que podrías hacer:

uses StrUtils;

function GetPathFromQry(const qStr:string): string;
var
p1,p2: Integer;
begin
Result:= '';
p1:= Pos('DBQ=', qStr) + Length('DBQ=');
p2:= PosEx(';', qStr , p1);
Result := Copy(qStr ,p1, p2-p1);
end;


Ej. de llamada:

ShowMessage(GetPathFromQry(ADOQuery1.ConnectionString));

De la cadena ejemplo de tu mensaje se obtendría: C:\OMH\Habitatge_Iris.mdb

Saludos :)

mblascog
30-05-2014, 20:51:08
Gracias Ecsisa,
Creo que no me expliqué bien.
He hecho un programa que accede a una base de datos Access.
Para hacer el programa me he copiado la base de datos a mi pc y desde él he trabajado.
Ahora que he acabado el programa, quiero copiarlo al servidor de la empresa, donde está la base de datos Access, por lo que tengo que cambiar el CconnectionString.
Pensaba que cambiando la ruta de la base de datos (DQQ) funcionaría, pero me da el error que comenté en el primer mensaje. Y la verdad es que ya no sé qué hacer.

Gracias

ecfisa
30-05-2014, 21:01:41
Hola mblascog.

El que te debe la disculpa soy yo que entendí cualquier cosa...

Una consulta que con seguridad ya te hayas planteado, ¿ Comparaste las cadenas de conexión de tu equipo con alguna de las existentes en el servidor como para darte una idea en que difieren ?

Saludos :)

mblascog
30-05-2014, 21:16:43
Buenas Ecfisa,
Todas la conexiones las he creado yo misma, desde Herramientas Administrativas - Orígines de Datos ODBC - DSN de usuario.
Por esto pensaba que en sólo cambiar la ruta debería funcionar, pero no.
En mi pc, como tengo instalado Delphi, obtengo la cadena de conexión desde el propio componente TADOquery, pero en el servidor no está instalador Delphi, por lo que no sé cómo generarla.
Si existiera una alguna manera de obtenerla me sería suficiente.

Gracias.

mblascog
01-06-2014, 22:54:50
Buenas,
He visto que el problema lo tengo por tener ubicada la base de datos en una unidad lógica correspondiente a un segundo disco del ordenador donde ejecuto. Si la copio a la c:\ y cambio la ruta del DSN funciona perfectamente.
Lo tengo así, si alguien ve por donde anda el error le estaré muy agradecida.

Query.ConnectionString := 'Provider=MSDASQL.1;Persist Security Info=False;Extended Properties="DSN=Alicia;DBQ=F:\DATOS\Alicia\Access\Habitatge_Alicia.mdb;DriverId=25;FIL=MS Access;MaxBufferSize=2048;PageTimeout=5;UID=admin;"'

Gracias.