2010-08-04 26 views
1

Je me connecte à un Jet 4 DB via ODBC. La base de données Jet utilise des requêtes directes vers une base de données Oracle. Cela fonctionne jusqu'à présent (impossible d'accéder directement aux requêtes p-t, mais créer une vue sur la requête fait l'affaire).Base de données Jet et requêtes directes, paramètres

J'ai besoin d'un sous-ensemble des données renvoyées par les p-ts. Les paramètres seraient les meilleurs, mais ne sont pas supportés.

Deux questions:

1) Jet ne semble pas être en mesure de pousser certaines clauses where à Oracle. Par exemple, j'ai une requête passthrough qui renvoie 100k lignes. Une vue sur le p-t avec une seule clause flitering (par exemple "district = '1010'") est très rapide, de sorte que le traitement semble se produire sur Oracle. L'ajout de plusieurs clauses peut ralentir la requête jusqu'à une analyse, en faisant une boucle pendant quelques minutes avec une utilisation élevée du processeur. Y a-t-il de la documentation sur ce qui est transmis et ce qui est fait dans le côté Jet?

2) Il y a beaucoup de tutoriels sur la façon de créer des requêtes passthrough dynamiques avec VBA/Access. Est-il possible de faire cela (ou quoi que ce soit à cet effet) avec Jet accessible via ODBC?

Merci Martin

Edit: Désolé d'être si peu claire.

J'ai un outil de reporting qui accède à un Jet db via ODBC. Le Jet db contient des données et plusieurs requêtes passthrough à une base de données Oracle. Un cas d'utilisation typique serait un rapport de génération pour un département donné et une date donnée, en utilisant les données de Jet et d'Oracle. Cela fonctionne très bien en principe.

Le problème est que les requêtes passthrough ne peuvent contenir aucun paramètre. Une requête passthrough fonctionne comme une vue, donc je peux simplement exécuter "select * from pt_query où dep = 'a' et date = somedate". Jet, cependant, charge toutes les lignes du pt et effectue un scan complet du côté client. Ceci est inutilement lent pour une vue de 100k-rangs et je dois trouver un moyen d'éviter cela.

Pour quelques simples sélectionne, Jet ne semble laisser Oracle faire le travail dur et ne se charge pas toutes les lignes, d'où ma question 1.

Si cela ne fonctionne pas, je dois trouver un moyen pour forcer Jet à charger uniquement les données dont j'ai besoin d'Oracle pour une requête donnée. Je sais que je peux modifier pts via Access VBA, mais je ne me connecte que par ODBC, donc je ne peux que passer SQL to Jet, pas appeler le vb api (sauf s'il est possible d'aligner VB dans l'instruction SQL).

+0

Pourquoi est-Jet nécessaire si vous interrogez Oracle? Pourquoi ne pas utiliser ODBC & ADO http://www.connectionstrings.com/oracle? – Fionnuala

+0

Comme toujours, la stratégie métier ... Je ne peux pas créer de tables ou télécharger des données d'arbitrage sur l'entrepôt de données Oracle. Je rejoins certaines données personnalisées actuellement stockées dans Access/Jet avec des données de la base de données Oracle. – Martin

+0

Ce que Jet transmet à une base de données de serveur dépend de la base de données du serveur concerné et de l'écriture du pilote ODBC. Jet demandera autant de métadonnées que possible pour optimiser la requête et en envoyer autant que possible au serveur pour traitement. Je regarderais votre trace SQL pour voir ce qui cause le ralentissement avec plus de critères. Je noterai que lorsque je regarde les traces dans SQL Server, de simples requêtes de Jet avec des critères sont exécutées avec un sproc paramétré générique. Je m'attendrais à quelque chose de similaire dans Oracle. –

Répondre

1

Il n'est pas impossible que la requête soit construite pour provoquer une analyse de table, ce qui cause le problème.

Vous semblez travailler dans VBA. Il est possible de construire plusieurs requêtes intéressantes en tant que chaînes SQL dans VBA et de les enregistrer dans de nouvelles requêtes, de mettre à jour des requêtes existantes, de les utiliser pour des sources d'enregistrements pour des formulaires ou des jeux d'enregistrements ouverts. Vous pouvez utiliser DAO ou ADO, selon ce que vous voulez faire. J'ai Oracle, donc tout ce que je peux faire est de suggérer des idées en utilisant SQL Server, la connexion entre crochets peut être obtenue en regardant la connexion d'une table liée (CurrentDb.TableDefs ("NameOfTable").Se connecter):

Dim cn As New ADODB.Connection 

''You can use Microsoft.ACE.OLEDB.12.0 or Microsoft.Jet.OLEDB.4.0 
scn = "Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=" _ 
    & CurrentProject.FullName 
cn.Open scn 

''An insert query, but you can see that is would be easy enough to 
''select from two different databases 
s = "INSERT into [ODBC;Description=TEST;DRIVER=SQL Server;" _ 
& "SERVER=ServerName\SQLEXPRESS;Trusted_Connection=Yes;" _ 
& "DATABASE=test].Table2 (id, atext) select id, atext from table1" 

cn.Execute s 

Ou

''http://www.carlprothman.net/Default.aspx?tabid=87 
strConnect = _ 
    "Provider=sqloledb;" & _ 
    "Data Source=myServerName;" & _ 
    "Initial Catalog=Test;" & _ 
    "Integrated Security=SSPI" 
With cmd 
    .ActiveConnection = strConnect 
    .CommandType = adCmdText 
    .CommandText = "SELECT ID, aText FROM table2 " _ 
       & "WHERE ID=?" 
    .Parameters.Append .CreateParameter _ 
     ("ID", adInteger, adParamInput, , 1) 
    .CommandTimeout = 0 
    Set rs = .Execute 
End With 
+0

Je ne suis pas sûr de comprendre ce que vous faites ici. Cela signifie-t-il que vous pouvez ouvrir des connexions arbitraires vers d'autres bases de données dans les requêtes Jet SQL en incluant la chaîne Connection? Si c'est le cas, puis-je également intégrer des requêtes de passe? – Martin

+0

Oui, vous pouvez. La réponse est quelque peu errante car je ne suis pas sûr de ce que vous voulez faire, par exemple, je ne suis pas du tout sûr de ce que vous voulez arriver avec la requête de transmission, ou pourquoi vous en avez besoin. – Fionnuala

+0

Si vous transmettez une chaîne de connexion en ligne dans un passthrough, elle sera traitée par le serveur distant. Cela peut ou peut ne pas fonctionner. –

0

Pouvez-vous dupliquer la requête PT dans votre propre db au lieu de lier à elle dans un autre db?

Tous les caractères SQL de la requête PT doivent être exécutés sur le serveur lié sans que Jet tente de les analyser ou de les exécuter. C'est dans une langue étrangère du point de vue de Jet.

Je vais utiliser le code comme celui-ci dans le PT:

SELECT * FROM DHSVIEWS.ClaimHeaderV WHERE 
DHSViews.claimheaderV.ClaimType = 'p' AND 
DHSViews.claimheaderV.FinalVersionInd = 'y' AND 
DHSViews.claimheaderV.ReimbursementAmount > 0 AND 
DHSViews.claimheaderV.majorProgram = 'HH' AND 
DHSViews.claimheaderV.ServiceDateFrom >= [qStart] AND 
DHSViews.claimheaderV.ServiceDateFrom <= [qEnd]; 

et ceci dans VBA:

Set qdef = db.QueryDefs(qryPT) 
sqlOld = qdef.sql 
iPosStart = InStr(sqlOld, "[") 
sqlNew = sqlOld 
Do While iPosStart > 0 
    iPosEnd = InStr(iPosStart, sqlNew, "]") 
    param = Mid(sqlNew, iPosStart + 1, iPosEnd - iPosStart - 1) 
    Select Case param 
     Case "qStart" 
      paramVal = "'" & rsQuarter("quarterStart") & "'" 
     Case "qEnd" 
      paramVal = "'" & rsQuarter("quarterEnd") & "'" 
    End Select 
    sqlNew = Mid(sqlNew, 1, iPosStart - 1) & paramVal & Mid(sqlNew, iPosEnd + 1) 
    iPosStart = InStr(iPosEnd, sqlNew, "[") 
Loop 
If sqlNew <> sqlOld Then 
    qdef.sql = sqlNew 
End If 
db.QueryDefs(rsPTAppend("append")).Execute 
If sqlNew <> sqlOld Then 
    qdef.sql = sqlOld 
End If