#**********************************************************************
# FILENAME : CallSPFindID.py
#
# DESCRIPTION :
# This example simulates using parameter arrays with a stored
# procedure by emulating the parameter arrays using tuples in
# Python.
#
# We take a random list of identity values and select records
# based on them, returning any matching record and an index value
# to indicate which tuple generated the result.
#
# Stored procedures can only be called though the cursor
# execute() or executemany() methods at this time since
# CallProc(), the intended method, has yet to be implemented.
#
# Input parameters are catered for but output parameters and procedure
# return values are not. Although limited, these can be be emulated
# via result set generating SELECTs, the output from which can be
# accessed though nextset(), fetchone() and fetchall() in the program.
# This is demonstrated by this example.
#
# ODBC USAGE :
#
# Emulates parameter array by creating a tuple array containing
# pairs of parameters representing a random PersonID (identity)
# value and an index value to indicate which tuple was used to
# generate the result.
#
# Connects to Data Source using Data Source Name
# Creates cursor on the connection
# Drops and recreates a procedure 'pyFind_ByID' which takes
# two parameters, one for each tuple entry.
# For each tuple,
# executes the procedure using cursor.execute()
# retrieves the results using cursor.fetchall() for the
# record details and cursor.nextset() and 'for rec in cursor'
# to retrieve the tuple index which was passed as param 2
# Closes and deletes cursor and closed connection
import pyodbc
# Emulating parameter arrays using tuples in python. The pairs of numbers
# are random PersonIDs and array indexs which map to @P1 and @P2 in the
# stored procedure.
params = [ (26, 0),\
(34, 1),\
(15, 2),\
(17, 3),\
(44, 4),\
(21, 5),\
(56, 6),\
(33, 7),\
(78, 8),\
(45, 9),\
(37, 10),\
(32, 11),\
(74, 12),\
(69, 13),\
(56, 14),\
(13, 15),\
(15, 16),\
(92, 17),\
(67, 18),\
(72, 19),\
(57, 20),\
(44, 21),\
(38, 22),\
(73, 23),\
(26, 24),\
(42, 25),\
]
# Stored Procedure Create Statement
sqlCreateSP="CREATE PROCEDURE pyFind_ByID \
(@pPersonID int, @pPersonIX int) AS \
DECLARE @RecCount INT;\
SELECT PersonID, FirstName, \
LastName, Address, City FROM TestTBL1 WHERE PersonID=@pPersonID \
ORDER BY PersonID; \
SELECT @pPersonIX;"
# Stored Procedure Drop Statement
sqlDropSP="IF EXISTS (SELECT * FROM sys.objects \
WHERE type='P' AND name='pyFind_ByID') \
DROP PROCEDURE pyFind_ByID"
# Stored Procedure Call Statement
sqlExecSP = "{CALL pyFind_ByID(?, ?)}";
# Connect to datasource
conn=pyodbc.connect('DSN=DATASOURCE', autocommit=True)
# Create cursor associated with connection
cursor=conn.cursor()
print "\nStored Procedure is : pyFind_ByID"
# Drop SP if exists
cursor.execute(sqlDropSP)
# Create SP using Create statement
cursor.execute(sqlCreateSP)
# Call SP with pairs of param values. We could use cursor.executemany() here
# to take the whole tuple list, but this would only give us the results from
# the last param tuple. i.e. the record with PersonID = 42 and index 25.
# We want the results for each tuple and since drivers often emulate parameter
# arrays by executing an SQL statement once for each set of parameter values,
# this is effectively what is done here.
for id in params:
try:
cursor.execute(sqlExecSP, id)
except pyodbc.Error, err:
print 'Error !!!!! %s' % err
recs = cursor.fetchall() # rows generated by parameter 1
for rec in recs:
print "\nPersonID : ", rec[0]
print "First Name : ", # Comma on end stops new line being output
if rec[1]!=None: # None indicates empty column
print rec[1][0:10] # print string from 0 upto 10
else:
print "-" # print - for empty column
print "Last Name : ",
if rec[2]!=None:
print rec[2][0:10]
else:
print "-"
print "Address : ",
if rec[3]!=None:
print rec[3][0:10]
else:
print "-"
print "City : ",
if rec[4]!=None:
print rec[4][0:10]
else:
print "-"
if cursor.nextset()==True: # value passed IN as as parameter 2
for rec in cursor:
print "\nSelection was on (@p1) : ", params[rec[0]][0]
print "Tuple index was (@p2) : ", rec[0]
print ("\nComplete.")
# Close and delete cursor
cursor.close()
del cursor
# Close Connection
conn.close()
Further information