#**********************************************************************
# FILENAME : CallSPEditRecord.py
#
# DESCRIPTION :
# Illustrates using a stored procedure to perform several
# actions relating to editing records within a table.
#
# Calls a stored procedure as follows:
#
# {CALL pyEdit_Record (?, ? ?, ?, ?, ?)}
#
# With parameter :
# 1 - action (SELECT,UPDATE,INSERT,DELETE or ALL)
# 2 - current record ID
# Used if action is Select, Update or Delete)
# 3 - 6 parameters for firstname, lastname, address, coty
# Used if action is Insert or Update
#
# ODBC USAGE :
#
# Uses the notion of current Person ID as current record
# (a value of -1 indicates none). Based on current record and
# action, the program loops, executing the stored procedure to
# either Select a specific record, Select all records, Update
# or Delete the current record or Insert a new one.
#
# Connects to Data Source using Data Source Name
# Creates cursor on the connection
# Drops and recreates a procedure 'pyEdit_Record'
# Prompts user for either a record number or an action.
# Actions available depend on whether a 'current' record
# exists. Select One, Update and Delete need a current record ID
# whereas Selecting all records and Insert don't.
#
import pyodbc
# Current record variables
currPID=-1
currFirstName=""
currLastName=""
currAddress=""
currCity=""
# List of actions
SEL=0 # action SELECT ONE
UPD=1 # action UPDATE
INS=2 # action INSERT
DEL=3 # action DELETE
ALL=4 # action SELECT ALL
#
# FUNCTION: getAction(currPID)
# Based on whether a current record is available, get next action to
# execute via stored procedure
# Returns two values, the action selected and a record ID to use as
# the current record id.
#
def getAction (currPID):
# Default action select
action=SEL
# Get PersonId to look up
print "\nNext Action: QUIT(0)\nSELECT (Rec No), SELECT ALL (A), INSERT (I),",
if currPID!=-1:
print "UPDATE (U), DELETE (D)",
next=raw_input(" ? : ")
# Check to see if we have a number or a letter
try:
PID=int(next)
if PID==0:
quit()
action=0
except ValueError:
PID=0
next=next.upper()
if next == "A":
action=4
elif next == "I":
action=2
elif next == "U":
PID=currPID
action=1
elif next == "D":
PID=currPID
action=3
else:
exit()
return (action, PID)
#
# FUNCTION: printRec(rec)
# Function to display the contents of a record retrieved by cursor.fetchone()
# or cursor.fetchall()
#
def printRec (rec):
print "\nPersonID : ", rec[0]
print "First Name : ", # Comma on end stops new line being output
if rec[1]!=None: # None appears for 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 "-"
#
# Stored Procedure statements
#
# Create Stored Procedure 'pyEdit_Record' statement
#
sqlCreateSP="CREATE PROCEDURE pyEdit_Record (\
@action int, @RecID int, \
@pFirstName nvarchar(256), @pLastName nvarchar(256),\
@pAddress nvarchar(256), @pCity nvarchar(256))\
AS \
IF (@action=0) BEGIN \
SELECT PersonID, FirstName, LastName, Address, City \
FROM TestTBL1 WHERE PersonID=@RecID; \
END \
ELSE \
IF (@action=1) BEGIN \
UPDATE TestTBL1 \
SET FirstName=@pFirstName, LastName=@pLastName, \
Address=@pAddress, City=@pCity \
WHERE PersonID=@RecID; \
END \
ELSE \
IF (@action=2) BEGIN \
INSERT INTO TestTBL1 \
(FirstName, LastName, Address, City) \
VALUES (@pFirstName, @pLastName, @pAddress, @pCity);\
SELECT @@IDENTITY; \
END \
ELSE \
IF (@action=3) BEGIN \
DELETE FROM TestTBL1 WHERE PersonID=@RecID; \
END \
ELSE \
IF (@action=4) BEGIN \
SELECT PersonID, FirstName, LastName, Address, City \
FROM TestTBL1 ORDER BY PersonID; \
END"
#
# Drop Stored Procedure statement
#
sqlDropSP="IF EXISTS (SELECT * FROM sys.objects \
WHERE type='P' AND name='pyEdit_Record') \
DROP PROCEDURE pyEdit_Record"
#
# Call Stored Procedure statement
# Parameters are action, recid, firstname, lastname, address, city
#
# 6 Parameters -- 1 - Action
# 2 - Record ID
# 3-6 READ - used in UPD and INS
#
#
sqlExecSP="{call pyEdit_Record (?,?,?,?,?,?)}"
# Connect to data source
conn=pyodbc.connect('DSN=DATASOURCE', autocommit=True) # either autocommit here
# Create cursor associated with connection
cursor=conn.cursor()
print "\nStored Procedure is : pyEdit_Record"
# Drop SP if exists
cursor.execute(sqlDropSP)
# Create SP using Create statement
cursor.execute(sqlCreateSP)
# Loop - prompt for next action. getAction() will call quit() if either
# blank or 0 entered
while currPID != 0:
#
# Returns action selected in next[0], and record ID in next[1]
#
next=getAction (currPID)
action=next[0]
currPID=next[1]
# If Select not chosen, it is either Update, Insert or Delete
# selected
if action!=SEL and action!=ALL:
ok='Y'
if action==UPD:
# Updating current record
print "\nPersonID : ", currPID
print "FirstName : ", currFirstName,
currFirstName=raw_input("\nFirst Name : ")
print "LastName : ", currLastName,
currLastName=raw_input("\nLast Name : ")
print "Address : ", currAddress,
currAddress=raw_input("\nAddress : ")
print "City : ", currCity,
currCity=raw_input("\nCity : ")
elif action==INS:
# Insert new record
currFirstName=raw_input("\nFirst Name : ")
currLastName=raw_input("Last Name : ")
currAddress=raw_input("Address : ")
currCity=raw_input("City : ")
elif action==DEL:
# Delete current record
print "\nDeleting record : ",currPID," confirm Y/N : ",
ok=raw_input()
ok=ok.upper()
if ok!='Y':
ok='N'
# If OK to continue
if ok=='Y':
# Execute Stored Procedure for Update, Insert or Delete
# and trap Error if raised
try:
cursor.execute(sqlExecSP,action,currPID,currFirstName,\
currLastName,currAddress,currCity)
except pyodbc.Error, err:
print 'Execute DML Error %s' % err
# All OK. If Insert set new records as current record
if action==INS:
rec=cursor.fetchone()
currPID=rec[0]
print "\nNew Record is : ", currPID
# If Delete current record is no longer available
elif action==DEL:
currPID=-1
# If we have a current record, reselect and display
if action==INS or action==UPD:
action=SEL
try:
cursor.execute(sqlExecSP,action,currPID,currFirstName,currLastName,currAddress,currCity)
except pyodbc.Error, err:
print 'Execute ReSelect Error %s' % err
recs=cursor.fetchall()
for rec in recs:
printRec(rec)
else:
#
# Either select one or select all
#
# Clear variables
currFirstName=""
currLastName=""
currAddress=""
currCity=""
# Action select one (using current record) or select all
try:
cursor.execute(sqlExecSP,action,currPID,currFirstName,currLastName,currAddress,currCity)
except pyodbc.Error, err:
print 'Execute SELECT error %s' % err
# Display results - one record if select one, many for select all
recs=cursor.fetchall()
for rec in recs:
printRec(rec)
if len(recs)==0:
print ("\nNo matching records found")
currPID=-1
elif action==SEL:
# If selected one record, it becomes the current record
currFirstName=rec[1]
currLastName=rec[2]
currAddress=rec[3]
currCity=rec[4]
if action==ALL:
# If selected all, we have no current record
currPID=-1;
print ("\n\nComplete.")
# Close and delete cursor
cursor.close()
del cursor
# Close connection
conn.close()
Further information