2011-06-16 2 views
1

Je travaille avec Python3 en utilisant un module appelé ceODBC et en essayant d'appeler une procédure stockée dans SQL Server 2005. Lorsque j'exécute la procédure stockée à partir de Sql Server Management Studio (sans Python impliqué), je reçois les résultats corrects et 278 lignes sont insérés dans la table souhaitée, mais en Python, il s'arrête après 31. Quelqu'un peut-il me dire pourquoi la procédure stockée peut s'arrêter prématurément? Voici mon code Python:Exécution d'une procédure stockée à partir de Python

import ceODBC 
connect=ceODBC.connect("""DSN=mydatabase;SERVER=xxx.xxx.x.xxx; 
DRIVER={SQLServer};UID=user;PWD=password""", autocommit= True) 
cursor = connect.cursor() 
cursor.execute(""" 
        CREATE TABLE mydatabase.dbo.Vision_TempTable 
        (
        CustId bigint, 
        PayProcId int, 
        WebUserId bigint, 
        SubTypeId bigint, 
        PayAmt decimal(18,2), 
        Paydate datetime, 
        PayType varchar(1), 
        DateCreated datetime, 
        PayStatus varchar(1), 
        Account varchar(30), 
        V_Account varchar(30) 
        )""")#Create a temp table which will be used in the SP insert 
connect.commit() 
f=open('F:/clients/UTA/Vision/Data/ExternalPay_Data/lbox.txt') 
CUST_ID=44 
PAYPROCID=4 
SUBTYPE_ID=64 
WEBUSER_ID=2432 
PAYTYPE='C' 
PAYSTATUS='J' 
for line in f: #parse a text file and insert values into temp table I just created 
    lineLength=len(line.strip()) 
    if lineLength>=49: 
     visionAccount=int(line[10:17]) 
     visionAccount=str(visionAccount) 
     recipientID=line[17:29] 
     invoiceAmount=line[31:39] 
     invoiceAmount=float(invoiceAmount) 
     pmtType=line[39:41]#make sure it will always be ck 
     pmtDate=line[45:47]+'/'+line[47:49]+'/'+line[41:45] 
     cursor.execute("""INSERT INTO mydatabase.dbo.Vision_TempTable 
          (CustId,PayProcId,WebUserId,SubTypeId,PayAmt,Paydate, 
          PayType,DateCreated,PayStatus,Account,V_Account) 
          VALUES 
           (?,?,?,?,?,?,?,GETDATE(),?,?,?)""", 
       CUST_ID,PAYPROCID,WEBUSER_ID,SUBTYPE_ID, 
       invoiceAmount,pmtDate,PAYTYPE,PAYSTATUS,recipientID,visionAccount) 

     connect.commit() 
cursor.callproc("mydatabase.dbo.VisionExternalPMTS")# turn over control to SP 

f.close() 
connect.close() 
print('Done') 

et juste si nous avons le tableau complet, je vais inclure la procédure stockée ci-dessous:

USE [mydatabase] 
GO 
/****** Object: StoredProcedure [dbo].[VisionExternalPMTS] Script Date: 06/16/2011 08:38:15 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[VisionExternalPMTS] as 

BEGIN 
declare @custid bigint, 
@payprocid int, 
@webuserid bigint, 
@subtypeid bigint, 
@payamt decimal(18,2), 
@paydate datetime, 
@paytype varchar(1), 
@datecreated datetime, 
@paystatus varchar(1), 
@account varchar(30), 
@v_account varchar(30) 

DECLARE update_webPayments CURSOR for --select from temp table created in python 
SELECT CustId,PayProcId,WebUserId,SubTypeId,PayAmt,Paydate,PayType, 
     DateCreated,PayStatus 
FROM Vision_TempTable 

OPEN update_webPayments 

FETCH NEXT FROM update_webPayments INTO @custid,@payprocid,@webuserid, 
       @subtypeid,@payamt,@paydate,@paytype,@datecreated, 
       @paystatus 

WHILE @@fetch_status = 0 --insert into target table 
    BEGIN 
     INSERT INTO WEBPAYMENTS(CUSTID,PAYPROCID,WEBUSERID,SUBTYPEID, 
           PAYAMT,PAYDATE,PAYTYPE,DATECREATED,PAYSTATUS) 
     VALUES (@custid,@payprocid,@webuserid,@subtypeid,@payamt, 
       @paydate,@paytype,@datecreated,@paystatus) 
     FETCH NEXT FROM update_webPayments INTO @custid,@payprocid,@webuserid, 
        @subtypeid,@payamt,@paydate,@paytype,@datecreated, 
        @paystatus       
    END 
--DROP TABLE VISION_TempTable 
END 

La create table et insert initial de Python travaille toujours, je reçois 278 lignes dans ma table temporaire, c'est seulement quand j'appelle la procédure stockée de python que les choses vont mal. La procédure stockée se termine tôt. Je pensais que c'était parce que Python ne lui donnait pas assez de temps pour s'exécuter avant la fin du programme. J'ai donc essayé de mettre en place une sorte de compteur, mais j'ai fini par obtenir des erreurs de base de données. compteur. Ce que je veux, c'est passer le contrôle à la procédure stockée et ne pas retourner au programme python tant que la procédure stockée n'est pas terminée. Toute aide serait grandement appréciée.

Merci

Répondre

1

En regardant http://ceodbc.sourceforge.net/html/cursor.html il y a ce commentaire:

Cursor.execdirect (déclaration)

exécuter une instruction contre la base de données à l'aide SQLExecDirect au lieu de SQLExecute. Cela est nécessaire dans certaines situations en raison de bogues dans les pilotes ODBC tels que ceux affichés par le pilote ODBC SQL Server lors de l'appel de certaines procédures stockées. Si l'instruction est une requête, le curseur est renvoyé pour plus de commodité car les curseurs implémentent le protocole d'itérateur et il n'est donc pas nécessaire d'appeler l'une des méthodes d'extraction appropriées; sinon Aucun n'est renvoyé.

On dirait qu'il y a un peu de folie avec des procédures stockées via SQL Server ODBC (étant donné qu'ils le choisissent pour un traitement spécial). Vous devrez peut-être essayer:

cursor.execdirect("mydatabase.dbo.VisionExternalPMTS") 

Faites-moi savoir si cela fonctionne.

+1

Merci, j'ai aussi lu cela dans la documentation et l'ai essayé hier mais je ne suis pas sûr d'utiliser les bons paramètres puisqu'ils ne vont pas dans les détails sur la page de documentation. Je continue d'obtenir des erreurs de syntaxe de base de données lorsque j'essaie la méthode execdirect. J'ai regardé autour de la syntaxe des instructions execdirect et j'expérimente pour voir si j'obtiens la bonne combinaison. – cloud311

+0

peu importe ce que je fais, je n'arrive pas à faire marcher ça! Il quitte toujours tôt sur moi. – cloud311

Questions connexes