使用 ODBC 驱动程序¶
本主题提供有关如何使用 ODBC 驱动程序的信息。
本主题内容:
编译代码¶
Linux¶
如果使用 Snowflake ODBC 驱动程序库构建 C/C++ 应用程序并加载与 pthread 不兼容的库,则应用程序可能会由于对共享内存的不安全并发访问而崩溃。为了防止这种情况,请使用以下选项编译应用程序,以确保应用程序只加载与 pthread 兼容的库。
对于 gcc/g++,选项是“-pthread”。
macOS¶
如果使用 Snowflake ODBC 驱动程序库构建 C/C++ 应用程序并加载与 pthread 不兼容的库,则应用程序可能会由于对共享内存的不安全并发访问而崩溃。为了防止这种情况,请使用以下选项编译应用程序,以确保应用程序只加载与 pthread 兼容的库。
对于 clang/clang++,选项是“-pthread”。
执行一批 SQL 语句(多语句支持)¶
在 ODBC 中,您可以发送一批 SQL 语句(用分号分隔),以在单个请求中执行。以下示例发送一批三个 SELECT 语句:
// 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);
要使用 Snowflake ODBC 驱动程序发送一批语句,必须指定批处理中的语句数。Snowflake 数据库需要确切数量的语句,以防止 SQL 注入攻击。
下一部分将介绍如何指定批处理中的语句数。
指定批处理中的语句数¶
默认情况下,Snowflake 数据库要求驱动程序准备并发送单个以供执行的语句。
您可以通过为给定请求指定批处理中的语句数或为当前会话或账户启用多个语句来替换此设置:
若要指定给定请求的语句数,请调用
SqlSetStmtAttr
以将SQL_SF_STMT_ATTR_MULTI_STATEMENT_COUNT
属性设置为批处理中的语句数。// 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);
如果要使用当前会话或账户的设置(而不是指定请求的数量),请将
SQL_SF_STMT_ATTR_MULTI_STATEMENT_COUNT
设置为-1
。要为当前会话或账户启用多个语句,请更改会话或账户,并将 Snowflake MULTI_STATEMENT_COUNT 参数设置为
0
。使用:
alter session set MULTI_STATEMENT_COUNT = 0;
或者:
alter account set MULTI_STATEMENT_COUNT = 0;
默认情况下,
MULTI_STATEMENT_COUNT
设置为1
,表示只能执行一条 SQL 语句。注意:在账户级别设置
MULTI_STATEMENT_COUNT
参数也会影响使用该账户的其他 Snowflake 连接器和驱动程序(例如,Snowflake JDBC 驱动程序)。
准备一批 SQL 语句¶
ODBC 驱动程序支持准备一批 SQL 语句的功能(例如,通过调用 SQLPrepare
函数)。请注意以下事项:
如果语句有参数,则调用
SQLNumParams
函数将返回批处理中所有语句中的参数总数。在调用
SQLExecute
或SQLExecDirect
时,有关结果集的列信息(例如,由SQLNumResultCols
、SQLDescribeCol
、SQLColAttribute
和SQLColAttributes
返回的数据)可用。尽管某些列信息在调用 SQLPrepare 时可用,但这些信息可能不完全准确,后续调用 SQLExecute 或 SQLExecDirect 可能会提供更准确的信息。
限制¶
GET 和 PUT 命令在批量 SQL 语句中不受支持。当您发送一批带有 GET 和 PUT 注释的 SQL 语句待执行时,将会忽略 GET 和 PUT 命令,并且不会报告任何错误。
将参数绑定到数组变量以进行批量插入¶
在应用程序代码中,可以通过将 INSERT 语句中的参数 绑定 到数组变量来在单个批处理中插入多行。
例如,下面的代码在包含 INTEGER 列和 VARCHAR 列的表中插入行。此示例将数组绑定到 INSERT 语句中的参数。
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);
使用此技术插入大量值时,驱动程序可以通过将数据流传输(而无需在本地计算机上创建文件)到临时暂存区进行引入来提高性能。当值数超过阈值时,驱动程序会自动执行此操作。
此外,您必须设置会话的当前数据库和架构。如果未设置这些值,则驱动程序执行的 CREATE TEMPORARY STAGE 命令可能会失败,并出现以下错误:
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.
备注
有关将数据加载到 Snowflake 数据库的其他方法(包括使用 COPY 命令进行批量加载),请参阅 将数据载入 Snowflake。