From 90124268465757c7bf27cf2a958fc007aead4d70 Mon Sep 17 00:00:00 2001 From: liuheng Date: Mon, 24 Apr 2023 15:13:13 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BD=BB=E9=87=8F=E7=89=88=E8=A1=A5=E5=85=85od?= =?UTF-8?q?bc=E8=B5=84=E6=96=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...nfiguring-a-data-source-in-the-linux-os.md | 510 +++++++++++++++++ .../development-based-on-odbc.md | 62 +++ .../development-process-ODBC.md | 108 ++++ ...mple-common-functions-and-batch-binding.md | 434 +++++++++++++++ .../odbc-interface-reference.md | 49 ++ ...es-dependent-libraries-and-header-files.md | 6 + ...pplication-scenarios-and-configurations.md | 492 +++++++++++++++++ content/docs-lite/en/menu/index.md | 59 +- ...56\346\225\260\346\215\256\346\272\220.md" | 511 ++++++++++++++++++ ...14\345\244\264\346\226\207\344\273\266.md" | 6 + ...45\345\217\243\345\217\202\350\200\203.md" | 49 ++ .../zh/docs/DeveloperGuide/SQLAllocConnect.md | 4 + .../zh/docs/DeveloperGuide/SQLAllocEnv.md | 4 + .../zh/docs/DeveloperGuide/SQLAllocHandle.md | 61 +++ .../zh/docs/DeveloperGuide/SQLAllocStmt.md | 4 + .../zh/docs/DeveloperGuide/SQLBindCol.md | 76 +++ .../docs/DeveloperGuide/SQLBindParameter.md | 100 ++++ .../zh/docs/DeveloperGuide/SQLColAttribute.md | 82 +++ .../zh/docs/DeveloperGuide/SQLConnect.md | 83 +++ .../zh/docs/DeveloperGuide/SQLDisconnect.md | 46 ++ .../zh/docs/DeveloperGuide/SQLExecDirect.md | 61 +++ .../zh/docs/DeveloperGuide/SQLExecute.md | 49 ++ .../zh/docs/DeveloperGuide/SQLFetch.md | 48 ++ .../zh/docs/DeveloperGuide/SQLFreeConnect.md | 4 + .../zh/docs/DeveloperGuide/SQLFreeEnv.md | 4 + .../zh/docs/DeveloperGuide/SQLFreeHandle.md | 54 ++ .../zh/docs/DeveloperGuide/SQLFreeStmt.md | 4 + .../zh/docs/DeveloperGuide/SQLGetData.md | 78 +++ .../zh/docs/DeveloperGuide/SQLGetDiagRec.md | 159 ++++++ .../zh/docs/DeveloperGuide/SQLPrepare.md | 59 ++ .../docs/DeveloperGuide/SQLSetConnectAttr.md | 64 +++ .../zh/docs/DeveloperGuide/SQLSetEnvAttr.md | 65 +++ .../zh/docs/DeveloperGuide/SQLSetStmtAttr.md | 64 +++ ...72\346\231\257\351\205\215\347\275\256.md" | 491 +++++++++++++++++ ...44\272\216ODBC\345\274\200\345\217\221.md" | 61 +++ ...5\217\221\346\265\201\347\250\213_ODBC.md" | 108 ++++ .../\347\244\272\344\276\213-2.md" | 339 ++++++++++++ ...71\351\207\217\347\273\221\345\256\232.md" | 434 +++++++++++++++ content/docs-lite/zh/menu/index.md | 68 ++- content/en/menu/index.md | 226 ++++---- ...44\272\216ODBC\345\274\200\345\217\221.md" | 2 +- ...71\346\200\247\344\273\213\347\273\215.md" | 22 +- ...2\346\225\260\344\273\213\347\273\215.rst" | 7 + .../ToolandCommandReference.rst | 15 + ...7\347\253\257\345\267\245\345\205\267.rst" | 6 + ...1\347\253\257\345\267\245\345\205\267.rst" | 19 + ...5\351\203\250\345\221\275\344\273\244.rst" | 37 ++ ...6\347\276\244\347\256\241\347\220\206.rst" | 11 + .../source/index-ToolandCommandReference.rst | 11 + 49 files changed, 5166 insertions(+), 150 deletions(-) create mode 100644 content/docs-lite/en/docs/Developerguide/configuring-a-data-source-in-the-linux-os.md create mode 100644 content/docs-lite/en/docs/Developerguide/development-based-on-odbc.md create mode 100644 content/docs-lite/en/docs/Developerguide/development-process-ODBC.md create mode 100644 content/docs-lite/en/docs/Developerguide/example-common-functions-and-batch-binding.md create mode 100644 content/docs-lite/en/docs/Developerguide/odbc-interface-reference.md create mode 100644 content/docs-lite/en/docs/Developerguide/odbc-packages-dependent-libraries-and-header-files.md create mode 100644 content/docs-lite/en/docs/Developerguide/typical-application-scenarios-and-configurations.md create mode 100644 "content/docs-lite/zh/docs/DeveloperGuide/Linux\344\270\213\351\205\215\347\275\256\346\225\260\346\215\256\346\272\220.md" create mode 100644 "content/docs-lite/zh/docs/DeveloperGuide/ODBC\345\214\205\345\217\212\344\276\235\350\265\226\347\232\204\345\272\223\345\222\214\345\244\264\346\226\207\344\273\266.md" create mode 100644 "content/docs-lite/zh/docs/DeveloperGuide/ODBC\346\216\245\345\217\243\345\217\202\350\200\203.md" create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLAllocConnect.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLAllocEnv.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLAllocHandle.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLAllocStmt.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLBindCol.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLBindParameter.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLColAttribute.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLConnect.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLDisconnect.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLExecDirect.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLExecute.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLFetch.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLFreeConnect.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLFreeEnv.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLFreeHandle.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLFreeStmt.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLGetData.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLGetDiagRec.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLPrepare.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLSetConnectAttr.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLSetEnvAttr.md create mode 100644 content/docs-lite/zh/docs/DeveloperGuide/SQLSetStmtAttr.md create mode 100644 "content/docs-lite/zh/docs/DeveloperGuide/\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\351\205\215\347\275\256.md" create mode 100644 "content/docs-lite/zh/docs/DeveloperGuide/\345\237\272\344\272\216ODBC\345\274\200\345\217\221.md" create mode 100644 "content/docs-lite/zh/docs/DeveloperGuide/\345\274\200\345\217\221\346\265\201\347\250\213_ODBC.md" create mode 100644 "content/docs-lite/zh/docs/DeveloperGuide/\347\244\272\344\276\213-2.md" create mode 100644 "content/docs-lite/zh/docs/DeveloperGuide/\347\244\272\344\276\213-\345\270\270\347\224\250\345\212\237\350\203\275\345\222\214\346\211\271\351\207\217\347\273\221\345\256\232.md" create mode 100644 "sphinx/source/ToolandCommandReference/CM\351\205\215\347\275\256\345\217\202\346\225\260\344\273\213\347\273\215.rst" create mode 100644 sphinx/source/ToolandCommandReference/ToolandCommandReference.rst create mode 100644 "sphinx/source/ToolandCommandReference/\345\256\242\346\210\267\347\253\257\345\267\245\345\205\267.rst" create mode 100644 "sphinx/source/ToolandCommandReference/\346\234\215\345\212\241\347\253\257\345\267\245\345\205\267.rst" create mode 100644 "sphinx/source/ToolandCommandReference/\347\263\273\347\273\237\345\206\205\351\203\250\345\221\275\344\273\244.rst" create mode 100644 "sphinx/source/ToolandCommandReference/\351\233\206\347\276\244\347\256\241\347\220\206.rst" create mode 100644 sphinx/source/index-ToolandCommandReference.rst diff --git a/content/docs-lite/en/docs/Developerguide/configuring-a-data-source-in-the-linux-os.md b/content/docs-lite/en/docs/Developerguide/configuring-a-data-source-in-the-linux-os.md new file mode 100644 index 000000000..166d54b5a --- /dev/null +++ b/content/docs-lite/en/docs/Developerguide/configuring-a-data-source-in-the-linux-os.md @@ -0,0 +1,510 @@ +# Configuring a Data Source in the Linux OS + +The ODBC DRIVER \(**psqlodbcw.so**\) provided by openGauss can be used after it has been configured in a data source. To configure a data source, you must configure the **odbc.ini** and **odbcinst.ini** files on the server. The two files are generated during the unixODBC compilation and installation, and are saved in the **/usr/local/etc** directory by default. + +## Procedure + +1. Obtain the source code package of unixODBC by following link: + + [https://sourceforge.net/projects/unixodbc/files/unixODBC/2.3.9/unixODBC-2.3.9pre.tar.gz/download](https://sourceforge.net/projects/unixodbc/files/unixODBC/2.3.9/unixODBC-2.3.9pre.tar.gz/download) + + After the download, validate the integrity based on the integrity validation algorithm provided by the community. + +2. Install unixODBC. It does not matter if unixODBC of another version has been installed. + + Currently, unixODBC-2.2.1 is not supported. For example, to install unixODBC-2.3.0, run the commands below. unixODBC is installed in the **/usr/local** directory by default. The data source file is generated in the **/usr/local/etc** directory, and the library file is generated in the **/usr/local/lib** directory. + + ``` + tar zxvf unixODBC-2.3.0.tar.gz + cd unixODBC-2.3.0 + # Modify the configure file. (If it does not exist, modify the configure.ac file.) Find LIB_VERSION. + # Change the value of LIB_VERSION to 1:0:0 to compile a *.so.1 dynamic library with the same dependency on psqlodbcw.so. + vim configure + + ./configure --enable-gui=no #To perform compilation on an ARM server, add the configure parameter --build=aarch64-unknown-linux-gnu. + make + # The installation may require root permissions. + make install + ``` + +3. Replace the openGauss client driver. + 1. Decompress the **openGauss-x.x.x-ODBC.tar.gz** package. After the decompression, the **lib** and **odbc** folders are generated. The **odbc** folder contains another **lib** folder. Copy the **psqlodbca.la**, **psqlodbca.so**, **psqlodbcw.la**, and **psqlodbcw.so** files from **/odbc/lib** to **/usr/local/lib**. + 2. Copy the library in the **lib** directory obtained after decompressing **openGauss-x.x.x-ODBC.tar.gz** to the **/usr/local/lib** directory. + +4. Configure a data source. + 1. Configure the ODBC driver file. + + Add the following content to the **/usr/local/etc/odbcinst.ini** file: + + ``` + [GaussMPP] + Driver64=/usr/local/lib/psqlodbcw.so + setup=/usr/local/lib/psqlodbcw.so + ``` + + For descriptions of the parameters in the **odbcinst.ini** file, see [Table 1](#en-us_topic_0283136654_en-us_topic_0237120407_en-us_topic_0059778464_td564f21e7c8e458bbd741b09896f5d91). + + **Table 1** odbcinst.ini configuration parameters + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Example

+

[DriverName]

+

Driver name, corresponding to Driver in DSN.

+

[DRIVER_N]

+

Driver64

+

Path of the dynamic driver library.

+

Driver64=/usr/local/lib/psqlodbcw.so

+

setup

+

Driver installation path, which is the same as the dynamic library path in Driver64.

+

setup=/usr/local/lib/psqlodbcw.so

+
+ + 2. Configure the data source file. + + Add the following content to the **/usr/local/etc/odbc.ini** file: + + ``` + [MPPODBC] + Driver=GaussMPP + Servername=10.145.130.26 (IP address of the server where the database resides) + Database=postgres (database name) + Username=omm (database username) + Password= (user password of the database) + Port=8000 (listening port of the database) + Sslmode = allow + ``` + + For descriptions of the parameters in the **odbc.ini** file, see [Table 2](#en-us_topic_0283136654_en-us_topic_0237120407_en-us_topic_0059778464_t55845a6555f2454297b64ce47ad3d648). + + **Table 2** odbc.ini configuration parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Example

+

[DSN]

+

Data source name.

+

[MPPODBC]

+

Driver

+

Driver name, corresponding to DriverName in odbcinst.ini.

+

Driver = DRIVER_N

+

Servername

+

Server IP address. Multiple IP addresses can be configured.

+

Servername = 10.145.130.26

+

Database

+

Name of the database to connect to.

+

Database = postgres

+

Username

+

Database username.

+

Username = omm

+

Password

+

Database user password.

+

Password=

+
NOTE:

After a user established a connection, the ODBC driver automatically clears their password stored in memory.

+

However, if this parameter is configured, UnixODBC will cache data source files, which may cause the password to be stored in the memory for a long time.

+

When you connect to an application, you are advised to send your password through an API instead of writing it in a data source configuration file. After the connection has been established, immediately clear the memory segment where your password is stored.

+
+

Port

+

Port number of the server.

+

Port = 8000

+

Sslmode

+

Whether to enable SSL.

+

Sslmode = allow

+

Debug

+

If this parameter is set to 1, the mylog file of the PostgreSQL ODBC driver will be printed. The directory generated for storing logs is /tmp/. If this parameter is set to 0, no directory is generated.

+

Debug = 1

+

UseServerSidePrepare

+

Whether to enable the extended query protocol for the database.

+

The value can be 0 or 1. The default value is 1, indicating that the extended query protocol is enabled.

+

UseServerSidePrepare = 1

+

UseBatchProtocol

+

Whether to enable the batch query protocol. If it is enabled, DML performance can be improved. The value can be 0 or 1. The default value is 1.

+

If this parameter is set to 0, the batch query protocol is disabled (mainly for communication with earlier database versions).

+

If this parameter is set to 1 and support_batch_bind is set to on, the batch query protocol is enabled.

+

UseBatchProtocol = 1

+

ForExtensionConnector

+

This parameter specifies whether the savepoint is sent.

+

ForExtensionConnector = 1

+

UnamedPrepStmtThreshold

+

Each time SQLFreeHandle is invoked to release statements, ODBC sends a Deallocate plan_name statement to the server. A large number of such statements exist in the service. To reduce the number of the statements to be sent, stmt->plan_name is left empty so that the database can identify them as unnamed statements. This parameter is added to control the threshold for unnamed statements.

+

UnamedPrepStmtThreshold = 100

+

ConnectionExtraInfo

+

Whether to display the driver deployment path and process owner in the connection_info parameter mentioned in connection_info.

+

ConnectionExtraInfo = 1

+
NOTE:

The default value is 0. If this parameter is set to 1, the ODBC driver reports the driver deployment path and process owner to the database and displays the information in the connection_info parameter (see connection_info). In this case, you can query the information from PG_STAT_ACTIVITY.

+
+

BoolAsChar

+

If this parameter is set to Yes, the Boolean value is mapped to the SQL_CHAR type. If this parameter is not set, the value is mapped to the SQL_BIT type.

+

BoolsAsChar = Yes

+

RowVersioning

+

When an attempt is made to update a row of data, setting this parameter to Yes allows the application to detect whether the data has been modified by other users.

+

RowVersioning = Yes

+

ShowSystemTables

+

By default, the driver regards the system table as a common SQL table.

+

ShowSystemTables = Yes

+
+ + The valid values of **Sslmode** are as follows: + + **Table 3** Sslmode options + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Sslmode

+

Whether SSL Encryption Is Enabled

+

Description

+

disable

+

No

+

SSL connection is not enabled.

+

allow

+

Possible

+

If the database server requires SSL connection, SSL connection can be enabled. However, authenticity of the database server will not be verified.

+

prefer

+

Possible

+

If the database supports SSL connection, SSL connection is recommended. However, authenticity of the database server will not be verified.

+

require

+

Yes

+

SSL connection is required and data is encrypted. However, authenticity of the database server will not be verified.

+

verify-ca

+

Yes

+

SSL connection is required and whether the database has a trusted certificate will be verified.

+

verify-full

+

Yes

+

SSL connection is required. In addition to the check scope specified by verify-ca, the system checks whether the name of the host where the database resides is the same as that on the certificate. openGauss does not support this mode.

+
+ +5. \(Optional\) Generate an SSL certificate. For details, see [Generating Certificates](en-us_topic_0289900216.md). This step and step [6](#en-us_topic_0283136654_li1724551081815) are required only when the server and client are connected in SSL mode. Skip the two steps if the non-SSL connection mode is used. +6. \(Optional\) Replace an SSL certificate. For details, see [Replacing Certificates](en-us_topic_0289900549.md). +7. Enable SSL mode. + + Declare the following environment variables and ensure that the permission for the **client.key\*** series files is set to **600**. + + ``` + Go back to the root directory, create the .postgresql directory, and save root.crt, client.crt, client.key, client.key.cipher, client.key.rand, client.req, server.crt, server.key, server.key.cipher, server.key.rand, and server.req to the .postgresql directory. + In the Unix OS, server.crt and server.key must deny the access from the external or any group. Run the following command to set this permission: + chmod 0600 server.key + Copy the certificate files whose names start with root.crt and server to the install/data directory of the database (the directory is the same as that of the postgresql.conf file). + Modify the postgresql.conf file. + ssl = on + ssl_cert_file = 'server.crt' + ssl_key_file = 'server.key' + ssl_ca_file = 'root.crt' + After modifying the parameters, restart the database. + Set the sslmode parameter to require or verify-ca in the odbc.ini file. + ``` + +8. Configure the database server. + 1. Log in as the OS user **omm** to the primary node of the database. + 2. Run the following command to add NIC IP addresses or host names, with values separated by commas \(,\). The NICs and hosts are used to provide external services. In the following command, _NodeName_ specifies the name of the current node. + + ``` + gs_guc reload -N NodeName -I all -c "listen_addresses='localhost,192.168.0.100,10.11.12.13'" + ``` + + If direct routing of LVS is used, add the virtual IP address \(10.11.12.13\) of LVS to the server listening list. + + You can also set **listen\_addresses** to **\*** or **0.0.0.0** to listen to all NICs, but this incurs security risks and is not recommended. + + 3. Run the following command to add an authentication rule to the configuration file of the primary database node. In this example, the IP address \(10.11.12.13\) of the client is the remote host IP address. + + ``` + gs_guc reload -N all -I all -h "host all jack 10.11.12.13/32 sha256" + ``` + + >![](public_sys-resources/icon-note.gif) **NOTE:** + >- **** + >- **-N all** indicates all hosts in openGauss. + >- **-I all** indicates all instances of the host. + >- **-h** specifies statements that need to be added in the **pg\_hba.conf** file. + >- **all** indicates that a client can connect to any database. + >- **jack** indicates the user that accesses the database. + >- **_10.11.12.13/__32_** indicates hosts whose IP address is 10.11.12.13 can be connected. Configure the parameter based on your network conditions. **32** indicates that there are 32 bits whose value is 1 in the subnet mask. That is, the subnet mask is 255.255.255.255. + >- **sha256** indicates that the password of user **jack** is encrypted using the SHA-256 algorithm. + + If the ODBC client and the primary database node to connect are deployed on the same machine, you can use the local trust authentication mode. Run the following command: + + ``` + local all all trust + ``` + + If the ODBC client and the primary database node to connect are deployed on different machines, use the SHA-256 authentication mode. Run the following command: + + ``` + host all all xxx.xxx.xxx.xxx/32 sha256 + ``` + + 4. Restart openGauss. + + ``` + gs_om -t stop + gs_om -t start + ``` + +9. Configure the environment variables on the client. + + ``` + vim ~/.bashrc + ``` + + Add the following information to the configuration file: + + ``` + export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH + export ODBCSYSINI=/usr/local/etc + export ODBCINI=/usr/local/etc/odbc.ini + ``` + +10. Run the following command to validate the addition: + + ``` + source ~/.bashrc + ``` + + +## Verifying the Data Source Configuration + +Run the **./isql -v** _MPPODBC_ command \(**_MPPODBC_** is the data source name\). + +- If the following information is displayed, the configuration is correct and the connection succeeds. + + ``` + +---------------------------------------+ + | Connected! | + | | + | sql-statement | + | help [tablename] | + | quit | + | | + +---------------------------------------+ + SQL> + ``` + +- If error information is displayed, the configuration is incorrect. Check the configuration. + +## FAQs + +- \[UnixODBC\]\[Driver Manager\]Can't open lib 'xxx/xxx/psqlodbcw.so' : file not found. + + Possible causes: + + - The path configured in the **odbcinst.ini** file is incorrect. + + Run **ls** to check the path in the error information, and ensure that the **psqlodbcw.so** file exists and you have execute permissions on it. + + - The dependent library of **psqlodbcw.so** does not exist or is not in system environment variables. + + Run **ldd** to check the path in the error information. If **libodbc.so.1** or other UnixODBC libraries do not exist, configure UnixODBC again following the procedure provided in this section, and add the **lib** directory under its installation directory to **LD\_LIBRARY\_PATH**. If other libraries do not exist, add the **lib** directory under the ODBC driver package to **LD\_LIBRARY\_PATH**. + + +- \[UnixODBC\]connect to server failed: no such file or directory + + Possible causes: + + - An incorrect or unreachable database IP address or port was configured. + + Check the **Servername** and **Port** configuration items in data sources. + + - Server monitoring is improper. + + If **Servername** and **Port** are correctly configured, ensure the proper network adapter and port are monitored by following the database server configurations in the procedure in this section. + + - Firewall and network gatekeeper settings are improper. + + Check firewall settings, and ensure that the database communication port is trusted. + + Check to ensure network gatekeeper settings are proper \(if any\). + + +- \[unixODBC\]The password-stored method is not supported. + + Possible causes: + + The **sslmode** configuration item is not configured in the data sources. + + Solution: + + Set the configuration item to **allow** or a higher level. For details, see [Table 3](#en-us_topic_0283136654_en-us_topic_0237120407_en-us_topic_0059778464_table22136585143846). + +- Server common name "xxxx" does not match host name "xxxxx" + + Possible causes: + + When **verify-full** is used for SSL encryption, the driver checks whether the host name in certificates is the same as the actual one. + + Solution: + + To solve this problem, use **verify-ca** to stop checking host names, or generate a set of CA certificates containing the actual host names. + +- Driver's SQLAllocHandle on SQL\_HANDLE\_DBC failed + + Possible causes: + + The executable file \(such as the **isql** tool of unixODBC\) and the database driver \(**psqlodbcw.so**\) depend on different library versions of ODBC, such as **libodbc.so.1** and **libodbc.so.2**. You can verify this problem by using the following method: + + ``` + ldd `which isql` | grep odbc + ldd psqlodbcw.so | grep odbc + ``` + + If the suffix digits of the outputs **libodbc.so** are different or indicate different physical disk files, this problem exists. Both **isql** and **psqlodbcw.so** load **libodbc.so**. If different physical files are loaded, different ODBC libraries with the same function list conflict with each other in a visible domain. As a result, the database driver cannot be loaded. + + Solution: + + Uninstall the unnecessary unixODBC, such as libodbc.so.2, and create a soft link with the same name and the .so.2 suffix for the remaining libodbc.so.1 library. + +- FATAL: Forbid remote connection with trust method! + + For security purposes, the primary database node forbids access from other nodes in openGauss without authentication. + + To access the primary database node from inside openGauss, deploy the ODBC program on the host where the primary database node is located and set the server address to **127.0.0.1**. It is recommended that the service system be deployed outside openGauss. If it is deployed inside, database performance may be affected. + +- \[unixODBC\]\[Driver Manager\]Invalid attribute value + + The unixODBC version may not be the recommended one. You are advised to run the **odbcinst --version** command to check the unixODBC version in the environment. + +- authentication method 10 not supported. + + If this error occurs on an open-source client, the cause may be: + + The database stores only the SHA-256 hash of the password, but the open-source client supports only MD5 hashes. + + >![](public_sys-resources/icon-note.gif) **NOTE:** + >- The database stores the hashes of user passwords instead of actual passwords. + >- If a password is updated or a user is created, both types of hashes will be stored, compatible with open-source authentication protocols. + >- An MD5 hash can only be generated using the original password, but the password cannot be obtained by reversing its SHA-256 hash. Passwords in the old version will only have SHA-256 hashes and not support MD5 authentication. + >- The MD5 encryption algorithm has lower security and poses security risks. Therefore, you are advised to use a more secure encryption algorithm. + + To solve this problem, you can update the user password \(see [ALTER USER](en-us_topic_0289900744.md)\) or create a user \(see [CREATE USER](en-us_topic_0289899951.md)\) having the same permissions as the faulty user. + +- unsupported frontend protocol 3.51: server supports 1.0 to 3.0 + + The database version is too early or the database is an open-source database. Use the driver of the required version to connect to the database. + +- FATAL: GSS authentication method is not allowed because XXXX user password is not disabled. + + In **pg\_hba.conf** of the target primary database node, the authentication mode is set to **gss** for authenticating the IP address of the current client. However, this authentication algorithm cannot authenticate clients. Change the authentication algorithm to **sha256** and try again. For details, see [8](#en-us_topic_0283136654_en-us_topic_0237120407_en-us_topic_0059778464_l4c0173b8af93447e91aba24005e368e5). + + diff --git a/content/docs-lite/en/docs/Developerguide/development-based-on-odbc.md b/content/docs-lite/en/docs/Developerguide/development-based-on-odbc.md new file mode 100644 index 000000000..9b59a1081 --- /dev/null +++ b/content/docs-lite/en/docs/Developerguide/development-based-on-odbc.md @@ -0,0 +1,62 @@ +# Development Based on ODBC + +Open Database Connectivity \(ODBC\) is a Microsoft API for accessing databases based on the X/OPEN CLI. Applications interact with the database through the APIs provided by ODBC, which enhances their portability, scalability, and maintainability. + +[Figure 1](#fig1255101034110) shows the system structure of ODBC. + +**Figure 1** ODBC system structure +![](figures/odbc-system-structure.png "odbc-system-structure") + +openGauss supports ODBC 3.5 in the following environments. + +**Table 1** OSs Supported by ODBC + + + + + + + + + + + + + + + + + + + +

OS

+

Platform

+

CentOS 6.4/6.5/6.6/6.7/6.8/6.9/7.0/7.1/7.2/7.3/7.4

+

x86_64

+

CentOS 7.6

+

ARM64

+

EulerOS 2.0 SP2/SP3

+

x86_64

+

EulerOS 2.0 SP8

+

ARM64

+
+ + +The ODBC Driver Manager running on UNIX or Linux can be unixODBC or iODBC. unixODBC-2.3.0 is used as the component for connecting the database. + +Windows has a native ODBC Driver Manager. You can locate **Data Sources \(ODBC\)** by choosing **Control Panel** \> **Administrative Tools**. + +>![](public_sys-resources/icon-note.gif) **NOTE:** +>The current database ODBC driver is based on an open-source version and may be incompatible with data types tinyint, smalldatetime, and nvarchar2. + +- **[ODBC Packages, Dependent Libraries, and Header Files](odbc-packages-dependent-libraries-and-header-files.md)** + +- **[Configuring a Data Source in the Linux OS](configuring-a-data-source-in-the-linux-os.md)** + +- **[Development Process](development-process-1.md)** + +- **[Example](example.md)** + +- **[ODBC Interface Reference](odbc-interface-reference.md)** + + diff --git a/content/docs-lite/en/docs/Developerguide/development-process-ODBC.md b/content/docs-lite/en/docs/Developerguide/development-process-ODBC.md new file mode 100644 index 000000000..2371e515f --- /dev/null +++ b/content/docs-lite/en/docs/Developerguide/development-process-ODBC.md @@ -0,0 +1,108 @@ +# Development Process + +**Figure 1** ODBC-based application development process +![](figures/odbc-based-application-development-process.png "odbc-based-application-development-process") + +## APIs Involved in the Development Process + +**Table 1** API description + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

API

+

Allocate a handle

+

SQLAllocHandle is a generic function for allocating a handle. It can replace the following functions:

+ +

Set environment attributes

+

SQLSetEnvAttr

+

Set connection attributes

+

SQLSetConnectAttr

+

Set statement attributes

+

SQLSetStmtAttr

+

Connect to a data source

+

SQLConnect

+

Bind a buffer to a column in the result set

+

SQLBindCol

+

Bind the parameter marker of an SQL statement to a buffer

+

SQLBindParameter

+

Return the error message of the last operation

+

SQLGetDiagRec

+

Prepare an SQL statement for execution

+

SQLPrepare

+

Run a prepared SQL statement

+

SQLExecute

+

Run an SQL statement directly

+

SQLExecDirect

+

Fetch the next row (or rows) from the result set

+

SQLFetch

+

Return data in a column of the result set

+

SQLGetData

+

Get the column information from a result set

+

SQLColAttribute

+

Disconnect from a data source

+

SQLDisconnect

+

Release a handle

+

SQLFreeHandle is a generic function for releasing a handle. It can replace the following functions:

+ +
+ +>![](public_sys-resources/icon-note.gif) **NOTE:** +>If an execution request \(not in a transaction block\) received in the database contains multiple statements, the request is packed into a transaction. If one of the statements fails, the entire request will be rolled back. + +> **警告:** +> +> ODBC is the central layer of the application program and the database. It is responsible for transmitting the SQL instructions issued by the application program to the database, and does not parse the SQL syntax by itself. Therefore, when an SQL statement with confidential information (such as a plaintext password) is written in an application, the confidential information will be exposed in the driver log. + diff --git a/content/docs-lite/en/docs/Developerguide/example-common-functions-and-batch-binding.md b/content/docs-lite/en/docs/Developerguide/example-common-functions-and-batch-binding.md new file mode 100644 index 000000000..c7ef34d26 --- /dev/null +++ b/content/docs-lite/en/docs/Developerguide/example-common-functions-and-batch-binding.md @@ -0,0 +1,434 @@ +# Example: Common Functions and Batch Binding + +## Code for Common Functions + +``` +//The following example shows how to obtain data from openGauss through the ODBC interface. +// DBtest.c (compile with: libodbc.so) +#include +#include +#include +#ifdef WIN32 +#include +#endif +SQLHENV V_OD_Env; // Handle ODBC environment +SQLHSTMT V_OD_hstmt; // Handle statement +SQLHDBC V_OD_hdbc; // Handle connection +char typename[100]; +SQLINTEGER value = 100; +SQLINTEGER V_OD_erg,V_OD_buffer,V_OD_err,V_OD_id; +int main(int argc,char *argv[]) +{ + // 1. Allocate an environment handle. + V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env); + if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO)) + { + printf("Error AllocHandle\n"); + exit(0); + } + // 2. Set environment attributes (version information). + SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); + // 3. Allocate a connection handle. + V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc); + if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO)) + { + SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env); + exit(0); + } + // 4. Set connection attributes. + SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0); + // 5. Connect to the data source. userName and password indicate the username and password for connecting to the database. Set them as needed. + // If the username and password have been set in the odbc.ini file, you do not need to set userName or password here, retaining "" for them. However, you are not advised to do so because the username and password will be disclosed if the permission for odbc.ini is abused. + V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "gaussdb", SQL_NTS, + (SQLCHAR*) "userName", SQL_NTS, (SQLCHAR*) "password", SQL_NTS); + if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO)) + { + printf("Error SQLConnect %d\n",V_OD_erg); + SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env); + exit(0); + } + printf("Connected !\n"); + // 6. Set statement attributes. + SQLSetStmtAttr(V_OD_hstmt,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER *)3,0); + // 7. Allocate a statement handle. + SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt); + // 8. Run SQL statements. + SQLExecDirect(V_OD_hstmt,"drop table IF EXISTS customer_t1",SQL_NTS); + SQLExecDirect(V_OD_hstmt,"CREATE TABLE customer_t1(c_customer_sk INTEGER, c_customer_name VARCHAR(32));",SQL_NTS); + SQLExecDirect(V_OD_hstmt,"insert into customer_t1 values(25,li)",SQL_NTS); + // 9. Prepare for execution. + SQLPrepare(V_OD_hstmt,"insert into customer_t1 values(?)",SQL_NTS); + // 10. Bind parameters. + SQLBindParameter(V_OD_hstmt,1,SQL_PARAM_INPUT,SQL_C_SLONG,SQL_INTEGER,0,0, + &value,0,NULL); + // 11. Run prepared statements. + SQLExecute(V_OD_hstmt); + SQLExecDirect(V_OD_hstmt,"select id from testtable",SQL_NTS); + // 12. Obtain attributes of a specific column in the result set. + SQLColAttribute(V_OD_hstmt,1,SQL_DESC_TYPE,typename,100,NULL,NULL); + printf("SQLColAtrribute %s\n",typename); + // 13. Bind the result set. + SQLBindCol(V_OD_hstmt,1,SQL_C_SLONG, (SQLPOINTER)&V_OD_buffer,150, + (SQLLEN *)&V_OD_err); + // 14. Obtain data in the result set by executing SQLFetch. + V_OD_erg=SQLFetch(V_OD_hstmt); + // 15. Obtain and return data by executing SQLGetData. + while(V_OD_erg != SQL_NO_DATA) + { + SQLGetData(V_OD_hstmt,1,SQL_C_SLONG,(SQLPOINTER)&V_OD_id,0,NULL); + printf("SQLGetData ----ID = %d\n",V_OD_id); + V_OD_erg=SQLFetch(V_OD_hstmt); + }; + printf("Done !\n"); + // 16. Disconnect data source connections and release handles. + SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt); + SQLDisconnect(V_OD_hdbc); + SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc); + SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env); + return(0); + } +``` + +## Code for Batch Processing + +``` +/********************************************************************** +* Enable UseBatchProtocol in the data source and set the database parameter support_batch_bind +* to on. +* The CHECK_ERROR command is used to check and print error information. +* This example is used to interactively obtain the DSN, data volume to be processed, and volume of ignored data from users, and insert required data into the test_odbc_batch_insert table. +***********************************************************************/ +#include +#include +#include +#include +#include + +void Exec(SQLHDBC hdbc, SQLCHAR* sql) +{ + SQLRETURN retcode; // Return status + SQLHSTMT hstmt = SQL_NULL_HSTMT; // Statement handle + SQLCHAR loginfo[2048]; + + // Allocate Statement Handle + retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLAllocHandle(SQL_HANDLE_STMT) failed"); + return; + } + + // Prepare Statement + retcode = SQLPrepare(hstmt, (SQLCHAR*) sql, SQL_NTS); + sprintf((char*)loginfo, "SQLPrepare log: %s", (char*)sql); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLPrepare(hstmt, (SQLCHAR*) sql, SQL_NTS) failed"); + return; + } + + // Execute Statement + retcode = SQLExecute(hstmt); + sprintf((char*)loginfo, "SQLExecute stmt log: %s", (char*)sql); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute(hstmt) failed"); + return; + } + // Free Handle + retcode = SQLFreeHandle(SQL_HANDLE_STMT, hstmt); + sprintf((char*)loginfo, "SQLFreeHandle stmt log: %s", (char*)sql); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLFreeHandle(SQL_HANDLE_STMT, hstmt) failed"); + return; + } +} + +int main () +{ + SQLHENV henv = SQL_NULL_HENV; + SQLHDBC hdbc = SQL_NULL_HDBC; + int batchCount = 1000; // Amount of data that is bound in batches + SQLLEN rowsCount = 0; + int ignoreCount = 0; // Amount of data that is not imported to the database among the data that is bound in batches + + SQLRETURN retcode; + SQLCHAR dsn[1024] = {'\0'}; + SQLCHAR loginfo[2048]; + + do + { + if (ignoreCount > batchCount) + { + printf("ignoreCount(%d) should be less than batchCount(%d)\n", ignoreCount, batchCount); + } + }while(ignoreCount > batchCount); + + retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLAllocHandle failed"); + goto exit; + } + + // Set ODBC Verion + retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, + (SQLPOINTER*)SQL_OV_ODBC3, 0); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLSetEnvAttr failed"); + goto exit; + } + + // Allocate Connection + retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLAllocHandle failed"); + goto exit; + } + + + // Set Login Timeout + retcode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLSetConnectAttr failed"); + goto exit; + } + + + // Set Auto Commit + retcode = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, + (SQLPOINTER)(1), 0); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLSetConnectAttr failed"); + goto exit; + } + + + // Connect to DSN + // gaussdb indicates the name of the data source used by users. + sprintf(loginfo, "SQLConnect(DSN:%s)", dsn); + retcode = SQLConnect(hdbc, (SQLCHAR*) "gaussdb", SQL_NTS, + (SQLCHAR*) NULL, 0, NULL, 0); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLConnect failed"); + goto exit; + } + + // init table info. + Exec(hdbc, "drop table if exists test_odbc_batch_insert"); + Exec(hdbc, "create table test_odbc_batch_insert(id int primary key, col varchar2(50))"); + + // The following code constructs the data to be inserted based on the data volume entered by users: + { + SQLRETURN retcode; + SQLHSTMT hstmtinesrt = SQL_NULL_HSTMT; + int i; + SQLCHAR *sql = NULL; + SQLINTEGER *ids = NULL; + SQLCHAR *cols = NULL; + SQLLEN *bufLenIds = NULL; + SQLLEN *bufLenCols = NULL; + SQLUSMALLINT *operptr = NULL; + SQLUSMALLINT *statusptr = NULL; + SQLULEN process = 0; + + // Data is constructed by column. Each column is stored continuously. + ids = (SQLINTEGER*)malloc(sizeof(ids[0]) * batchCount); + cols = (SQLCHAR*)malloc(sizeof(cols[0]) * batchCount * 50); + // Data size in each row for a column + bufLenIds = (SQLLEN*)malloc(sizeof(bufLenIds[0]) * batchCount); + bufLenCols = (SQLLEN*)malloc(sizeof(bufLenCols[0]) * batchCount); + // Whether this row needs to be processed. The value is SQL_PARAM_IGNORE or SQL_PARAM_PROCEED. + operptr = (SQLUSMALLINT*)malloc(sizeof(operptr[0]) * batchCount); + memset(operptr, 0, sizeof(operptr[0]) * batchCount); + // Processing result of the row + // Note: In the database, a statement belongs to one transaction. Therefore, data is processed as a unit. Either all data is inserted successfully or all data fails to be inserted. + statusptr = (SQLUSMALLINT*)malloc(sizeof(statusptr[0]) * batchCount); + memset(statusptr, 88, sizeof(statusptr[0]) * batchCount); + + if (NULL == ids || NULL == cols || NULL == bufLenCols || NULL == bufLenIds) + { + fprintf(stderr, "FAILED:\tmalloc data memory failed\n"); + goto exit; + } + + for (int i = 0; i < batchCount; i++) + { + ids[i] = i; + sprintf(cols + 50 * i, "column test value %d", i); + bufLenIds[i] = sizeof(ids[i]); + bufLenCols[i] = strlen(cols + 50 * i); + operptr[i] = (i < ignoreCount) ? SQL_PARAM_IGNORE : SQL_PARAM_PROCEED; + } + + // Allocate Statement Handle + retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmtinesrt); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLAllocHandle failed"); + goto exit; + } + + // Prepare Statement + sql = (SQLCHAR*)"insert into test_odbc_batch_insert values(?, ?)"; + retcode = SQLPrepare(hstmtinesrt, (SQLCHAR*) sql, SQL_NTS); + sprintf((char*)loginfo, "SQLPrepare log: %s", (char*)sql); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLPrepare failed"); + goto exit; + } + + retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER)batchCount, sizeof(batchCount)); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLSetStmtAttr failed"); + goto exit; + } + + retcode = SQLBindParameter(hstmtinesrt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(ids[0]), 0,&(ids[0]), 0, bufLenIds); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLBindParameter failed"); + goto exit; + } + + retcode = SQLBindParameter(hstmtinesrt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 50, 50, cols, 50, bufLenCols); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLBindParameter failed"); + goto exit; + } + + retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAMS_PROCESSED_PTR, (SQLPOINTER)&process, sizeof(process)); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLSetStmtAttr failed"); + goto exit; + } + + retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAM_STATUS_PTR, (SQLPOINTER)statusptr, sizeof(statusptr[0]) * batchCount); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLSetStmtAttr failed"); + goto exit; + } + + retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAM_OPERATION_PTR, (SQLPOINTER)operptr, sizeof(operptr[0]) * batchCount); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLSetStmtAttr failed"); + goto exit; + } + + retcode = SQLExecute(hstmtinesrt); + sprintf((char*)loginfo, "SQLExecute stmt log: %s", (char*)sql); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute(hstmtinesrt) failed"); + goto exit; + + retcode = SQLRowCount(hstmtinesrt, &rowsCount); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLRowCount failed"); + goto exit; + } + + if (rowsCount != (batchCount - ignoreCount)) + { + sprintf(loginfo, "(batchCount - ignoreCount)(%d) != rowsCount(%d)", (batchCount - ignoreCount), rowsCount); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute failed"); + goto exit; + } + } + else + { + sprintf(loginfo, "(batchCount - ignoreCount)(%d) == rowsCount(%d)", (batchCount - ignoreCount), rowsCount); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute failed"); + goto exit; + } + } + + // check row number returned + if (rowsCount != process) + { + sprintf(loginfo, "process(%d) != rowsCount(%d)", process, rowsCount); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute failed"); + goto exit; + } + } + else + { + sprintf(loginfo, "process(%d) == rowsCount(%d)", process, rowsCount); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute failed"); + goto exit; + } + } + + for (int i = 0; i < batchCount; i++) + { + if (i < ignoreCount) + { + if (statusptr[i] != SQL_PARAM_UNUSED) + { + sprintf(loginfo, "statusptr[%d](%d) != SQL_PARAM_UNUSED", i, statusptr[i]); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute failed"); + goto exit; + } + } + } + else if (statusptr[i] != SQL_PARAM_SUCCESS) + { + sprintf(loginfo, "statusptr[%d](%d) != SQL_PARAM_SUCCESS", i, statusptr[i]); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute failed"); + goto exit; + } + } + } + + retcode = SQLFreeHandle(SQL_HANDLE_STMT, hstmtinesrt); + sprintf((char*)loginfo, "SQLFreeHandle hstmtinesrt"); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLFreeHandle failed"); + goto exit; + } + } + + +exit: + (void) printf ("\nComplete.\n"); + + // Connection + if (hdbc != SQL_NULL_HDBC) { + SQLDisconnect(hdbc); + SQLFreeHandle(SQL_HANDLE_DBC, hdbc); + } + + // Environment + if (henv != SQL_NULL_HENV) + SQLFreeHandle(SQL_HANDLE_ENV, henv); + + return 0; +} +``` + diff --git a/content/docs-lite/en/docs/Developerguide/odbc-interface-reference.md b/content/docs-lite/en/docs/Developerguide/odbc-interface-reference.md new file mode 100644 index 000000000..540615ca1 --- /dev/null +++ b/content/docs-lite/en/docs/Developerguide/odbc-interface-reference.md @@ -0,0 +1,49 @@ +# ODBC Interface Reference + +The ODBC interface is a set of API functions provided to users. This chapter describes its common interfaces. For details on other interfaces, see "ODBC Programmer's Reference" at MSDN \(https://msdn.microsoft.com/en-us/library/windows/desktop/ms714177\(v=vs.85\).aspx\). + +- **[SQLAllocEnv](sqlallocenv.md)** + +- **[SQLAllocConnect](sqlallocconnect.md)** + +- **[SQLAllocHandle](sqlallochandle.md)** + +- **[SQLAllocStmt](sqlallocstmt.md)** + +- **[SQLBindCol](sqlbindcol.md)** + +- **[SQLBindParameter](sqlbindparameter.md)** + +- **[SQLColAttribute](sqlcolattribute.md)** + +- **[SQLConnect](sqlconnect.md)** + +- **[SQLDisconnect](sqldisconnect.md)** + +- **[SQLExecDirect](sqlexecdirect.md)** + +- **[SQLExecute](sqlexecute.md)** + +- **[SQLFetch](sqlfetch.md)** + +- **[SQLFreeStmt](sqlfreestmt.md)** + +- **[SQLFreeConnect](sqlfreeconnect.md)** + +- **[SQLFreeHandle](sqlfreehandle.md)** + +- **[SQLFreeEnv](sqlfreeenv.md)** + +- **[SQLPrepare](sqlprepare.md)** + +- **[SQLGetData](sqlgetdata.md)** + +- **[SQLGetDiagRec](sqlgetdiagrec.md)** + +- **[SQLSetConnectAttr](sqlsetconnectattr.md)** + +- **[SQLSetEnvAttr](sqlsetenvattr.md)** + +- **[SQLSetStmtAttr](sqlsetstmtattr.md)** + +- **[Examples](example-odbc.md)** diff --git a/content/docs-lite/en/docs/Developerguide/odbc-packages-dependent-libraries-and-header-files.md b/content/docs-lite/en/docs/Developerguide/odbc-packages-dependent-libraries-and-header-files.md new file mode 100644 index 000000000..5aab997df --- /dev/null +++ b/content/docs-lite/en/docs/Developerguide/odbc-packages-dependent-libraries-and-header-files.md @@ -0,0 +1,6 @@ +# ODBC Packages, Dependent Libraries, and Header Files + +## ODBC Packages for the Linux OS + +Obtain the **openGauss-\*.\*.0-ODBC.tar.gz** package from the release package. In the Linux OS, header files \(including **sql.h** and **sqlext.h**\) and a library file \(**libodbc.so**\) are required in application development. The header files and library file can be obtained from the **unixODBC-2.3.0** installation package. + diff --git a/content/docs-lite/en/docs/Developerguide/typical-application-scenarios-and-configurations.md b/content/docs-lite/en/docs/Developerguide/typical-application-scenarios-and-configurations.md new file mode 100644 index 000000000..0d4095693 --- /dev/null +++ b/content/docs-lite/en/docs/Developerguide/typical-application-scenarios-and-configurations.md @@ -0,0 +1,492 @@ +# Typical Application Scenarios and Configurations + +## Log Diagnosis Scenario + +ODBC logs are classified into unixODBC driver manager logs and psqlODBC driver logs. The former is used to trace whether the application API is successfully executed, and the latter is used to locate problems based on DFX logs generated during underlying implementation. + +The unixODBC log needs to be configured in the **odbcinst.ini** file: + +``` +[ODBC] +Trace=Yes +TraceFile=/path/to/odbctrace.log + +[GaussMPP] +Driver64=/usr/local/lib/psqlodbcw.so +setup=/usr/local/lib/psqlodbcw.so +``` + +You only need to add the following information to the **odbc.ini** file: + +``` +[gaussdb] +Driver=GaussMPP +Servername=10.10.0.13 (database server IP address) +... +Debug=1 (Enable the debug log function of the driver.) +``` + +>![](public_sys-resources/icon-note.gif) **NOTE:** +>The unixODBC logs are generated in the path configured by **TraceFile**. The psqlODBC generates the **mylog\_**_xxx_**.log** file in the **/tmp/** directory. + +## High Performance + +If a large amount of data needs to be inserted, you are advised to perform the following operations: + +- You need to set **UseBatchProtocol** to **1** in the **odbc.ini** file and **support\_batch\_bind** to **on** in the database. +- The ODBC program binding type must be the same as that in the database. +- The character set of the client is the same as that of the database. +- The transaction is committed manually. + +**odbc.ini** configuration file: + +``` +[gaussdb] +Driver=GaussMPP +Servername=10.10.0.13 (database server IP address) +... +UseBatchProtocol=1 (enabled by default) +ConnSettings=set client_encoding=UTF8 (Set the character code on the client to be the same as that on the server.) +``` + +Binding type case: + +``` +#include +#include +#include +#include +#include +#include + +#define MESSAGE_BUFFER_LEN 128 +SQLHANDLE h_env = NULL; +SQLHANDLE h_conn = NULL; +SQLHANDLE h_stmt = NULL; +void print_error() +{ + SQLCHAR Sqlstate[SQL_SQLSTATE_SIZE+1]; + SQLINTEGER NativeError; + SQLCHAR MessageText[MESSAGE_BUFFER_LEN]; + SQLSMALLINT TextLength; + SQLRETURN ret = SQL_ERROR; + + ret = SQLGetDiagRec(SQL_HANDLE_STMT, h_stmt, 1, Sqlstate, &NativeError, MessageText, MESSAGE_BUFFER_LEN, &TextLength); + if ( SQL_SUCCESS == ret) + { + printf("\n STMT ERROR-%05d %s", NativeError, MessageText); + return; + } + + ret = SQLGetDiagRec(SQL_HANDLE_DBC, h_conn, 1, Sqlstate, &NativeError, MessageText, MESSAGE_BUFFER_LEN, &TextLength); + if ( SQL_SUCCESS == ret) + { + printf("\n CONN ERROR-%05d %s", NativeError, MessageText); + return; + } + + ret = SQLGetDiagRec(SQL_HANDLE_ENV, h_env, 1, Sqlstate, &NativeError, MessageText, MESSAGE_BUFFER_LEN, &TextLength); + if ( SQL_SUCCESS == ret) + { + printf("\n ENV ERROR-%05d %s", NativeError, MessageText); + return; + } + + return; +} + +/* Expect the function to return SQL_SUCCESS. */ +#define RETURN_IF_NOT_SUCCESS(func) \ +{\ + SQLRETURN ret_value = (func);\ + if (SQL_SUCCESS != ret_value)\ + {\ + print_error();\ + printf("\n failed line = %u: expect SQL_SUCCESS, but ret = %d", __LINE__, ret_value);\ + return SQL_ERROR; \ + }\ +} + +/* Expect the function to return SQL_SUCCESS. */ +#define RETURN_IF_NOT_SUCCESS_I(i, func) \ +{\ + SQLRETURN ret_value = (func);\ + if (SQL_SUCCESS != ret_value)\ + {\ + print_error();\ + printf("\n failed line = %u (i=%d): : expect SQL_SUCCESS, but ret = %d", __LINE__, (i), ret_value);\ + return SQL_ERROR; \ + }\ +} + +/* Expect the function to return SQL_SUCCESS_WITH_INFO. */ +#define RETURN_IF_NOT_SUCCESS_INFO(func) \ +{\ + SQLRETURN ret_value = (func);\ + if (SQL_SUCCESS_WITH_INFO != ret_value)\ + {\ + print_error();\ + printf("\n failed line = %u: expect SQL_SUCCESS_WITH_INFO, but ret = %d", __LINE__, ret_value);\ + return SQL_ERROR; \ + }\ +} + +/* Expect the values are the same. */ +#define RETURN_IF_NOT(expect, value) \ +if ((expect) != (value))\ +{\ + printf("\n failed line = %u: expect = %u, but value = %u", __LINE__, (expect), (value)); \ + return SQL_ERROR;\ +} + +/* Expect the character strings are the same. */ +#define RETURN_IF_NOT_STRCMP_I(i, expect, value) \ +if (( NULL == (expect) ) || (NULL == (value)))\ +{\ + printf("\n failed line = %u (i=%u): input NULL pointer !", __LINE__, (i)); \ + return SQL_ERROR; \ +}\ +else if (0 != strcmp((expect), (value)))\ +{\ + printf("\n failed line = %u (i=%u): expect = %s, but value = %s", __LINE__, (i), (expect), (value)); \ + return SQL_ERROR;\ +} + + +// prepare + execute SQL statement +int execute_cmd(SQLCHAR *sql) +{ + if ( NULL == sql ) + { + return SQL_ERROR; + } + + if ( SQL_SUCCESS != SQLPrepare(h_stmt, sql, SQL_NTS)) + { + return SQL_ERROR; + } + + if ( SQL_SUCCESS != SQLExecute(h_stmt)) + { + return SQL_ERROR; + } + + return SQL_SUCCESS; +} +// execute + commit handle +int commit_exec() +{ + if ( SQL_SUCCESS != SQLExecute(h_stmt)) + { + return SQL_ERROR; + } + + // Manual committing + if ( SQL_SUCCESS != SQLEndTran(SQL_HANDLE_DBC, h_conn, SQL_COMMIT)) + { + return SQL_ERROR; + } + + return SQL_SUCCESS; +} + +int begin_unit_test() +{ + SQLINTEGER ret; + + /* Allocate an environment handle. */ + ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &h_env); + if ((SQL_SUCCESS != ret) && (SQL_SUCCESS_WITH_INFO != ret)) + { + printf("\n begin_unit_test::SQLAllocHandle SQL_HANDLE_ENV failed ! ret = %d", ret); + return SQL_ERROR; + } + + /* Set the version number before connection. */ + if (SQL_SUCCESS != SQLSetEnvAttr(h_env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0)) + { + print_error(); + printf("\n begin_unit_test::SQLSetEnvAttr SQL_ATTR_ODBC_VERSION failed ! ret = %d", ret); + SQLFreeHandle(SQL_HANDLE_ENV, h_env); + return SQL_ERROR; + } + + /* Allocate a connection handle. */ + ret = SQLAllocHandle(SQL_HANDLE_DBC, h_env, &h_conn); + if (SQL_SUCCESS != ret) + { + print_error(); + printf("\n begin_unit_test::SQLAllocHandle SQL_HANDLE_DBC failed ! ret = %d", ret); + SQLFreeHandle(SQL_HANDLE_ENV, h_env); + return SQL_ERROR; + } + + /* Establish a connection. */ + ret = SQLConnect(h_conn, (SQLCHAR*) "gaussdb", SQL_NTS, + (SQLCHAR*) NULL, 0, NULL, 0); + if (SQL_SUCCESS != ret) + { + print_error(); + printf("\n begin_unit_test::SQLConnect failed ! ret = %d", ret); + SQLFreeHandle(SQL_HANDLE_DBC, h_conn); + SQLFreeHandle(SQL_HANDLE_ENV, h_env); + return SQL_ERROR; + } + + /* Allocate a statement handle. */ + ret = SQLAllocHandle(SQL_HANDLE_STMT, h_conn, &h_stmt); + if (SQL_SUCCESS != ret) + { + print_error(); + printf("\n begin_unit_test::SQLAllocHandle SQL_HANDLE_STMT failed ! ret = %d", ret); + SQLFreeHandle(SQL_HANDLE_DBC, h_conn); + SQLFreeHandle(SQL_HANDLE_ENV, h_env); + return SQL_ERROR; + } + + return SQL_SUCCESS; +} + +void end_unit_test() +{ + /* Release a statement handle. */ + if (NULL != h_stmt) + { + SQLFreeHandle(SQL_HANDLE_STMT, h_stmt); + } + + /* Release a connection handle. */ + if (NULL != h_conn) + { + SQLDisconnect(h_conn); + SQLFreeHandle(SQL_HANDLE_DBC, h_conn); + } + + /* Release an environment handle. */ + if (NULL != h_env) + { + SQLFreeHandle(SQL_HANDLE_ENV, h_env); + } + + return; +} + +int main() +{ + // begin test + if (begin_unit_test() != SQL_SUCCESS) + { + printf("\n begin_test_unit failed."); + return SQL_ERROR; + } + // The handle configuration is the same as that in the preceding case + int i = 0; + SQLCHAR* sql_drop = "drop table if exists test_bindnumber_001"; + SQLCHAR* sql_create = "create table test_bindnumber_001(" + "f4 number, f5 number(10, 2)" + ")"; + SQLCHAR* sql_insert = "insert into test_bindnumber_001 values(?, ?)"; + SQLCHAR* sql_select = "select * from test_bindnumber_001"; + SQLLEN RowCount; + SQL_NUMERIC_STRUCT st_number; + SQLCHAR getValue[2][MESSAGE_BUFFER_LEN]; + + /* Step 1. Create a table. */ + RETURN_IF_NOT_SUCCESS(execute_cmd(sql_drop)); + RETURN_IF_NOT_SUCCESS(execute_cmd(sql_create)); + + /* Step 2.1 Bind parameters using the SQL_NUMERIC_STRUCT structure. */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + + // First line: 1234.5678 + memset(st_number.val, 0, SQL_MAX_NUMERIC_LEN); + st_number.precision = 8; + st_number.scale = 4; + st_number.sign = 1; + st_number.val[0] = 0x4E; + st_number.val[1] = 0x61; + st_number.val[2] = 0xBC; + + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_NUMERIC, SQL_NUMERIC, sizeof(SQL_NUMERIC_STRUCT), 4, &st_number, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_NUMERIC, SQL_NUMERIC, sizeof(SQL_NUMERIC_STRUCT), 4, &st_number, 0, NULL)); + + // Disable the automatic commit function. + SQLSetConnectAttr(h_conn, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0); + + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + // Second line: 12345678 + memset(st_number.val, 0, SQL_MAX_NUMERIC_LEN); + st_number.precision = 8; + st_number.scale = 0; + st_number.sign = 1; + st_number.val[0] = 0x4E; + st_number.val[1] = 0x61; + st_number.val[2] = 0xBC; + + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_NUMERIC, SQL_NUMERIC, sizeof(SQL_NUMERIC_STRUCT), 0, &st_number, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_NUMERIC, SQL_NUMERIC, sizeof(SQL_NUMERIC_STRUCT), 0, &st_number, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + // Third line: 12345678 + memset(st_number.val, 0, SQL_MAX_NUMERIC_LEN); + st_number.precision = 0; + st_number.scale = 4; + st_number.sign = 1; + st_number.val[0] = 0x4E; + st_number.val[1] = 0x61; + st_number.val[2] = 0xBC; + + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_NUMERIC, SQL_NUMERIC, sizeof(SQL_NUMERIC_STRUCT), 4, &st_number, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_NUMERIC, SQL_NUMERIC, sizeof(SQL_NUMERIC_STRUCT), 4, &st_number, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + + /* Step 2.2 Bind parameters by using the SQL_C_CHAR character string in the fourth line. */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + SQLCHAR* szNumber = "1234.5678"; + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_NUMERIC, strlen(szNumber), 0, szNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_NUMERIC, strlen(szNumber), 0, szNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + /* Step 2.3 Bind parameters by using SQL_C_FLOAT in the fifth line. */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + SQLREAL fNumber = 1234.5678; + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_NUMERIC, sizeof(fNumber), 4, &fNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_NUMERIC, sizeof(fNumber), 4, &fNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + /* Step 2.4 Bind parameters by using SQL_C_DOUBLE in the sixth line. */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + SQLDOUBLE dNumber = 1234.5678; + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_NUMERIC, sizeof(dNumber), 4, &dNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_NUMERIC, sizeof(dNumber), 4, &dNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + SQLBIGINT bNumber1 = 0xFFFFFFFFFFFFFFFF; + SQLBIGINT bNumber2 = 12345; + + /* Step 2.5 Bind parameters by using SQL_C_SBIGINT in the seventh line. */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_SBIGINT, SQL_NUMERIC, sizeof(bNumber1), 4, &bNumber1, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_SBIGINT, SQL_NUMERIC, sizeof(bNumber2), 4, &bNumber2, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + /* Step 2.6 Bind parameters by using SQL_C_UBIGINT in the eighth line. */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_UBIGINT, SQL_NUMERIC, sizeof(bNumber1), 4, &bNumber1, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_UBIGINT, SQL_NUMERIC, sizeof(bNumber2), 4, &bNumber2, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + SQLLEN lNumber1 = 0xFFFFFFFFFFFFFFFF; + SQLLEN lNumber2 = 12345; + + /* Step 2.7 Bind parameters by using SQL_C_LONG in the ninth line. */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_NUMERIC, sizeof(lNumber1), 0, &lNumber1, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_NUMERIC, sizeof(lNumber2), 0, &lNumber2, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + /* Step 2.8 Bind parameters by using SQL_C_ULONG in the tenth line. */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_NUMERIC, sizeof(lNumber1), 0, &lNumber1, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_NUMERIC, sizeof(lNumber2), 0, &lNumber2, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + SQLSMALLINT sNumber = 0xFFFF; + + /* Step 2.9 Bind parameters by using SQL_C_SHORT in the eleventh line. */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_SHORT, SQL_NUMERIC, sizeof(sNumber), 0, &sNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_SHORT, SQL_NUMERIC, sizeof(sNumber), 0, &sNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + /* Step 2.10 Bind parameters by using SQL_C_USHORT in the twelfth line. */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_NUMERIC, sizeof(sNumber), 0, &sNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_NUMERIC, sizeof(sNumber), 0, &sNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + SQLCHAR cNumber = 0xFF; + + /* Step 2.11 Bind parameters by using SQL_C_TINYINT in the thirteenth line. */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_TINYINT, SQL_NUMERIC, sizeof(cNumber), 0, &cNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_TINYINT, SQL_NUMERIC, sizeof(cNumber), 0, &cNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + /* Step 2.12 Bind parameters by using SQL_C_UTINYINT in the fourteenth line.*/ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_UTINYINT, SQL_NUMERIC, sizeof(cNumber), 0, &cNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_UTINYINT, SQL_NUMERIC, sizeof(cNumber), 0, &cNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + /* Use the character string type to unify the expectation. */ + SQLCHAR* expectValue[14][2] = {{"1234.5678", "1234.57"}, + {"12345678", "12345678"}, + {"0", "0"}, + {"1234.5678", "1234.57"}, + {"1234.5677", "1234.57"}, + {"1234.5678", "1234.57"}, + {"-1", "12345"}, + {"18446744073709551615", "12345"}, + {"-1", "12345"}, + {"4294967295", "12345"}, + {"-1", "-1"}, + {"65535", "65535"}, + {"-1", "-1"}, + {"255", "255"}, + }; + + RETURN_IF_NOT_SUCCESS(execute_cmd(sql_select)); + while ( SQL_NO_DATA != SQLFetch(h_stmt)) + { + RETURN_IF_NOT_SUCCESS_I(i, SQLGetData(h_stmt, 1, SQL_C_CHAR, &getValue[0], MESSAGE_BUFFER_LEN, NULL)); + RETURN_IF_NOT_SUCCESS_I(i, SQLGetData(h_stmt, 2, SQL_C_CHAR, &getValue[1], MESSAGE_BUFFER_LEN, NULL)); + + //RETURN_IF_NOT_STRCMP_I(i, expectValue[i][0], getValue[0]); + //RETURN_IF_NOT_STRCMP_I(i, expectValue[i][1], getValue[1]); + i++; + } + + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(i, RowCount); + SQLCloseCursor(h_stmt); + /* Final step. Delete the table and restore the environment. */ + RETURN_IF_NOT_SUCCESS(execute_cmd(sql_drop)); + + end_unit_test(); +} +``` + +>![](public_sys-resources/icon-note.gif) **NOTE:** +>In the preceding example, the number column is defined. When the **SQLBindParameter** API is called, the performance of binding SQL\_NUMERIC is higher than that of SQL\_LONG. If char is used, the data type needs to be converted when data is inserted to the database server, causing a performance bottleneck. + diff --git a/content/docs-lite/en/menu/index.md b/content/docs-lite/en/menu/index.md index 4571c280e..aff1602c7 100644 --- a/content/docs-lite/en/menu/index.md +++ b/content/docs-lite/en/menu/index.md @@ -235,30 +235,36 @@ headless: true - [JDBC Interface Reference]({{< relref "./docs/DeveloperGuide/jdbc-interface-reference.md" >}}) - [Common JDBC Parameters]({{< relref "./docs/DeveloperGuide/common-jdbc-parameters.md" >}}) - [Development Based on ODBC]({{< relref "./docs/Developerguide/odbc.md" >}}) - - [SQLAllocEnv]({{< relref "./docs/Developerguide/sqlallocenv.md" >}}) - - [SQLAllocConnect]({{< relref "./docs/Developerguide/sqlallocconnect.md" >}}) - - [SQLAllocHandle]({{< relref "./docs/Developerguide/sqlallochandle.md" >}}) - - [SQLAllocStmt]({{< relref "./docs/Developerguide/sqlallocstmt.md" >}}) - - [SQLBindCol]({{< relref "./docs/Developerguide/sqlbindcol.md" >}}) - - [SQLBindParameter]({{< relref "./docs/Developerguide/sqlbindparameter.md" >}}) - - [SQLColAttribute]({{< relref "./docs/Developerguide/sqlcolattribute.md" >}}) - - [SQLConnect]({{< relref "./docs/Developerguide/sqlconnect.md" >}}) - - [SQLDisconnect]({{< relref "./docs/Developerguide/sqldisconnect.md" >}}) - - [SQLExecDirect]({{< relref "./docs/Developerguide/sqlexecdirect.md" >}}) - - [SQLExecute]({{< relref "./docs/Developerguide/sqlexecute.md" >}}) - - [SQLFetch]({{< relref "./docs/Developerguide/sqlfetch.md" >}}) - - [SQLFreeStmt]({{< relref "./docs/Developerguide/sqlfreestmt.md" >}}) - - [SQLFreeConnect]({{< relref "./docs/Developerguide/sqlfreeconnect.md" >}}) - - [SQLFreeHandle]({{< relref "./docs/Developerguide/sqlfreehandle.md" >}}) - - [SQLFreeEnv]({{< relref "./docs/Developerguide/sqlfreeenv.md" >}}) - - [SQLPrepare]({{< relref "./docs/Developerguide/sqlprepare.md" >}}) - - [SQLGetData]({{< relref "./docs/Developerguide/sqlgetdata.md" >}}) - - [SQLGetDiagRec]({{< relref "./docs/Developerguide/sqlgetdiagrec.md" >}}) - - [SQLSetConnectAttr]({{< relref "./docs/Developerguide/sqlsetconnectattr.md" >}}) - - [SQLSetEnvAttr]({{< relref "./docs/Developerguide/sqlsetenvattr.md" >}}) - - [SQLSetStmtAttr]({{< relref "./docs/Developerguide/sqlsetstmtattr.md" >}}) - - [Example]({{< relref "./docs/Developerguide/example-odbc.md" >}}) - - [Development Based on libpq]({{< relref "./docs/DeveloperGuide/development-based-on-libpq.md" >}}) + - [ODBC Packages, Dependent Libraries, and Header Files]({{< relref "./docs/DeveloperGuide/odbc-packages-dependent-libraries-and-header-files.md" >}}) + - [Configuring a Data Source in the Linux OS]({{< relref "./docs/DeveloperGuide/configuring-a-data-source-in-the-linux-os.md" >}}) + - [Development Process]({{< relref "./docs/DeveloperGuide/development-process-odbc.md" >}}) + - [Example: Common Functions and Batch Binding]({{< relref "./docs/DeveloperGuide/example-common-functions-and-batch-binding.md" >}}) + - [Typical Application Scenarios and Configurations]({{< relref "./docs/DeveloperGuide/typical-application-scenarios-and-configurations.md" >}}) + - [ODBC Interface Reference]({{< relref "./docs/DeveloperGuide/odbc-interface-reference.md" >}}) + - [SQLAllocEnv]({{< relref "./docs/Developerguide/sqlallocenv.md" >}}) + - [SQLAllocConnect]({{< relref "./docs/Developerguide/sqlallocconnect.md" >}}) + - [SQLAllocHandle]({{< relref "./docs/Developerguide/sqlallochandle.md" >}}) + - [SQLAllocStmt]({{< relref "./docs/Developerguide/sqlallocstmt.md" >}}) + - [SQLBindCol]({{< relref "./docs/Developerguide/sqlbindcol.md" >}}) + - [SQLBindParameter]({{< relref "./docs/Developerguide/sqlbindparameter.md" >}}) + - [SQLColAttribute]({{< relref "./docs/Developerguide/sqlcolattribute.md" >}}) + - [SQLConnect]({{< relref "./docs/Developerguide/sqlconnect.md" >}}) + - [SQLDisconnect]({{< relref "./docs/Developerguide/sqldisconnect.md" >}}) + - [SQLExecDirect]({{< relref "./docs/Developerguide/sqlexecdirect.md" >}}) + - [SQLExecute]({{< relref "./docs/Developerguide/sqlexecute.md" >}}) + - [SQLFetch]({{< relref "./docs/Developerguide/sqlfetch.md" >}}) + - [SQLFreeStmt]({{< relref "./docs/Developerguide/sqlfreestmt.md" >}}) + - [SQLFreeConnect]({{< relref "./docs/Developerguide/sqlfreeconnect.md" >}}) + - [SQLFreeHandle]({{< relref "./docs/Developerguide/sqlfreehandle.md" >}}) + - [SQLFreeEnv]({{< relref "./docs/Developerguide/sqlfreeenv.md" >}}) + - [SQLPrepare]({{< relref "./docs/Developerguide/sqlprepare.md" >}}) + - [SQLGetData]({{< relref "./docs/Developerguide/sqlgetdata.md" >}}) + - [SQLGetDiagRec]({{< relref "./docs/Developerguide/sqlgetdiagrec.md" >}}) + - [SQLSetConnectAttr]({{< relref "./docs/Developerguide/sqlsetconnectattr.md" >}}) + - [SQLSetEnvAttr]({{< relref "./docs/Developerguide/sqlsetenvattr.md" >}}) + - [SQLSetStmtAttr]({{< relref "./docs/Developerguide/sqlsetstmtattr.md" >}}) + - [Example]({{< relref "./docs/Developerguide/example-odbc.md" >}}) + - [Development Based on libpq]({{< relref "./docs/DeveloperGuide/development-based-on-libpq.md" >}}) - [Dependent Header Files of libpq]({{< relref "./docs/DeveloperGuide/dependent-header-files-of-libpq.md" >}}) - [Development Process]({{< relref "./docs/DeveloperGuide/development-process-libpq.md" >}}) - [Example]({{< relref "./docs/DeveloperGuide/example-libpq.md" >}}) @@ -270,13 +276,13 @@ headless: true - [Loading a Driver]({{< relref "./docs/DeveloperGuide/loading-a-driver.md" >}}) - [Connecting to a Database]({{< relref "./docs/DeveloperGuide/connecting-to-a-database-psycopg.md" >}}) - [Executing SQL Statements]({{< relref "./docs/DeveloperGuide/executing-sql-statements.md" >}}) - - [Processing the Result Set]({{< relref "./docs/DeveloperGuide/processing-the-result-set.md" >}}) + - [Processing the Result Set]({{< relref "./docs/DeveloperGuide/processing-the-result-set.md" >}}) - [Closing the Connection]({{< relref "./docs/DeveloperGuide/closing-the-connection.md" >}}) - [Connecting to the Database (Using SSL)]({{< relref "./docs/DeveloperGuide/connecting-to-the-database-using-ssl-psycopg.md" >}}) - [Example: Common Operations]({{< relref "./docs/DeveloperGuide/example-common-operations-psycopg.md" >}}) - [Psycopg API Reference]({{< relref "./docs/DeveloperGuide/psycopg-api-reference.md" >}}) - [Commissioning]({{< relref "./docs/DeveloperGuide/commissioning.md" >}}) - + - [Compilation Guide]({{< relref "./docs/CompilationGuide/Compilation.md" >}}) - [Introduction]({{< relref "./docs/CompilationGuide/introduction.md" >}}) - [Setting up the Build Environment]({{< relref "./docs/CompilationGuide/setting-up-the-build-environment.md" >}}) @@ -1281,7 +1287,6 @@ headless: true - [pg\_controldata]({{< relref "./docs/ToolandCommandReference/pg_controldata.md" >}}) - [pg\_resetxlog]({{< relref "./docs/ToolandCommandReference/pg_resetxlog.md" >}}) - - [Database Reference]({{< relref "./docs/DatabaseReference/database-reference.md" >}}) - [System Catalogs and System Views]({{< relref "./docs/DatabaseReference/system-catalogs-and-system-views.md" >}}) - [Overview of System Catalogs and System Views]({{< relref "./docs/DatabaseReference/overview-of-system-catalogs-and-system-views.md" >}}) diff --git "a/content/docs-lite/zh/docs/DeveloperGuide/Linux\344\270\213\351\205\215\347\275\256\346\225\260\346\215\256\346\272\220.md" "b/content/docs-lite/zh/docs/DeveloperGuide/Linux\344\270\213\351\205\215\347\275\256\346\225\260\346\215\256\346\272\220.md" new file mode 100644 index 000000000..199d522ab --- /dev/null +++ "b/content/docs-lite/zh/docs/DeveloperGuide/Linux\344\270\213\351\205\215\347\275\256\346\225\260\346\215\256\346\272\220.md" @@ -0,0 +1,511 @@ +# Linux下配置数据源 + +将openGauss提供的ODBC DRIVER(psqlodbcw.so)配置到数据源中便可使用。配置数据源需要配置“odbc.ini”和“odbcinst.ini”两个文件(在编译安装unixODBC过程中生成且默认放在“/usr/local/etc”目录下),并在服务器端进行配置。 + +## 操作步骤 + +1. 获取unixODBC源码包。 + + 获取参考地址:https://sourceforge.net/projects/unixodbc/files/unixODBC + + 下载后请先按照社区提供的完整性校验算法进行完整性校验。 + +2. 安装unixODBC。如果机器上已经安装了其他版本的unixODBC,可以直接覆盖安装。 + + 目前不支持unixODBC-2.2.1版本。以unixODBC-2.3.0版本为例,在客户端执行如下命令安装unixODBC。默认安装到“/usr/local”目录下,生成数据源文件到 “/usr/local/etc”目录下,库文件生成在“/usr/local/lib”目录。 + + ``` + tar zxvf unixODBC-2.3.0.tar.gz + cd unixODBC-2.3.0 + #修改configure文件(如果不存在,那么请修改configure.ac),找到LIB_VERSION + #将它的值修改为"1:0:0",这样将编译出*.so.1的动态库,与psqlodbcw.so的依赖关系相同。 + vim configure + + ./configure --enable-gui=no #如果要在ARM服务器上编译,请追加一个configure参数: --build=aarch64-unknown-linux-gnu + make + #安装可能需要root权限 + make install + ``` + +3. 替换客户端openGauss驱动程序。 + 1. 将openGauss-x.x.x-ODBC.tar.gz解压。解压后会得到两个文件夹:lib与odbc,在odbc文件夹中还会有一个lib文件夹。/odbc/lib中会有“psqlodbca.la”,“psqlodbca.so”,“psqlodbcw.la”和“psqlodbcw.so”四个文件,将这四个文件拷贝到“/usr/local/lib”目录下。 + 2. 将openGauss-x.x.x-ODBC.tar.gz解压后lib目录中的库拷贝到“/usr/local/lib”目录下。 + +4. 配置数据源。 + 1. 配置ODBC驱动文件。 + + 在“/usr/local/etc/odbcinst.ini”文件中追加以下内容。 + + ``` + [GaussMPP] + Driver64=/usr/local/lib/psqlodbcw.so + setup=/usr/local/lib/psqlodbcw.so + ``` + + odbcinst.ini文件中的配置参数说明如[表1](#zh-cn_topic_0283136654_zh-cn_topic_0237120407_zh-cn_topic_0059778464_td564f21e7c8e458bbd741b09896f5d91)所示。 + + **表 1** odbcinst.ini文件配置参数 + + + + + + + + + + + + + + + + + + + + +

参数

+

描述

+

示例

+

[DriverName]

+

驱动器名称,对应数据源DSN中的驱动名。

+

[DRIVER_N]

+

Driver64

+

驱动动态库的路径。

+

Driver64=/usr/local/lib/psqlodbcw.so

+

setup

+

驱动安装路径,与Driver64中动态库的路径一致。

+

setup=/usr/local/lib/psqlodbcw.so

+
+ + 2. 配置数据源文件。 + + 在“/usr/local/etc/odbc.ini”文件中追加以下内容。 + + ``` + [MPPODBC] + Driver=GaussMPP + Servername=10.145.130.26(数据库Server IP) + Database=postgres (数据库名) + Username=omm (数据库用户名) + Password= (数据库用户密码) + Port=8000 (数据库侦听端口) + Sslmode=allow + ``` + + odbc.ini文件配置参数说明如[表2](#zh-cn_topic_0283136654_zh-cn_topic_0237120407_zh-cn_topic_0059778464_t55845a6555f2454297b64ce47ad3d648)所示。 + + **表 2** odbc.ini文件配置参数 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数

+

描述

+

示例

+

[DSN]

+

数据源的名称。

+

[MPPODBC]

+

Driver

+

驱动名,对应odbcinst.ini中的DriverName。

+

Driver=DRIVER_N

+

Servername

+

服务器的IP地址。可配置多个IP地址。

+

Servername=10.145.130.26

+

Database

+

要连接的数据库的名称。

+

Database=postgres

+

Username

+

数据库用户名称。

+

Username=omm

+

Password

+

数据库用户密码。

+

Password=

+
说明:

ODBC驱动本身已经对内存密码进行过清理,以保证用户密码在连接后不会再在内存中保留。

+

但是如果配置了此参数,由于UnixODBC对数据源文件等进行缓存,可能导致密码长期保留在内存中。

+

推荐在应用程序连接时,将密码传递给相应API,而非写在数据源配置文件中。同时连接成功后,应当及时清理保存密码的内存段。

+
+

Port

+

服务器的端口号。

+

Port=8000

+

Sslmode

+

开启SSL模式

+

Sslmode=allow

+

Debug

+

设置为1时,将会打印psqlodbc驱动的mylog,日志生成目录为/tmp/。设置为0时则不会生成。

+

Debug=1

+

UseServerSidePrepare

+

是否开启数据库端扩展查询协议。

+

可选值0或1,默认为1,表示打开扩展查询协议。

+

UseServerSidePrepare=1

+

UseBatchProtocol

+

是否开启批量查询协议(打开可提高DML性能);可选值0或者1,默认为1。

+

当此值为0时,不使用批量查询协议(主要用于与早期数据库版本通信兼容)。

+

当此值为1,并且数据库support_batch_bind参数存在且为on时,将打开批量查询协议。

+

UseBatchProtocol=1

+

ForExtensionConnector

+

这个开关控制着savepoint是否发送,savepoint相关问题可以注意这个开关。

+

ForExtensionConnector=1

+

UnamedPrepStmtThreshold

+

每次调用SQLFreeHandle释放Stmt时,ODBC都会向server端发送一个Deallocate plan_name语句,业务中存在大量这类语句。为了减少这类语句的发送,我们将 stmt->plan_name置空,从而使得数据库识别这个为unamed stmt。增加这个参数对unamed stmt的阈值进行控制。

+

UnamedPrepStmtThreshold=100

+

ConnectionExtraInfo

+

GUC参数connection_info(参见connection_info)中显示驱动部署路径和进程属主用户的开关。

+

ConnectionExtraInfo=1

+
说明:

默认值为0。当设置为1时,ODBC驱动会将当前驱动的部署路径、进程属主用户上报到数据库中,记录在connection_info参数(参见connection_info)里;同时可以在PG_STAT_ACTIVITY中查询到。

+
+

BoolAsChar

+

设置为Yes是,Bools值将会映射为SQL_CHAR。如不设置将会映射为SQL_BIT。

+

BoolsAsChar = Yes

+

RowVersioning

+

当尝试更新一行数据时,设置为Yes会允许应用检测数据有没有被其他用户进行修改。

+

RowVersioning=Yes

+

ShowSystemTables

+

驱动将会默认系统表格为普通SQL表格。

+

ShowSystemTables=Yes

+
+ + 其中关于Sslmode的选项的允许值,具体信息见下表: + + **表 3** Sslmode的可选项及其描述 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Sslmode

+

是否会启用SSL加密

+

描述

+

disable

+

+

不使用SSL安全连接。

+

allow

+

可能

+

如果数据库服务器要求使用,则可以使用SSL安全加密连接,但不验证数据库服务器的真实性。

+

prefer

+

可能

+

如果数据库支持,那么建议使用SSL安全加密连接,但不验证数据库服务器的真实性。

+

require

+

+

必须使用SSL安全连接,但是只做了数据加密,而并不验证数据库服务器的真实性。

+

verify-ca

+

+

必须使用SSL安全连接,并且验证数据库是否具有可信证书机构签发的证书。

+

verify-full

+

+

必须使用SSL安全连接,在verify-ca的验证范围之外,同时验证数据库所在主机的主机名是否与证书内容一致。openGauss不支持此模式。

+
+ +5. (可选)生成SSL证书,具体请参见[证书生成](../DatabaseAdministrationGuide/证书生成.md)。此步骤和6在服务端与客户端通过ssl方式连接的情况下需要执行。非ssl方式连接情况下可以跳过。 +6. (可选)替换SSL证书,具体请参见[证书替换](../DatabaseAdministrationGuide/证书替换.md)。 +7. SSL模式: + + 声明如下环境变量,同时保证client.key\*系列文件为600权限: + + ``` + 退回根目录,创建.postgresql目录,并将root.crt,client.crt,client.key,client.key.cipher,client.key.rand,client.req,server.crt,server.key,server.key.cipher,server.key.rand,server.req放在此路径下。 + Unix系统下,server.crt、server.key的权限设置必须禁止任何外部或组的访问,请执行如下命令实现这一点。 + chmod 600 server.key + 将root.crt以及server开头的证书相关文件全部拷贝进数据库install/data目录下(与postgresql.conf文件在同一路径)。 + 修改postgresql.conf文件: + ssl = on + ssl_cert_file = 'server.crt' + ssl_key_file = 'server.key' + ssl_ca_file = 'root.crt' + 修改完参数后需重启数据库。 + 修改配置文件odbc.ini中的sslmode参数(require或verify-ca)。 + ``` + +8. 配置数据库服务器。 + 1. 以操作系统用户omm登录数据库主节点。 + 2. 执行如下命令增加对外提供服务的网卡IP或者主机名(英文逗号分隔),其中NodeName为当前节点名称: + + ``` + gs_guc reload -N NodeName -I all -c "listen_addresses='localhost,192.168.0.100,10.11.12.13'" + ``` + + 在DR(Direct Routing,LVS的直接路由DR模式)模式中需要将虚拟IP地址(10.11.12.13)加入到服务器的侦听地址列表中。 + + listen\_addresses也可以配置为“\*”或“0.0.0.0”,此配置下将侦听所有网卡,但存在安全风险,不推荐用户使用,推荐用户按照需要配置IP或者主机名,打开侦听。 + + 3. 执行如下命令在数据库主节点配置文件中增加一条认证规则。(这里假设客户端IP地址为10.11.12.13,即远程连接的机器的IP地址) + + ``` + gs_guc reload -N all -I all -h "host all jack 10.11.12.13/32 sha256" + ``` + + >![](public_sys-resources/icon-note.gif) **说明:** + > + >- -N all表示openGauss中的所有主机。 + >- -I all表示主机中的所有实例。 + >- -h表示指定需要在“pg\_hba.conf”增加的语句。 + >- all表示允许客户端连接到任意的数据库。 + >- jack表示连接数据库的用户。 + >- 10.11.12.13/_32_表示只允许IP地址为10.11.12.13的主机连接。在使用过程中,请根据用户的网络进行配置修改。32表示子网掩码为1的位数,即255.255.255.255。 + >- sha256表示连接时jack用户的密码使用sha256算法加密。 + + 如果将ODBC客户端配置在和要连接的数据库主节点在同一台机器上,则可使用local trust认证方式,如下: + + ``` + local all all trust + ``` + + 如果将ODBC客户端配置在和要连接的数据库主节点在不同机器上,则需要使用sha256认证方式,如下: + + ``` + host all all xxx.xxx.xxx.xxx/32 sha256 + ``` + + 4. 重启openGauss。 + + ``` + gs_om -t stop + gs_om -t start + ``` + +9. 在客户端配置环境变量。 + + ``` + vim ~/.bashrc + ``` + + 在配置文件中追加以下内容。 + + ``` + export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH + export ODBCSYSINI=/usr/local/etc + export ODBCINI=/usr/local/etc/odbc.ini + ``` + +10. 执行如下命令使设置生效。 + + ``` + source ~/.bashrc + ``` + + +## 测试数据源配置 + +安装后/usr/bin下面会存放生成的二进制,可执行./isql -v MPPODBC(数据源名称)命令。 + +- 如果显示如下信息,表明配置正确,连接成功。 + + ``` + +---------------------------------------+ + | Connected! | + | | + | sql-statement | + | help [tablename] | + | quit | + | | + +---------------------------------------+ + SQL> + ``` + +- 若显示ERROR信息,则表明配置错误。请检查上述配置是否正确。 + +## 常见问题处理 + +- \[UnixODBC\]\[Driver Manager\]Can't open lib 'xxx/xxx/psqlodbcw.so' : file not found. + + 此问题的可能原因: + + - odbcinst.ini文件中配置的路径不正确 + + 确认的方法:'ls'一下错误信息中的路径,以确保该psqlodbcw.so文件存在,同时具有执行权限。 + + - psqlodbcw.so的依赖库不存在,或者不在系统环境变量中 + + 确认的办法:ldd一下错误信息中的路径,如果是缺少libodbc.so.1等UnixODBC的库,那么按照“操作步骤”中的方法重新配置UnixODBC,并确保它的安装路径下的lib目录添加到了LD\_LIBRARY\_PATH中;如果是缺少其他库,请将ODBC驱动包中的lib目录添加到LD\_LIBRARY\_PATH中。 + + +- \[UnixODBC\]connect to server failed: no such file or directory + + 此问题可能的原因: + + - 配置了错误的/不可达的数据库地址,或者端口 + + 请检查数据源配置中的Servername及Port配置项。 + + - 服务器侦听不正确 + + 如果确认Servername及Port配置正确,请根据“操作步骤”中数据库服务器的相关配置,确保数据库侦听了合适的网卡及端口。 + + - 防火墙及网闸设备 + + 请确认防火墙设置,将数据库的通信端口添加到可信端口中。 + + 如果有网闸设备,请确认一下相关的设置。 + + +- \[unixODBC\]The password-stored method is not supported. + + 此问题可能原因: + + 数据源中未配置sslmode配置项。 + + 解决办法: + + 请配置该选项至allow或以上选项。此配置的更多信息,见[表3](#zh-cn_topic_0283136654_zh-cn_topic_0237120407_zh-cn_topic_0059778464_table22136585143846)。 + +- Server common name "xxxx" does not match host name "xxxxx" + + 此问题的原因: + + 使用了SSL加密的“verify-full”选项,驱动程序会验证证书中的主机名与实际部署数据库的主机名是否一致。 + + 解决办法: + + 碰到此问题可以使用“verify-ca”选项,不再校验主机名;或者重新生成一套与数据库所在主机名相同的CA证书。 + +- Driver's SQLAllocHandle on SQL\_HANDLE\_DBC failed + + 此问题的可能原因: + + 可执行文件(比如UnixODBC的isql,以下都以isql为例)与数据库驱动(psqlodbcw.so)依赖于不同的odbc的库版本:libodbc.so.1或者libodbc.so.2。此问题可以通过如下方式确认: + + ``` + ldd `which isql` | grep odbc + ldd psqlodbcw.so | grep odbc + ``` + + 这时,如果输出的libodbc.so最后的后缀数字不同或者指向不同的磁盘物理文件,那么基本就可以断定是此问题。isql与psqlodbcw.so都会要求加载libodbc.so,这时如果它们加载的是不同的物理文件,便会导致两套完全同名的函数列表,同时出现在同一个可见域里(UnixODBC的libodbc.so.\*的函数导出列表完全一致),产生冲突,无法加载数据库驱动。 + + 解决办法: + + 确定一个要使用的UnixODBC,然后卸载另外一个(比如卸载库版本号为.so.2的UnixODBC),然后将剩下的.so.1的库,新建一个同名但是后缀为.so.2的软链接,便可解决此问题。 + +- FATAL: Forbid remote connection with trust method! + + 由于安全原因,数据库主节点禁止openGauss内部其他节点无认证接入。 + + 如果要在openGauss内部访问数据库主节点,请将ODBC程序部署在数据库主节点所在机器,服务器地址使用"127.0.0.1"。建议业务系统单独部署在openGauss外部,否则可能会影响数据库运行性能。 + +- \[unixODBC\]\[Driver Manager\]Invalid attribute value + + 有可能是unixODBC的版本并非推荐版本,建议通过“odbcinst --version”命令排查环境中的unixODBC版本。 + +- authentication method 10 not supported. + + 使用开源客户端碰到此问题,可能原因: + + 数据库中存储的口令校验只存储了SHA256格式哈希,而开源客户端只识别MD5校验,双方校验方法不匹配报错。 + + >![](public_sys-resources/icon-note.gif) **说明:** + > + >- 数据库并不存储用户口令,只存储用户口令的哈希码。 + >- 数据库当用户更新用户口令或者新建用户时,会同时存储两种格式的哈希码,这时将兼容开源的认证协议。 + >- 但是当老版本升级到新版本时,由于哈希的不可逆性,所以数据库无法还原用户口令,进而生成新格式的哈希,所以仍然只保留了SHA256格式的哈希,导致仍然无法使用MD5做口令认证。 + >- MD5加密算法安全性低,存在安全风险,建议使用更安全的加密算法。 + + 要解决该问题,可以更新用户口令(参见[ALTER USER](../SQLReference/ALTER-USER.md));或者新建一个用户(参见[CREATE USER](../SQLReference/CREATE-USER.md)),赋于同等权限,使用新用户连接数据库。 + +- unsupported frontend protocol 3.51: server supports 1.0 to 3.0 + + 目标数据库版本过低,或者目标数据库为开源数据库。请使用对应版本的数据库驱动连接目标数据库。 + +- FATAL: GSS authentication method is not allowed because XXXX user password is not disabled. + + 目标数据库主节点的pg\_hba.conf里配置了当前客户端IP使用"gss"方式来做认证,该认证算法不支持用作客户端的身份认证,请修改到"sha256"后再试。配置方法见[8](#zh-cn_topic_0283136654_zh-cn_topic_0237120407_zh-cn_topic_0059778464_l4c0173b8af93447e91aba24005e368e5)。 + + diff --git "a/content/docs-lite/zh/docs/DeveloperGuide/ODBC\345\214\205\345\217\212\344\276\235\350\265\226\347\232\204\345\272\223\345\222\214\345\244\264\346\226\207\344\273\266.md" "b/content/docs-lite/zh/docs/DeveloperGuide/ODBC\345\214\205\345\217\212\344\276\235\350\265\226\347\232\204\345\272\223\345\222\214\345\244\264\346\226\207\344\273\266.md" new file mode 100644 index 000000000..0498715f1 --- /dev/null +++ "b/content/docs-lite/zh/docs/DeveloperGuide/ODBC\345\214\205\345\217\212\344\276\235\350\265\226\347\232\204\345\272\223\345\222\214\345\244\264\346\226\207\344\273\266.md" @@ -0,0 +1,6 @@ +# ODBC包及依赖的库和头文件 + +## Linux下的ODBC包 + +从发布包中获取,包名为openGauss-x.x.x-ODBC.tar.gz。Linux环境下,开发应用程序要用到unixODBC提供的头文件(sql.h、sqlext.h等)和库libodbc.so。这些头文件和库可从unixODBC-2.3.0的安装包中获得。 + diff --git "a/content/docs-lite/zh/docs/DeveloperGuide/ODBC\346\216\245\345\217\243\345\217\202\350\200\203.md" "b/content/docs-lite/zh/docs/DeveloperGuide/ODBC\346\216\245\345\217\243\345\217\202\350\200\203.md" new file mode 100644 index 000000000..ea03164bd --- /dev/null +++ "b/content/docs-lite/zh/docs/DeveloperGuide/ODBC\346\216\245\345\217\243\345\217\202\350\200\203.md" @@ -0,0 +1,49 @@ +# ODBC接口参考 + +ODBC接口是一套提供给用户的API函数,本节将对部分常用接口做具体描述,若涉及其他接口可参考[msdn](https://docs.microsoft.com/zh-cn/sql/odbc/reference/odbc-programmer-s-reference?view=sql-server-ver15)中ODBC Programmer's Reference项的相关内容。 + +- **[SQLAllocEnv](SQLAllocEnv.md)** + +- **[SQLAllocConnect](SQLAllocConnect.md)** + +- **[SQLAllocHandle](SQLAllocHandle.md)** + +- **[SQLAllocStmt](SQLAllocStmt.md)** + +- **[SQLBindCol](SQLBindCol.md)** + +- **[SQLBindParameter](SQLBindParameter.md)** + +- **[SQLColAttribute](SQLColAttribute.md)** + +- **[SQLConnect](SQLConnect.md)** + +- **[SQLDisconnect](SQLDisconnect.md)** + +- **[SQLExecDirect](SQLExecDirect.md)** + +- **[SQLExecute](SQLExecute.md)** + +- **[SQLFetch](SQLFetch.md)** + +- **[SQLFreeStmt](SQLFreeStmt.md)** + +- **[SQLFreeConnect](SQLFreeConnect.md)** + +- **[SQLFreeHandle](SQLFreeHandle.md)** + +- **[SQLFreeEnv](SQLFreeEnv.md)** + +- **[SQLPrepare](SQLPrepare.md)** + +- **[SQLGetData](SQLGetData.md)** + +- **[SQLGetDiagRec](SQLGetDiagRec.md)** + +- **[SQLSetConnectAttr](SQLSetConnectAttr.md)** + +- **[SQLSetEnvAttr](SQLSetEnvAttr.md)** + +- **[SQLSetStmtAttr](SQLSetStmtAttr.md)** + +- **[示例](示例-2.md)** \ No newline at end of file diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLAllocConnect.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLAllocConnect.md new file mode 100644 index 000000000..2a9c6afce --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLAllocConnect.md @@ -0,0 +1,4 @@ +# SQLAllocConnect + +在ODBC 3.x版本中,ODBC 2.x的函数SQLAllocConnect已被SQLAllocHandle代替。有关详细信息请参阅[SQLAllocHandle](SQLAllocHandle.md)。 + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLAllocEnv.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLAllocEnv.md new file mode 100644 index 000000000..5bcbac38f --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLAllocEnv.md @@ -0,0 +1,4 @@ +# SQLAllocEnv + +在ODBC 3.x版本中,ODBC 2.x的函数SQLAllocEnv已被SQLAllocHandle代替。有关详细信息请参阅[SQLAllocHandle](SQLAllocHandle.md)。 + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLAllocHandle.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLAllocHandle.md new file mode 100644 index 000000000..9de8da77b --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLAllocHandle.md @@ -0,0 +1,61 @@ +# SQLAllocHandle + +## 功能描述 + +分配环境、连接、语句或描述符的句柄,它替代了ODBC 2.x函数SQLAllocEnv、SQLAllocConnect及SQLAllocStmt。 + +## 原型 + +``` +SQLRETURN SQLAllocHandle(SQLSMALLINT HandleType, + SQLHANDLE InputHandle, + SQLHANDLE *OutputHandlePtr); +``` + +## 参数 + +**表 1** SQLAllocHandle参数 + + + + + + + + + + + + + + + + +

关键字

+

参数说明

+

HandleType

+

由SQLAllocHandle分配的句柄类型。必须为下列值之一:

+
  • SQL_HANDLE_ENV(环境句柄)
  • SQL_HANDLE_DBC(连接句柄)
  • SQL_HANDLE_STMT(语句句柄)
  • SQL_HANDLE_DESC(描述句柄)
+

申请句柄顺序为,先申请环境句柄,再申请连接句柄,最后申请语句句柄,后申请的句柄都要依赖它前面申请的句柄。

+

InputHandle

+

将要分配的新句柄的类型。

+
  • 如果HandleType为SQL_HANDLE_ENV,则这个值为SQL_NULL_HANDLE。
  • 如果HandleType为SQL_HANDLE_DBC,则这一定是一个环境句柄。
  • 如果HandleType为SQL_HANDLE_STMT或SQL_HANDLE_DESC,则它一定是一个连接句柄。
+

OutputHandlePtr

+

输出参数:一个缓冲区的指针,此缓冲区以新分配的数据结构存放返回的句柄。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 + +## 注意事项 + +当分配的句柄并非环境句柄时,如果SQLAllocHandle返回的值为SQL\_ERROR,则它会将OutputHandlePtr的值设置为SQL\_NULL\_HDBC、SQL\_NULL\_HSTMT或SQL\_NULL\_HDESC。之后,通过调用带有适当参数的[SQLGetDiagRec](SQLGetDiagRec.md),其中HandleType和Handle被设置为IntputHandle的值,可得到相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 + +## 示例 + +参见:[示例](示例-2.md) + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLAllocStmt.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLAllocStmt.md new file mode 100644 index 000000000..ae101f65a --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLAllocStmt.md @@ -0,0 +1,4 @@ +# SQLAllocStmt + +在ODBC 3.x版本中,ODBC 2.x的函数SQLAllocStmt已被SQLAllocHandle代替。有关详细信息请参阅[SQLAllocHandle](SQLAllocHandle.md)。 + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLBindCol.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLBindCol.md new file mode 100644 index 000000000..fc286d0e2 --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLBindCol.md @@ -0,0 +1,76 @@ +# SQLBindCol + +## 功能描述 + +将应用程序数据缓冲区绑定到结果集的列中。 + +## 原型 + +``` +SQLRETURN SQLBindCol(SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLSMALLINT TargetType, + SQLPOINTER TargetValuePtr, + SQLLEN BufferLength, + SQLLEN *StrLen_or_IndPtr); +``` + +## 参数 + +**表 1** SQLBindCol参数 + + + + + + + + + + + + + + + + + + + + + + + + + +

关键字

+

参数说明

+

StatementHandle

+

语句句柄。

+

ColumnNumber

+

要绑定结果集的列号。起始列号为0,以递增的顺序计算列号,第0列是书签列。若未设置书签页,则起始列号为1。

+

TargetType

+

缓冲区中C数据类型的标识符。

+

TargetValuePtr

+

输出参数:指向与列绑定的数据缓冲区的指针。SQLFetch函数返回这个缓冲区中的数据。如果此参数为一个空指针,则StrLen_or_IndPtr是一个有效值。

+

BufferLength

+

TargetValuePtr指向缓冲区的长度,以字节为单位。

+

StrLen_or_IndPtr

+

输出参数:缓冲区的长度或指示器指针。若为空值,则未使用任何长度或指示器值。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 + +## 注意事项 + +当SQLBindCol返回SQL\_ERROR或SQL\_SUCCESS\_WITH\_INFO时,通过调用[SQLGetDiagRec](SQLGetDiagRec.md)函数,并将HandleType和Handle参数设置为SQL\_HANDLE\_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 + +## 示例 + +参见:[示例](示例-2.md) + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLBindParameter.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLBindParameter.md new file mode 100644 index 000000000..e6a6bb197 --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLBindParameter.md @@ -0,0 +1,100 @@ +# SQLBindParameter + +## 功能描述 + +将一条SQL语句中的一个参数标志和一个缓冲区绑定起来。 + +## 原型 + +``` +SQLRETURN SQLBindParameter(SQLHSTMT StatementHandle, + SQLUSMALLINT ParameterNumber, + SQLSMALLINT InputOutputType, + SQLSMALLINT ValuetType, + SQLSMALLINT ParameterType, + SQLULEN ColumnSize, + SQLSMALLINT DecimalDigits, + SQLPOINTER ParameterValuePtr, + SQLLEN BufferLength, + SQLLEN *StrLen_or_IndPtr); +``` + +## 参数 + +**表 1** SQLBindParameter + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

关键词

+

参数说明

+

StatementHandle

+

语句句柄。

+

ParameterNumber

+

参数序号,起始为1,依次递增。

+

InputOutputType

+

输入输出参数类型。

+

ValueType

+

参数的C数据类型。

+

ParameterType

+

参数的SQL数据类型。

+

ColumnSize

+

列的大小或相应参数标记的表达式。

+

DecimalDigits

+

列的十进制数字或相应参数标记的表达式。

+

ParameterValuePtr

+

指向存储参数数据缓冲区的指针。

+

BufferLength

+

ParameterValuePtr指向缓冲区的长度,以字节为单位。

+

StrLen_or_IndPtr

+

缓冲区的长度或指示器指针。若为空值,则未使用任何长度或指示器值。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 + +## 注意事项 + +当SQLBindParameter返回SQL\_ERROR或SQL\_SUCCESS\_WITH\_INFO时,通过调用[SQLGetDiagRec](SQLGetDiagRec.md)函数,并将HandleType和Handle参数设置为SQL\_HANDLE\_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 + +## 示例 + +参见:[示例](示例-2.md) + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLColAttribute.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLColAttribute.md new file mode 100644 index 000000000..bb92a7ad7 --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLColAttribute.md @@ -0,0 +1,82 @@ +# SQLColAttribute + +## 功能描述 + +返回结果集中一列的描述符信息。 + +## 原型 + +``` +SQLRETURN SQLColAttibute(SQLHSTMT StatementHandle, + SQLUSMALLINT ColumnNumber, + SQLUSMALLINT FieldIdentifier, + SQLPOINTER CharacterAtrriburePtr, + SQLSMALLINT BufferLength, + SQLSMALLINT *StringLengthPtr, + SQLLEN *NumericAttributePtr); +``` + +## 参数 + +**表 1** SQLColAttribute参数 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

关键字

+

参数说明

+

StatementHandle

+

语句句柄。

+

ColumnNumber

+

要检索字段的列号,起始为1,依次递增。

+

FieldIdentifier

+

IRD中ColumnNumber行的字段。

+

CharacterAttributePtr

+

输出参数:一个缓冲区指针,返回FieldIdentifier字段值。

+

BufferLength

+
  • 如果FieldIdentifier是一个ODBC定义的字段,而且CharacterAttributePtr指向一个字符串或二进制缓冲区,则此参数为该缓冲区的长度。
  • 如果FieldIdentifier是一个ODBC定义的字段,而且CharacterAttributePtr指向一个整数,则会忽略该字段。
+

StringLengthPtr

+

输出参数:缓冲区指针,存放*CharacterAttributePtr中字符类型数据的字节总数,对于非字符类型,忽略BufferLength的值。

+

NumericAttributePtr

+

输出参数:指向一个整型缓冲区的指针,返回IRD中ColumnNumber行FieldIdentifier字段的值。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 + +## 注意事项 + +当SQLColAttribute返回SQL\_ERROR或SQL\_SUCCESS\_WITH\_INFO时,通过调用[SQLGetDiagRec](SQLGetDiagRec.md)函数,并将HandleType和Handle参数设置为SQL\_HANDLE\_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 + +## 示例 + +参见:[示例](示例-2.md) + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLConnect.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLConnect.md new file mode 100644 index 000000000..0fdfbb6d6 --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLConnect.md @@ -0,0 +1,83 @@ +# SQLConnect + +## 功能描述 + +在驱动程序和数据源之间建立连接。连接上数据源之后,可以通过连接句柄访问到所有有关连接数据源的信息,包括程序运行状态、事务处理状态和错误信息。 + +## 原型 + +``` +SQLRETURN SQLConnect(SQLHDBC ConnectionHandle, + SQLCHAR *ServerName, + SQLSMALLINT NameLength1, + SQLCHAR *UserName, + SQLSMALLINT NameLength2, + SQLCHAR *Authentication, + SQLSMALLINT NameLength3); +``` + +## 参数 + +**表 1** SQLConnect参数 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

关键字

+

参数说明

+

ConnectionHandle

+

连接句柄,通过SQLAllocHandle获得。

+

ServerName

+

要连接数据源的名称。

+

NameLength1

+

ServerName的长度。

+

UserName

+

数据源中数据库用户名。

+

NameLength2

+

UserName的长度。

+

Authentication

+

数据源中数据库用户密码。

+

NameLength3

+

Authentication的长度。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 +- SQL\_STILL\_EXECUTING:表示语句正在执行。 + +## 注意事项 + +当调用SQLConnect函数返回SQL\_ERROR或SQL\_SUCCESS\_WITH\_INFO时,通过调用[SQLGetDiagRec](SQLGetDiagRec.md)函数,并将HandleType和Handle参数设置为SQL\_HANDLE\_DBC和ConnectionHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 + +## 示例 + +参见:[示例](示例-2.md) + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLDisconnect.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLDisconnect.md new file mode 100644 index 000000000..93bea4108 --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLDisconnect.md @@ -0,0 +1,46 @@ +# SQLDisconnect + +## 功能描述 + +关闭一个与特定连接句柄相关的连接。 + +## 原型 + +``` +SQLRETURN SQLDisconnect(SQLHDBC ConnectionHandle); +``` + +## 参数 + +**表 1** SQLDisconnect参数 + + + + + + + + + + +

关键字

+

参数说明

+

ConnectionHandle

+

连接句柄,通过SQLAllocHandle获得。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 + +## 注意事项 + +当调用SQLDisconnect函数返回SQL\_ERROR或SQL\_SUCCESS\_WITH\_INFO时,通过调用[SQLGetDiagRec](SQLGetDiagRec.md)函数,并将HandleType和Handle参数设置为SQL\_HANDLE\_DBC和ConnectionHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 + +## 示例 + +参见:[示例](示例-2.md) + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLExecDirect.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLExecDirect.md new file mode 100644 index 000000000..8e1e16b56 --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLExecDirect.md @@ -0,0 +1,61 @@ +# SQLExecDirect + +## 功能描述 + +使用参数的当前值,执行一条准备好的语句。对于一次只执行一条SQL语句,SQLExecDirect是最快的执行方式。 + +## 原型 + +``` +SQLRETURN SQLExecDirect(SQLHSTMT StatementHandle, + SQLCHAR *StatementText, + SQLINTEGER TextLength); +``` + +## 参数 + +**表 1** SQLExecDirect参数 + + + + + + + + + + + + + + + + +

关键字

+

参数说明

+

StatementHandle

+

语句句柄,通过SQLAllocHandle获得。

+

StatementText

+

要执行的SQL语句。不支持一次执行多条语句。

+

TextLength

+

StatementText的长度。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_NEED\_DATA:在执行SQL语句前没有提供足够的参数。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 +- SQL\_STILL\_EXECUTING:表示语句正在执行。 +- SQL\_NO\_DATA:表示SQL语句不返回结果集。 + +## 注意事项 + +当调用SQLExecDirect函数返回SQL\_ERROR或SQL\_SUCCESS\_WITH\_INFO时,通过调用[SQLGetDiagRec](SQLGetDiagRec.md)函数,并将HandleType和Handle参数设置为SQL\_HANDLE\_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 + +## 示例 + +参见:[示例](示例-2.md) + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLExecute.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLExecute.md new file mode 100644 index 000000000..d3f124942 --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLExecute.md @@ -0,0 +1,49 @@ +# SQLExecute + +## 功能描述 + +如果语句中存在参数标记的话,SQLExecute函数使用参数标记参数的当前值,执行一条准备好的SQL语句。 + +## 原型 + +``` +SQLRETURN SQLExecute(SQLHSTMT StatementHandle); +``` + +## 参数 + +**表 1** SQLExecute参数 + + + + + + + + + + +

关键字

+

参数说明

+

StatementHandle

+

要执行语句的语句句柄。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_NEED\_DATA:表示在执行SQL语句前没有提供足够的参数。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_NO\_DATA:表示SQL语句不返回结果集。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 +- SQL\_STILL\_EXECUTING:表示语句正在执行。 + +## 注意事项 + +当SQLExecute函数返回SQL\_ERROR或SQL\_SUCCESS\_WITH\_INFO时,可通过调用[SQLGetDiagRec](SQLGetDiagRec.md)函数,并将HandleType和Handle参数设置为SQL\_HANDLE\_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 + +## 示例 + +参见:[示例](示例-2.md) + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLFetch.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLFetch.md new file mode 100644 index 000000000..f81744555 --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLFetch.md @@ -0,0 +1,48 @@ +# SQLFetch + +## 功能描述 + +从结果集中取下一个行集的数据,并返回所有被绑定列的数据。 + +## 原型 + +``` +SQLRETURN SQLFetch(SQLHSTMT StatementHandle); +``` + +## 参数 + +**表 1** SQLFetch参数 + + + + + + + + + + +

关键字

+

参数说明

+

StatementHandle

+

语句句柄,通过SQLAllocHandle获得。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_NO\_DATA:表示SQL语句不返回结果集。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 +- SQL\_STILL\_EXECUTING:表示语句正在执行。 + +## 注意事项 + +当调用SQLFetch函数返回SQL\_ERROR或SQL\_SUCCESS\_WITH\_INFO时,通过调用[SQLGetDiagRec](SQLGetDiagRec.md)函数,并将HandleType和Handle参数设置为SQL\_HANDLE\_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 + +## 示例 + +参见:[示例](示例-2.md) + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLFreeConnect.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLFreeConnect.md new file mode 100644 index 000000000..62b03fac4 --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLFreeConnect.md @@ -0,0 +1,4 @@ +# SQLFreeConnect + +在ODBC 3.x版本中,ODBC 2.x的函数SQLFreeConnect已被SQLFreeHandle代替。有关详细信息请参阅[SQLFreeHandle](SQLFreeHandle.md)。 + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLFreeEnv.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLFreeEnv.md new file mode 100644 index 000000000..e8b6397b9 --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLFreeEnv.md @@ -0,0 +1,4 @@ +# SQLFreeEnv + +在ODBC 3.x版本中,ODBC 2.x的函数SQLFreeEnv已被SQLFreeHandle代替。有关详细信息请参阅[SQLFreeHandle](SQLFreeHandle.md)。 + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLFreeHandle.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLFreeHandle.md new file mode 100644 index 000000000..645e58863 --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLFreeHandle.md @@ -0,0 +1,54 @@ +# SQLFreeHandle + +## 功能描述 + +释放与指定环境、连接、语句或描述符相关联的资源,它替代了ODBC 2.x函数SQLFreeEnv、SQLFreeConnect及SQLFreeStmt。 + +## 原型 + +``` +SQLRETURN SQLFreeHandle(SQLSMALLINT HandleType, + SQLHANDLE Handle); +``` + +## 参数 + +**表 1** SQLFreeHandle参数 + + + + + + + + + + + + + +

关键字

+

参数说明

+

HandleType

+

SQLFreeHandle要释放的句柄类型。必须为下列值之一:

+
  • SQL_HANDLE_ENV
  • SQL_HANDLE_DBC
  • SQL_HANDLE_STMT
  • SQL_HANDLE_DESC
+

如果HandleType不是这些值之一,SQLFreeHandle返回SQL_INVALID_HANDLE。

+

Handle

+

要释放的句柄。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 + +## 注意事项 + +如果SQLFreeHandle返回SQL\_ERROR,句柄仍然有效。 + +## 示例 + +参见:[示例](示例-2.md) + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLFreeStmt.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLFreeStmt.md new file mode 100644 index 000000000..0be4250f0 --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLFreeStmt.md @@ -0,0 +1,4 @@ +# SQLFreeStmt + +在ODBC 3.x版本中,ODBC 2.x的函数SQLFreeStmt已被SQLFreeHandle代替。有关详细信息请参阅[SQLFreeHandle](SQLFreeHandle.md)。 + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLGetData.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLGetData.md new file mode 100644 index 000000000..5fc5a161a --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLGetData.md @@ -0,0 +1,78 @@ +# SQLGetData + +## 功能描述 + +SQLGetData返回结果集中某一列的数据。可以多次调用它来部分地检索不定长度的数据。 + +## 原型 + +``` +SQLRETURN SQLGetData(SQLHSTMT StatementHandle, + SQLUSMALLINT Col_or_Param_Num, + SQLSMALLINT TargetType, + SQLPOINTER TargetValuePtr, + SQLLEN BufferLength, + SQLLEN *StrLen_or_IndPtr); +``` + +## 参数 + +**表 1** SQLGetData参数 + + + + + + + + + + + + + + + + + + + + + + + + + +

关键字

+

参数说明

+

StatementHandle

+

语句句柄,通过SQLAllocHandle获得。

+

Col_or_Param_Num

+

要返回数据的列号。结果集的列按增序从1开始编号。书签列的列号为0。

+

TargetType

+

TargetValuePtr缓冲中的C数据类型的类型标识符。若TargetType为SQL_ARD_TYPE,驱动使用ARD中SQL_DESC_CONCISE_TYPE字段的类型标识符。若为SQL_C_DEFAULT,驱动根据源的SQL数据类型选择缺省的数据类型。

+

TargetValuePtr

+

输出参数:指向返回数据所在缓冲区的指针。

+

BufferLength

+

TargetValuePtr所指向缓冲区的长度。

+

StrLen_or_IndPtr

+

输出参数:指向缓冲区的指针,在此缓冲区中返回长度或标识符的值。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_NO\_DATA:表示SQL语句不返回结果集。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 +- SQL\_STILL\_EXECUTING:表示语句正在执行。 + +## 注意事项 + +当调用SQLGetData函数返回SQL\_ERROR或SQL\_SUCCESS\_WITH\_INFO时,通过调用[SQLGetDiagRec](SQLGetDiagRec.md)函数,并将HandleType和Handle参数分别设置为SQL\_HANDLE\_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 + +## 示例 + +参见:[示例](示例-2.md) + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLGetDiagRec.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLGetDiagRec.md new file mode 100644 index 000000000..a32d9bc59 --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLGetDiagRec.md @@ -0,0 +1,159 @@ +# SQLGetDiagRec + +## 功能描述 + +返回诊断记录的多个字段的当前值,其中诊断记录包含错误、警告及状态信息。 + +## 原型 + +``` +SQLRETURN SQLGetDiagRec(SQLSMALLINT HandleType + SQLHANDLE Handle, + SQLSMALLINT RecNumber, + SQLCHAR *SQLState, + SQLINTEGER *NativeErrorPtr, + SQLCHAR *MessageText, + SQLSMALLINT BufferLength + SQLSMALLINT *TextLengthPtr); +``` + +## 参数 + +**表 1** SQLGetDiagRec参数 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

关键字

+

参数说明

+

HandleType

+

句柄类型标识符,它说明诊断所要求的句柄类型。必须为下列值之一:

+
  • SQL_HANDLE_ENV
  • SQL_HANDLE_DBC
  • SQL_HANDLE_STMT
  • SQL_HANDLE_DESC
+

Handle

+

诊断数据结构的句柄,其类型由HandleType来指出。如果HandleType是SQL_HANDLE_ENV,Handle可以是共享的或非共享的环境句柄。

+

RecNumber

+

指出应用从查找信息的状态记录。状态记录从1开始编号。

+

SQLState

+

输出参数:指向缓冲区的指针,该缓冲区存储着有关RecNumber的五字符的SQLSTATE码。

+

NativeErrorPtr

+

输出参数:指向缓冲区的指针,该缓冲区存储着本地的错误码。

+

MessageText

+

指向缓冲区的指针,该缓冲区存储着诊断信息文本串。

+

BufferLength

+

MessageText的长度。

+

TextLengthPtr

+

输出参数:指向缓冲区的指针,返回MessageText中的字节总数。如果返回字节数大于BufferLength,则MessageText中的诊断信息文本被截断成BufferLength减去NULL结尾字符的长度。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 + +## 注意事项 + +SQLGetDiagRec不发布自己的诊断记录。它用下列返回值来报告它自己的执行结果: + +- SQL\_SUCCESS:函数成功返回诊断信息。 +- SQL\_SUCCESS\_WITH\_INFO:MessageText太小以致不能容纳所请求的诊断信息。没有诊断记录生成。 +- SQL\_INVALID\_HANDLE:由HandType和Handle所指出的句柄是不合法句柄。 +- SQL\_ERROR:RecNumber小于等于0或BufferLength小于0。 + +如果调用ODBC函数返回SQL\_ERROR或SQL\_SUCCESS\_WITH\_INFO,可调用SQLGetDiagRec返回诊断信息值SQLSTATE,SQLSTATE值的如下表。 + +**表 2** SQLSTATE值 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

SQLSATATE

+

错误

+

描述

+

HY000

+

一般错误

+

未定义特定的SQLSTATE所产生的一个错误。

+

HY001

+

内存分配错误

+

驱动程序不能分配所需要的内存来支持函数的执行或完成。

+

HY008

+

取消操作

+

调用SQLCancel取消执行语句后,依然在StatementHandle上调用函数。

+

HY010

+

函数系列错误

+

在为执行中的所有数据参数或列发送数据前就调用了执行函数。

+

HY013

+

内存管理错误

+

不能处理函数调用,可能由当前内存条件差引起。

+

HYT01

+

连接超时

+

数据源响应请求之前,连接超时。

+

IM001

+

驱动程序不支持此函数

+

调用了StatementHandle相关的驱动程序不支持的函数。

+
+ +## 示例 + +参见:[示例](示例-2.md) + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLPrepare.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLPrepare.md new file mode 100644 index 000000000..179ee5dd7 --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLPrepare.md @@ -0,0 +1,59 @@ +# SQLPrepare + +## 功能描述 + +准备一个将要进行的SQL语句。 + +## 原型 + +``` +SQLRETURN SQLPrepare(SQLHSTMT StatementHandle, + SQLCHAR *StatementText, + SQLINTEGER TextLength); +``` + +## 参数 + +**表 1** SQLPrepare参数 + + + + + + + + + + + + + + + + +

关键字

+

参数说明

+

StatementHandle

+

语句句柄。

+

StatementText

+

SQL文本串。

+

TextLength

+

StatementText的长度。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 +- SQL\_STILL\_EXECUTING:表示语句正在执行。 + +## 注意事项 + +当SQLPrepare返回的值为SQL\_ERROR或SQL\_SUCCESS\_WITH\_INFO时,通过调用[SQLGetDiagRec](SQLGetDiagRec.md)函数,并将HandleType和Handle参数分别设置为SQL\_HANDLE\_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 + +## 示例 + +参见:[示例](示例-2.md) + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLSetConnectAttr.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLSetConnectAttr.md new file mode 100644 index 000000000..37763929d --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLSetConnectAttr.md @@ -0,0 +1,64 @@ +# SQLSetConnectAttr + +## 功能描述 + +设置控制连接各方面的属性。 + +## 原型 + +``` +SQLRETURN SQLSetConnectAttr(SQLHDBC ConnectionHandle + SQLINTEGER Attribute, + SQLPOINTER ValuePtr, + SQLINTEGER StringLength); +``` + +## 参数 + +**表 1** SQLSetConnectAttr参数 + + + + + + + + + + + + + + + + + + + +

关键字

+

参数说明

+

ConnectionHandle

+

连接句柄。

+

Attribute

+

设置属性。

+

ValuePtr

+

指向对应Attribute的值。依赖于Attribute的值,ValuePtr是32位无符号整型值或指向以空结束的字符串。注意,如果ValuePtr参数是驱动程序指定值。ValuePtr可能是有符号的整数。

+

StringLength

+

如果ValuePtr指向字符串或二进制缓冲区,这个参数是*ValuePtr长度,如果ValuePtr指向整型,忽略StringLength。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 + +## 注意事项 + +当SQLSetConnectAttr的返回值为SQL\_ERROR或SQL\_SUCCESS\_WITH\_INFO时,通过借助SQL\_HANDLE\_DBC的HandleType和ConnectionHandle的Handle,调用[SQLGetDiagRec](SQLGetDiagRec.md)可得到相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 + +## 示例 + +参见:[示例](示例-2.md) + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLSetEnvAttr.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLSetEnvAttr.md new file mode 100644 index 000000000..41259509b --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLSetEnvAttr.md @@ -0,0 +1,65 @@ +# SQLSetEnvAttr + +## 功能描述 + +设置控制环境各方面的属性。 + +## 原型 + +``` +SQLRETURN SQLSetEnvAttr(SQLHENV EnvironmentHandle + SQLINTEGER Attribute, + SQLPOINTER ValuePtr, + SQLINTEGER StringLength); +``` + +## 参数 + +**表 1** SQLSetEnvAttr参数 + + + + + + + + + + + + + + + + + + + +

关键字

+

参数说明

+

EnvironmentHandle

+

环境句柄。

+

Attribute

+

需设置的环境属性,可为如下值:

+
  • SQL_ATTR_ODBC_VERSION:指定ODBC版本。
  • SQL_CONNECTION_POOLING:连接池属性。
  • SQL_OUTPUT_NTS:指明驱动器返回字符串的形式。
+

ValuePtr

+

指向对应Attribute的值。依赖于Attribute的值,ValuePtr可能是32位整型值,或为以空结束的字符串。

+

StringLength

+

如果ValuePtr指向字符串或二进制缓冲区,这个参数是*ValuePtr长度,如果ValuePtr指向整型,忽略StringLength。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 + +## 注意事项 + +当SQLSetEnvAttr的返回值为SQL\_ERROR或SQL\_SUCCESS\_WITH\_INFO时,通过借助SQL\_HANDLE\_ENV的HandleType和EnvironmentHandle的Handle,调用[SQLGetDiagRec](SQLGetDiagRec.md)可得到相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 + +## 示例 + +参见:[示例](示例-2.md) + diff --git a/content/docs-lite/zh/docs/DeveloperGuide/SQLSetStmtAttr.md b/content/docs-lite/zh/docs/DeveloperGuide/SQLSetStmtAttr.md new file mode 100644 index 000000000..fb958e2f7 --- /dev/null +++ b/content/docs-lite/zh/docs/DeveloperGuide/SQLSetStmtAttr.md @@ -0,0 +1,64 @@ +# SQLSetStmtAttr + +## 功能描述 + +设置相关语句的属性。 + +## 原型 + +``` +SQLRETURN SQLSetStmtAttr(SQLHSTMT StatementHandle + SQLINTEGER Attribute, + SQLPOINTER ValuePtr, + SQLINTEGER StringLength); +``` + +## 参数 + +**表 1** SQLSetStmtAttr参数 + + + + + + + + + + + + + + + + + + + +

关键字

+

参数说明

+

StatementHandle

+

语句句柄。

+

Attribute

+

需设置的属性。

+

ValuePtr

+

指向对应Attribute的值。依赖于Attribute的值,ValuePtr可能是32位无符号整型值,或指向以空结束的字符串,二进制缓冲区,或者驱动定义值。注意,如果ValuePtr参数是驱动程序指定值。ValuePtr可能是有符号的整数。

+

StringLength

+

如果ValuePtr指向字符串或二进制缓冲区,这个参数是*ValuePtr长度,如果ValuePtr指向整型,忽略StringLength。

+
+ +## 返回值 + +- SQL\_SUCCESS:表示调用正确。 +- SQL\_SUCCESS\_WITH\_INFO:表示会有一些警告信息。 +- SQL\_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 +- SQL\_INVALID\_HANDLE:表示调用无效句柄。其他API的返回值同理。 + +## 注意事项 + +当SQLSetStmtAttr的返回值为SQL\_ERROR或SQL\_SUCCESS\_WITH\_INFO时,通过借助SQL\_HANDLE\_STMT的HandleType和StatementHandle的Handle,调用[SQLGetDiagRec](SQLGetDiagRec.md)可得到相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 + +## 示例 + +参见:[示例](示例-2.md) + diff --git "a/content/docs-lite/zh/docs/DeveloperGuide/\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\351\205\215\347\275\256.md" "b/content/docs-lite/zh/docs/DeveloperGuide/\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\351\205\215\347\275\256.md" new file mode 100644 index 000000000..f066338b6 --- /dev/null +++ "b/content/docs-lite/zh/docs/DeveloperGuide/\345\205\270\345\236\213\345\272\224\347\224\250\345\234\272\346\231\257\351\205\215\347\275\256.md" @@ -0,0 +1,491 @@ +# 典型应用场景配置 + +## 日志诊断场景 + +ODBC日志分为unixODBC驱动管理器日志和psqlODBC驱动端日志。前者可以用于追溯应用程序API的执行是否成功,后者是底层实现过程中的一些DFX日志,用来帮助定位问题。 + +unixODBC日志需要在odbcinst.ini文件中配置: + +``` +[ODBC] +Trace=Yes +TraceFile=/path/to/odbctrace.log + +[GaussMPP] +Driver64=/usr/local/lib/psqlodbcw.so +setup=/usr/local/lib/psqlodbcw.so +``` + +psqlODBC日志只需要在odbc.ini加上: + +``` +[gaussdb] +Driver=GaussMPP +Servername=10.10.0.13(数据库Server IP) +... +Debug=1(打开驱动端debug日志) +``` + +>![](public_sys-resources/icon-note.gif) **说明:** unixODBC日志将会生成在TraceFile配置的路径下,psqlODBC会在系统/tmp/下生成mylog\_xxx.log。 + +## 高性能场景 + +进行大量数据插入时,建议如下: + +- 需要设置批量绑定:odbc.ini配置文件中设置UseBatchProtocol=1、数据库设置support\_batch\_bind=on。 +- ODBC程序绑定类型要和数据库中类型一致。 +- 客户端字符集和数据库字符集一致。 +- 事务改成手动提交。 + +odbc.ini配置文件: + +``` +[gaussdb] +Driver=GaussMPP +Servername=10.10.0.13(数据库Server IP) +... +UseBatchProtocol=1 (默认打开) +ConnSettings=set client_encoding=UTF8 (设置客户端字符编码,保证和server端一致) +``` + +绑定类型用例: + +``` +#include +#include +#include +#include +#include +#include + +#define MESSAGE_BUFFER_LEN 128 +SQLHANDLE h_env = NULL; +SQLHANDLE h_conn = NULL; +SQLHANDLE h_stmt = NULL; +void print_error() +{ + SQLCHAR Sqlstate[SQL_SQLSTATE_SIZE+1]; + SQLINTEGER NativeError; + SQLCHAR MessageText[MESSAGE_BUFFER_LEN]; + SQLSMALLINT TextLength; + SQLRETURN ret = SQL_ERROR; + + ret = SQLGetDiagRec(SQL_HANDLE_STMT, h_stmt, 1, Sqlstate, &NativeError, MessageText, MESSAGE_BUFFER_LEN, &TextLength); + if ( SQL_SUCCESS == ret) + { + printf("\n STMT ERROR-%05d %s", NativeError, MessageText); + return; + } + + ret = SQLGetDiagRec(SQL_HANDLE_DBC, h_conn, 1, Sqlstate, &NativeError, MessageText, MESSAGE_BUFFER_LEN, &TextLength); + if ( SQL_SUCCESS == ret) + { + printf("\n CONN ERROR-%05d %s", NativeError, MessageText); + return; + } + + ret = SQLGetDiagRec(SQL_HANDLE_ENV, h_env, 1, Sqlstate, &NativeError, MessageText, MESSAGE_BUFFER_LEN, &TextLength); + if ( SQL_SUCCESS == ret) + { + printf("\n ENV ERROR-%05d %s", NativeError, MessageText); + return; + } + + return; +} + +/* 期盼函数返回SQL_SUCCESS */ +#define RETURN_IF_NOT_SUCCESS(func) \ +{\ + SQLRETURN ret_value = (func);\ + if (SQL_SUCCESS != ret_value)\ + {\ + print_error();\ + printf("\n failed line = %u: expect SQL_SUCCESS, but ret = %d", __LINE__, ret_value);\ + return SQL_ERROR; \ + }\ +} + +/* 期盼函数返回SQL_SUCCESS */ +#define RETURN_IF_NOT_SUCCESS_I(i, func) \ +{\ + SQLRETURN ret_value = (func);\ + if (SQL_SUCCESS != ret_value)\ + {\ + print_error();\ + printf("\n failed line = %u (i=%d): : expect SQL_SUCCESS, but ret = %d", __LINE__, (i), ret_value);\ + return SQL_ERROR; \ + }\ +} + +/* 期盼函数返回SQL_SUCCESS_WITH_INFO */ +#define RETURN_IF_NOT_SUCCESS_INFO(func) \ +{\ + SQLRETURN ret_value = (func);\ + if (SQL_SUCCESS_WITH_INFO != ret_value)\ + {\ + print_error();\ + printf("\n failed line = %u: expect SQL_SUCCESS_WITH_INFO, but ret = %d", __LINE__, ret_value);\ + return SQL_ERROR; \ + }\ +} + +/* 期盼数值相等 */ +#define RETURN_IF_NOT(expect, value) \ +if ((expect) != (value))\ +{\ + printf("\n failed line = %u: expect = %u, but value = %u", __LINE__, (expect), (value)); \ + return SQL_ERROR;\ +} + +/* 期盼字符串相同 */ +#define RETURN_IF_NOT_STRCMP_I(i, expect, value) \ +if (( NULL == (expect) ) || (NULL == (value)))\ +{\ + printf("\n failed line = %u (i=%u): input NULL pointer !", __LINE__, (i)); \ + return SQL_ERROR; \ +}\ +else if (0 != strcmp((expect), (value)))\ +{\ + printf("\n failed line = %u (i=%u): expect = %s, but value = %s", __LINE__, (i), (expect), (value)); \ + return SQL_ERROR;\ +} + + +// prepare + execute SQL语句 +int execute_cmd(SQLCHAR *sql) +{ + if ( NULL == sql ) + { + return SQL_ERROR; + } + + if ( SQL_SUCCESS != SQLPrepare(h_stmt, sql, SQL_NTS)) + { + return SQL_ERROR; + } + + if ( SQL_SUCCESS != SQLExecute(h_stmt)) + { + return SQL_ERROR; + } + + return SQL_SUCCESS; +} +// execute + commit 句柄 +int commit_exec() +{ + if ( SQL_SUCCESS != SQLExecute(h_stmt)) + { + return SQL_ERROR; + } + + // 手动提交 + if ( SQL_SUCCESS != SQLEndTran(SQL_HANDLE_DBC, h_conn, SQL_COMMIT)) + { + return SQL_ERROR; + } + + return SQL_SUCCESS; +} + +int begin_unit_test() +{ + SQLINTEGER ret; + + /* 申请环境句柄 */ + ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &h_env); + if ((SQL_SUCCESS != ret) && (SQL_SUCCESS_WITH_INFO != ret)) + { + printf("\n begin_unit_test::SQLAllocHandle SQL_HANDLE_ENV failed ! ret = %d", ret); + return SQL_ERROR; + } + + /* 进行连接前必须要先设置版本号 */ + if (SQL_SUCCESS != SQLSetEnvAttr(h_env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0)) + { + print_error(); + printf("\n begin_unit_test::SQLSetEnvAttr SQL_ATTR_ODBC_VERSION failed ! ret = %d", ret); + SQLFreeHandle(SQL_HANDLE_ENV, h_env); + return SQL_ERROR; + } + + /* 申请连接句柄 */ + ret = SQLAllocHandle(SQL_HANDLE_DBC, h_env, &h_conn); + if (SQL_SUCCESS != ret) + { + print_error(); + printf("\n begin_unit_test::SQLAllocHandle SQL_HANDLE_DBC failed ! ret = %d", ret); + SQLFreeHandle(SQL_HANDLE_ENV, h_env); + return SQL_ERROR; + } + + /* 建立连接 */ + ret = SQLConnect(h_conn, (SQLCHAR*) "gaussdb", SQL_NTS, + (SQLCHAR*) NULL, 0, NULL, 0); + if (SQL_SUCCESS != ret) + { + print_error(); + printf("\n begin_unit_test::SQLConnect failed ! ret = %d", ret); + SQLFreeHandle(SQL_HANDLE_DBC, h_conn); + SQLFreeHandle(SQL_HANDLE_ENV, h_env); + return SQL_ERROR; + } + + /* 申请语句句柄 */ + ret = SQLAllocHandle(SQL_HANDLE_STMT, h_conn, &h_stmt); + if (SQL_SUCCESS != ret) + { + print_error(); + printf("\n begin_unit_test::SQLAllocHandle SQL_HANDLE_STMT failed ! ret = %d", ret); + SQLFreeHandle(SQL_HANDLE_DBC, h_conn); + SQLFreeHandle(SQL_HANDLE_ENV, h_env); + return SQL_ERROR; + } + + return SQL_SUCCESS; +} + +void end_unit_test() +{ + /* 释放语句句柄 */ + if (NULL != h_stmt) + { + SQLFreeHandle(SQL_HANDLE_STMT, h_stmt); + } + + /* 释放连接句柄 */ + if (NULL != h_conn) + { + SQLDisconnect(h_conn); + SQLFreeHandle(SQL_HANDLE_DBC, h_conn); + } + + /* 释放环境句柄 */ + if (NULL != h_env) + { + SQLFreeHandle(SQL_HANDLE_ENV, h_env); + } + + return; +} + +int main() +{ + // begin test + if (begin_unit_test() != SQL_SUCCESS) + { + printf("\n begin_test_unit failed."); + return SQL_ERROR; + } + // 句柄配置同前面用例 + int i = 0; + SQLCHAR* sql_drop = "drop table if exists test_bindnumber_001"; + SQLCHAR* sql_create = "create table test_bindnumber_001(" + "f4 number, f5 number(10, 2)" + ")"; + SQLCHAR* sql_insert = "insert into test_bindnumber_001 values(?, ?)"; + SQLCHAR* sql_select = "select * from test_bindnumber_001"; + SQLLEN RowCount; + SQL_NUMERIC_STRUCT st_number; + SQLCHAR getValue[2][MESSAGE_BUFFER_LEN]; + + /* step 1. 建表 */ + RETURN_IF_NOT_SUCCESS(execute_cmd(sql_drop)); + RETURN_IF_NOT_SUCCESS(execute_cmd(sql_create)); + + /* step 2.1 通过SQL_NUMERIC_STRUCT结构绑定参数 */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + + //第一行: 1234.5678 + memset(st_number.val, 0, SQL_MAX_NUMERIC_LEN); + st_number.precision = 8; + st_number.scale = 4; + st_number.sign = 1; + st_number.val[0] = 0x4E; + st_number.val[1] = 0x61; + st_number.val[2] = 0xBC; + + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_NUMERIC, SQL_NUMERIC, sizeof(SQL_NUMERIC_STRUCT), 4, &st_number, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_NUMERIC, SQL_NUMERIC, sizeof(SQL_NUMERIC_STRUCT), 4, &st_number, 0, NULL)); + + // 关闭自动提交 + SQLSetConnectAttr(h_conn, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0); + + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + //第二行: 12345678 + memset(st_number.val, 0, SQL_MAX_NUMERIC_LEN); + st_number.precision = 8; + st_number.scale = 0; + st_number.sign = 1; + st_number.val[0] = 0x4E; + st_number.val[1] = 0x61; + st_number.val[2] = 0xBC; + + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_NUMERIC, SQL_NUMERIC, sizeof(SQL_NUMERIC_STRUCT), 0, &st_number, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_NUMERIC, SQL_NUMERIC, sizeof(SQL_NUMERIC_STRUCT), 0, &st_number, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + //第三行: 12345678 + memset(st_number.val, 0, SQL_MAX_NUMERIC_LEN); + st_number.precision = 0; + st_number.scale = 4; + st_number.sign = 1; + st_number.val[0] = 0x4E; + st_number.val[1] = 0x61; + st_number.val[2] = 0xBC; + + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_NUMERIC, SQL_NUMERIC, sizeof(SQL_NUMERIC_STRUCT), 4, &st_number, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_NUMERIC, SQL_NUMERIC, sizeof(SQL_NUMERIC_STRUCT), 4, &st_number, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + + /* step 2.2 第四行通过SQL_C_CHAR字符串绑定参数 */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + SQLCHAR* szNumber = "1234.5678"; + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_NUMERIC, strlen(szNumber), 0, szNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_NUMERIC, strlen(szNumber), 0, szNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + /* step 2.3 第五行通过SQL_C_FLOAT绑定参数 */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + SQLREAL fNumber = 1234.5678; + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_NUMERIC, sizeof(fNumber), 4, &fNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_NUMERIC, sizeof(fNumber), 4, &fNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + /* step 2.4 第六行通过SQL_C_DOUBLE绑定参数 */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + SQLDOUBLE dNumber = 1234.5678; + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_NUMERIC, sizeof(dNumber), 4, &dNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_NUMERIC, sizeof(dNumber), 4, &dNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + SQLBIGINT bNumber1 = 0xFFFFFFFFFFFFFFFF; + SQLBIGINT bNumber2 = 12345; + + /* step 2.5 第七行通过SQL_C_SBIGINT绑定参数 */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_SBIGINT, SQL_NUMERIC, sizeof(bNumber1), 4, &bNumber1, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_SBIGINT, SQL_NUMERIC, sizeof(bNumber2), 4, &bNumber2, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + /* step 2.6 第八行通过SQL_C_UBIGINT绑定参数 */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_UBIGINT, SQL_NUMERIC, sizeof(bNumber1), 4, &bNumber1, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_UBIGINT, SQL_NUMERIC, sizeof(bNumber2), 4, &bNumber2, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + SQLLEN lNumber1 = 0xFFFFFFFFFFFFFFFF; + SQLLEN lNumber2 = 12345; + + /* step 2.7 第九行通过SQL_C_LONG绑定参数 */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_NUMERIC, sizeof(lNumber1), 0, &lNumber1, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_NUMERIC, sizeof(lNumber2), 0, &lNumber2, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + /* step 2.8 第十行通过SQL_C_ULONG绑定参数 */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_NUMERIC, sizeof(lNumber1), 0, &lNumber1, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_NUMERIC, sizeof(lNumber2), 0, &lNumber2, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + SQLSMALLINT sNumber = 0xFFFF; + + /* step 2.9 第十一行通过SQL_C_SHORT绑定参数 */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_SHORT, SQL_NUMERIC, sizeof(sNumber), 0, &sNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_SHORT, SQL_NUMERIC, sizeof(sNumber), 0, &sNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + /* step 2.10 第十二行通过SQL_C_USHORT绑定参数 */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_NUMERIC, sizeof(sNumber), 0, &sNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_NUMERIC, sizeof(sNumber), 0, &sNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + SQLCHAR cNumber = 0xFF; + + /* step 2.11 第十三行通过SQL_C_TINYINT绑定参数 */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_TINYINT, SQL_NUMERIC, sizeof(cNumber), 0, &cNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_TINYINT, SQL_NUMERIC, sizeof(cNumber), 0, &cNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + /* step 2.12 第十四行通过SQL_C_UTINYINT绑定参数 */ + RETURN_IF_NOT_SUCCESS(SQLPrepare(h_stmt, sql_insert, SQL_NTS)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 1, SQL_PARAM_INPUT, SQL_C_UTINYINT, SQL_NUMERIC, sizeof(cNumber), 0, &cNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(SQLBindParameter(h_stmt, 2, SQL_PARAM_INPUT, SQL_C_UTINYINT, SQL_NUMERIC, sizeof(cNumber), 0, &cNumber, 0, NULL)); + RETURN_IF_NOT_SUCCESS(commit_exec()); + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(1, RowCount); + + /* 用字符串类型统一进行期盼 */ + SQLCHAR* expectValue[14][2] = {{"1234.5678", "1234.57"}, + {"12345678", "12345678"}, + {"0", "0"}, + {"1234.5678", "1234.57"}, + {"1234.5677", "1234.57"}, + {"1234.5678", "1234.57"}, + {"-1", "12345"}, + {"18446744073709551615", "12345"}, + {"-1", "12345"}, + {"4294967295", "12345"}, + {"-1", "-1"}, + {"65535", "65535"}, + {"-1", "-1"}, + {"255", "255"}, + }; + + RETURN_IF_NOT_SUCCESS(execute_cmd(sql_select)); + while ( SQL_NO_DATA != SQLFetch(h_stmt)) + { + RETURN_IF_NOT_SUCCESS_I(i, SQLGetData(h_stmt, 1, SQL_C_CHAR, &getValue[0], MESSAGE_BUFFER_LEN, NULL)); + RETURN_IF_NOT_SUCCESS_I(i, SQLGetData(h_stmt, 2, SQL_C_CHAR, &getValue[1], MESSAGE_BUFFER_LEN, NULL)); + + //RETURN_IF_NOT_STRCMP_I(i, expectValue[i][0], getValue[0]); + //RETURN_IF_NOT_STRCMP_I(i, expectValue[i][1], getValue[1]); + i++; + } + + RETURN_IF_NOT_SUCCESS(SQLRowCount(h_stmt, &RowCount)); + RETURN_IF_NOT(i, RowCount); + SQLCloseCursor(h_stmt); + /* step final. 删除表还原环境 */ + RETURN_IF_NOT_SUCCESS(execute_cmd(sql_drop)); + + end_unit_test(); +} +``` + +>![](public_sys-resources/icon-note.gif) **说明:** +>上述用例中定义了number列,调用SQLBindParameter接口时,绑定SQL\_NUMERIC会比SQL\_LONG性能高一些。因为如果是char,在数据库服务端插入数据时需要进行数据类型转换,从而引发性能瓶颈。 + diff --git "a/content/docs-lite/zh/docs/DeveloperGuide/\345\237\272\344\272\216ODBC\345\274\200\345\217\221.md" "b/content/docs-lite/zh/docs/DeveloperGuide/\345\237\272\344\272\216ODBC\345\274\200\345\217\221.md" new file mode 100644 index 000000000..ee17bb775 --- /dev/null +++ "b/content/docs-lite/zh/docs/DeveloperGuide/\345\237\272\344\272\216ODBC\345\274\200\345\217\221.md" @@ -0,0 +1,61 @@ +# 基于ODBC开发 + +- **[ODBC包及依赖的库和头文件](ODBC包及依赖的库和头文件.md)** + +- **[Linux下配置数据源](Linux下配置数据源.md)** + +- **[开发流程](开发流程_ODBC.md)** + +- **[示例](示例-常用功能和批量绑定.md)** + +- **[ODBC接口参考](ODBC接口参考.md)** + +ODBC(Open Database Connectivity,开放数据库互连)是由Microsoft公司基于X/OPEN CLI提出的用于访问数据库的应用程序编程接口。应用程序通过ODBC提供的API与数据库进行交互,增强了应用程序的可移植性、扩展性和可维护性。 + +ODBC的系统结构参见[图1](#fig1255101034110)。 + +**图 1** ODBC系统机构 +![](figures/ODBC系统机构.png "ODBC系统机构") + +openGauss目前在以下环境中提供对ODBC3.5的支持。 + +**表 1** ODBC支持平台 + + + + + + + + + + + + + + + + + + + +

操作系统

+

平台

+

CentOS 6.4/6.5/6.6/6.7/6.8/6.9/7.0/7.1/7.2/7.3/7.4

+

x86_64位

+

CentOS 7.6

+

ARM64位

+

EulerOS 2.0 SP2/SP3

+

x86_64位

+

EulerOS 2.0 SP8

+

ARM64位

+
+ +UNIX/Linux系统下的驱动程序管理器主要有unixODBC和iODBC,在这选择驱动管理器unixODBC-2.3.0作为连接数据库的组件。 + +Windows系统自带ODBC驱动程序管理器,在控制面板-\>管理工具中可以找到数据源(ODBC)选项。 + +>![](public_sys-resources/icon-note.gif) **说明:** +>当前数据库ODBC驱动基于开源版本,对于tinyint、smalldatetime、nvarchar、nvarchar2类型,在获取数据类型的时候,可能会出现不兼容。 + + diff --git "a/content/docs-lite/zh/docs/DeveloperGuide/\345\274\200\345\217\221\346\265\201\347\250\213_ODBC.md" "b/content/docs-lite/zh/docs/DeveloperGuide/\345\274\200\345\217\221\346\265\201\347\250\213_ODBC.md" new file mode 100644 index 000000000..4a16b3aa2 --- /dev/null +++ "b/content/docs-lite/zh/docs/DeveloperGuide/\345\274\200\345\217\221\346\265\201\347\250\213_ODBC.md" @@ -0,0 +1,108 @@ +# 开发流程 + +**图 1** ODBC开发应用程序的流程 +![](figures/ODBC开发应用程序的流程.png "ODBC开发应用程序的流程") + +## 开发流程中涉及的API + +**表 1** 相关API说明 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

功能

+

API

+

申请句柄资源

+

SQLAllocHandle:申请句柄资源,可替代如下函数:

+ +

设置环境属性

+

SQLSetEnvAttr

+

设置连接属性

+

SQLSetConnectAttr

+

设置语句属性

+

SQLSetStmtAttr

+

连接数据源

+

SQLConnect

+

绑定缓冲区到结果集的列中

+

SQLBindCol

+

绑定SQL语句的参数标志和缓冲区

+

SQLBindParameter

+

查看最近一次操作错误信息

+

SQLGetDiagRec

+

为执行SQL语句做准备

+

SQLPrepare

+

执行一条准备好的SQL语句

+

SQLExecute

+

直接执行SQL语句

+

SQLExecDirect

+

结果集中取行集

+

SQLFetch

+

返回结果集中某一列的数据

+

SQLGetData

+

获取结果集中列的描述信息

+

SQLColAttribute

+

断开与数据源的连接

+

SQLDisconnect

+

释放句柄资源

+

SQLFreeHandle:释放句柄资源,可替代如下函数:

+ +
+ +>![](public_sys-resources/icon-note.gif) **说明:** +>数据库中收到的一次执行请求(不在事务块中),如果含有多条语句,将会被打包成一个事务,同时如果其中有一个语句失败,那么整个请求都将会被回滚。 + +> **警告:** +> +> ODBC为应用程序与数据库的中心层,负责把应用程序发出的SQL指令传到数据库当中,自身并不解析SQL语法。故在应用程序中写入带有保密信息的SQL语句时(如明文密码),保密信息会被暴露在驱动日志中。 + diff --git "a/content/docs-lite/zh/docs/DeveloperGuide/\347\244\272\344\276\213-2.md" "b/content/docs-lite/zh/docs/DeveloperGuide/\347\244\272\344\276\213-2.md" new file mode 100644 index 000000000..13413d1f0 --- /dev/null +++ "b/content/docs-lite/zh/docs/DeveloperGuide/\347\244\272\344\276\213-2.md" @@ -0,0 +1,339 @@ +# 示例 + +## 常用功能示例代码 + +``` +// 此示例演示如何通过ODBC方式获取openGauss中的数据。 +// DBtest.c (compile with: libodbc.so) +#include +#include +#include +#ifdef WIN32 +#include +#endif +SQLHENV V_OD_Env; // Handle ODBC environment +SQLHSTMT V_OD_hstmt; // Handle statement +SQLHDBC V_OD_hdbc; // Handle connection +char typename[100]; +SQLINTEGER value = 100; +SQLINTEGER V_OD_erg,V_OD_buffer,V_OD_err,V_OD_id; +int main(int argc,char *argv[]) +{ + // 1. 申请环境句柄 + V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env); + if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO)) + { + printf("Error AllocHandle\n"); + exit(0); + } + // 2. 设置环境属性(版本信息) + SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); + // 3. 申请连接句柄 + V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc); + if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO)) + { + SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env); + exit(0); + } + // 4. 设置连接属性 + SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0); + // 5. 连接数据源,这里的“userName”与“password”分别表示连接数据库的用户名和用户密码,请根据实际情况修改。 + // 如果odbc.ini文件中已经配置了用户名密码,那么这里可以留空("");但是不建议这么做,因为一旦odbc.ini权限管理不善,将导致数据库用户密码泄露。 + V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "gaussdb", SQL_NTS, + (SQLCHAR*) "userName", SQL_NTS, (SQLCHAR*) "password", SQL_NTS); + if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO)) + { + printf("Error SQLConnect %d\n",V_OD_erg); + SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env); + exit(0); + } + printf("Connected !\n"); + // 6. 设置语句属性 + SQLSetStmtAttr(V_OD_hstmt,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER *)3,0); + // 7. 申请语句句柄 + SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt); + // 8. 直接执行SQL语句。 + SQLExecDirect(V_OD_hstmt,"drop table IF EXISTS customer_t1",SQL_NTS); + SQLExecDirect(V_OD_hstmt,"CREATE TABLE customer_t1(c_customer_sk INTEGER, c_customer_name VARCHAR(32));",SQL_NTS); + SQLExecDirect(V_OD_hstmt,"insert into customer_t1 values(25,li)",SQL_NTS); + // 9. 准备执行 + SQLPrepare(V_OD_hstmt,"insert into customer_t1 values(?)",SQL_NTS); + // 10. 绑定参数 + SQLBindParameter(V_OD_hstmt,1,SQL_PARAM_INPUT,SQL_C_SLONG,SQL_INTEGER,0,0, + &value,0,NULL); + // 11. 执行准备好的语句 + SQLExecute(V_OD_hstmt); + SQLExecDirect(V_OD_hstmt,"select id from testtable",SQL_NTS); + // 12. 获取结果集某一列的属性 + SQLColAttribute(V_OD_hstmt,1,SQL_DESC_TYPE,typename,100,NULL,NULL); + printf("SQLColAtrribute %s\n",typename); + // 13. 绑定结果集 + SQLBindCol(V_OD_hstmt,1,SQL_C_SLONG, (SQLPOINTER)&V_OD_buffer,150, + (SQLLEN *)&V_OD_err); + // 14. 通过SQLFetch取结果集中数据 + V_OD_erg=SQLFetch(V_OD_hstmt); + // 15. 通过SQLGetData获取并返回数据。 + while(V_OD_erg != SQL_NO_DATA) + { + SQLGetData(V_OD_hstmt,1,SQL_C_SLONG,(SQLPOINTER)&V_OD_id,0,NULL); + printf("SQLGetData ----ID = %d\n",V_OD_id); + V_OD_erg=SQLFetch(V_OD_hstmt); + }; + printf("Done !\n"); + // 16. 断开数据源连接并释放句柄资源 + SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt); + SQLDisconnect(V_OD_hdbc); + SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc); + SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env); + return(0); + } +``` + +## 批量绑定示例代码 + +``` +/********************************************************************** +* 请在数据源中打开UseBatchProtocol,同时指定数据库中参数support_batch_bind +* 为on +* CHECK_ERROR的作用是检查并打印错误信息。 +* 此示例将与用户交互式获取DSN、模拟的数据量,忽略的数据量,并将最终数据入库到test_odbc_batch_insert中 +***********************************************************************/ +#include +#include +#include +#include +#include + +#include "util.c" + +void Exec(SQLHDBC hdbc, SQLCHAR* sql) +{ + SQLRETURN retcode; // Return status + SQLHSTMT hstmt = SQL_NULL_HSTMT; // Statement handle + SQLCHAR loginfo[2048]; + + // Allocate Statement Handle + retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); + CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_STMT)", + hstmt, SQL_HANDLE_STMT); + + // Prepare Statement + retcode = SQLPrepare(hstmt, (SQLCHAR*) sql, SQL_NTS); + sprintf((char*)loginfo, "SQLPrepare log: %s", (char*)sql); + CHECK_ERROR(retcode, loginfo, hstmt, SQL_HANDLE_STMT); + + // Execute Statement + retcode = SQLExecute(hstmt); + sprintf((char*)loginfo, "SQLExecute stmt log: %s", (char*)sql); + CHECK_ERROR(retcode, loginfo, hstmt, SQL_HANDLE_STMT); + + // Free Handle + retcode = SQLFreeHandle(SQL_HANDLE_STMT, hstmt); + sprintf((char*)loginfo, "SQLFreeHandle stmt log: %s", (char*)sql); + CHECK_ERROR(retcode, loginfo, hstmt, SQL_HANDLE_STMT); +} + +int main () +{ + SQLHENV henv = SQL_NULL_HENV; + SQLHDBC hdbc = SQL_NULL_HDBC; + int batchCount = 1000; + SQLLEN rowsCount = 0; + int ignoreCount = 0; + + SQLRETURN retcode; + SQLCHAR dsn[1024] = {'\0'}; + SQLCHAR loginfo[2048]; + + // 交互获取数据源名称 + getStr("Please input your DSN", (char*)dsn, sizeof(dsn), 'N'); + // 交互获取批量绑定的数据量 + getInt("batchCount", &batchCount, 'N', 1); + do + { + // 交互获取批量绑定的数据中,不要入库的数据量 + getInt("ignoreCount", &ignoreCount, 'N', 1); + if (ignoreCount > batchCount) + { + printf("ignoreCount(%d) should be less than batchCount(%d)\n", ignoreCount, batchCount); + } + }while(ignoreCount > batchCount); + + retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); + CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_ENV)", + henv, SQL_HANDLE_ENV); + + // Set ODBC Verion + retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, + (SQLPOINTER*)SQL_OV_ODBC3, 0); + CHECK_ERROR(retcode, "SQLSetEnvAttr(SQL_ATTR_ODBC_VERSION)", + henv, SQL_HANDLE_ENV); + + // Allocate Connection + retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); + CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_DBC)", + henv, SQL_HANDLE_DBC); + + // Set Login Timeout + retcode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0); + CHECK_ERROR(retcode, "SQLSetConnectAttr(SQL_LOGIN_TIMEOUT)", + hdbc, SQL_HANDLE_DBC); + + // Set Auto Commit + retcode = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, + (SQLPOINTER)(1), 0); + CHECK_ERROR(retcode, "SQLSetConnectAttr(SQL_ATTR_AUTOCOMMIT)", + hdbc, SQL_HANDLE_DBC); + + // Connect to DSN + sprintf(loginfo, "SQLConnect(DSN:%s)", dsn); + retcode = SQLConnect(hdbc, (SQLCHAR*) dsn, SQL_NTS, + (SQLCHAR*) NULL, 0, NULL, 0); + CHECK_ERROR(retcode, loginfo, hdbc, SQL_HANDLE_DBC); + + // init table info. + Exec(hdbc, "drop table if exists test_odbc_batch_insert"); + Exec(hdbc, "create table test_odbc_batch_insert(id int primary key, col varchar2(50))"); + + // 下面的代码根据用户输入的数据量,构造出将要入库的数据: + { + SQLRETURN retcode; + SQLHSTMT hstmtinesrt = SQL_NULL_HSTMT; + int i; + SQLCHAR *sql = NULL; + SQLINTEGER *ids = NULL; + SQLCHAR *cols = NULL; + SQLLEN *bufLenIds = NULL; + SQLLEN *bufLenCols = NULL; + SQLUSMALLINT *operptr = NULL; + SQLUSMALLINT *statusptr = NULL; + SQLULEN process = 0; + + // 这里是按列构造,每个字段的内存连续存放在一起。 + ids = (SQLINTEGER*)malloc(sizeof(ids[0]) * batchCount); + cols = (SQLCHAR*)malloc(sizeof(cols[0]) * batchCount * 50); + // 这里是每个字段中,每一行数据的内存长度。 + bufLenIds = (SQLLEN*)malloc(sizeof(bufLenIds[0]) * batchCount); + bufLenCols = (SQLLEN*)malloc(sizeof(bufLenCols[0]) * batchCount); + // 该行是否需要被处理,SQL_PARAM_IGNORE 或 SQL_PARAM_PROCEED + operptr = (SQLUSMALLINT*)malloc(sizeof(operptr[0]) * batchCount); + memset(operptr, 0, sizeof(operptr[0]) * batchCount); + // 该行的处理结果。 + // 注:由于数据库中处理方式是同一语句隶属同一事务中,所以如果出错,那么待处理数据都将是出错的,并不会部分入库。 + statusptr = (SQLUSMALLINT*)malloc(sizeof(statusptr[0]) * batchCount); + memset(statusptr, 88, sizeof(statusptr[0]) * batchCount); + + if (NULL == ids || NULL == cols || NULL == bufLenCols || NULL == bufLenIds) + { + fprintf(stderr, "FAILED:\tmalloc data memory failed\n"); + goto exit; + } + + for (int i = 0; i < batchCount; i++) + { + ids[i] = i; + sprintf(cols + 50 * i, "column test value %d", i); + bufLenIds[i] = sizeof(ids[i]); + bufLenCols[i] = strlen(cols + 50 * i); + operptr[i] = (i < ignoreCount) ? SQL_PARAM_IGNORE : SQL_PARAM_PROCEED; + } + + // Allocate Statement Handle + retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmtinesrt); + CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_STMT)", + hstmtinesrt, SQL_HANDLE_STMT); + + // Prepare Statement + sql = (SQLCHAR*)"insert into test_odbc_batch_insert values(?, ?)"; + retcode = SQLPrepare(hstmtinesrt, (SQLCHAR*) sql, SQL_NTS); + sprintf((char*)loginfo, "SQLPrepare log: %s", (char*)sql); + CHECK_ERROR(retcode, loginfo, hstmtinesrt, SQL_HANDLE_STMT); + + retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER)batchCount, sizeof(batchCount)); + CHECK_ERROR(retcode, "SQLSetStmtAttr", hstmtinesrt, SQL_HANDLE_STMT); + + retcode = SQLBindParameter(hstmtinesrt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(ids[0]), 0,&(ids[0]), 0, bufLenIds); + CHECK_ERROR(retcode, "SQLBindParameter for id", hstmtinesrt, SQL_HANDLE_STMT); + + retcode = SQLBindParameter(hstmtinesrt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 50, 50, cols, 50, bufLenCols); + CHECK_ERROR(retcode, "SQLBindParameter for cols", hstmtinesrt, SQL_HANDLE_STMT); + + retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAMS_PROCESSED_PTR, (SQLPOINTER)&process, sizeof(process)); + CHECK_ERROR(retcode, "SQLSetStmtAttr for SQL_ATTR_PARAMS_PROCESSED_PTR", hstmtinesrt, SQL_HANDLE_STMT); + + retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAM_STATUS_PTR, (SQLPOINTER)statusptr, sizeof(statusptr[0]) * batchCount); + CHECK_ERROR(retcode, "SQLSetStmtAttr for SQL_ATTR_PARAM_STATUS_PTR", hstmtinesrt, SQL_HANDLE_STMT); + + retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAM_OPERATION_PTR, (SQLPOINTER)operptr, sizeof(operptr[0]) * batchCount); + CHECK_ERROR(retcode, "SQLSetStmtAttr for SQL_ATTR_PARAM_OPERATION_PTR", hstmtinesrt, SQL_HANDLE_STMT); + + retcode = SQLExecute(hstmtinesrt); + sprintf((char*)loginfo, "SQLExecute stmt log: %s", (char*)sql); + CHECK_ERROR(retcode, loginfo, hstmtinesrt, SQL_HANDLE_STMT); + + retcode = SQLRowCount(hstmtinesrt, &rowsCount); + CHECK_ERROR(retcode, "SQLRowCount execution", hstmtinesrt, SQL_HANDLE_STMT); + + if (rowsCount != (batchCount - ignoreCount)) + { + sprintf(loginfo, "(batchCount - ignoreCount)(%d) != rowsCount(%d)", (batchCount - ignoreCount), rowsCount); + CHECK_ERROR(SQL_ERROR, loginfo, NULL, SQL_HANDLE_STMT); + } + else + { + sprintf(loginfo, "(batchCount - ignoreCount)(%d) == rowsCount(%d)", (batchCount - ignoreCount), rowsCount); + CHECK_ERROR(SQL_SUCCESS, loginfo, NULL, SQL_HANDLE_STMT); + } + + // check row number returned + if (rowsCount != process) + { + sprintf(loginfo, "process(%d) != rowsCount(%d)", process, rowsCount); + CHECK_ERROR(SQL_ERROR, loginfo, NULL, SQL_HANDLE_STMT); + } + else + { + sprintf(loginfo, "process(%d) == rowsCount(%d)", process, rowsCount); + CHECK_ERROR(SQL_SUCCESS, loginfo, NULL, SQL_HANDLE_STMT); + } + + for (int i = 0; i < batchCount; i++) + { + if (i < ignoreCount) + { + if (statusptr[i] != SQL_PARAM_UNUSED) + { + sprintf(loginfo, "statusptr[%d](%d) != SQL_PARAM_UNUSED", i, statusptr[i]); + CHECK_ERROR(SQL_ERROR, loginfo, NULL, SQL_HANDLE_STMT); + } + } + else if (statusptr[i] != SQL_PARAM_SUCCESS) + { + sprintf(loginfo, "statusptr[%d](%d) != SQL_PARAM_SUCCESS", i, statusptr[i]); + CHECK_ERROR(SQL_ERROR, loginfo, NULL, SQL_HANDLE_STMT); + } + } + + retcode = SQLFreeHandle(SQL_HANDLE_STMT, hstmtinesrt); + sprintf((char*)loginfo, "SQLFreeHandle hstmtinesrt"); + CHECK_ERROR(retcode, loginfo, hstmtinesrt, SQL_HANDLE_STMT); + } + + +exit: + printf ("\nComplete.\n"); + + // Connection + if (hdbc != SQL_NULL_HDBC) { + SQLDisconnect(hdbc); + SQLFreeHandle(SQL_HANDLE_DBC, hdbc); + } + + // Environment + if (henv != SQL_NULL_HENV) + SQLFreeHandle(SQL_HANDLE_ENV, henv); + + return 0; +} +``` + diff --git "a/content/docs-lite/zh/docs/DeveloperGuide/\347\244\272\344\276\213-\345\270\270\347\224\250\345\212\237\350\203\275\345\222\214\346\211\271\351\207\217\347\273\221\345\256\232.md" "b/content/docs-lite/zh/docs/DeveloperGuide/\347\244\272\344\276\213-\345\270\270\347\224\250\345\212\237\350\203\275\345\222\214\346\211\271\351\207\217\347\273\221\345\256\232.md" new file mode 100644 index 000000000..9a0ebdcab --- /dev/null +++ "b/content/docs-lite/zh/docs/DeveloperGuide/\347\244\272\344\276\213-\345\270\270\347\224\250\345\212\237\350\203\275\345\222\214\346\211\271\351\207\217\347\273\221\345\256\232.md" @@ -0,0 +1,434 @@ +# 示例:常用功能和批量绑定 + +## 常用功能示例代码 + +``` +// 此示例演示如何通过ODBC方式获取openGauss中的数据。 +// DBtest.c (compile with: libodbc.so) +#include +#include +#include +#ifdef WIN32 +#include +#endif +SQLHENV V_OD_Env; // Handle ODBC environment +SQLHSTMT V_OD_hstmt; // Handle statement +SQLHDBC V_OD_hdbc; // Handle connection +char typename[100]; +SQLINTEGER value = 100; +SQLINTEGER V_OD_erg,V_OD_buffer,V_OD_err,V_OD_id; +int main(int argc,char *argv[]) +{ + // 1. 申请环境句柄 + V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env); + if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO)) + { + printf("Error AllocHandle\n"); + exit(0); + } + // 2. 设置环境属性(版本信息) + SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); + // 3. 申请连接句柄 + V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc); + if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO)) + { + SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env); + exit(0); + } + // 4. 设置连接属性 + SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0); + // 5. 连接数据源,这里的“userName”与“password”分别表示连接数据库的用户名和用户密码,请根据实际情况修改。 + // 如果odbc.ini文件中已经配置了用户名密码,那么这里可以留空("");但是不建议这么做,因为一旦odbc.ini权限管理不善,将导致数据库用户密码泄露。 + V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "gaussdb", SQL_NTS, + (SQLCHAR*) "userName", SQL_NTS, (SQLCHAR*) "password", SQL_NTS); + if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO)) + { + printf("Error SQLConnect %d\n",V_OD_erg); + SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env); + exit(0); + } + printf("Connected !\n"); + // 6. 设置语句属性 + SQLSetStmtAttr(V_OD_hstmt,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER *)3,0); + // 7. 申请语句句柄 + SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt); + // 8. 直接执行SQL语句。 + SQLExecDirect(V_OD_hstmt,"drop table IF EXISTS customer_t1",SQL_NTS); + SQLExecDirect(V_OD_hstmt,"CREATE TABLE customer_t1(c_customer_sk INTEGER, c_customer_name VARCHAR(32));",SQL_NTS); + SQLExecDirect(V_OD_hstmt,"insert into customer_t1 values(25,li)",SQL_NTS); + // 9. 准备执行 + SQLPrepare(V_OD_hstmt,"insert into customer_t1 values(?)",SQL_NTS); + // 10. 绑定参数 + SQLBindParameter(V_OD_hstmt,1,SQL_PARAM_INPUT,SQL_C_SLONG,SQL_INTEGER,0,0, + &value,0,NULL); + // 11. 执行准备好的语句 + SQLExecute(V_OD_hstmt); + SQLExecDirect(V_OD_hstmt,"select id from testtable",SQL_NTS); + // 12. 获取结果集某一列的属性 + SQLColAttribute(V_OD_hstmt,1,SQL_DESC_TYPE,typename,100,NULL,NULL); + printf("SQLColAtrribute %s\n",typename); + // 13. 绑定结果集 + SQLBindCol(V_OD_hstmt,1,SQL_C_SLONG, (SQLPOINTER)&V_OD_buffer,150, + (SQLLEN *)&V_OD_err); + // 14. 通过SQLFetch取结果集中数据 + V_OD_erg=SQLFetch(V_OD_hstmt); + // 15. 通过SQLGetData获取并返回数据。 + while(V_OD_erg != SQL_NO_DATA) + { + SQLGetData(V_OD_hstmt,1,SQL_C_SLONG,(SQLPOINTER)&V_OD_id,0,NULL); + printf("SQLGetData ----ID = %d\n",V_OD_id); + V_OD_erg=SQLFetch(V_OD_hstmt); + }; + printf("Done !\n"); + // 16. 断开数据源连接并释放句柄资源 + SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt); + SQLDisconnect(V_OD_hdbc); + SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc); + SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env); + return(0); + } +``` + +## 批量绑定示例代码 + +``` +/********************************************************************** +* 请在数据源中打开UseBatchProtocol,同时指定数据库中参数support_batch_bind +* 为on +* CHECK_ERROR的作用是检查并打印错误信息。 +* 此示例将与用户交互式获取DSN、模拟的数据量,忽略的数据量,并将最终数据入库到test_odbc_batch_insert中 +***********************************************************************/ +#include +#include +#include +#include +#include + +void Exec(SQLHDBC hdbc, SQLCHAR* sql) +{ + SQLRETURN retcode; // Return status + SQLHSTMT hstmt = SQL_NULL_HSTMT; // Statement handle + SQLCHAR loginfo[2048]; + + // Allocate Statement Handle + retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLAllocHandle(SQL_HANDLE_STMT) failed"); + return; + } + + // Prepare Statement + retcode = SQLPrepare(hstmt, (SQLCHAR*) sql, SQL_NTS); + sprintf((char*)loginfo, "SQLPrepare log: %s", (char*)sql); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLPrepare(hstmt, (SQLCHAR*) sql, SQL_NTS) failed"); + return; + } + + // Execute Statement + retcode = SQLExecute(hstmt); + sprintf((char*)loginfo, "SQLExecute stmt log: %s", (char*)sql); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute(hstmt) failed"); + return; + } + // Free Handle + retcode = SQLFreeHandle(SQL_HANDLE_STMT, hstmt); + sprintf((char*)loginfo, "SQLFreeHandle stmt log: %s", (char*)sql); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLFreeHandle(SQL_HANDLE_STMT, hstmt) failed"); + return; + } +} + +int main () +{ + SQLHENV henv = SQL_NULL_HENV; + SQLHDBC hdbc = SQL_NULL_HDBC; + long int batchCount = 1000; // 批量绑定的数据量 + SQLLEN rowsCount = 0; + int ignoreCount = 0; // 批量绑定的数据中,不要入库的数据量 + + SQLRETURN retcode; + SQLCHAR dsn[1024] = {'\0'}; + SQLCHAR loginfo[2048]; + + do + { + if (ignoreCount > batchCount) + { + printf("ignoreCount(%d) should be less than batchCount(%d)\n", ignoreCount, batchCount); + } + }while(ignoreCount > batchCount); + + retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLAllocHandle failed"); + goto exit; + } + + // Set ODBC Verion + retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, + (SQLPOINTER*)SQL_OV_ODBC3, 0); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLSetEnvAttr failed"); + goto exit; + } + + // Allocate Connection + retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLAllocHandle failed"); + goto exit; + } + + + // Set Login Timeout + retcode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLSetConnectAttr failed"); + goto exit; + } + + + // Set Auto Commit + retcode = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, + (SQLPOINTER)(1), 0); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLSetConnectAttr failed"); + goto exit; + } + + + // Connect to DSN + // gaussdb替换成用户所使用的数据源名称 + sprintf(loginfo, "SQLConnect(DSN:%s)", dsn); + retcode = SQLConnect(hdbc, (SQLCHAR*) "gaussdb", SQL_NTS, + (SQLCHAR*) NULL, 0, NULL, 0); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLConnect failed"); + goto exit; + } + + // init table info. + Exec(hdbc, "drop table if exists test_odbc_batch_insert"); + Exec(hdbc, "create table test_odbc_batch_insert(id int primary key, col varchar2(50))"); + + // 下面的代码根据用户输入的数据量,构造出将要入库的数据: + { + SQLRETURN retcode; + SQLHSTMT hstmtinesrt = SQL_NULL_HSTMT; + int i; + SQLCHAR *sql = NULL; + SQLINTEGER *ids = NULL; + SQLCHAR *cols = NULL; + SQLLEN *bufLenIds = NULL; + SQLLEN *bufLenCols = NULL; + SQLUSMALLINT *operptr = NULL; + SQLUSMALLINT *statusptr = NULL; + SQLULEN process = 0; + + // 这里是按列构造,每个字段的内存连续存放在一起。 + ids = (SQLINTEGER*)malloc(sizeof(ids[0]) * batchCount); + cols = (SQLCHAR*)malloc(sizeof(cols[0]) * batchCount * 50); + // 这里是每个字段中,每一行数据的内存长度。 + bufLenIds = (SQLLEN*)malloc(sizeof(bufLenIds[0]) * batchCount); + bufLenCols = (SQLLEN*)malloc(sizeof(bufLenCols[0]) * batchCount); + // 该行是否需要被处理,SQL_PARAM_IGNORE 或 SQL_PARAM_PROCEED + operptr = (SQLUSMALLINT*)malloc(sizeof(operptr[0]) * batchCount); + memset(operptr, 0, sizeof(operptr[0]) * batchCount); + // 该行的处理结果。 + // 注:由于数据库中处理方式是同一语句隶属同一事务中,所以如果出错,那么待处理数据都将是出错的,并不会部分入库。 + statusptr = (SQLUSMALLINT*)malloc(sizeof(statusptr[0]) * batchCount); + memset(statusptr, 88, sizeof(statusptr[0]) * batchCount); + + if (NULL == ids || NULL == cols || NULL == bufLenCols || NULL == bufLenIds) + { + fprintf(stderr, "FAILED:\tmalloc data memory failed\n"); + goto exit; + } + + for (int i = 0; i < batchCount; i++) + { + ids[i] = i; + sprintf(cols + 50 * i, "column test value %d", i); + bufLenIds[i] = sizeof(ids[i]); + bufLenCols[i] = strlen(cols + 50 * i); + operptr[i] = (i < ignoreCount) ? SQL_PARAM_IGNORE : SQL_PARAM_PROCEED; + } + + // Allocate Statement Handle + retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmtinesrt); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLAllocHandle failed"); + goto exit; + } + + // Prepare Statement + sql = (SQLCHAR*)"insert into test_odbc_batch_insert values(?, ?)"; + retcode = SQLPrepare(hstmtinesrt, (SQLCHAR*) sql, SQL_NTS); + sprintf((char*)loginfo, "SQLPrepare log: %s", (char*)sql); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLPrepare failed"); + goto exit; + } + + retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER)batchCount, sizeof(batchCount)); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLSetStmtAttr failed"); + goto exit; + } + + retcode = SQLBindParameter(hstmtinesrt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(ids[0]), 0,&(ids[0]), 0, bufLenIds); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLBindParameter failed"); + goto exit; + } + + retcode = SQLBindParameter(hstmtinesrt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 50, 50, cols, 50, bufLenCols); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLBindParameter failed"); + goto exit; + } + + retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAMS_PROCESSED_PTR, (SQLPOINTER)&process, sizeof(process)); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLSetStmtAttr failed"); + goto exit; + } + + retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAM_STATUS_PTR, (SQLPOINTER)statusptr, sizeof(statusptr[0]) * batchCount); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLSetStmtAttr failed"); + goto exit; + } + + retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAM_OPERATION_PTR, (SQLPOINTER)operptr, sizeof(operptr[0]) * batchCount); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLSetStmtAttr failed"); + goto exit; + } + + retcode = SQLExecute(hstmtinesrt); + sprintf((char*)loginfo, "SQLExecute stmt log: %s", (char*)sql); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute(hstmtinesrt) failed"); + goto exit; + + retcode = SQLRowCount(hstmtinesrt, &rowsCount); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLRowCount failed"); + goto exit; + } + + if (rowsCount != (batchCount - ignoreCount)) + { + sprintf(loginfo, "(batchCount - ignoreCount)(%d) != rowsCount(%d)", (batchCount - ignoreCount), rowsCount); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute failed"); + goto exit; + } + } + else + { + sprintf(loginfo, "(batchCount - ignoreCount)(%d) == rowsCount(%d)", (batchCount - ignoreCount), rowsCount); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute failed"); + goto exit; + } + } + + // check row number returned + if (rowsCount != process) + { + sprintf(loginfo, "process(%d) != rowsCount(%d)", process, rowsCount); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute failed"); + goto exit; + } + } + else + { + sprintf(loginfo, "process(%d) == rowsCount(%d)", process, rowsCount); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute failed"); + goto exit; + } + } + + for (int i = 0; i < batchCount; i++) + { + if (i < ignoreCount) + { + if (statusptr[i] != SQL_PARAM_UNUSED) + { + sprintf(loginfo, "statusptr[%d](%d) != SQL_PARAM_UNUSED", i, statusptr[i]); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute failed"); + goto exit; + } + } + } + else if (statusptr[i] != SQL_PARAM_SUCCESS) + { + sprintf(loginfo, "statusptr[%d](%d) != SQL_PARAM_SUCCESS", i, statusptr[i]); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLExecute failed"); + goto exit; + } + } + } + + retcode = SQLFreeHandle(SQL_HANDLE_STMT, hstmtinesrt); + sprintf((char*)loginfo, "SQLFreeHandle hstmtinesrt"); + + if (!SQL_SUCCEEDED(retcode)) { + printf("SQLFreeHandle failed"); + goto exit; + } + } + + +exit: + (void) printf ("\nComplete.\n"); + + // Connection + if (hdbc != SQL_NULL_HDBC) { + SQLDisconnect(hdbc); + SQLFreeHandle(SQL_HANDLE_DBC, hdbc); + } + + // Environment + if (henv != SQL_NULL_HENV) + SQLFreeHandle(SQL_HANDLE_ENV, henv); + + return 0; +} +``` + diff --git a/content/docs-lite/zh/menu/index.md b/content/docs-lite/zh/menu/index.md index 38565b9c8..0a8d7f8e2 100644 --- a/content/docs-lite/zh/menu/index.md +++ b/content/docs-lite/zh/menu/index.md @@ -236,24 +236,54 @@ headless: true - [示例:jdbc主备集群负载均衡]({{< relref "./docs/Developerguide/示例-jdbc主备集群负载均衡.md" >}}) - [JDBC接口参考]({{< relref "./docs/DeveloperGuide/JDBC接口参考.md" >}}) - [JDBC常用参数参考]({{< relref "./docs/DeveloperGuide/JDBC常用参数参考.md" >}}) - - [基于libpq开发]({{< relref "./docs/DeveloperGuide/基于libpq开发.md" >}}) - - [libpq使用依赖的头文件]({{< relref "./docs/DeveloperGuide/libpq使用依赖的头文件.md" >}}) - - [开发流程]({{< relref "./docs/DeveloperGuide/开发流程_libpq.md" >}}) - - [示例]({{< relref "./docs/DeveloperGuide/示例-libpq.md" >}}) - - [libpq接口参考]({{< relref "./docs/DeveloperGuide/libpq接口参考.md" >}}) - - [链接参数]({{< relref "./docs/DeveloperGuide/链接参数.md" >}}) - - [基于Psycopg开发]({{< relref "./docs/DeveloperGuide/基于Psycopg开发.md" >}}) - - [Psycopg包]({{< relref "./docs/DeveloperGuide/Psycopg包.md" >}}) - - [开发流程]({{< relref "./docs/DeveloperGuide/开发流程_Psycopg.md" >}}) - - [加载驱动]({{< relref "./docs/DeveloperGuide/加载驱动_Psycopg.md" >}}) - - [连接数据库]({{< relref "./docs/DeveloperGuide/连接数据库_Psycopg.md" >}}) - - [执行SQL语句]({{< relref "./docs/DeveloperGuide/执行SQL语句_Psycopg.md" >}}) - - [处理结果集]({{< relref "./docs/DeveloperGuide/处理结果集_Psycopg.md" >}}) - - [关闭连接]({{< relref "./docs/DeveloperGuide/关闭连接_Psycopg.md" >}}) - - [连接数据库(SSL方式)]({{< relref "./docs/DeveloperGuide/连接数据库_SSL方式_Psycopg.md" >}}) - - [示例:常用操作]({{< relref "./docs/DeveloperGuide/示例-常用操作_Psycopg.md" >}}) - - [Psycopg接口参考]({{< relref "./docs/DeveloperGuide/Psycopg接口参考.md" >}}) - - [编译与调试]({{< relref "./docs/DeveloperGuide/编译与调试.md" >}}) + - [基于ODBC开发]({{< relref "./docs/DeveloperGuide/基于ODBC开发.md" >}}) + - [ODBC包及依赖的库和头文件]({{< relref "./docs/DeveloperGuide/ODBC包及依赖的库和头文件.md" >}}) + - [Linux下配置数据源]({{< relref "./docs/DeveloperGuide/Linux下配置数据源.md" >}}) + - [开发流程]({{< relref "./docs/DeveloperGuide/开发流程_ODBC.md" >}}) + - [示例:常用功能和批量绑定]({{< relref "./docs/DeveloperGuide/示例-常用功能和批量绑定.md" >}}) + - [典型应用场景配置]({{< relref "./docs/DeveloperGuide/典型应用场景配置.md" >}}) + - [ODBC接口参考]({{< relref "./docs/DeveloperGuide/ODBC接口参考.md" >}}) + - [SQLAllocEnv]({{< relref "./docs/DeveloperGuide/SQLAllocEnv.md" >}}) + - [SQLAllocConnect]({{< relref "./docs/DeveloperGuide/SQLAllocConnect.md" >}}) + - [SQLAllocHandle]({{< relref "./docs/DeveloperGuide/SQLAllocHandle.md" >}}) + - [SQLAllocStmt]({{< relref "./docs/DeveloperGuide/SQLAllocStmt.md" >}}) + - [SQLBindCol]({{< relref "./docs/DeveloperGuide/SQLBindCol.md" >}}) + - [SQLBindParameter]({{< relref "./docs/DeveloperGuide/SQLBindParameter.md" >}}) + - [SQLColAttribute]({{< relref "./docs/DeveloperGuide/SQLColAttribute.md" >}}) + - [SQLConnect]({{< relref "./docs/DeveloperGuide/SQLConnect.md" >}}) + - [SQLDisconnect]({{< relref "./docs/DeveloperGuide/SQLDisconnect.md" >}}) + - [SQLExecDirect]({{< relref "./docs/DeveloperGuide/SQLExecDirect.md" >}}) + - [SQLExecute]({{< relref "./docs/DeveloperGuide/SQLExecute.md" >}}) + - [SQLFetch]({{< relref "./docs/DeveloperGuide/SQLFetch.md" >}}) + - [SQLFreeStmt]({{< relref "./docs/DeveloperGuide/SQLFreeStmt.md" >}}) + - [SQLFreeConnect]({{< relref "./docs/DeveloperGuide/SQLFreeConnect.md" >}}) + - [SQLFreeHandle]({{< relref "./docs/DeveloperGuide/SQLFreeHandle.md" >}}) + - [SQLFreeEnv]({{< relref "./docs/DeveloperGuide/SQLFreeEnv.md" >}}) + - [SQLPrepare]({{< relref "./docs/DeveloperGuide/SQLPrepare.md" >}}) + - [SQLGetData]({{< relref "./docs/DeveloperGuide/SQLGetData.md" >}}) + - [SQLGetDiagRec]({{< relref "./docs/DeveloperGuide/SQLGetDiagRec.md" >}}) + - [SQLSetConnectAttr]({{< relref "./docs/DeveloperGuide/SQLSetConnectAttr.md" >}}) + - [SQLSetEnvAttr]({{< relref "./docs/DeveloperGuide/SQLSetEnvAttr.md" >}}) + - [SQLSetStmtAttr]({{< relref "./docs/DeveloperGuide/SQLSetStmtAttr.md" >}}) + - [示例]({{< relref "./docs/DeveloperGuide/示例-2.md" >}}) + - [基于libpq开发]({{< relref "./docs/DeveloperGuide/基于libpq开发.md" >}}) + - [libpq使用依赖的头文件]({{< relref "./docs/DeveloperGuide/libpq使用依赖的头文件.md" >}}) + - [开发流程]({{< relref "./docs/DeveloperGuide/开发流程_libpq.md" >}}) + - [示例]({{< relref "./docs/DeveloperGuide/示例-libpq.md" >}}) + - [libpq接口参考]({{< relref "./docs/DeveloperGuide/libpq接口参考.md" >}}) + - [链接参数]({{< relref "./docs/DeveloperGuide/链接参数.md" >}}) + - [基于Psycopg开发]({{< relref "./docs/DeveloperGuide/基于Psycopg开发.md" >}}) + - [Psycopg包]({{< relref "./docs/DeveloperGuide/Psycopg包.md" >}}) + - [开发流程]({{< relref "./docs/DeveloperGuide/开发流程_Psycopg.md" >}}) + - [加载驱动]({{< relref "./docs/DeveloperGuide/加载驱动_Psycopg.md" >}}) + - [连接数据库]({{< relref "./docs/DeveloperGuide/连接数据库_Psycopg.md" >}}) + - [执行SQL语句]({{< relref "./docs/DeveloperGuide/执行SQL语句_Psycopg.md" >}}) + - [处理结果集]({{< relref "./docs/DeveloperGuide/处理结果集_Psycopg.md" >}}) + - [关闭连接]({{< relref "./docs/DeveloperGuide/关闭连接_Psycopg.md" >}}) + - [连接数据库(SSL方式)]({{< relref "./docs/DeveloperGuide/连接数据库_SSL方式_Psycopg.md" >}}) + - [示例:常用操作]({{< relref "./docs/DeveloperGuide/示例-常用操作_Psycopg.md" >}}) + - [Psycopg接口参考]({{< relref "./docs/DeveloperGuide/Psycopg接口参考.md" >}}) + - [编译与调试]({{< relref "./docs/DeveloperGuide/编译与调试.md" >}}) - [编译指南]({{< relref "./docs/CompilationGuide/Compilation.md" >}}) - [简介]({{< relref "./docs/CompilationGuide/简介.md" >}}) @@ -570,7 +600,7 @@ headless: true - [案例:改写SQL消除子查询(案例1)]({{< relref "./docs/PerformanceTuningGuide/案例-改写SQL消除子查询_案例1.md" >}}) - [案例:改写SQL消除子查询(案例2)]({{< relref "./docs/PerformanceTuningGuide/案例-改写SQL消除子查询_案例2.md" >}}) - [案例:改写SQL消除in-clause]({{< relref "./docs/PerformanceTuningGuide/案例-改写SQL消除in-clause.md" >}}) - + - [SQL参考]({{< relref "./docs/SQLReference/SQL参考.md" >}}) - [SQL语法格式说明]({{< relref "./docs/SQLReference/SQL语法格式说明.md" >}}) - [SQL语言结构和语法]({{< relref "./docs/SQLReference/SQL语言结构和语法.md" >}}) diff --git a/content/en/menu/index.md b/content/en/menu/index.md index 154ece41d..75de9beec 100644 --- a/content/en/menu/index.md +++ b/content/en/menu/index.md @@ -238,71 +238,93 @@ headless: true - [Primary/Standby Shared Storage]({{< relref "./docs/BriefTutorial/primary-standby-shared-storage.md" >}}) - [Appendix: SQL Syntax]({{< relref "./docs/BriefTutorial/appendix-sql-syntax.md" >}}) - [Application Development Guide]({{< relref "./docs/DeveloperGuide/application-development-guide.md" >}}) - - [Query Request Handling Process]({{< relref "./docs/DeveloperGuide/query-request-handling-process.md" >}}) - - [Development and Design Proposal]({{< relref "./docs/DeveloperGuide/development-and-design-proposal.md" >}}) - - [Overview]({{< relref "./docs/DeveloperGuide/development-and-design-proposal-overview.md" >}}) - - [Database Object Naming Conventions]({{< relref "./docs/DeveloperGuide/database-object-naming-conventions.md" >}}) - - [Database Object Design]({{< relref "./docs/DeveloperGuide/database-object-design.md" >}}) - - [Database and Schema Design]({{< relref "./docs/DeveloperGuide/database-and-schema-design.md" >}}) - - [Table Design]({{< relref "./docs/DeveloperGuide/table-design.md" >}}) - - [Planning a Storage Model]({{< relref "./docs/DeveloperGuide/planning-a-storage-model.md" >}}) - - [Field Design]({{< relref "./docs/DeveloperGuide/field-design.md" >}}) - - [Constraint Design]({{< relref "./docs/DeveloperGuide/constraint-design.md" >}}) - - [View and Joined Table Design]({{< relref "./docs/DeveloperGuide/view-and-joined-table-design.md" >}}) - - [SQL Compilation]({{< relref "./docs/DeveloperGuide/sql-compilation.md" >}}) - - [Application Development Specifications]({{< relref "./docs/DeveloperGuide/application-development-specifications.md" >}}) - - [Development Specifications]({{< relref "./docs/DeveloperGuide/development-specifications.md" >}}) - - [Tool Interconnection]({{< relref "./docs/DeveloperGuide/tool-interconnection.md" >}}) - - [JDBC Configuration]({{< relref "./docs/DeveloperGuide/jdbc-configuration.md" >}}) - - [Development Based on JDBC]({{< relref "./docs/DeveloperGuide/development-based-on-jdbc.md" >}}) - - [JDBC Package, Driver Class, and Environment Class]({{< relref "./docs/DeveloperGuide/jdbc-package-driver-class-and-environment-class.md" >}}) - - [Development Process]({{< relref "./docs/DeveloperGuide/development-process-jdbc.md" >}}) - - [Loading the Driver]({{< relref "./docs/DeveloperGuide/loading-the-driver-jdbc.md" >}}) - - [Connecting to a Database]({{< relref "./docs/DeveloperGuide/connecting-to-a-database-jdbc.md" >}}) - - [Connecting to the Database \(Using SSL\)]({{< relref "./docs/DeveloperGuide/connecting-to-a-database-using-ssl-jdbc.md" >}}) - - [Connecting to a Database (Using UDS)]({{< relref "./docs/DeveloperGuide/connecting-to-a-database-using-uds.md" >}}) - - [Running SQL Statements]({{< relref "./docs/DeveloperGuide/running-sql-statements-jdbc.md" >}}) - - [Processing Data in a Result Set]({{< relref "./docs/DeveloperGuide/processing-data-in-a-result-set-jdbc.md" >}}) - - [Closing a Connection]({{< relref "./docs/DeveloperGuide/closing-a-connection-jdbc.md" >}}) - - [Log Management]({{< relref "./docs/DeveloperGuide/log-management.md" >}}) - - [Examples: Common Operations]({{< relref "./docs/DeveloperGuide/example-common-operations-jdbc.md" >}}) - - [Example: Retrying SQL Queries for Applications]({{< relref "./docs/DeveloperGuide/example-retrying-sql-queries-for-applications.md" >}}) - - [Example: Importing and Exporting Data Through Local Files]({{< relref "./docs/DeveloperGuide/example-importing-and-exporting-data-through-local-files.md" >}}) - - [Example: Migrating Data from a MY Database to openGauss]({{< relref "./docs/DeveloperGuide/example-migrating-data-from-a-my-database-to-opengauss.md" >}}) - - [Example: Logical Replication Code]({{< relref "./docs/DeveloperGuide/example-logic-replication-code.md" >}}) - - [Example: Parameters for Connecting to the Database in Different Scenarios]({{< relref "./docs/DeveloperGuide/example-parameters-for-connecting-to-the-database-in-different-scenarios.md" >}}) - - [JDBC Interface Reference]({{< relref "./docs/DeveloperGuide/jdbc-interface-reference.md" >}}) - - [Common JDBC Parameters]({{< relref "./docs/DeveloperGuide/common-jdbc-parameters.md" >}}) - - [Development Based on ODBC]({{< relref "./docs/DeveloperGuide/development-based-on-odbc.md" >}}) - - [ODBC Packages, Dependent Libraries, and Header Files]({{< relref "./docs/DeveloperGuide/odbc-packages-dependent-libraries-and-header-files.md" >}}) - - [Configuring a Data Source in the Linux OS]({{< relref "./docs/DeveloperGuide/configuring-a-data-source-in-the-linux-os.md" >}}) - - [Development Process]({{< relref "./docs/DeveloperGuide/development-process-odbc.md" >}}) - - [Example: Common Functions and Batch Binding]({{< relref "./docs/DeveloperGuide/example-common-functions-and-batch-binding.md" >}}) - - [Typical Application Scenarios and Configurations]({{< relref "./docs/DeveloperGuide/typical-application-scenarios-and-configurations.md" >}}) - - [ODBC Interface Reference]({{< relref "./docs/DeveloperGuide/odbc-interface-reference.md" >}}) - - [Example]({{< relref "./docs/DeveloperGuide/example-odbc.md" >}}) - - [Psycopg-Based Development]({{< relref "./docs/DeveloperGuide/psycopg-based-development.md" >}}) - - [Psycopg Package]({{< relref "./docs/DeveloperGuide/psycopg-package.md" >}}) - - [Development Process]({{< relref "./docs/DeveloperGuide/development-process-psycopg.md" >}}) - - [Loading a Driver]({{< relref "./docs/DeveloperGuide/loading-a-driver-psycopg.md" >}}) - - [Connecting to a Database]({{< relref "./docs/DeveloperGuide/connecting-to-a-database-psycopg.md" >}}) - - [Executing SQL Statements]({{< relref "./docs/DeveloperGuide/executing-sql-statements-psycopg.md" >}}) - - [Processing the Result Set]({{< relref "./docs/DeveloperGuide/processing-the-result-set-psycopg.md" >}}) - - [Closing the Connection]({{< relref "./docs/DeveloperGuide/closing-the-connection-psycopg.md" >}}) - - [Connecting to the Database \(Using SSL\)]({{< relref "./docs/DeveloperGuide/connecting-to-the-database-using-ssl-psycopg.md" >}}) - - [xamples: Common Operations]({{< relref "./docs/DeveloperGuide/example-common-operations-psycopg.md" >}}) - - [Psycopg API Reference]({{< relref "./docs/DeveloperGuide/psycopg-api-reference.md" >}}) - - [Development Based on libpq]({{< relref "./docs/DeveloperGuide/development-based-on-libpq.md" >}}) - - [Dependent Header Files of libpq]({{< relref "./docs/DeveloperGuide/dependent-header-files-of-libpq.md" >}}) - - [Development Process]({{< relref "./docs/DeveloperGuide/development-process-libpq.md" >}}) - - [Example]({{< relref "./docs/DeveloperGuide/example-libpq.md" >}}) - - [libpq API Reference]({{< relref "./docs/DeveloperGuide/libpq-api-reference.md" >}}) - - [Database Connection Control Functions]({{< relref "./docs/DeveloperGuide/database-connection-control-functions.md" >}}) - - [Database Statement Execution Functions]({{< relref "./docs/DeveloperGuide/database-statement-execution-functions.md" >}}) - - [Functions for Asynchronous Command Processing]({{< relref "./docs/DeveloperGuide/functions-for-asynchronous-command-processing.md" >}}) - - [Functions for Canceling Queries in Progress]({{< relref "./docs/DeveloperGuide/functions-for-canceling-queries-in-progress.md" >}}) - - [Link Parameters]({{< relref "./docs/DeveloperGuide/link-parameters-libpq.md" >}}) - - [Compilation and Debugging]({{< relref "./docs/DeveloperGuide/commissioning.md" >}}) + - [Query Request Handling Process]({{< relref "./docs/DeveloperGuide/query-request-handling-process.md" >}}) + - [Development and Design Proposal]({{< relref "./docs/DeveloperGuide/development-and-design-proposal.md" >}}) + - [Overview]({{< relref "./docs/DeveloperGuide/development-and-design-proposal-overview.md" >}}) + - [Database Object Naming Conventions]({{< relref "./docs/DeveloperGuide/database-object-naming-conventions.md" >}}) + - [Database Object Design]({{< relref "./docs/DeveloperGuide/database-object-design.md" >}}) + - [Database and Schema Design]({{< relref "./docs/DeveloperGuide/database-and-schema-design.md" >}}) + - [Table Design]({{< relref "./docs/DeveloperGuide/table-design.md" >}}) + - [Planning a Storage Model]({{< relref "./docs/DeveloperGuide/planning-a-storage-model.md" >}}) + - [Field Design]({{< relref "./docs/DeveloperGuide/field-design.md" >}}) + - [Constraint Design]({{< relref "./docs/DeveloperGuide/constraint-design.md" >}}) + - [View and Joined Table Design]({{< relref "./docs/DeveloperGuide/view-and-joined-table-design.md" >}}) + - [SQL Compilation]({{< relref "./docs/DeveloperGuide/sql-compilation.md" >}}) + - [Application Development Specifications]({{< relref "./docs/DeveloperGuide/application-development-specifications.md" >}}) + - [Development Specifications]({{< relref "./docs/DeveloperGuide/development-specifications.md" >}}) + - [Tool Interconnection]({{< relref "./docs/DeveloperGuide/tool-interconnection.md" >}}) + - [JDBC Configuration]({{< relref "./docs/DeveloperGuide/jdbc-configuration.md" >}}) + - [Development Based on JDBC]({{< relref "./docs/DeveloperGuide/development-based-on-jdbc.md" >}}) + - [JDBC Package, Driver Class, and Environment Class]({{< relref "./docs/DeveloperGuide/jdbc-package-driver-class-and-environment-class.md" >}}) + - [Development Process]({{< relref "./docs/DeveloperGuide/development-process-jdbc.md" >}}) + - [Loading the Driver]({{< relref "./docs/DeveloperGuide/loading-the-driver-jdbc.md" >}}) + - [Connecting to a Database]({{< relref "./docs/DeveloperGuide/connecting-to-a-database-jdbc.md" >}}) + - [Connecting to the Database \(Using SSL\)]({{< relref "./docs/DeveloperGuide/connecting-to-a-database-using-ssl-jdbc.md" >}}) + - [Connecting to a Database (Using UDS)]({{< relref "./docs/DeveloperGuide/connecting-to-a-database-using-uds.md" >}}) + - [Running SQL Statements]({{< relref "./docs/DeveloperGuide/running-sql-statements-jdbc.md" >}}) + - [Processing Data in a Result Set]({{< relref "./docs/DeveloperGuide/processing-data-in-a-result-set-jdbc.md" >}}) + - [Closing a Connection]({{< relref "./docs/DeveloperGuide/closing-a-connection-jdbc.md" >}}) + - [Log Management]({{< relref "./docs/DeveloperGuide/log-management.md" >}}) + - [Examples: Common Operations]({{< relref "./docs/DeveloperGuide/example-common-operations-jdbc.md" >}}) + - [Example: Retrying SQL Queries for Applications]({{< relref "./docs/DeveloperGuide/example-retrying-sql-queries-for-applications.md" >}}) + - [Example: Importing and Exporting Data Through Local Files]({{< relref "./docs/DeveloperGuide/example-importing-and-exporting-data-through-local-files.md" >}}) + - [Example: Migrating Data from a MY Database to openGauss]({{< relref "./docs/DeveloperGuide/example-migrating-data-from-a-my-database-to-opengauss.md" >}}) + - [Example: Logical Replication Code]({{< relref "./docs/DeveloperGuide/example-logic-replication-code.md" >}}) + - [Example: Parameters for Connecting to the Database in Different Scenarios]({{< relref "./docs/DeveloperGuide/example-parameters-for-connecting-to-the-database-in-different-scenarios.md" >}}) + - [JDBC Interface Reference]({{< relref "./docs/DeveloperGuide/jdbc-interface-reference.md" >}}) + - [Common JDBC Parameters]({{< relref "./docs/DeveloperGuide/common-jdbc-parameters.md" >}}) + - [Development Based on ODBC]({{< relref "./docs/DeveloperGuide/development-based-on-odbc.md" >}}) + - [ODBC Packages, Dependent Libraries, and Header Files]({{< relref "./docs/DeveloperGuide/odbc-packages-dependent-libraries-and-header-files.md" >}}) + - [Configuring a Data Source in the Linux OS]({{< relref "./docs/DeveloperGuide/configuring-a-data-source-in-the-linux-os.md" >}}) + - [Development Process]({{< relref "./docs/DeveloperGuide/development-process-odbc.md" >}}) + - [Example: Common Functions and Batch Binding]({{< relref "./docs/DeveloperGuide/example-common-functions-and-batch-binding.md" >}}) + - [Typical Application Scenarios and Configurations]({{< relref "./docs/DeveloperGuide/typical-application-scenarios-and-configurations.md" >}}) + - [ODBC Interface Reference]({{< relref "./docs/DeveloperGuide/odbc-interface-reference.md" >}}) + - [SQLAllocEnv]({{< relref "./docs/DeveloperGuide/sqlallocenv.md" >}}) + - [SQLAllocConnect]({{< relref "./docs/DeveloperGuide/sqlallocconnect.md" >}}) + - [SQLAllocHandle]({{< relref "./docs/DeveloperGuide/sqlallochandle.md" >}}) + - [SQLAllocStmt]({{< relref "./docs/DeveloperGuide/sqlallocstmt.md" >}}) + - [SQLBindCol]({{< relref "./docs/DeveloperGuide/sqlbindcol.md" >}}) + - [SQLBindParameter]({{< relref "./docs/DeveloperGuide/sqlbindparameter.md" >}}) + - [SQLColAttribute]({{< relref "./docs/DeveloperGuide/sqlcolattribute.md" >}}) + - [SQLConnect]({{< relref "./docs/DeveloperGuide/sqlconnect.md" >}}) + - [SQLDisconnect]({{< relref "./docs/DeveloperGuide/sqldisconnect.md" >}}) + - [SQLExecDirect]({{< relref "./docs/DeveloperGuide/sqlexecdirect.md" >}}) + - [SQLExecute]({{< relref "./docs/DeveloperGuide/sqlexecute.md" >}}) + - [SQLFetch]({{< relref "./docs/DeveloperGuide/sqlfetch.md" >}}) + - [SQLFreeStmt]({{< relref "./docs/DeveloperGuide/sqlfreestmt.md" >}}) + - [SQLFreeConnect]({{< relref "./docs/DeveloperGuide/sqlfreeconnect.md" >}}) + - [SQLFreeHandle]({{< relref "./docs/DeveloperGuide/sqlfreehandle.md" >}}) + - [SQLFreeEnv]({{< relref "./docs/DeveloperGuide/sqlfreeenv.md" >}}) + - [SQLPrepare]({{< relref "./docs/DeveloperGuide/sqlprepare.md" >}}) + - [SQLGetData]({{< relref "./docs/DeveloperGuide/sqlgetdata.md" >}}) + - [SQLGetDiagRec]({{< relref "./docs/DeveloperGuide/sqlgetdiagrec.md" >}}) + - [SQLSetConnectAttr]({{< relref "./docs/DeveloperGuide/sqlsetconnectattr.md" >}}) + - [SQLSetEnvAttr]({{< relref "./docs/DeveloperGuide/sqlsetenvattr.md" >}}) + - [SQLSetStmtAttr]({{< relref "./docs/DeveloperGuide/sqlsetstmtattr.md" >}}) + - [Example]({{< relref "./docs/DeveloperGuide/example-odbc.md" >}}) + - [Psycopg-Based Development]({{< relref "./docs/DeveloperGuide/psycopg-based-development.md" >}}) + - [Psycopg Package]({{< relref "./docs/DeveloperGuide/psycopg-package.md" >}}) + - [Development Process]({{< relref "./docs/DeveloperGuide/development-process-psycopg.md" >}}) + - [Loading a Driver]({{< relref "./docs/DeveloperGuide/loading-a-driver-psycopg.md" >}}) + - [Connecting to a Database]({{< relref "./docs/DeveloperGuide/connecting-to-a-database-psycopg.md" >}}) + - [Executing SQL Statements]({{< relref "./docs/DeveloperGuide/executing-sql-statements-psycopg.md" >}}) + - [Processing the Result Set]({{< relref "./docs/DeveloperGuide/processing-the-result-set-psycopg.md" >}}) + - [Closing the Connection]({{< relref "./docs/DeveloperGuide/closing-the-connection-psycopg.md" >}}) + - [Connecting to the Database \(Using SSL\)]({{< relref "./docs/DeveloperGuide/connecting-to-the-database-using-ssl-psycopg.md" >}}) + - [xamples: Common Operations]({{< relref "./docs/DeveloperGuide/example-common-operations-psycopg.md" >}}) + - [Psycopg API Reference]({{< relref "./docs/DeveloperGuide/psycopg-api-reference.md" >}}) + - [Development Based on libpq]({{< relref "./docs/DeveloperGuide/development-based-on-libpq.md" >}}) + - [Dependent Header Files of libpq]({{< relref "./docs/DeveloperGuide/dependent-header-files-of-libpq.md" >}}) + - [Development Process]({{< relref "./docs/DeveloperGuide/development-process-libpq.md" >}}) + - [Example]({{< relref "./docs/DeveloperGuide/example-libpq.md" >}}) + - [libpq API Reference]({{< relref "./docs/DeveloperGuide/libpq-api-reference.md" >}}) + - [Database Connection Control Functions]({{< relref "./docs/DeveloperGuide/database-connection-control-functions.md" >}}) + - [Database Statement Execution Functions]({{< relref "./docs/DeveloperGuide/database-statement-execution-functions.md" >}}) + - [Functions for Asynchronous Command Processing]({{< relref "./docs/DeveloperGuide/functions-for-asynchronous-command-processing.md" >}}) + - [Functions for Canceling Queries in Progress]({{< relref "./docs/DeveloperGuide/functions-for-canceling-queries-in-progress.md" >}}) + - [Link Parameters]({{< relref "./docs/DeveloperGuide/link-parameters-libpq.md" >}}) + - [Compilation and Debugging]({{< relref "./docs/DeveloperGuide/commissioning.md" >}}) - [Compilation Guide]({{< relref "./docs/CompilationGuide/Compilation.md" >}}) - [Setting up the Compilation Environment]({{< relref "./docs/CompilationGuide/setting-up-the-compilation-environment.md" >}}) - [Compiling the Version]({{< relref "./docs/CompilationGuide/compiling-the-version.md" >}}) @@ -779,44 +801,44 @@ headless: true - [CREATE-FUNCTION]({{< relref "./docs/ExtensionReference/dolphin-create-function.md" >}}) - [CREATE-INDEX]({{< relref "./docs/ExtensionReference/dolphin-create-index.md" >}}) - [CREATE-PROCEDURE]({{< relref "./docs/ExtensionReference/dolphin-create-procedure.md" >}}) - - [CREATE-TABLE]({{< relref "./docs/ExtensionReference/dolphin-create-table.md" >}}) - - [CREATE-TABLE-AS]({{< relref "./docs/ExtensionReference/dolphin-create-table-as.md" >}}) - - [CREATE-TABLE-PARTITION]({{< relref "./docs/ExtensionReference/dolphin-create-table-partition.md" >}}) - - [CREATE-TABLESPACE]({{< relref "./docs/ExtensionReference/dolphin-create-tablespace.md" >}}) - - [CREATE-INDEX]({{< relref "./docs/ExtensionReference/dolphin-create-index.md" >}}) - - [DESCRIBE-TABLE]({{< relref "./docs/ExtensionReference/dolphin-describe-table.md" >}}) - - [DROP-TABLESPACE]({{< relref "./docs/ExtensionReference/dolphin-drop-tablespace.md" >}}) - - [GRANT]({{< relref "./docs/ExtensionReference/dolphin-GRANT.md" >}}) - - [INSERT]({{< relref "./docs/ExtensionReference/dolphin-INSERT.md" >}}) - - [KILL]({{< relref "./docs/ExtensionReference/dolphin-KILL.md" >}}) - - [OPTIMIZE-TABLE]({{< relref "./docs/ExtensionReference/dolphin-OPTIMIZE-TABLE.md" >}}) - - [PREPARE]({{< relref "./docs/ExtensionReference/dolphin-PREPARE.md" >}}) - - [RENAME-USER]({{< relref "./docs/ExtensionReference/dolphin-RENAME-USER.md" >}}) - - [REVOKE]({{< relref "./docs/ExtensionReference/dolphin-REVOKE.md" >}}) - - [SELECT]({{< relref "./docs/ExtensionReference/dolphin-SELECT.md" >}}) - - [SET-CHARSET]({{< relref "./docs/ExtensionReference/dolphin-SET-CHARSET.md" >}}) - - [SET-PASSWORD]({{< relref "./docs/ExtensionReference/dolphin-SET-PASSWORD.md" >}}) - - [SHOW_COLUMNS]({{< relref "./docs/ExtensionReference/dolphin-SHOW_COLUMNS.md" >}}) - - [SHOW-DATABASES]({{< relref "./docs/ExtensionReference/dolphin-SHOW-DATABASES.md" >}}) - - [SHOW-FUNCTION-STATUS]({{< relref "./docs/ExtensionReference/dolphin-show-function-status.md" >}}) - - [SHOW-GRANTS]({{< relref "./docs/ExtensionReference/dolphin-show-grants.md" >}}) - - [SHOW-INDEX]({{< relref "./docs/ExtensionReference/dolphin-show-index.md" >}}) - - [SHOW-MASTER-STATUS]({{< relref "./docs/ExtensionReference/dolphin-show-master-status.md" >}}) - - [SHOW_PLUGINS]({{< relref "./docs/ExtensionReference/dolphin-show-plugins.md" >}}) - - [SHOW-PROCEDURE-STATUS]({{< relref "./docs/ExtensionReference/dolphin-show-procedure-status.md" >}}) - - [SHOW-PROCESSLIST]({{< relref "./docs/ExtensionReference/dolphin-show-processlist.md" >}}) - - [SHOW-SLAVE-HOSTS]({{< relref "./docs/ExtensionReference/dolphin-show-slave-hosts.md" >}}) - - [SHOW_TABLES]({{< relref "./docs/ExtensionReference/dolphin-show-tables.md" >}}) - - [SHOW-TRIGGERS]({{< relref "./docs/ExtensionReference/dolphin-show-triggers.md" >}}) - - [UPDATE]({{< relref "./docs/ExtensionReference/dolphin-update.md" >}}) - - [USE-DB_NAME]({{< relref "./docs/ExtensionReference/dolphin-use-db-name.md" >}}) - - [CHECKSUM-TABLE]({{< relref "./docs/ExtensionReference/dolphin-checksum-table.md" >}}) - - [GRANT-REVOKE-PROXY]({{< relref "./docs/ExtensionReference/dolphin-grant-revoke-proxy.md" >}}) + - [CREATE-TABLE]({{< relref "./docs/ExtensionReference/dolphin-create-table.md" >}}) + - [CREATE-TABLE-AS]({{< relref "./docs/ExtensionReference/dolphin-create-table-as.md" >}}) + - [CREATE-TABLE-PARTITION]({{< relref "./docs/ExtensionReference/dolphin-create-table-partition.md" >}}) + - [CREATE-TABLESPACE]({{< relref "./docs/ExtensionReference/dolphin-create-tablespace.md" >}}) + - [CREATE-INDEX]({{< relref "./docs/ExtensionReference/dolphin-create-index.md" >}}) + - [DESCRIBE-TABLE]({{< relref "./docs/ExtensionReference/dolphin-describe-table.md" >}}) + - [DROP-TABLESPACE]({{< relref "./docs/ExtensionReference/dolphin-drop-tablespace.md" >}}) + - [GRANT]({{< relref "./docs/ExtensionReference/dolphin-GRANT.md" >}}) + - [INSERT]({{< relref "./docs/ExtensionReference/dolphin-INSERT.md" >}}) + - [KILL]({{< relref "./docs/ExtensionReference/dolphin-KILL.md" >}}) + - [OPTIMIZE-TABLE]({{< relref "./docs/ExtensionReference/dolphin-OPTIMIZE-TABLE.md" >}}) + - [PREPARE]({{< relref "./docs/ExtensionReference/dolphin-PREPARE.md" >}}) + - [RENAME-USER]({{< relref "./docs/ExtensionReference/dolphin-RENAME-USER.md" >}}) + - [REVOKE]({{< relref "./docs/ExtensionReference/dolphin-REVOKE.md" >}}) + - [SELECT]({{< relref "./docs/ExtensionReference/dolphin-SELECT.md" >}}) + - [SET-CHARSET]({{< relref "./docs/ExtensionReference/dolphin-SET-CHARSET.md" >}}) + - [SET-PASSWORD]({{< relref "./docs/ExtensionReference/dolphin-SET-PASSWORD.md" >}}) + - [SHOW_COLUMNS]({{< relref "./docs/ExtensionReference/dolphin-SHOW_COLUMNS.md" >}}) + - [SHOW-DATABASES]({{< relref "./docs/ExtensionReference/dolphin-SHOW-DATABASES.md" >}}) + - [SHOW-FUNCTION-STATUS]({{< relref "./docs/ExtensionReference/dolphin-show-function-status.md" >}}) + - [SHOW-GRANTS]({{< relref "./docs/ExtensionReference/dolphin-show-grants.md" >}}) + - [SHOW-INDEX]({{< relref "./docs/ExtensionReference/dolphin-show-index.md" >}}) + - [SHOW-MASTER-STATUS]({{< relref "./docs/ExtensionReference/dolphin-show-master-status.md" >}}) + - [SHOW_PLUGINS]({{< relref "./docs/ExtensionReference/dolphin-show-plugins.md" >}}) + - [SHOW-PROCEDURE-STATUS]({{< relref "./docs/ExtensionReference/dolphin-show-procedure-status.md" >}}) + - [SHOW-PROCESSLIST]({{< relref "./docs/ExtensionReference/dolphin-show-processlist.md" >}}) + - [SHOW-SLAVE-HOSTS]({{< relref "./docs/ExtensionReference/dolphin-show-slave-hosts.md" >}}) + - [SHOW_TABLES]({{< relref "./docs/ExtensionReference/dolphin-show-tables.md" >}}) + - [SHOW-TRIGGERS]({{< relref "./docs/ExtensionReference/dolphin-show-triggers.md" >}}) + - [UPDATE]({{< relref "./docs/ExtensionReference/dolphin-update.md" >}}) + - [USE-DB_NAME]({{< relref "./docs/ExtensionReference/dolphin-use-db-name.md" >}}) + - [CHECKSUM-TABLE]({{< relref "./docs/ExtensionReference/dolphin-checksum-table.md" >}}) + - [GRANT-REVOKE-PROXY]({{< relref "./docs/ExtensionReference/dolphin-grant-revoke-proxy.md" >}}) - [System Views]({{< relref "./docs/ExtensionReference/dolphin-system-views.md" >}}) - - [PG TYPE NONSTRICT BASIC VALUE]({{< relref "./docs/ExtensionReference/dolphin-pg-type-nonstrict-basic-value.md" >}}) - - [INDEX STATISTIC]({{< relref "./docs/ExtensionReference/dolphin-index-statistic.md" >}}) - - [GUC Parameters]({{< relref "./docs/ExtensionReference/dolphin-guc-parameters.md" >}}) - - [Resetting Parameters]({{< relref "./docs/ExtensionReference/dolphin-resetting-parameters.md" >}}) + - [PG TYPE NONSTRICT BASIC VALUE]({{< relref "./docs/ExtensionReference/dolphin-pg-type-nonstrict-basic-value.md" >}}) + - [INDEX STATISTIC]({{< relref "./docs/ExtensionReference/dolphin-index-statistic.md" >}}) + - [GUC Parameters]({{< relref "./docs/ExtensionReference/dolphin-guc-parameters.md" >}}) + - [Resetting Parameters]({{< relref "./docs/ExtensionReference/dolphin-resetting-parameters.md" >}}) - [PostGIS Extensions]({{< relref "./docs/ExtensionReference/postgis-extension.md" >}}) - [Overview]({{< relref "./docs/ExtensionReference/overview-PostGIS.md" >}}) - [Installing PostGIS]({{< relref "./docs/ExtensionReference/installing-postgis.md" >}}) diff --git "a/content/zh/docs/DeveloperGuide/\345\237\272\344\272\216ODBC\345\274\200\345\217\221.md" "b/content/zh/docs/DeveloperGuide/\345\237\272\344\272\216ODBC\345\274\200\345\217\221.md" index 092a1b32b..ee17bb775 100644 --- "a/content/zh/docs/DeveloperGuide/\345\237\272\344\272\216ODBC\345\274\200\345\217\221.md" +++ "b/content/zh/docs/DeveloperGuide/\345\237\272\344\272\216ODBC\345\274\200\345\217\221.md" @@ -6,7 +6,7 @@ - **[开发流程](开发流程_ODBC.md)** -- **[示例](示例-常用功能和批量绑定.md.md)** +- **[示例](示例-常用功能和批量绑定.md)** - **[ODBC接口参考](ODBC接口参考.md)** diff --git "a/content/zh/docs/ToolandCommandReference/\347\211\271\346\200\247\344\273\213\347\273\215.md" "b/content/zh/docs/ToolandCommandReference/\347\211\271\346\200\247\344\273\213\347\273\215.md" index b15f1acfd..cd363b17c 100644 --- "a/content/zh/docs/ToolandCommandReference/\347\211\271\346\200\247\344\273\213\347\273\215.md" +++ "b/content/zh/docs/ToolandCommandReference/\347\211\271\346\200\247\344\273\213\347\273\215.md" @@ -323,7 +323,27 @@ cm\_server是用来进行数据库实例管理和实例仲裁的组件。主要 - Voting disk和share disk确保包括至少1G空间,由CM独占,其他应用不能使用。 - 在资源池化架构仲裁模式下,才启用磁盘心跳。 -## CM支持DN仲裁 +## CM支持DN仲裁 + +- CM支持的DN仲裁模式主要分为: + - Quorum 模式:基于多数派模式仲裁,选出同步备 + - 简介:CM 基于Quorum模式进行仲裁,当DN分片处于无主场景时,CM在多数派DN redo完成后,选择 term和lsn最大的节点(同步备)发送failover升主。 + - 约束:最小满足一主两备集群 + - DCF 模式: + - 自动选主模式:基于paxos 协议: + - 简介:dcf模式自动选主,在此场景下,CM不再进行对DN选主,只负责数据采集,假死检测等。 + - 约束:switchover只能使用cm_ctl switchover -n NODEID -D DATADIR + - CM配置:enable_dcf=ON、dn_arbitrate_mode=paxos + - DN配置:enable_dcf=ON + - 总体约束: + - 最小满足一主两备集群 + - 默认安装:DCF自动选主模式 + - 共享存储模式: + - 简介:在此场景下,CM不再进行对DN选主,只负责数据采集,假死检测等。 + - CM配置:dn_arbitrate_mode=share_disk + - 介绍和约束:参考[共享存储](https://gitee.com/opengauss/docs/blob/5b0ab0d649009a536dd771fa15ea2f3130163510/content/zh/docs/Toolreference/特性介绍.md#section135462412052) + +## CM支持VIP仲裁 **简介:**VIP是虚拟IP,随主DN状态进行动态绑定和切换,即如果DN主发生了切换,原主DN上的虚拟IP可能动态绑定到新主DN上,用户可以只通过该IP与数据库连接,不用感知数据库在哪个节点上。 diff --git "a/sphinx/source/ToolandCommandReference/CM\351\205\215\347\275\256\345\217\202\346\225\260\344\273\213\347\273\215.rst" "b/sphinx/source/ToolandCommandReference/CM\351\205\215\347\275\256\345\217\202\346\225\260\344\273\213\347\273\215.rst" new file mode 100644 index 000000000..e72565027 --- /dev/null +++ "b/sphinx/source/ToolandCommandReference/CM\351\205\215\347\275\256\345\217\202\346\225\260\344\273\213\347\273\215.rst" @@ -0,0 +1,7 @@ +CM配置参数介绍 +=============== +.. toctree:: + + ../content/zh/docs/ToolandCommandReference/cm_agent参数 + ../content/zh/docs/ToolandCommandReference/cm_server参数 + diff --git a/sphinx/source/ToolandCommandReference/ToolandCommandReference.rst b/sphinx/source/ToolandCommandReference/ToolandCommandReference.rst new file mode 100644 index 000000000..7dde4f840 --- /dev/null +++ b/sphinx/source/ToolandCommandReference/ToolandCommandReference.rst @@ -0,0 +1,15 @@ + + +.. toctree:: + + ../content/zh/docs/ToolandCommandReference/工具一览表 + 客户端工具 + 服务端工具 + 系统内部命令 + 集群管理 + ../content/zh/docs/ToolandCommandReference/openGauss可运行脚本功能说明 + ../content/zh/docs/ToolandCommandReference/gs_collector工具支持收集的系统表和视图列表 + ../content/zh/docs/ToolandCommandReference/DataKit + ../content/zh/docs/ToolandCommandReference/FAQ + + diff --git "a/sphinx/source/ToolandCommandReference/\345\256\242\346\210\267\347\253\257\345\267\245\345\205\267.rst" "b/sphinx/source/ToolandCommandReference/\345\256\242\346\210\267\347\253\257\345\267\245\345\205\267.rst" new file mode 100644 index 000000000..30a59df7a --- /dev/null +++ "b/sphinx/source/ToolandCommandReference/\345\256\242\346\210\267\347\253\257\345\267\245\345\205\267.rst" @@ -0,0 +1,6 @@ +客户端工具 +========== +.. toctree:: + + ../content/zh/docs/ToolandCommandReference/gsql + diff --git "a/sphinx/source/ToolandCommandReference/\346\234\215\345\212\241\347\253\257\345\267\245\345\205\267.rst" "b/sphinx/source/ToolandCommandReference/\346\234\215\345\212\241\347\253\257\345\267\245\345\205\267.rst" new file mode 100644 index 000000000..e3771fc51 --- /dev/null +++ "b/sphinx/source/ToolandCommandReference/\346\234\215\345\212\241\347\253\257\345\267\245\345\205\267.rst" @@ -0,0 +1,19 @@ +服务端工具 +========== +.. toctree:: + + ../content/zh/docs/ToolandCommandReference/gs_cgroup + ../content/zh/docs/ToolandCommandReference/gs_check + ../content/zh/docs/ToolandCommandReference/gs_checkos + ../content/zh/docs/ToolandCommandReference/gs_checkperf + ../content/zh/docs/ToolandCommandReference/gs_collector + ../content/zh/docs/ToolandCommandReference/gs_dump + ../content/zh/docs/ToolandCommandReference/gs_dumpall + ../content/zh/docs/ToolandCommandReference/gs_guc + ../content/zh/docs/ToolandCommandReference/gs_encrypt + ../content/zh/docs/ToolandCommandReference/gs_om + ../content/zh/docs/ToolandCommandReference/gs_plan_simulator + ../content/zh/docs/ToolandCommandReference/gs_restore + ../content/zh/docs/ToolandCommandReference/gs_ssh + ../content/zh/docs/ToolandCommandReference/gs_sdr + diff --git "a/sphinx/source/ToolandCommandReference/\347\263\273\347\273\237\345\206\205\351\203\250\345\221\275\344\273\244.rst" "b/sphinx/source/ToolandCommandReference/\347\263\273\347\273\237\345\206\205\351\203\250\345\221\275\344\273\244.rst" new file mode 100644 index 000000000..106b0e687 --- /dev/null +++ "b/sphinx/source/ToolandCommandReference/\347\263\273\347\273\237\345\206\205\351\203\250\345\221\275\344\273\244.rst" @@ -0,0 +1,37 @@ +系统内部命令 +============ +.. toctree:: + + ../content/zh/docs/ToolandCommandReference/dsscmd + ../content/zh/docs/ToolandCommandReference/dssserver + ../content/zh/docs/ToolandCommandReference/gaussdb + ../content/zh/docs/ToolandCommandReference/gs_backup + ../content/zh/docs/ToolandCommandReference/gs_basebackup + ../content/zh/docs/ToolandCommandReference/gs_ctl + ../content/zh/docs/ToolandCommandReference/gs_initdb + ../content/zh/docs/ToolandCommandReference/gs_install + ../content/zh/docs/ToolandCommandReference/gs_postuninstall + ../content/zh/docs/ToolandCommandReference/gs_preinstall + ../content/zh/docs/ToolandCommandReference/gs_sshexkey + ../content/zh/docs/ToolandCommandReference/gs_tar + ../content/zh/docs/ToolandCommandReference/gs_uninstall + ../content/zh/docs/ToolandCommandReference/gs_upgradectl + ../content/zh/docs/ToolandCommandReference/gs_expansion + ../content/zh/docs/ToolandCommandReference/gs_dropnode + ../content/zh/docs/ToolandCommandReference/gs_probackup + ../content/zh/docs/ToolandCommandReference/gstrace + ../content/zh/docs/ToolandCommandReference/kdb5_util + ../content/zh/docs/ToolandCommandReference/kadmin-local + ../content/zh/docs/ToolandCommandReference/kinit + ../content/zh/docs/ToolandCommandReference/klist + ../content/zh/docs/ToolandCommandReference/krb5kdc + ../content/zh/docs/ToolandCommandReference/kdestroy + ../content/zh/docs/ToolandCommandReference/pg_config + ../content/zh/docs/ToolandCommandReference/pg_controldata + ../content/zh/docs/ToolandCommandReference/pg_recvlogical + ../content/zh/docs/ToolandCommandReference/pg_resetxlog + ../content/zh/docs/ToolandCommandReference/pg_archivecleanup + ../content/zh/docs/ToolandCommandReference/pssh + ../content/zh/docs/ToolandCommandReference/pscp + ../content/zh/docs/ToolandCommandReference/transfer-py + diff --git "a/sphinx/source/ToolandCommandReference/\351\233\206\347\276\244\347\256\241\347\220\206.rst" "b/sphinx/source/ToolandCommandReference/\351\233\206\347\276\244\347\256\241\347\220\206.rst" new file mode 100644 index 000000000..3c7aa9ee3 --- /dev/null +++ "b/sphinx/source/ToolandCommandReference/\351\233\206\347\276\244\347\256\241\347\220\206.rst" @@ -0,0 +1,11 @@ +集群管理 +======== +.. toctree:: + + ../content/zh/docs/ToolandCommandReference/特性介绍 + ../content/zh/docs/ToolandCommandReference/cm_ctl工具介绍 + ../content/zh/docs/ToolandCommandReference/cm_persit工具介绍 + ../content/zh/docs/ToolandCommandReference/安装和卸载工具介绍 + ../content/zh/docs/ToolandCommandReference/安全设计 + CM配置参数介绍 + \ No newline at end of file diff --git a/sphinx/source/index-ToolandCommandReference.rst b/sphinx/source/index-ToolandCommandReference.rst new file mode 100644 index 000000000..bb9ff8ac3 --- /dev/null +++ b/sphinx/source/index-ToolandCommandReference.rst @@ -0,0 +1,11 @@ + + +Welcome to openGauss's documentation! +===================================== + +.. toctree:: + + ToolandCommandReference/ToolandCommandReference + + + -- Gitee