VB + OLAP: EXCEPTION_ACCESS_VIOLATION al correr EXE, bien al depurar

26/05/2005 - 03:34 por battletroll | Informe spam
Buenas noches a todos. Perdonen el cross-posting, no sabia bien a bien
en dónde tendria mas probabilidades de que alguien me pudiera ayudar.
Les expongo mi caso, esperando alguien pueda ayudarme:

Tengo un programa en visual basic 6 que se conecta a una base de datos
en sql server, la cual contiene un hipercubo OLAP mismo que se pretende
llamar el programa para cargar los datos de un formulario.

La forma en que se piden los datos es:
- se tiene vinculado el servidor OLAP al servidor SQL Server (residen
en la misma máquina)
- se tiene un procedimiento almacenado en SQL Server que recibe como
parámetro una cadena que es en sí la consulta MDX que se quiere
realizar al hipercubo
- este proc. almacenado ejecuta la consulta MDX mediante SQL dinamico y
regresa un recordset bidimensional con los datos (en si son ventas por
cliente por mes de un año para atrás a la fecha)

Cuando se ejecuta desde el analizador de consultas este SP con la misma
cadena que se manda como parametro se obtienen los resultados
esperados.

Se espera que los resultados que regresa este procedimiento almacenado
sean interceptados en visual basic, para lo cual se abre una conexion
ADO (estandar) hacia el servidor SQL Server, se abre un recordset
(tambien ADODB estandar, no acabo de entender como manejar conexiones y
recordsets ADOMD multidimensionales). Para el recordset se pone como
proveedor "MSOLAP", se dan los datos del servidor SQL Server y del
hipercubo que se quiere manejar, asi como el UserID y password para
acceder al SQL Server.

Cuando el programa se ejecuta DENTRO del entorno de programación se
obtienen los datos correctamente; empero, cuando el mismo programa es
compilado y el .EXE se ejecuta se obtiene el siguiente error en una
ventana de dialogo:

<<

[ODBC SQL server driver][SQL server][SqlDumpExceptionHandler]

Process 55 generated fatal exception
c0000005 EXCEPTION_ACCESS_VIOLATION
SQL Server is terminating this process









Tras lo cual el recordset queda vacio.

No se por que el error solo se presenta con la version compilada y no
en el entorno de programacion. El servidor es un Win2000(SP4) corriendo
SQL Server (SP4) pero dicho servidor NO es un controlador de dominio -
el controlador de dominio es un servidor WinNT 4 (de hecho, el win2000
esta en su propio dominio).

La conexion ADO hacia el servidor SQL Server, por tanto, se hace
utilizando autentificacion de sql server + la propia de mi aplicacion,
en vez de usar la autentificacion de windows (que seria factible
utilizar si estuvieran en el mismo dominio). No se si tenga que ver o
no, pero creo que es un dato que pudiera ayudar.

Cualesquier ayuda que alguien pudiera ofrecerme le estare muy
agradecido
Atte.
Jose Pineda
 

Leer las respuestas

#1 battletroll
26/05/2005 - 17:26 | Informe spam
Añado mas datos, a ver si alguien pudiera ayudarme:

La consulta MDX que se envia al SP es mas o menos asi:

select NON EMPTY { MiCliente.Cliente.Members } on rows,
{ MiTiempo_AnhoTriMesDia.[2004].[Trimestre 2].June :
MiTiempo_AnhoTriMesDia.[2005].[Trimestre 2].May } on columns
From IcMonitor_Cubo Where ( Measures.MiImporte, MiVendedor.[25].AHP )



Si desde el Query Analyzer mando llamar a mi SP asi:
USE "icmonitor"
EXEC ics2_EjecutaConsultaMDX 'select NON EMPTY ...'

Obtengo los resultados deseados, tanto si me conecto al servidor usando
autentificacion de windows como con el nombre de usuario y password que
uso en mi programa.
Cuando voy depurando y corriendo mi programa paso a paso, tambien
funciona, el problema surge exclusivamente al compilar...

Este es el Stored Procedure con el que ejecuto las consultas MDX:

<codigo>
CREATE PROC ics2_EjecutaConsultaMDX( @ConsultaMDX VARCHAR(8000) ) AS

DECLARE @MiConsulta VARCHAR(8000)

SET @MiConsulta = 'SELECT * FROM OpenQuery( OLAP_SERVER, ' + CHAR(39) +
@ConsultaMDX + CHAR(39) + ' )'

EXEC (@MiConsulta)
GO
</codigo>


Y este es el codigo con el que hago la conexion en visual basic:

<codigo>
Const ConsultaMDX_1$ = "select NON EMPTY { MiCliente.Cliente.Members }
on rows, {"
'Const EjemploIntervalo$ = "MiTiempo_AnhoTriMesDia.[2004].[Trimestre
2].June :" & " MiTiempo_AnhoTriMesDia.[2005].[Trimestre 2].May"
Const ConsultaMDX_2$ = "} on columns From IcMonitor_Cubo Where (
Measures.MiImporte, "
'Const EjemploDimensionVendedor$ = "MiVendedor.[25].AHP"
Const ConsultaMDX_3$ = " )"

Const CorcheteAbierto$ = "["
Const CorcheteCerrado$ = "]"

Private IntervaloFechasMDX$
Private CadenaDimensionVendedor$

Public Sub OpenDataSource(ByRef RsDatos As ADODB.Recordset)
Dim ConsultaMDX$, ConsultaSQL$
Dim RsTemp As ADODB.Recordset
Dim N&, N2&, NumCamposEntrada&, NumCamposSalida&
Const CamposInicialesPorIgnorar& = 3
Const CampoIndiceCliente& = 2

On Error GoTo OpenDataSource_Error

CrearIntervaloFechasMDX
CrearCadenaDimensionVendedor
ConsultaMDX = ConsultaMDX_1 & IntervaloFechasMDX & ConsultaMDX_2 &
_
CadenaDimensionVendedor & ConsultaMDX_3
ConsultaSQL = SP_EjecutaConsultaMDX & CadenaApostrofe & ConsultaMDX
& CadenaApostrofe

Debug.Print ConsultaMDX
Debug.Print ConsultaSQL
Set RsTemp = New ADODB.Recordset
With RsTemp
.CursorLocation = adUseClient
.ActiveConnection = ConexionADO
.Open ConsultaSQL, , adOpenStatic, adLockReadOnly
Set .ActiveConnection = Nothing

NumCamposEntrada = .Fields.Count
NumCamposSalida = RsDatos.Fields.Count
Debug.Print .RecordCount

While Not .EOF
RsDatos.MoveFirst
RsDatos.Find "Cliente='" & .Fields(CampoIndiceCliente) &
CadenaApostrofe
If Not (RsDatos.EOF Or RsDatos.BOF) Then

N2 = NumCamposSalida - 1
For N = NumCamposEntrada - 1 To
CamposInicialesPorIgnorar + 1 Step -1
RsDatos.Fields(N2) = Nz(.Fields(N), 0)
N2 = N2 - 1
Next

End If
.MoveNext
Wend

.Close
End With
Set RsTemp = Nothing

On Error GoTo 0
Exit Sub

OpenDataSource_Error:
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in
procedure OpenDataSource of Módulo de clase
DatagridVentasMensualesClientes"
Resume Next
End Sub
</codigo>

"ConexionADO" es una variable global de tipo ADODB.Connection que
contiene una conexion hacia el servidor SQL Server que se abre desde
que arranca el programa y no expira.

"CadenaDimensionVendedor " e "IntervaloFechasMDX" son variables
globales cuyos valores son puestos por los subprocedimientos
"CrearCadenaDimensionVendedor" y "CrearIntervaloFechasMDX",
respectivamente. Para fines de ejemplo, los valores que toman dichas
variables son como los de las constantes "EjemploIntervalo" y
"EjemploDimensionVendedor".

¿alguna idea?

Preguntas similares