Verwenden des ODBC-Treibers

Unter diesem Thema werden Informationen zur Verwendung des ODBC-Treibers bereitgestellt.

Unter diesem Thema:

Kompilieren von Code

Linux

  • Wenn eine C/C++-Anwendung mit der Snowflake-ODBC-Treiberbibliothek erstellt wird und eine Bibliothek lädt, die nicht mit pthread kompatibel ist, kann die Anwendung aufgrund eines unsicheren gleichzeitigen Zugriffs auf den gemeinsam genutzten Speicher abstürzen. Um dies zu verhindern, kompilieren Sie die Anwendung mit der Option, die sicherstellt, dass nur pthread-kompatible Bibliotheken mit der Anwendung geladen werden.

    Für gcc/g++ lautet die Option „-pthread“.

macOS

  • Wenn eine C/C++-Anwendung mit der Snowflake-ODBC-Treiberbibliothek erstellt wird und eine Bibliothek lädt, die nicht mit pthread kompatibel ist, kann die Anwendung aufgrund eines unsicheren gleichzeitigen Zugriffs auf den gemeinsam genutzten Speicher abstürzen. Um dies zu verhindern, kompilieren Sie die Anwendung mit der Option, die sicherstellt, dass nur pthread-kompatible Bibliotheken mit der Anwendung geladen werden.

    Für clang/clang++ lautet die Option „-pthread“.

Ausführen eines Batches mit SQL-Anweisungen (Unterstützung von mehreren Anweisungen)

In ODBC können Sie einen Batch mit SQL-Anweisungen (durch Semikolons getrennt) senden, der mit einer einzigen Anforderung ausgeführt wird. Beispiel:

// Sending a batch of SQL statements to be executed
rc = SQLExecDirect(hstmt,
     (SQLCHAR *) "select c1 from t1; select c2 from t2; select c3 from t3",
     SQL_NTS);
Copy

Um einen Batch von Anweisungen mit dem Snowflake-ODBC-Treiber zu senden, müssen Sie die Anzahl der Anweisungen im Batch angeben. Die Snowflake-Datenbank benötigt die genaue Anzahl von Anweisungen, um sich vor Angriffen durch Einschleusung von SQL-Befehlen zu schützen.

Im nächsten Abschnitt wird erläutert, wie Sie die Anzahl der in einem Batch enthaltenen Anweisungen angeben.

Angeben der Anzahl der in einem Batch enthaltenen Anweisungen

Standardmäßig erwartet die Snowflake-Datenbank, dass der Treiber eine einzelne Anweisung zur Ausführung vorbereitet und sendet.

Sie können dies übersteuern, indem Sie die Anzahl der in einem Batch enthaltenen Anweisungen für eine bestimmte Anforderung angeben oder indem Sie die Verwendung mehrerer Anweisungen für die aktuelle Sitzung oder das aktuelle Konto aktivieren:

  • Um die Anzahl für eine bestimmte Anforderung anzugeben, rufen Sie SqlSetStmtAttr auf und setzen Sie das Attribut SQL_SF_STMT_ATTR_MULTI_STATEMENT_COUNT auf die Anzahl der im Batch enthaltenen Anweisungen.

    // Specify that you want to execute a batch of 3 SQL statements
    rc = SQLSetStmtAttr(hstmt, SQL_SF_STMT_ATTR_MULTI_STATEMENT_COUNT, (SQLPOINTER)3, 0);
    
    Copy

    Wenn Sie die Einstellung für die aktuelle Sitzung oder das aktuelle Konto verwenden möchten (anstatt die Anzahl für die Anforderung anzugeben), setzen Sie SQL_SF_STMT_ATTR_MULTI_STATEMENT_COUNT auf -1.

  • Um mehrere Anweisungen für die aktuelle Sitzung oder das aktuelle Konto zu aktivieren, ändern Sie die Sitzung oder das Konto und setzen Sie den Snowflake-Parameter MULTI_STATEMENT_COUNT auf 0.

    Verwendung:

    alter session set MULTI_STATEMENT_COUNT = 0;
    
    Copy

    oder:

    alter account set MULTI_STATEMENT_COUNT = 0;
    
    Copy

    Standardmäßig ist MULTI_STATEMENT_COUNT auf 1 gesetzt, was angibt, dass nur eine SQL-Anweisung ausgeführt werden kann.

    Hinweis: Das Festlegen des Parameters MULTI_STATEMENT_COUNT auf Kontoebene wirkt sich auch auf andere Snowflake-Konnektoren und -Treiber aus, die das Konto verwenden (z. B. auf den Snowflake-JDBC-Treiber).

Vorbereiten eines Batches mit SQL-Anweisungen

Der ODBC-Treiber unterstützt die Möglichkeit, einen Batch mit SQL-Anweisungen vorzubereiten (z. B. durch Aufrufen der Funktion SQLPrepare). Beachten Sie Folgendes:

  • Wenn die Anweisungen Parameter haben, gibt der Aufruf der Funktion SQLNumParams die Gesamtzahl der Parameter in allen Anweisungen des Batches zurück.

  • Spalteninformationen zum Resultset (z. B. von SQLNumResultCols, SQLDescribeCol, SQLColAttribute und SQLColAttributes zurückgegebene Daten) sind erst verfügbar, wenn Sie SQLExecute oder SQLExecDirect aufrufen.

    Obwohl beim Aufruf von SQLPrepare einige Spalteninformationen verfügbar sind, sind die Informationen möglicherweise nicht wirklich genau, und nachfolgende Aufrufe von SQLExecute oder SQLExecDirect liefern möglicherweise genauere Informationen.

Einschränkungen

GET/PUT-Befehle werden in Batches mit SQL-Anweisungen nicht unterstützt. Wenn Sie einen Batch mit SQL-Anweisungen senden, der auszuführende GET/PUT-Kommentare enthält, werden die GET/PUT-Befehle ignoriert und es werden keine Fehler gemeldet.

Binden von Parametern an Array-Variablen für Batcheinfügungen

In Ihrem Anwendungscode können Sie mehrere Zeilen in einen einzelnen Batch einfügen, indem Sie Parameter in einer INSERT-Anweisung an Array-Variablen binden.

Der folgende Code fügt beispielsweise Zeilen in eine Tabelle ein, die eine INTEGER-Spalte und eine VARCHAR-Spalte enthält. Im Beispiel werden die Parameter in der INSERT-Anweisung an Arrays gebunden.

SQLCHAR * Statement = "INSERT INTO t (c1, c2) VALUES (?, ?)";

SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, ARRAY_SIZE, 0);
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_STATUS_PTR, ParamStatusArray, 0);
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &ParamsProcessed, 0);
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,
                 IntValuesArray, 0, IntValuesIndArray);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, STR_VALUE_LEN - 1, 0,
                 StringValuesArray, STR_VALUE_LEN, StringValuesLenOrIndArray);
...
SQLExecDirect(hstmt, Statement, SQL_NTS);
Copy

Wenn Sie dieses Verfahren verwenden, um eine große Anzahl von Werten einzufügen, kann die Treiberleistung verbessert werden, indem die Daten (ohne Erstellen von Dateien auf dem lokalen Computer) an einen temporären Stagingbereich gestreamt werden. Der Treiber führt dies automatisch durch, wenn die Anzahl der Werte einen Schwellenwert überschreitet.

Außerdem müssen die aktuelle Datenbank und das aktuelle Schema für die Sitzung festgelegt sein. Wenn diese nicht festgelegt sind, kann der vom Treiber ausgeführte CREATE TEMPORARY STAGE-Befehl folgenden Fehler generieren:

CREATE TEMPORARY STAGE SYSTEM$BIND file_format=(type=csv field_optionally_enclosed_by='"')
Cannot perform CREATE STAGE. This session does not have a current schema. Call 'USE SCHEMA', or use a qualified name.
Copy

Bemerkung

Alternative Möglichkeiten zum Laden von Daten in die Snowflake-Datenbank (einschließlich Massenladen mit dem COPY-Befehl) finden Sie unter Daten in Snowflake laden.