Search code examples
pythonsqlpyodbc

How can I perform an UPDATE if EXISTS based on existing data in SQL Server


I am pulling data from an application (via Python) and writing that data into a SQL Server database. My initial data loads, however I will need to UPDATE that data based on subsequent API retrievals from my Python script. While I am successfully able to update all existing rows in the my database I only want to update the values that are different. To visualize:

dev_name    userID
========    ======
abc          def
ghi          jkl
mno          NULL

When Python pulls new data and sees a different uid value for row 'mno' for example, the UPDATE statement should only update that row. Non NULL columns could be updated as well. I thought the following should have worked, however it doesn't.

rslt = cursor.execute(IF EXISTS(SELECT device_name from Devices where device_name = ?) UPDATE Devices SET userID = (?) where device_name = ? and userID <> ?", dev, uid, dev, uid) 

To clarify, the parameters of dev and uid refer to the Python variables that contain the data from the API call.

Any clarification or explanation is greatly appreciated.


Solution

  • In SQL, the WHERE predicate is how you determine existence of a record.

    Presumably you want to set the userID to the current owner of the device. Supposing the new userID is 'pqr', then:

    UPDATE Devices 
    SET userID = 'pqr'
    where device_name = 'mno'
    and userID <> 'pqr';
    

    So for this specific example:

    query = """UPDATE Devices 
               SET userID = ?
               where device_name = ?
               and userID <> ? """
    args = ('pqr', 'mno', 'pqr')
    cursor.execute(query, args)
    

    Or in your case:

    query = """UPDATE Devices 
               SET userID = ?
               where device_name = ?
               and userID <> ? """
    args = (uid, dev, uid)
    cursor.execute(query, args)
    

    Reference

    EDIT to handle NULL values:

    query = """UPDATE Devices 
               SET userID = ? 
               WHERE device_name = ? 
               AND COALESCE(userID,'NULL') <> COALESCE(?,'NULL'))) """ 
    args = (uid,dev,uid)