0%

Daten sicher ändern · Übung

Nur diesen Gegenstand aktualisieren

Die Vorschau bestätigt, dass EL-300 der Projektor ist und seine aktuelle Leihdauer 2.5 beträgt. Der nächste Aufruf soll diesen einen Wert auf 8 ändern und jeden anderen Gegenstand unverändert lassen:

change_loan_days(connection, "EL-300", 8)

Die Argumente nach der offenen Verbindung sind das identifizierende Inventarkennzeichen und die neue Leihdauer. Öffne catalog_changes.py und finde die neue Funktion:

def change_loan_days(connection, asset_tag, loan_days):
    statement = """
        UPDATE items
        SET loan_days = ?
        WHERE asset_tag = ?
    """
    connection.execute(statement, (asset_tag, loan_days))

UPDATE items benennt die zu ändernde Tabelle. SET loan_days = ? gibt dem ersten Platzhalter den neuen Wert. WHERE asset_tag = ? lässt den zweiten Platzhalter die beabsichtigte Zeile identifizieren. Die ändernde Anweisung hat ihren eigenen präzisen Wirkungsbereich, obwohl der aufrufende Code die Zeile zuerst in einer Vorschau angesehen hat.

Das anfängliche Tupel hat die beiden Python-Werte vertauscht. Vergleiche vor dem Bearbeiten die Positionen:

SQL-PositionPython-Argumentwert
erstes ?, neue loan_daysloan_days
zweites ?, Ziel-asset_tagasset_tag

Beachte, dass die frühere Vorschau und diese Aktualisierung zwei separate Anweisungen sind. Den Projektor in der Vorschau zu sehen hat dir geholfen zu entscheiden, was zu tun ist, begrenzt aber eine spätere Aktualisierung nicht. Das UPDATE muss sein eigenes WHERE asset_tag = ? enthalten. Wenn der Aufruf "EL-300" verwendet, erhält die Datenbank die Anweisung unverändert und (8, "EL-300") als Werte: 8 beantwortet „Was soll geändert werden?“ und "EL-300" beantwortet „Welche Zeile?“

Bei einem fehlenden Kennzeichen wird diese Unterscheidung besonders deutlich. (8, "NO-404") ist weiterhin ein gültiges Paar gebundener Werte, aber die WHERE-Bedingung findet nichts. Daher ändert sich keine Zeile. Der benachbarte Lautsprecher wird nicht zu einem Ersatzziel. Eine präzise Bedingung bedeutet „diese Zeile, falls sie existiert“, nicht „irgendeine ähnliche Zeile“.

Ändere das letzte Tupel zu (loan_days, asset_tag) und klicke dann auf Run.

before EL-300
(5, 'EL-300', 'Projector', 'electronics', 2.5)
change_loan_days(connection, "EL-300", 8)
None
after EL-300
(5, 'EL-300', 'Projector', 'electronics', 8)

Die Funktion gibt vorerst weiterhin None zurück. Lies die Zeilen vor und nach der Änderung als Nachweis: Nur der letzte Wert hat sich geändert. Run probiert auch NO-404, das zu keiner Zeile passt, und zeigt danach EL-400 als unveränderte Nachbarzeile.

Die vorhandene Regel der Tabelle für positive Leihdauern gilt weiterhin. Diese Funktion ersetzt die Regel nicht und fängt ihren Fehler nicht ab. Sie bindet den vorgeschlagenen Wert sicher; die Datenbank entscheidet weiterhin, ob der Wert das Schema erfüllt.

Submit verwendet unbekannte Kennzeichen, ein fehlendes Kennzeichen, Apostrophe, SQL-ähnlichen Text und unterschiedliche positive Leihdauern mit und ohne Nachkommastellen. Halte beide veränderlichen Werte außerhalb der Anweisung, in Platzhalterreihenfolge. Filtere nicht nach einem nicht eindeutigen Namen oder einer Kategorie und öffne keine andere Verbindung.

Eine sichere Änderung braucht beide Hälften, die du jetzt sehen kannst: den neuen Wert in SET und den eindeutig identifizierenden Wert im WHERE derselben Anweisung.

Aufgabe

Korrigiere in change_loan_days das Parametertupel zu (loan_days, asset_tag). Behalte das gebundene WHERE asset_tag = ? innerhalb des UPDATE bei.

Führe das Projekt aus, vergleiche die Zeile vor und nach der Änderung sowie die unveränderte Nachbarzeile und reiche es dann ein.