2017-05-13 4 views
0

J'essaie d'interroger une base de données Access pour obtenir des résultats dans un certain laps de temps. Comme j'interroge, je voudrais ajouter automagically une colonne à la production indiquant quelle semaine (à partir d'une gamme de semaines) les données appartiennent. La colonne automagic est générée en passant un paramètre à l'instruction select. Je continue d'aller et venir entre deux erreurs et je n'arrive pas à comprendre pourquoi.pyodbc avec MS Access attend trop de paramètres

ERREUR 1) Trop peu de paramètres.

ERREUR 2) Erreur de syntaxe dans REJOIGNEZ

Mon code python:

erreur 1 Code:

qry = ''' 
    SELECT [PreQuery].[defect], SUM([PreQuery].[qty_rej] + [PreQuery].[qty_rew]) AS [qty_defect], ? AS [wk_no] 
    FROM (
     SELECT [Sort].[Date of Sort] AS [srt_date], [Part].[Part Name] AS [prt_no], [Defect Table].[Defect2] AS [defect], [Defect Table].[Quantity Rejected] AS [qty_rej], [Defect Table].[Quantity Reworked] AS [qty_rew] 
     FROM (([Defect Table] LEFT JOIN [Sort] ON [Defect Table].[Sort Number] = [Sort].[Sort Number]) LEFT JOIN [Part] ON [Sort].[Part Number] = [Part].[Part Number])) AS PreQuery LEFT JOIN [Defects] ON [Defects].[Defect Code] = [PreQuery].[Defect2] 
    WHERE (([Sort].[Date of Sort] BETWEEN ? AND ?) AND ([Part].[Part Name] LIKE ? & '_TZ______')) 
    GROUP BY [defect], [wk_no];''' 

génère l'erreur suivante:

pyodbc.Error: ('07002', '[07002] [Microsoft][ODBC Microsoft Access Driver] Too few parameters. Expected 8. (-3010) (SQLExecDirectW)') 

Suppression des alias de [Trier]. [Date du tri] et [Pièce]. [Nom de la pièce] reproduit la même erreur, à l'exception du pilote expe cts paramètres au lieu de comme avant. Dans les deux cas, il n'y en a que quatre ? s dans l'instruction entière, de sorte que le DB devrait attendre 4 paramètres.

erreur 2 Code:

qry = ''' 
    SELECT ? AS [wk_no], [defect], SUM([qty_rej] + [qty_rew]) AS [qty_defect] 
    FROM (
     SELECT [Sort].[Date of Sort], [Part].[Part Name], [Defect Table].[Defect2] AS [defect], [Defect Table].[Quantity Rejected] AS [qty_rej], [Defect Table].[Quantity Reworked] AS [qty_rew] 
     FROM (([Defect Table] LEFT JOIN [Sort] ON [Defect Table].[Sort Number] = [Sort].[Sort Number]) 
     LEFT JOIN [Part] ON [Sort].[Part Number] = [Part].[Part Number])) 
    LEFT JOIN [Defects] ON [Defects].[Defect Code] = [Defect Table].[Defect2] 
    WHERE (([Sort].[Date of Sort] BETWEEN ? AND ?) AND ([Part].[Part Name] LIKE ? & '_TZ______')) 
    GROUP BY [defect], [wk_no];''' 

Cela soulève:

pyodbc.ProgrammingError: ('42000', '[42000] [Microsoft][ODBC Microsoft Access Driver] Syntax error in JOIN operation. (-3510) (SQLExecDirectW)') 

j'ai vérifié l'instruction select interne par lui-même et il exécute parfaitement bien dans les deux cas. De plus, je ne pouvais pas voir d'erreurs de syntaxe évidentes (et PyCharm ne pouvait pas non plus vérifier avec le dialecte MySQL).

+0

Sur votre deuxième erreur, je pense que la sous-requête doit recevoir un alias. –

+0

En outre, vous ne devriez pas avoir besoin de tous ces crochets. L'accès n'en a besoin que si le nom de la colonne contient un espace.Si l'une des colonnes n'existe pas dans le DB d'accès, l'élément entre crochets sera traité comme un paramètre. Donc, si possible, je supprimerais les espaces des noms de champ/table et supprimerais tous les crochets de la chaîne de requête. –

+0

@SteveLovell - Les identificateurs qui ne sont pas reconnus comme noms de colonne seront traités comme des noms de paramètre, qu'ils soient entre crochets ou non. Supprimer les crochets n'est pas nécessaire. –

Répondre

0

Dans l'ensemble, il y a plusieurs problèmes entre les deux tentatives de requête:

  1. concaténer la '_TZ______' littérale à la dernière valeur du paramètre que l'espace réservé, ?, doit se tenir debout sur ses propres.
  2. Vous devez affecter un alias de table à la table dérivée, PreQuery, comme vous l'avez fait dans la première requête.
  3. Le JOIN doit être sur l'alias de la nouvelle colonne, défaut, pas Defect2.
  4. Déplacer la clause WHERE à l'intérieur de la sous-requête.
  5. Supprimer le wk_no dans GROUP BY car ce n'est pas un champ réel. Les constantes n'ont pas besoin de GROUP BY.

Considérer ci-dessous l'ajustement de la syntaxe en utilisant des alias de table pour réduire la longueur et la lisibilité. Bien sûr, sans données, je ne peux pas tester correctement. Par conséquent, vous devrez peut-être ajuster plus loin:

qry = """ 
    SELECT ? AS [wk_no], [defect], SUM([qty_rej] + [qty_rew]) AS [qty_defect] 
    FROM 
     (
     SELECT s.[Date of Sort], p.[Part Name], d.[Defect2] AS [defect], 
       d.[Quantity Rejected] AS [qty_rej], d.[Quantity Reworked] AS [qty_rew] 
     FROM (([Defect Table] d LEFT JOIN [Sort] s ON d.[Sort Number] = s.[Sort Number]) 
       LEFT JOIN [Part] p ON s.[Part Number] = p.[Part Number]) 
     WHERE ((s.[Date of Sort] BETWEEN ? AND ?) AND (p.[Part Name] LIKE ?)) 
    ) As PreQuery 
    LEFT JOIN [Defects] ON [Defects].[Defect Code] = [PreQuery].[defect]   
    GROUP BY [defect]; 
""" 

cursor.execute(qry, myparams) # WHERE LAST PARAM HAS '_TZ______' CONCATENATED TO ORIG VALUE 
+0

* "l'espace réservé,'? ', Doit être autonome" * - Ce n'est pas vraiment nécessaire. Les paramètres de chaîne peuvent en fait être utilisés dans le cadre d'une expression de chaîne dans le texte de la commande SQL. –

+0

Merci pour votre réponse. Je vais mettre en œuvre vos suggestions et rendre compte des résultats. –

+0

Il vous manque une parenthèse ouvrante dans la section 'FROM ... JOIN'. Compter pour voir. Access SQL est strict sur les parenthèses pour entourer les appariements de table contrairement aux autres dialectes. Les débutants doivent créer une requête dans le programme graphique MSAccess.exe avec le générateur de conception. – Parfait