[PYTHON] [Einführung in cx_Oracle] (Teil 7) Umgang mit Bindevariablen

Überprüfungsumgebung

Einführung

In der letzten Serie wurden nur feste SQL-Anweisungen behandelt, aber in der Realität gibt es viele Situationen, in denen Sie Bindungsvariablen (Platzhalter) verwenden möchten. Dieses Mal werde ich erklären, wie eine Abfrage mithilfe von Bindungsvariablen ausgegeben wird.

Vorbereitungen

Dieses Mal verwenden wir eine Beispiel-SH-Schematabelle. Wenn Sie keine autonome Datenbank verwenden, wählen Sie bitte [Manuell](https://docs.oracle.com/cd/F19136_01/comsc/installing-sample-schemas.html#GUID-A2C3DC59-CDA1-47C0- Sie müssen eine Beispieltabelle des SH-Schemas gemäß BA6B-F6EA6395A85F erstellen. Es ist auch erforderlich, die Beispiel-SQL-Anweisungen und -Berechtigungen entsprechend der Umgebung anzupassen. Sie können das Beispiel ändern, um eine andere Tabelle zu verwenden.

Was ist eine Bindevariable?

Wenn Sie wissen, wie wichtig es ist, Bindungsvariablen in anderen Entwicklungsumgebungen zu verwenden, überspringen Sie dies bitte, da dies eine langweilige Erklärung ist.

Abhängig von der Logik der Anwendung kann die SQL-Anweisung mit genau demselben Inhalt bis auf den Bedingungswert viele Male ausgeführt werden, während die Anwendung ausgeführt wird. Oracle Database speichert Informationen zu einmal ausgegebenen SQL-Anweisungen zwischen. Wenn dieselbe SQL-Anweisung ausgegeben wird, wird SQL nicht von Grund auf neu überprüft, sondern die zwischengespeicherten Informationen werden verwendet, um die Leistung zu steigern. Das Ziel des Cache-Treffers ist jedoch dasselbe SQL im gesamten Satz. Daher unterscheiden sich beispielsweise "SELECT ... WHEWE COL1 = 1" und "SELECT ... WHEWE COL1 = 2" nur im letzten Bedingungswert, jedoch in unterschiedlichem SQL. Wird behandelt als. Es handelt sich in der Regel um SQL, für das der Primärschlüssel als Bedingung erforderlich ist. Wenn jedoch viel SQL ausgegeben wird, besteht ein Leistungsproblem, dass die SQL-Analyse (Syntaxprüfung, Berechtigungsprüfung usw.) jedes Mal durchgeführt werden muss. Sie müssen viel SQL zwischenspeichern, was den Speicher unter Druck setzt. Um eine solche Situation zu vermeiden, aktiviert Oracle Database eine solche SQL-Freigabe, indem Bedingungswerte als Bindungsvariablen bezeichnet werden (einige DBMS werden als Platzhalter bezeichnet). Beispielsweise werden "SELECT ... WHEWE COL1 =: B01" und die Teile "1" und "2" durch die Variable ": B01" ersetzt, und der tatsächliche Wert wird zur Laufzeit festgelegt (gebunden). Die Teile, die für die Bindevariable angegeben werden können, sind die Teile, die sich auf den Dateninhalt in der Tabelle beziehen. Beispielsweise können Sie Spaltennamen oder Tabellennamen nicht durch Bindungsvariablen ersetzen. Bindungsvariablen können für Spaltenwerte und SELECT-Listen angegeben werden.

SELECT-Anweisung mit Bindevariablen

Bevor wir die SELECT-Anweisung mit Bindevariablen erläutern, stellen wir ein Muster vor, das keine Bindevariablen verwendet. Ich werde dies in Form einer Überarbeitung erklären.

sample07a.py


import cx_Oracle

USERID = "admin"
PASSWORD = "FooBar"
DESTINATION = "atp1_low"
SQL1 = """
select prod_id, prod_name from sh.products
 where prod_category = 'Photo' and prod_subcategory = 'Camera Batteries'
"""
SQL2 = """
select prod_id, prod_name from sh.products
 where prod_category = 'Software/Other' and prod_subcategory = 'Bulk Pack Diskettes'
"""

with cx_Oracle.connect(USERID, PASSWORD, DESTINATION, encoding="UTF-8") as connection:
        with connection.cursor() as cursor:
                cursor.execute(SQL1)
                cursor.execute(SQL2)

SQL1 und SQL2 werden in Codierungen, die keine Bindevariablen verwenden, wie sample07a.py, nicht gemeinsam genutzt. Es gibt zwei Möglichkeiten, Bindungsvariablen für die gemeinsame Nutzung zu verwenden.

Geben Sie den Inhalt der Bindevariablen zum Zeitpunkt der Ausführung an ()

sample07b.py


import cx_Oracle

USERID = "admin"
PASSWORD = "FooBar"
DESTINATION = "atp1_low"
SQL = """
select prod_id, prod_name from sh.products
 where prod_category = :pc and prod_subcategory = :ps
"""

with cx_Oracle.connect(USERID, PASSWORD, DESTINATION, encoding="UTF-8") as connection:
        with connection.cursor() as cursor:
                cursor.execute(SQL, pc="Photo", ps="Camera Batteries")
                cursor.execute(SQL, pc="Software/Other", ps="Bulk Pack Diskettes")

Erstens wird die Anzahl der SQL-Anweisungen auf eins reduziert, da SQL gemeinsam genutzt wird. ": Pc" und ": ps" in der SQL-Anweisung sind Bindungsvariablen. Beginnen Sie mit ":" und geben Sie dann einen Namen an, der den Namenskonventionen von Python entspricht. Der Inhalt der Bindevariablen: pc,: ps wird als Argument der Methode execute () angegeben.

Erstellen Sie einen Wörterbuchtyp für die Bindungsvariable und geben Sie ihn zur Laufzeit an

sample07c.py


import cx_Oracle

USERID = "admin"
PASSWORD = "FooBar"
DESTINATION = "atp1_low"
SQL = """
select prod_id, prod_name from sh.products
 where prod_category = :pc and prod_subcategory = :ps
"""
bind_variables1 = {"pc":"Photo", "ps":"Camera Batteries"}
bind_variables2 = {"pc":"Software/Other", "ps":"Bulk Pack Diskettes"}

with cx_Oracle.connect(USERID, PASSWORD, DESTINATION, encoding="UTF-8") as connection:
        with connection.cursor() as cursor:
                cursor.execute(SQL, bind_variables1)
                cursor.execute(SQL, bind_variables2)

Erstellen Sie in der Mitte des Beispiels (dem Teil des Satzes von bind_variables1 und 2) ein Wörterbuch, das aus dem Namen der Bindungsvariablen und dem entsprechenden Wert besteht, und geben Sie den Wörterbuchnamen zum Zeitpunkt von execute () an.

Bereiten Sie die SQL-Anweisung vor

Wenn Sie SQL mithilfe von Bindevariablen ausgeben, wird es mithilfe des Anweisungscaches schneller ausgeführt. Einfaches SQL wie das Beispiel in diesem Artikel macht keinen großen Unterschied, aber das [Handbuch] von cx_Oracle (https://cx-oracle.readthedocs.io/en/latest/api_manual/connection.html#Connection.stmtcachesize) ) Sagt bis zu 100 Mal, es gibt also keinen Grund, es nicht zu verwenden.

sample07d.py


import cx_Oracle

USERID = "admin"
PASSWORD = "FooBar"
DESTINATION = "atp1_low"
SQL = """
select prod_id, prod_name from sh.products
 where prod_category = :pc and prod_subcategory = :ps
"""
bind_variables1 = {"pc":"Photo", "ps":"Camera Batteries"}
bind_variables2 = {"pc":"Software/Other", "ps":"Bulk Pack Diskettes"}

with cx_Oracle.connect(USERID, PASSWORD, DESTINATION, encoding="UTF-8") as connection:
        with connection.cursor() as cursor:
                cursor.prepare(SQL)
                cursor.execute(None, bind_variables1)
                cursor.execute(None, bind_variables2)

Die prepare () -Methode in der dritten Zeile von unten fügt die SQL in den Anweisungscache ein. Obwohl in der Quelle nicht ausdrücklich erwähnt, beträgt die Standardgröße des Anweisungscaches 20 (20 SQL-Anweisungen). Es ist möglich, auf die Cache-Größe zu verweisen und diese zu ändern, indem auf den Attributwert stmtcachesize des Verbindungsobjekts verwiesen oder dieser geändert wird. Geben Sie beim Ausführen von SQL None als erstes Argument der Methode execute () an, da die entsprechende SQL-Anweisung bereits vorbereitet wurde. Dies funktioniert auch dann, wenn Sie anstelle von None eine vorbereitete SQL-Typvariable angeben. Persönlich denke ich, dass es einfacher ist zu verstehen, dass diejenigen, die None angeben, prep verwenden, aber bitte verwenden Sie das, das Sie mögen.

Vermeiden Sie das Erstellen von SQL-Anweisungen mit F-Zeichenfolgen oder Zeichenfolgenverkettung

Ich sehe oft Fälle, in denen SQL-Anweisungen direkt in Form von "f" erstellt werden ... wobei prod_category = {pc} "" oder "... wo prod_category =" + pc ", aber dies ist nicht sehr gut. Es gibt zwei Hauptgründe.

--Die von diesen Logiken generierten SQL-Anweisungen sind Nachdrucke der zuvor gegebenen Erklärungen. Sie können jedoch die gemeinsame Nutzung von SQL-Anweisungen verhindern, die in Bindungsvariablen umgewandelt werden können, was zu Leistungseinbußen und Speicherauslastung führt. es gibt.

Ein solches SQL ist jedoch nicht immer schlecht. Es sei denn, Sie haben eine SQL, die nur einmal am Tag ausgeführt wird und für das Caching keinen Sinn ergibt, oder eine SQL, bei der Sie sich keine Gedanken über die SQL-Injection machen müssen, und Sie haben einen schnelleren Ausführungsplan, wenn Sie keine Bindevariablen verwenden. Ist nicht. Beachten Sie die flexible Implementierung von Fall zu Fall, basierend auf den in diesem Artikel enthaltenen Richtlinien.

Recommended Posts

[Einführung in cx_Oracle] (Teil 7) Umgang mit Bindevariablen
[Einführung in cx_Oracle] (16.) Umgang mit LOB-Typen
[Cx_Oracle Primer] (Teil 3) Grundlagen zum Durchsuchen von Tabellen
[Einführung in cx_Oracle] (5.) Umgang mit japanischen Daten
[Einführung in cx_Oracle] Übersicht über cx_Oracle
[Einführung in cx_Oracle] (Teil 11) Grundlagen der PL / SQL-Ausführung
[Einführung in cx_Oracle] (Teil 4) Abrufen und Scrollen der Ergebnismenge
[Einführung in cx_Oracle] (12.) DB-Ausnahmebehandlung
[Einführung in cx_Oracle] (17.) Datumsbehandlung
[Einführung in cx_Oracle] (Teil 2) Grundlagen zum Verbinden und Trennen mit Oracle Database
Einführung in PyQt4 Teil 1
[Einführung in cx_Oracle] (13.) Verbindung über Verbindungspool (Client-Seite)
[Einführung in cx_Oracle] (8.) Version cx_Oracle 8.0
Einführung in Ansible Teil In'Inventory '
Serie: Einführung in den Inhalt von cx_Oracle
Einführung in Ansible Teil ④'Variable '
[Einführung in cx_Oracle] (Teil 6) Zuordnung von DB- und Python-Datentypen
Einführung in Ansible Teil 2 'Grundlegende Grammatik'
Einführung in Python Hands On Teil 1
Einführung in Ansible Teil 1'Hallo Welt !! '
Web-WF Python Tornado Teil 3 (Einführung in Openpyexcel)
[Einführung in die Udemy Python3 + -Anwendung] 65. Ausnahmebehandlung
[Einführung in Datenwissenschaftler] Grundlagen der Wahrscheinlichkeit und Statistik ♬ Wahrscheinlichkeits- / Wahrscheinlichkeitsvariable und Wahrscheinlichkeitsverteilung
Einführung in Scapy ① (Von der Installation bis zur Ausführung von Scapy)
[Einführung in Data Scientist] Grundlagen von Python ♬
Kaggle: Einführung in das manuelle Feature Engineering Teil 1
[Einführung in cx_Oracle] (Teil 9) Zuordnung von DB- und Python-Datentypen (Version 8 oder höher)
[Einführung in die Udemy Python3 + -Anwendung] 26. Kopie des Wörterbuchs
[Einführung in die Udemy Python3 + -Anwendung] 19. Kopie der Liste
Von der Einführung von Pyethapp bis zur Vertragsabwicklung
[Einführung in Python] Grundlegende Verwendung von Lambda-Ausdrücken
Einführung in MQTT (Einführung)
Einführung in Scrapy (1)
Einführung in Scrapy (3)
Erste Schritte mit Supervisor
Einführung von Scikit-Optimize
Einführung in Tkinter 1: Einführung
Einführung von PyGMT
Einführung in PyQt
Einführung in Scrapy (2)
[Linux] Einführung in Linux
Einführung in das maschinelle Lernen ~ Zeigen wir die Tabelle der K-Methode für den nächsten Nachbarn ~ (+ Fehlerbehandlung)
Einführung in Scrapy (4)
Einführung in discord.py (2)
Einführung von Python
[Kapitel 6] Einführung in Scicit-Learn mit 100 Klopfen Sprachverarbeitung
[Einführung in Udemy Python3 + Application] 53. Wörterbuch der Schlüsselwortargumente
[Kapitel 3] Einführung in Python mit 100 Klopfen Sprachverarbeitung
[Kapitel 2] Einführung in Python mit 100 Klopfen Sprachverarbeitung
Ich habe versucht, den negativen Teil von Meros zu löschen
[Einführung in Python] Grundlegende Verwendung der Bibliothek matplotlib
[Einführung in Udemy Python3 + Application] 52. Tapple von Positionsargumenten
Einführung in Python numpy pandas matplotlib (für ~ B3 ~ part2)
[Kapitel 4] Einführung in Python mit 100 Klopfen Sprachverarbeitung