linked table or Passthrough query (1 Viewer)

focus10

Registered User.
Local time
Today, 17:45
Joined
Mar 8, 2009
Messages
38
can someone help me to solve a dilemma
i need to check by access timer changes in an sql table every second
now my dilemma is to link the sql table constantly and lookup the table every second
or run a Passthrough query every second
witch method will be moe effective>

thanks
 

mdlueck

Sr. Application Developer
Local time
Today, 12:45
Joined
Jun 23, 2011
Messages
2,631
Every second you need to issue SQL to check for changes??? Ouch!!!

First comes to mind executing a Stored Procedure so that the SQL back end would not have to prepare the query each time.

If you need to download records into an FE temp table, then I suggest invoking the SP thusly:

"Replace pass-through DAO.QueryDef with DAO execution of Stored Procedure Q's"
http://www.access-programmers.co.uk/forums/showthread.php?t=223414#post1140657

"Example of DAO.QueryDef objects downloading records from a SQL BE DB via Pass-Through query and populating a FE temp table with them"
http://www.access-programmers.co.uk/forums/showthread.php?p=1119605&posted=1#post1119605

If you do not need the records downloaded into an Access table, then I would suggest using ADO objects to execute the SP and receive results in an ADO.Recordset object:

"Using VBA ADO objects to execute a Stored Procedure"
http://www.access-programmers.co.uk/forums/showthread.php?t=216860#post1104120

Oops, I see that is an INSERT SP, so an example of a SELECT SP here:

Code:
'This API reads a value from the products table for a given id
Public Function LocateProductByID() As Boolean
On Error GoTo Err_LocateProductByID

  Dim adoCMD As ADODB.Command
  Dim adoRS As ADODB.Recordset

  'Define attachment to database table specifics and execute commands via With block
  Set adoCMD = New ADODB.Command
  With adoCMD
    .ActiveConnection = ObjBEDBConnection.getADODBConnectionObj()
    .CommandText = "clsObjProductsTbl_LocateProductByID"
    .CommandType = adCmdStoredProc
    .Parameters.Refresh
    .Parameters("@id").Value = Me.id

    Set adoRS = .Execute()
  End With

  With adoRS
    'Was no record found?
    If .BOF Or .EOF Then
      'Clear the class attributes
      Me.Clear
      LocateProductByID = False
    Else
      'Fetch the values found
      Me.id = Nz(adoRS!id, 0)
      Me.authid = Nz(adoRS!authid, 0)
      'Field resulting from the join to auth to look up the username for field authid
      Me.authusername = Nz(adoRS!authusername, vbNullString)
      Me.logtimestamp = Nz(adoRS!logtimestamp, vbNullString)
      Me.projectid = Nz(adoRS!projectid, 0)
      Me.title = Nz(adoRS!title, vbNullString)
      Me.productnumber = Nz(adoRS!productnumber, vbNullString)
      Me.bomcad = Nz(adoRS!bomcad, vbNullString)
      'Set a good return code
      LocateProductByID = True
    End If

    'Close the database table
    .Close
  End With

Exit_LocateProductByID:
  'Clean up the connection to the database
  Set adoCMD = Nothing
  Set adoRS = Nothing

  Exit Function

Err_LocateProductByID:
  Call errorhandler_MsgBox("Class: clsObjProductsTbl, Function: LocateProductByID()")
  LocateProductByID = False
  Resume Exit_LocateProductByID

End Function
Again, SP's are the most efficient way to run a query on a remote SQL database. If SP's are not available to you, then next best would be a passthrough query.
 

lionna

New member
Local time
Today, 09:45
Joined
Mar 13, 2013
Messages
8
Dear Michael
question: is this code valid only for MS Access? When I run it in Excel, I get an error, that the ODBC Driver doesn't support the properties. The error appears here:
Code:
Set adoRS = .Execute()

Do you happen to know, what is the reason?
Thanks in advance,
Lionna
 

mdlueck

Sr. Application Developer
Local time
Today, 12:45
Joined
Jun 23, 2011
Messages
2,631
Excel should be able to run the LOC you provided. Please paste in more of your code.

Do you have either ADO 2.8 enabled as a VBA reference for your project, or are you using Late Binding syntax to create the object? Still, your code would not blow up on that LOC if it was a reference problem, so probably not that.
 

lionna

New member
Local time
Today, 09:45
Joined
Mar 13, 2013
Messages
8
thanks for such a quick answer. Yes, the library Microsoft ADO Ext. 2.8 for DDL and Security is enabled.
My problem is, that I can't save the return value of one oracle stored procedure. The return value of the function is semi-colon separated string, and not the recordset. Here is the code:
Code:
Public Sub obj_classif()

    Dim cn As New ADODB.Connection
    Dim db_name, Username, Password As String

    Dim adoCMD As ADODB.Command
    Dim adoRS As ADODB.Recordset
    Dim param1, param2 As ADODB.Parameter

    Set wb = Excel.ActiveWorkbook
    Set ih = wb.Sheets("InfoSheet")
    db_name = ih.Cells(1, 2)   'Instanzname
    Username = ih.Cells(2, 2)  'Login
    Password = ih.Cells(3, 2)  'Passwort

    Set cn = New ADODB.Connection
    cn.ConnectionTimeout = 600
    cn.Open db_name, Username, Password

    'Define attachment to database table specifics and execute commands via With block
    Set adoCMD = New ADODB.Command
    With adoCMD
        .ActiveConnection = cn
        .CommandText = "s#mdb$stg_da_extr_util.get_all_classes_of_classif"
        .CommandType = adCmdStoredProc
        .Parameters.Refresh
        Set ParamReturn = .CreateParameter("result_line", adVarChar, adParamReturnValue, 1)
            .Parameters.Append ParamReturn
        Set param1 = .CreateParameter("STG_DATA_REQUEST", adVarChar, adParamInput, 1)
            .Parameters.Append param1
        Set param2 = .CreateParameter(120, adInteger, adParamInput, 1)
            .Parameters.Append param2

        Set adoRS = .Execute() '******here comes the error
    End With

    MsgBox adoCMD.Parameters("result_line")

End Sub
This functions as well, but I can't get the right return value:

Code:
Private Sub obj_classif()

    Set wb = Excel.ActiveWorkbook
    Set ih = wb.Sheets("InfoSheet")

    With New ADODB.Connection
      .ConnectionTimeout = 600
      .Open Sheets("InfoSheet").Cells(1, 2).Value, Sheets("InfoSheet").Cells(2, 2).Value, Sheets("InfoSheet").Cells(3, 2).Value
      sn = .Execute("declare result_line varchar2(2000) := ''; begin result_line := s#mdb$stg_da_extr_util.get_all_classes_of_classif('STG_DATA_REQUEST', 120); dbms_output.put_line(result_line);commit;commit;end;")
      .close
    End With

    MsgBox TypeName(sn)

End Sub
Interestingly, the sn is a String with Value "Fields". No idea, where it comes from. It should look like: "Text;number;text;number" etc...
 

mdlueck

Sr. Application Developer
Local time
Today, 12:45
Joined
Jun 23, 2011
Messages
2,631
thanks for such a quick answer. Yes, the library Microsoft ADO Ext. 2.8 for DDL and Security is enabled.

That binding enables ADOX objects, not ADO objects.

Do you have one: Microsoft ActiveX Data Objects 2.8 Library? That will be the one you need.

My problem is, that I can't save the return value of one oracle stored procedure. The return value of the function is semi-colon separated string, and not the recordset.

I have never heard of an adoCMD object not returning an adoRS object. Even if the answer from Oracle were a semicolon delimited string, that would still be received from the adoCMD object as an adoRS object, and the semicolon delimited string would be an element of the adoRS object.

Also in your code, the call to .Parameters.Refresh will populate the adoCMD object with the Stored Procedure (SP) parameter list. You do not need to create new Parameters objects, merely fill in the values to the Parameters objects it sees the SP asking for.

<><><><>

What in the world...

This functions as well, but I can't get the right return value:
Code:
Private Sub obj_classif()

    Set wb = Excel.ActiveWorkbook
    Set ih = wb.Sheets("InfoSheet")

    With New ADODB.Connection
      .ConnectionTimeout = 600
      .Open Sheets("InfoSheet").Cells(1, 2).Value, Sheets("InfoSheet").Cells(2, 2).Value, Sheets("InfoSheet").Cells(3, 2).Value
      sn = .Execute("declare result_line varchar2(2000) := ''; begin result_line := s#mdb$stg_da_extr_util.get_all_classes_of_classif('STG_DATA_REQUEST', 120); dbms_output.put_line(result_line);commit;commit;end;")
      .close
    End With

    MsgBox TypeName(sn)

End Sub

Looks like you are trying to connect to a spreadsheet as the data source for ADO database objects... :confused:
 

lionna

New member
Local time
Today, 09:45
Joined
Mar 13, 2013
Messages
8
Yes, this library is also available.
omg, sorry, I am not a DB Expert. What I meant is, when I call this function in e.g. SQL Developer, the return appears in Script Output, and not in Results, where you normally expect the results from SELECT query to appear...

I have changed the code to this:
Code:
Public Sub obj_classif()

    Dim cn As New ADODB.Connection
    Dim strSQL As String
    Dim db_name, Username, Password As String

    Dim adoCMD As ADODB.Command
    Dim adoRS As ADODB.Recordset
    Dim param1, param2 As ADODB.Parameter

    Set wb = Excel.ActiveWorkbook
    Set ih = wb.Sheets("InfoSheet")
    db_name = ih.Cells(1, 2)   'Instanzname
    Username = ih.Cells(2, 2)  'Login
    Password = ih.Cells(3, 2)  'Passwort

    Set cn = New ADODB.Connection
    cn.ConnectionTimeout = 600
    cn.Open db_name, Username, Password

    'Define attachment to database table specifics and execute commands via With block
    Set adoCMD = New ADODB.Command
    With adoCMD
        .ActiveConnection = cn
        .CommandText = "s#mdb$stg_da_extr_util.get_all_classes_of_classif"
        .CommandType = adCmdStoredProc
        .Parameters.Refresh
        Set param1 = .CreateParameter("STG_DATA_REQUEST", adVarChar, adParamInput, 1)
            .Parameters.Append param1
        Set param2 = .CreateParameter(120, adInteger, adParamInput, 1)
            .Parameters.Append param2

        Set adoRS = .Execute()
    End With
End Sub
but I still have the same error, saying something like: The ODBC-Driver does not support the claimed properties... still can't solve this issue... :(
 

mdlueck

Sr. Application Developer
Local time
Today, 12:45
Joined
Jun 23, 2011
Messages
2,631
What I meant is, when I call this function in e.g. SQL Developer, the return appears in Script Output, and not in Results, where you normally expect the results from SELECT query to appear...

Yes using ADO objects is far different than running queries interactively in the SQL developer tool.

I have changed the code to this:

Still, you should not need to create the parameters. ADO should already have read them due to the call to .Parameters.Refresh Please refer to this post for an example of executing a SP and setting Parameter values:

Using VBA ADO objects to execute a Stored Procedure (INSERT)
http://www.access-programmers.co.uk/forums/showthread.php?t=216860#post1104120

Additionally you may find useful to run with stepped execution via the debugger and place watches on your ADO objects. Then you may see what is inside them each step of the way... watch data end up in the Parameter values, inspect the resulting adoRS object once you get that far, etc...
 

lionna

New member
Local time
Today, 09:45
Joined
Mar 13, 2013
Messages
8
thanks again for the tipps. Unfortunately, I couldn't manage to make my code work... I do run the code in debug mode, now I get following error:

Code:
Public Sub obj_classif()

    Dim cn As New ADODB.Connection
    Dim strSQL As String
    Dim db_name, Username, Password As String

    Dim adoCMD As ADODB.Command
    Dim adoRS As ADODB.Recordset

    Set wb = Excel.ActiveWorkbook
    Set ih = wb.Sheets("InfoSheet")
    db_name = ih.Cells(1, 2)   'Instanzname
    Username = ih.Cells(2, 2)  'Login
    Password = ih.Cells(3, 2)  'Passwort

    Set cn = New ADODB.Connection
    cn.ConnectionTimeout = 600
    cn.Open db_name, Username, Password

    Set adoCMD = New ADODB.Command
    With adoCMD
        .ActiveConnection = cn
        .CommandText = "s#mdb$stg_da_extr_util.get_all_classes_of_classif"
        .CommandType = adCmdStoredProc
        .Parameters.Refresh

        .Parameters("@i_caller").Value = "STG_DATA_REQUEST" '*****error
        .Parameters("@i_obj_classif_id").Value = 120

        Set adoRS = .Execute()
    End With

The error says something like:
an object with the requested name or corresponding original reference can not be found.

i_caller is the input parameter name. What can be wrong here?
What does @ notation means? Couldn't find it anywhere...
 

mdlueck

Sr. Application Developer
Local time
Today, 12:45
Joined
Jun 23, 2011
Messages
2,631
All right, excellent trouble shooting on your part, lionna! :D

With stepped execution, get past the .Parameters.Refresh LOC, then expand the adoCMD object in your Watches window. (That means you have a watch on that object in the first place.)

Drill under Parameters and look for the @i_caller paramter. You will have to look inside each one to see what its name is. See if it has the correct datatype defined for it... something that ADO must be accurately picking up in chatting with the DB server. Sometimes ADO guesses wrong. See my post here about this trouble:

I have resolved the trouble storing dates to SQL Server via ADO objects and Stored Procedures:
http://www.access-programmers.co.uk/forums/showthread.php?p=1104450#post1104450

See how far you can get now... Thanks!
 

lionna

New member
Local time
Today, 09:45
Joined
Mar 13, 2013
Messages
8
hi Michael
wasn't able to get over my error ;(
I am really stuck und you're the only hope I have... I couldn't attach the screenshot, 'cause I have only 4 posts in this forum.

Anyway, when I explore my adoCMD Object in detail, the parameters of the function are not there... Under Parameters I only see "count" with the value of 0.
 

mdlueck

Sr. Application Developer
Local time
Today, 12:45
Joined
Jun 23, 2011
Messages
2,631
Anyway, when I explore my adoCMD Object in detail, the parameters of the function are not there... Under Parameters I only see "count" with the value of 0.

In that case, that means that ADO saw no parameters to the Stored Procedure (SP).

Perhaps go back and see that you named the SP correctly / the same as it really is on the server.

Yes, I have typo'ed SP names, and the code blows up on the LOC you describe... setting the first Parameter value. What you are describing is consistent with a SP name spelling mistake.
 

lionna

New member
Local time
Today, 09:45
Joined
Mar 13, 2013
Messages
8
No mis-spellings found. Still can't get it work. Here's what I have also tried (I know you mentioned that there's no need to create parameters, didn't work for me though...).

Code:
Public Sub obj_class()

    Dim cnn As ADODB.Connection
    Dim cmd As ADODB.Command
    Dim strConn As String

    Set cmd = New ADODB.Command
    Set cnn = New ADODB.Connection

    strConn = "DSN=***;UID=***;PWD=***"

    'Open the connection to the database
    cnn.Open strConn

    'use a stored procedure to get the data
    With cmd

        .CommandText = "S#mdb$stg_da_extr_util.get_all_classes_of_classif"
        .CommandTimeout = 60
        .CommandType = adCmdStoredProc
        .ActiveConnection = cnn

        Call .Parameters.Append(.CreateParameter("retVal", adInteger, adParamReturnValue))

        Call .Parameters.Append(.CreateParameter("i_caller", adVarChar, adParamInput, 100, "STG_DATA_REQUEST"))
        Call .Parameters.Append(.CreateParameter("i_obj_classif_id", adNumeric, adParamInput, 30, 120))
 
        ' The current commandtext look like:
        '  "{ ? = call S#mdb$stg_da_extr_util.get_all_classes_of_classif(?, ?) }"
        ' The cmd object parameters look like this:
        ' cmd.Parameters.Item1.Value = Empty
        ' cmd.Parameters.Item2.Value = "STG_DATA_REQUEST"
        ' cmd.Parameters.Item3.Value = 120

       ' it crashes here
        .Execute , , adExecuteNoRecords

       ' with the following error:
       ' Run-time error '-2147217887 (80040e21):
       'Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done. 

End Sub
Somehow I start to think something is wrong with my connection. I use the same connection as for retrieving the data from Oracle DB using SELECT statements.

Code:
'ConnectionString : "Provider=MSDASQL.1;Extended Properties="DSN=***;UID=***;PWD=***;DBQ=EE_AVA35;DBA=W;APA=T;EXC=F;FEN=T;QTO=T;FRC=10;FDL=10;LOB=T;RST=T;BTD=F;BNF=F;BAM=IfAllSuccessful;NUM=NLS;"
Might it be I need to create another one?
I use Oracle in XE 11.0 driver.
 

lionna

New member
Local time
Today, 09:45
Joined
Mar 13, 2013
Messages
8
Hallulujah!!! Finally I made it!

My guess about wrong connector was correct! It is not possible to call stored oracle functions using ODBC. Instead, 'Microsoft OLE DB for Oracle' Driver should be used here. Then we need to create new connector, in order to make it work. Here's the code (VBA Excel 2003) to call native PL/SQL function (function in a package) and save its return value to a variable:

Code:
Private Sub obj_class()

    Dim cmd As New ADODB.Command
    Dim cn As ADODB.Connection
    Dim rslt as String
    Dim db_name, UserName, PassWord As String
    Dim i_caller As ADODB.Parameter
    Dim i_obj_class_id As ADODB.Parameter
    Dim ParamReturn As ADODB.Parameter

    Set cn = New ADODB.Connection

    With cn
        .ConnectionString = "Provider=MSDAORA.1;Data Source=EE_AVA35;User Id=***;Password=***"
        .CursorLocation = adUseClient
        .Open
    End With
    
    Set cmd = New ADODB.Command
    
    With cmd
        Set .ActiveConnection = cn
        .CommandText = "S#mdb$stg_da_extr_util.get_all_classes_of_classif"
        .CommandType = adCmdStoredProc
        
        Set ParamReturn = .CreateParameter("RESULT", adVarChar, adParamReturnValue, 10000) '10000 stands here for the character number in a string
            .Parameters.Append ParamReturn
        Set i_caller = .CreateParameter("Caller Identification", adVarChar, adParamInput, 50, "STG_DATA_REQUEST")
            .Parameters.Append i_caller
        Set i_obj_class_id = .CreateParameter("Class ID", adInteger, adParamInput, 1000, 42)
            .Parameters.Append i_obj_class_id
        
        .Execute , , adExecuteNoRecords 
        cn.Close
        rslt = .Parameters("RESULT")
    End With

End Sub
Au revoir and thanks again for looking at my problem!
 

mdlueck

Sr. Application Developer
Local time
Today, 12:45
Joined
Jun 23, 2011
Messages
2,631
Hallulujah!!! Finally I made it!

My guess about wrong connector was correct!

Congratulations lionna! Indeed, a connection problem is what I was suspecting when the call to .Parameters.Refresh was failing.

Perhaps stop back a quick second and see if that call works now, and that you do not need to create Parameters objects on your own, but now that the connection works ADO can successfully detect the Parameters from the SP definition on the server.
 

lionna

New member
Local time
Today, 09:45
Joined
Mar 13, 2013
Messages
8
Surprisingly, this doesn't work:
Code:
'...
    With cmd
        Set .ActiveConnection = cn
        .CommandText = "S#mdb$stg_da_extr_util.get_all_classes_of_classif"
        .CommandType = adCmdStoredProc
        
        .Parameters.Refresh 'ORA-06550 Wrong number or types of arguments in call to GET_ALL_CLASSES_OF_CLASSIF
        .Parameters("@i_caller").Value = "STG_DATA_REQUEST" 
        .Parameters("@i_obj_classif_id").Value = 120
End with
'...
when I change this .CommandText line to

Code:
  .CommandText = "S#mdb$stg_da_extr_util.get_all_classes_of_classif(?,?)"
Then .Parameters.Refresh says: Either BOF or EOF is true, or the actual data set was deleted.. Seems to me, that the output parameter is missing, what do you think?

Strange, huh? Note, that with ODBC the Refresh method has functioned well, and I had an error in the next line, when trying to pass the value of parameters...
 

mdlueck

Sr. Application Developer
Local time
Today, 12:45
Joined
Jun 23, 2011
Messages
2,631
when I change this .CommandText line to

Code:
  .CommandText = "S#mdb$stg_da_extr_util.get_all_classes_of_classif[COLOR=Blue][B](?,?)[/B][/COLOR]"
Then .Parameters.Refresh says: Either BOF or EOF is true, or the actual data set was deleted..

That syntax is definitely incorrect for ADO objects.

Strange, huh? Note, that with ODBC the Refresh method has functioned well, and I had an error in the next line, when trying to pass the value of parameters... Seems to me, that the output parameter is missing, what do you think?

You could do the stepped debug mode, get just passed the .Parameters.Refersh LOC, and see what Parametes then exist under the adoCMD object. The one thing different this time is you know the connection syntax is valid, so must actually be connected to the server, and the call to .Parameters.Refresh hopefully would have succeeded. You should see both input and output parameters under the Parameters branch in the watches window, watching the adoCMD object.

If not, perhaps the driver does not support .Parameters.Refersh at all, and you must manually create the .Parameters as your working code was doing.
 

Users who are viewing this thread

Top Bottom