Cari di MySQL 
    MySQL Manual
Daftar Isi
(Sebelumnya) 22.3. MySQL Connector/J22.8. MySQL C API (Berikutnya)

22.4. MySQL Connector/C++

MySQL Connector/C++ is a MySQL database connector for C++. It lets you develop applications in C++ that connect to the MySQL Server.

MySQL Connector/C++ Benefits

Using MySQL Connector/C++ instead of the MySQL C API (MySQL Client Library) offers the following benefits for C++ users:

  • Convenience of pure C++, no C function calls required.

  • Supports an industry standard API, JDBC 4.0.

  • Supports the object-oriented programming paradigm.

  • Reduces development time.

  • MySQL Connector/C++ is licensed under the GPL with the FLOSS License Exception.

  • MySQL Connector/C++ is available under a commercial license upon request.

JDBC Compatibility

The MySQL Connector/C++ is compatible with the JDBC 4.0 API. However, MySQL Connector/C++ does not implement all of the JDBC 4.0 API. The MySQL Connector/C++ current version features the following classes:

  • Connection

  • DatabaseMetaData

  • Driver

  • PreparedStatement

  • ResultSet

  • ResultSetMetaData

  • Savepoint

  • Statement

The JDBC 4.0 API defines approximately 450 methods for the above mentioned classes. MySQL Connector/C++ implements around 80% of these and makes them available in the current release.

Platform Support and Prerequisites

MySQL Connector/C++ supports MySQL 5.1 and later.

MySQL Connector/C++ supports only Microsoft Visual Studio 2003 and above on Windows.

The release has been successfully compiled and tested on the following platforms:

AIX

  • 5.2 (PPC32, PPC64)

  • 5.3 (PPC32, PPC64)

FreeBSD

  • 6.0 (x86, x86_64)

HPUX

  • 11.11 (PA-RISC 32bit, PA-RISC 64bit)

Linux

  • Debian 3.1 (PPC32, x86)

  • FC4 (x86)

  • RHEL 3 (ia64, x86, x86_64)

  • RHEL 4 (ia64, x86, x86_64)

  • RHEL 5 (ia64, x86, x86_64)

  • SLES 9 (ia64, x86, x86_64)

  • SLES 10 (ia64, x86_64)

  • SuSE 10.3, (x86_64)

  • Ubuntu 8.04 (x86)

  • Ubuntu 8.10 (x86_64)

Mac

  • MacOSX 10.3 (PPC32, PPC64)

  • MacOSX 10.4 (PPC32, PPC64, x86)

  • MacOSX 10.5 (PPC32, PPC64, x86, x86_64)

SunOS

  • Solaris 8 (SPARC32, SPARC64, x86)

  • Solaris 9 (SPARC32, SPARC64, x86)

  • Solaris 10 (SPARC32, SPARC64, x86, x86_64)

Windows

  • XP Professional (32bit)

  • 2003 (64bit)

Future versions will run on all platforms supported by the MySQL Server.

How to Get Connector/C++

MySQL Connector/C++ Download

You can download the source code for the MySQL Connector/C++ current release at the MySQL Connector/C++ downloads.

MySQL Connector/C++ Source repository

The latest development version is also available through Launchpad.

Bazaar is used for the MySQL Connector/C++ code repository. You can check out the latest source code using the bzr command line tool:

shell> bzr branch lp:~mysql/mysql-connector-cpp/trunk .

Binary distributions

Starting with 1.0.4 Beta, binary distributions were made available in addition to source code releases. The releases available are shown below.

Microsoft Windows platform:

  • Without installer, a Zip file

  • MSI installer package

Other platforms:

  • Compressed GNU TAR archive (tar.gz)

Note

Note that source packages are available for all platforms in the Compressed GNU TAR archive (tar.gz) format.

Binary and source packages can be obtained from MySQL Connector/C++ downloads.

Release Status

MySQL Connector/C++ is available as a GA version. We kindly ask users and developers to try it out and provide us with feedback.

Note that MySQL Workbench is successfully using MySQL Connector/C++.

If you have any queries please contact us.

Licensing

The MySQL Connector/C++ is licensed under the terms of the GPL, like most MySQL Connectors. There are special exceptions to the terms and conditions of the GPL as it is applied to this software, see FLOSS License Exception. If you need a non-GPL license for commercial distribution, please contact us.

22.4.1. Installing the MySQL Connector/C++ Binary

Caution

One problem that can occur is when the tools you use to build your application are not compatible with the tools used to build the binary versions of MySQL Connector/C++. Ideally, build your application with the same tools that were used to build the MySQL Connector/C++ binaries. To help with this, the following resources are provided.

All distributions contain a README file, which contains platform-specific notes. At the end of the README file contained in the binary distribution you will find the settings used to build the binaries. If you experience build-related issues on a platform, it may help to check the settings used on the platform to build the binary.

Developers using Microsoft Windows must meet the following requirements:

  1. Use a supported version of Visual Studio, either Visual Studio 2005 or Visual Studio 2008.

  2. Ensure that your application uses the same run time library as that used to build MySQL Connector/C++. Visual Studio 2005 builds use Microsoft.VC80.CRT (8.0.50727.762), and Visual Studio 2008 builds use Microsoft.VC90.CRT (9.0.21022.8).

  3. Your application should use the same linker configuration as MySQL Connector/C++, for example use one of /MD, /MDd, /MT, or /MTd.

To use a variation of the requirements previously listed, such as a different compiler version, release configuration, or run time library, compile MySQL Connector/C++ from source using your desired settings, and then ensure that your application is built with these same settings. Ensure that the three variables of compiler version, run time library, and run time linker configuration settings are the same for both application and MySQL Connector/C++ itself, to avoid issues.

A better solution is to build your MySQL Connector/C++ libraries from the source code, using the same tools that you use for building your application. This ensures compatibility.

Downloading MySQL Connector/C++

Binary and source packages can be obtained from MySQL Connector/C++ downloads.

Archive Package

Unpack the archive into an appropriate directory. If you plan to use a dynamically linked version of MySQL Connector/C++, make sure that your system can reference the MySQL Client Library. Consult your operating system documentation on how do modify and expand the search path for libraries. In case you cannot modify the library search path it may help to copy your application, the MySQL Connector/C++ library and the MySQL Client Library into the same directory. Most systems search for libraries in the current directory.

Windows MSI Installer

Windows users can choose between two binary packages:

  1. Without installer (unzip in C:\)

  2. Windows MSI Installer (x86)

Using the MSI Installer may be the easiest solution. Running the MSI Installer does not require any administrative permissions as it simply copies files.

Figure 22.70. Windows Installer Welcome Screen

Windows Installer Welcome Screen

Figure 22.71. Windows Installer Overview Screen

Windows Installer Overview Screen

The "Typical" installation consists of all required header files and the Release libraries. The only available "Custom" installation option enables you to install additional Debug versions of the connector libraries.

Figure 22.72. Windows Installer Custom Setup Screen

Windows Installer Custom Setup Screen

22.4.2. Installing MySQL Connector/C++ from Source

The MySQL Connector/C++ is based on the MySQL Client Library (MySQL C API). MySQL Connector/C++ is linked against the MySQL Client Library. You need the MySQL Client Library installed to compile MySQL Connector/C++.

You also need the cross-platform build tool CMake 2.4, or newer, and GLib 2.2.3 or newer installed. Check the README file included with the distribution for platform specific notes on building for Windows and SunOS.

Typically the MySQL Client Library is installed when the MySQL Server is installed. However, check your operating system documentation for other installation options.

As of MySQL Connector/C++ version 1.1.0, it is necessary to have the Boost C++ libraries 1.34.0 or newer installed. Boost is only required to build the connector, it is not required to use the connector. You can obtain Boost and its installation instructions from the official site. Once Boost is installed, tell the make system where the Boost files are, by setting the define -DBOOST_ROOT:STRING=. This can be done when initially invoking CMake, for example:

shell> CMake . -DBOOST_ROOT:STRING=/usr/local/boost_1_40_0

You might need to change /usr/local/boost_1_40_0/ to match your installation. See the Section 22.4.2.1, "Building MySQL Connector/C++ from Source on Unix, Solaris and Mac OS X" and Section 22.4.2.2, "Building MySQL Connector/C++ from Source on Windows" for further details.

22.4.2.1. Building MySQL Connector/C++ from Source on Unix, Solaris and Mac OS X

  1. Run CMake to build a Makefile:

    shell> me@host:/path/to/mysql-connector-cpp> cmake .-- Check for working C compiler: /usr/local/bin/gcc-- Check for working C compiler: /usr/local/bin/gcc -- works[...]-- Generating done-- Build files have been written to: /path/to/mysql-connector-cpp/

    On non-Windows systems, CMake first checks to see if the CMake variable MYSQL_CONFIG_EXECUTABLE is set. If it is not found CMake tries to locate mysql_config in the default locations.

    If you have any problems with the configure process please check the troubleshooting instructions below.

  2. Use make to build the libraries. First make sure you have a clean build:

    shell> me@host:/path/to/mysql-connector-cpp> make clean

    Then build the connector:

    me@host:/path/to/mysql-connector-cpp> make[  1%] Building CXX object »driver/CMakeFiles/mysqlcppconn.dir/mysql_connection.o[  3%] Building CXX object »driver/CMakeFiles/mysqlcppconn.dir/mysql_constructed_resultset.o[...][100%] Building CXX object examples/CMakeFiles/statement.dir/statement.oLinking CXX executable statement

    If all goes well, you will find the MySQL Connector/C++ library in /path/to/cppconn/libmysqlcppconn.so.

  3. Finally make sure the header and library files are installed to their correct locations:

    make install

    Unless you have changed this in the configuration step, the header files are copied to the directory /usr/local/include. The header files copied are mysql_connection.h and mysql_driver.h.

    Again, unless you have specified otherwise, the library files are copied to /usr/local/lib. The files copied are libmysqlcppconn.so, the dynamic library, and libmysqlcppconn-static.a, the static library.

If you encounter any errors, please first carry out the checks shown below:

  1. CMake options: MySQL installation path, debug version and more

    In case of configuration or compilation problems, check the list of CMake options:

    shell> me@host:/path/to/mysql-connector-cpp> cmake -L[...]CMAKE_BACKWARDS_COMPATIBILITY:STRING=2.4CMAKE_BUILD_TYPE:STRING=CMAKE_INSTALL_PREFIX:PATH=/usr/localEXECUTABLE_OUTPUT_PATH:PATH=LIBRARY_OUTPUT_PATH:PATH=MYSQLCPPCONN_GCOV_ENABLE:BOOL=0MYSQLCPPCONN_TRACE_ENABLE:BOOL=0MYSQL_CONFIG_EXECUTABLE:FILEPATH=/usr/bin/mysql_config

    For example, if your MySQL Server installation path is not /usr/local/mysql and you want to build a debug version of the MySQL Connector/C++, use:

    shell> me@host:/path/to/mysql-connector-cpp> cmake »-D CMAKE_BUILD_TYPE:STRING=Debug »-D MYSQL_CONFIG_EXECUTABLE=/path/to/my/mysql/server/bin/mysql_config .
  2. Verify your settings with cmake -L:

    shell> me@host:/path/to/mysql-connector-cpp> cmake -L[...]CMAKE_BACKWARDS_COMPATIBILITY:STRING=2.4CMAKE_BUILD_TYPE:STRING=CMAKE_INSTALL_PREFIX:PATH=/usr/localEXECUTABLE_OUTPUT_PATH:PATH=LIBRARY_OUTPUT_PATH:PATH=MYSQLCPPCONN_GCOV_ENABLE:BOOL=0MYSQLCPPCONN_TRACE_ENABLE:BOOL=0MYSQL_CONFIG_EXECUTABLE=/path/to/my/mysql/server/bin/mysql_config

    Proceed by carrying out a make clean command followed by a make command, as described above.

Once you have installed MySQL Connector/C++ you can carry out a quick test to check the installation. To do this you can compile and run one of the example programs, such as examples/standalone_example.cpp. This example is discussed in more detail later, but for now you can use it to test the connector has been correctly installed. This procedure assumes you have a working MySQL Server that you can connect to.

  1. First compile the example. To do this change to the examples directory and type:

    shell> g++ -o test_install -I/usr/local/include -I/usr/local/include/cppconn-Wl,-Bdynamic -lmysqlcppconn standalone_example.cpp
  2. Make sure the dynamic library which is used in this case can be found at runtime:

    shell> export LD_LIBRARY_PATH=/usr/local/lib
  3. Now run the program to test your installation, substituting the appropriate host, user, password and database names for your system:

    ./test_install localhost root password database

    You will see something similar to the following:

    Connector/C++ standalone program example...... running 'SELECT 'Welcome to Connector/C++' AS _message'... MySQL replies: Welcome to Connector/C++... say it again, MySQL....MySQL replies: Welcome to Connector/C++... find more at http://www.mysql.com

    If you see any errors, take note of them and go through the troubleshooting procedures discussed earlier.

22.4.2.2. Building MySQL Connector/C++ from Source on Windows

Note

Please note the only compiler formally supported for Windows is Microsoft Visual Studio 2003 and above.

The basic steps for building the connector on Windows are the same as for Unix. It is important to use CMake 2.6.2 or newer to generate build files for your compiler and to invoke the compiler.

Note

On Windows, mysql_config is not present, so CMake will attempt to retrieve the location of MySQL from the environment variable $ENV{MYSQL_DIR}. If MYSQL_DIR is not set, CMake will then proceed to check for MySQL in the following locations: $ENV{ProgramFiles}/MySQL/*/include, and $ENV{SystemDrive}/MySQL/*/include.

CMake makes it easy for you to try other compilers. However, you may experience compile warnings, compile errors or linking issues not detected by Visual Studio. Patches are gratefully accepted to fix issues with other compilers.

Consult the CMake manual or check cmake --help to find out which build systems are supported by your CMake version:

C:\>cmake --helpcmake version 2.6-patch 2Usage[...]GeneratorsThe following generators are available on this platform:  Borland Makefiles   = Generates Borland makefiles.  MSYS Makefiles  = Generates MSYS makefiles.  MinGW Makefiles = Generates a make file for use with mingw32-make.  NMake Makefiles = Generates NMake makefiles.  Unix Makefiles  = Generates standard UNIX makefiles.  Visual Studio 6 = Generates Visual Studio 6 project files.  Visual Studio 7 = Generates Visual Studio .NET 2002 project files.  Visual Studio 7 .NET 2003   = Generates Visual Studio .NET 2003 project files.  Visual Studio 8 2005 = Generates Visual Studio .NET 2005 project files.  Visual Studio 8 2005 Win64  = Generates Visual Studio .NET 2005 Win64 project files.  Visual Studio 9 2008 = Generates Visual Studio 9 2008 project fil  Visual Studio 9 2008 Win64  = Generates Visual Studio 9 2008 Win64 proje files.[...]

It is likely that your CMake binary will support more compilers, known by CMake as generators, than supported by MySQL Connector/C++. We have built the connector using the following generators:

  • Microsoft Visual Studio 8 (Visual Studio 2005)

  • Microsoft Visual Studio 9 (Visual Studio 2008, Visual Studio 2008 Express)

  • NMake

Please see the building instructions for Unix, Solaris and Mac OS X for troubleshooting and configuration hints.

The steps to build the connector are given below:

  1. Run CMake to generate build files for your generator:

    Visual Studio

     C:\path_to_mysql_cpp>cmake -G "Visual Studio 9 2008"-- Check for working C compiler: cl-- Check for working C compiler: cl -- works-- Detecting C compiler ABI info-- Detecting C compiler ABI info - done-- Check for working CXX compiler: cl-- Check for working CXX compiler: cl -- works-- Detecting CXX compiler ABI info-- Detecting CXX compiler ABI info - done-- ENV{MYSQL_DIR} =-- MySQL Include dir: C:/Programme/MySQL/MySQL Server 5.1/include-- MySQL Library : C:/Progams/MySQL/MySQL Server 5.1/lib/opt/mysqlclient.lib-- MySQL Library dir: C:/Progams/MySQL/MySQL Server 5.1/lib/opt-- MySQL CFLAGS:-- MySQL Link flags:-- MySQL Include dir: C:/Progams/MySQL/MySQL Server 5.1/include-- MySQL Library dir: C:/Progams/MySQL/MySQL Server 5.1/lib/opt-- MySQL CFLAGS:-- MySQL Link flags:-- Configuring cppconn-- Configuring test cases-- Looking for isinf-- Looking for isinf - not found-- Looking for isinf-- Looking for isinf - not found.-- Looking for finite-- Looking for finite - not found.-- Configuring C/J junit tests port-- Configuring examples-- Configuring done-- Generating done-- Build files have been written to: C:\path_to_mysql_cppC:\path_to_mysql_cpp>dir *.sln *.vcproj[...]19.11.2008  12:16 23.332 MYSQLCPPCONN.sln[...]19.11.2008  12:16 27.564 ALL_BUILD.vcproj19.11.2008  12:16 27.869 INSTALL.vcproj19.11.2008  12:16 28.073 PACKAGE.vcproj19.11.2008  12:16 27.495 ZERO_CHECK.vcproj

    NMake

     C:\path_to_mysql_cpp>cmake -G "NMake Makefiles"-- The C compiler identification is MSVC-- The CXX compiler identification is MSVC[...]-- Build files have been written to: C:\path_to_mysql_cpp
  2. Use your compiler to build MySQL Connector/C++

    Visual Studio - GUI

    Open the newly generated project files in the Visual Studio GUI or use a Visual Studio command line to build the driver. The project files contain a variety of different configurations. Among them debug and nondebug versions.

    Visual Studio - NMake

    C:\path_to_mysql_cpp>nmakeMicrosoft (R) Program Maintenance Utility Version 9.00.30729.01Copyright (C) Microsoft Corporation.  All rights reserved.Scanning dependencies of target mysqlcppconn[  2%] Building CXX object driver/CMakeFiles/mysqlcppconn.dir/mysql_connection.objmysql_connection.cpp[...]Linking CXX executable statement.exe[100%] Built target statement

22.4.2.3. Dynamically Linking MySQL Connector/C++ against the MySQL Client Library

Note

Note this section refers to dynamic linking of the MySQL Connector/C++ with the client library, not the dynamic linking of the application to MySQL Connector/C++.

An application that uses MySQL Connector/C++ can be either statically or dynamically linked to the MySQL Connector/C++ libraries. MySQL Connector/C++ is usually statically linked to the underlying MySQL Client Library (or Connector/C). Note, that unless otherwise stated, reference to the MySQL Client Library is also taken to include Connector/C, which is a separately packaged, stand alone version of the MySQL Client Library. From MySQL Connector/C++ version 1.1.0 it is possible to also dynamically link to the underlying MySQL Client Library. The ability of MySQL Connector/C++ to dynamically link to MySQL Client Library is not enabled by default, and enabling this feature is done through a compile time option, when compiling the MySQL Connector/C++ source code.

To use the ability to dynamically link the client library to MySQL Connector/C++, define the MYSQLCLIENT_STATIC_BINDING:BOOL when building the MySQL Connector/C++ source code:

rm CMakeCache.txtcmake -DMYSQLCLIENT_STATIC_BINDING:BOOL=1 .make cleanmakemake install

Note that precompiled binaries of MySQL Connector/C++ use static binding with the client library by default.

Now, in your application, when creating a connection, MySQL Connector/C++ will select and load a client library at runtime. It will choose the client library by searching defined locations and environment variables depending on the host operating system. It is also possible when creating a connection in an application to define an absolute path to the client library to be loaded at runtime. This can be convenient if you have defined a standard location from which you want the client library to be loaded. This is sometimes done to circumvent possible conflicts with other versions of the client library that may be located on the system.

22.4.3. MySQL Connector/C++ Building Windows Applications with Microsoft Visual Studio

MySQL Connector/C++ is available as a static or dynamic library to use with your application. This section looks at how to link the library to your application.

Note

To avoid potential crashes the build configuration of MySQL Connector/C++ should match the build configuration of the application using it. For example, do not use the release build of MySQL Connector/C++ with a debug build of the client application.

Static library

The MySQL Connector/C++ static library file is mysqlcppconn-static.lib. You link this library statically with your application. Also link against the files libmysql.dll and libmysql.lib. Once linking has been successfully completed, the application will require access to libmysql.dll at run time.

Dynamic library

The MySQL Connector/C++ dynamic library file is mysqlcppconn.dll. To build your client application, link it with the file mysqlcppconn.lib. At run time, the application will require access to the files mysqlcppconn.dll and libmysql.dll.

Building a MySQL Connector/C++ application with Microsoft Visual Studio

Initially, the procedure for building an application to use either the static or dynamic library is the same. You then carry out some additional steps depending on whether you are building your application to use the static or dynamic library.

  1. Select File, New, Project from the main menu.

    Figure 22.73. Creating a New Project

    Creating a new project

  2. In the wizard, select Visual C++, Win32. From Visual Studio Installed Templates, select the application type Win32 Console Application. Enter a name for the application, then click OK, to move to the Win32 Application Wizard.

    Figure 22.74. The New Project Dialog Box

    The New Project dialog box

  3. In the Win32 Application Wizard, click Application Settings and ensure the defaults are selected. The radio button Console application and the check box Precompiled headers are selected. Click Finish to close the wizard.

    Figure 22.75. The Win32 Application Wizard

    The Win32 Application Wizard

  4. From the drop down list box on the toolbar, change from the default Debug build to the Release build.

    Figure 22.76. Selecting the Release Build

    Selecting the Release build

  5. From the main menu select Project, Properties. This can also be accessed using the hot key ALT + F7.

    Figure 22.77. Selecting Project Properties from the Main Menu

    Selecting Project Properties from the main menu

  6. Under Configuration Properties, open the tree view.

  7. Select C++, General in the tree view.

    Figure 22.78. Setting Properties

    Setting properties

  8. Now ensure that Visual Studio can find the MySQL include directory. This directory includes header files that can optionally be installed when installing MySQL Server.

    Figure 22.79. MySQL Include Directory

    MySQL include directory

  9. In the Additional Include Directories text field, add the MySQL include/ directory.

    Figure 22.80. Select Directory Dialog

    Select Directory dialog

  10. Also set the location of additional libraries that Visual Studio needs to build the application. These are located in the MySQL lib/opt directory, a subdirectory of the MySQL Server installation directory.

    Figure 22.81. Typical Contents of MySQL lib/opt Directory

    Typical contents of MySQL lib/opt directory

  11. In the tree view, open Linker, General, Additional Library Directories.

    Figure 22.82. Additional Library Directories

    Additional Library Directories

  12. Add the lib/opt directory into the Additional Library Directories text field. This enables the library file libmysql.lib to be found.

    Figure 22.83. Additional Library Directories Dialog

    Additional Library Directories dialog

The remaining steps depend on whether you are building an application to use the MySQL Connector/C++ static or dynamic library. If you are building your application to use the dynamic library go here. If you are building your application to use the static library, carry out the following steps:

  1. Then open Linker, Input, Additional Dependencies.

    Figure 22.84. Additional Dependencies

    Additional Dependencies

  2. Enter mysqlcppconn-static.lib and libmysql.lib.

    Figure 22.85. Adding Additional Dependencies

    Adding additional dependencies

  3. By default CPPCONN_PUBLIC_FUNC is defined to declare functions to be compatible with an application that calls a DLL. If building an application to call the static library, ensure that function prototypes are compatible with this. In this case, define CPPCONN_PUBLIC_FUNC to be an empty string, so that functions are declared with the correct prototype.

    In the Project, Properties tree view, under C++, Preprocessor, enter CPPCONN_PUBLIC_FUNC= into the Preprocessor Definitions text field.

    Figure 22.86. Setting the CPPCONN_PUBLIC_FUNC Define

    Setting the CPPCONN_PUBLIC_FUNC define

    Note

    Make sure you enter CPPCONN_PUBLIC_FUNC= and not CPPCONN_PUBLIC_FUNC, so that it is defined as an empty string.

If building an application to use the MySQL Connector/C++ dynamically linked library carry out these steps:

  1. Under Linker, Input, add mysqlcppconn.lib into the Additional Dependencies text field.

  2. mysqlcppconn.dll must be in the same directory as the application executable, or somewhere on the system's path, so that the application can access the MySQL Connector/C++ Dynamic Linked Library at runtime.

    Copy mysqlcppconn.dll to the same directory as the application. Alternatively, extend the PATH environment variable using SET PATH=%PATH%;C:\path\to\cpp. Alternatively, you can copy mysqlcppconn.dll to the Windows installation Directory, typically c:\windows.

22.4.4. MySQL Connector/C++ Building Linux Applications with NetBeans

This section describes how to build MySQL Connector/C++ applications for Linux using the NetBeans IDE.

Figure 22.87. The NetBeans IDE


Note

To avoid potential crashes the build configuration of MySQL Connector/C++ should match the build configuration of the application using it. For example, do not use the release build of MySQL Connector/C++ with a debug build of the client application.

  1. The first step of building your application is to create a new project. Select File, New Project. Choose a C/C++ Application and click Next.

  2. Give the project a name and click Finish. A new project is created.

  3. In the Projects tab, right-click Source Files and select New, then Main C++ File....

  4. Change the filename, or simply select the defaults and click Finish to add the new file to the project.

  5. Now add some working code to your main source file. Explore your MySQL Connector/C++ installation and navigate to the examples directory.

  6. Select a suitable example, such as standalone_example_docs1.cpp. Copy all the code in this file, and use it to replace the code in your existing main source file. Amend the code to reflect the connection properties required for your test database. You now have a working example that will access a MySQL database using MySQL Connector/C++.

  7. At this point, NetBeans is showing some errors in the source code. Direct NetBeans to the necessary header files to include. Select File, Project Properties from the main menu.

  8. In the Categories: tree view panel, navigate to Build, C++ Compiler.

  9. In the General panel, select Include Directories.

  10. Click the ... button.

  11. Click Add, then navigate to the directory where the MySQL Connector/C++ header files are located. This will be /usr/local/include unless you have installed the files to a different location. Click Select. Click OK.

    Figure 22.88. Setting the Header Include Directory

    Setting the header include directory

  12. Click OK again to close the Project Properties dialog.

At this point, you have created a NetBeans project, containing a single C++ source file. You have also ensured that the necessary include files are accessible. Before continuing, decide whether your project is to use the MySQL Connector/C++ static or dynamic library. The project settings are slightly different in each case, because you link against a different library.

Using the static library

To use the static library, link against two library files, libmysqlcppconn-static.a and libmysqlclient.a. The locations of the files depend on your setup, but typically the former are in /usr/local/lib and the latter in /usr/lib. Note the file libmysqlclient.a is not part of MySQL Connector/C++, but is the MySQL Client Library file distributed with MySQL Server. Remember, the MySQL Client Library is an optional component as part of the MySQL Server installation process. Note the MySQL Client Library is also available as part of the MySQL Connector/C distribution.

  1. The first step is to set the project to link the necessary library files. Select File, Project Properties from the main menu.

  2. In the Categories: tree view, navigate to Linker.

  3. In the General panel, select Additional Library Directories. Click the ... button.

  4. Select and add the /usr/lib and /usr/local/lib directories.

  5. In the same panel, add the two library files required for static linking as discussed earlier. The properties panel should then look similar to the following screenshot:

    Figure 22.89. Setting the Static Library Directories and File Names

    Setting the static library directories and file names

  6. Click OK to close the Project Properties dialog.

Using the dynamic library

For your application to use the MySQL Connector/C++ dynamic library, you link your project with a single library file, libmysqlcppconn.so. The location of this file depends on how you configured your installation of MySQL Connector/C++, but is typically /usr/local/lib.

  1. The first step is to set the project to link the necessary library file. Select File, Project Properties from the main menu.

  2. In the Categories: tree view, navigate to Linker.

  3. In the General panel, select Additional Library Directories. Click the ... button.

  4. Select and add the /usr/local/lib directories.

  5. In the same panel, add the library file required for static linking as discussed earlier. The properties panel should then look similar to the following screenshot:

    Figure 22.90. Setting the Dynamic Library Directory and File Name

    Setting the dynamic library directory and file name

  6. Click OK to close the Project Properties dialog.

Having configured your project, you build it by selecting Run, Build Main Project from the main menu. You then run the project using Run, Run Main Project.

On running the application, you should see a screen similar to the following (this is actually the static version of the application shown):

Figure 22.91. The Example Application Running

The example application running

Note

Note the above settings and procedures were carried out for the default Debug configuration. To create a Release configuration, select that configuration before setting the Project Properties.

22.4.5. MySQL Connector/C++ Getting Started: Usage Examples

The download package contains usage examples in the directory examples/. The examples explain the basic usage of the following classes:

  • Connection

  • Driver

  • PreparedStatement

  • ResultSet

  • ResultSetMetaData

  • Statement

The examples cover:

  • Using the Driver class to connect to MySQL

  • Creating tables, inserting rows, fetching rows using (simple) statements

  • Creating tables, inserting rows, fetching rows using prepared statements

  • Hints for working around prepared statement limitations

  • Accessing result set metadata

The examples in this document are only code snippets. The code snippets provide a brief overview on the API. They are not complete programs. Please check the examples/ directory of your MySQL Connector/C++ installation for complete programs. Please also read the README file in the examples/ directory. To test the example code, first edit the examples.h file in the examples/ directory, to add your connection information. Then rebuild the code by issuing a make command.

The examples in the examples/ directory include:

  • examples/connect.cpp:

    How to create a connection, insert data into MySQL and handle exceptions.

  • examples/connection_meta_schemaobj.cpp:

    How to obtain metadata associated with a connection object, for example, a list of tables, databases, MySQL version, connector version.

  • examples/debug_output.cpp:

    How to activate and deactivate the MySQL Connector/C++ debug protocol.

  • examples/exceptions.cpp:

    A closer look at the exceptions thrown by the connector and how to fetch error information.

  • examples/prepared_statements.cpp:

    How to run Prepared Statements including an example how to handle SQL commands that cannot be prepared by the MySQL Server.

  • examples/resultset.cpp:

    How to fetch data and iterate over the result set (cursor).

  • examples/resultset_meta.cpp:

    How to obtain metadata associated with a result set, for example, number of columns and column types.

  • examples/resultset_types.cpp:

    Result sets returned from metadata methods - this is more a test than much of an example.

  • examples/standalone_example.cpp:

    Simple standalone program not integrated into regular CMake builds.

  • examples/statements.cpp:

    How to run SQL commands without using Prepared Statements.

  • examples/cpp_trace_analyzer.cpp:

    This example shows how to filter the output of the debug trace. Please see the inline comments for further documentation. This script is unsupported.

22.4.5.1. MySQL Connector/C++ Connecting to MySQL

A connection to MySQL is established by retrieving an instance of sql::Connection from a sql::mysql::MySQL_Driver object. A sql::mysql::MySQL_Driver object is returned by sql::mysql::MySQL_Driver::get_mysql_driver_instance().

sql::mysql::MySQL_Driver *driver;sql::Connection *con;driver = sql::mysql::MySQL_Driver::get_mysql_driver_instance();con = driver->connect("tcp://127.0.0.1:3306", "user", "password");delete con;

Make sure that you free the sql::Connection object as soon as you do not need it any more. But do not explicitly free the connector object!

22.4.5.2. MySQL Connector/C++ Running a simple query

For running simple queries, you can use the methods sql::Statement::execute(), sql::Statement::executeQuery() and sql::Statement::executeUpdate(). Use the method sql::Statement::execute() if your query does not return a result set or if your query returns more than one result set. See the examples/ directory for more on this.

sql::mysql::MySQL_Driver *driver;sql::Connection *con;sql::Statement *stmt;driver = sql::mysql::get_mysql_driver_instance();con = driver->connect("tcp://127.0.0.1:3306", "user", "password");stmt = con->createStatement();stmt->execute("USE " EXAMPLE_DB);stmt->execute("DROP TABLE IF EXISTS test");stmt->execute("CREATE TABLE test(id INT, label CHAR(1))");stmt->execute("INSERT INTO test(id, label) VALUES (1, 'a')");delete stmt;delete con;

Note that you have to free sql::Statement and sql::Connection objects explicitly using delete.

22.4.5.3. MySQL Connector/C++ Fetching results

The API for fetching result sets is identical for (simple) statements and prepared statements. If your query returns one result set, use sql::Statement::executeQuery() or sql::PreparedStatement::executeQuery() to run your query. Both methods return sql::ResultSet objects. The preview version does buffer all result sets on the client to support cursors.

// ...sql::Connection *con;sql::Statement *stmt;sql::ResultSet  *res;// ...stmt = con->createStatement();// ...res = stmt->executeQuery("SELECT id, label FROM test ORDER BY id ASC");while (res->next()) {  // You can use either numeric offsets...  cout << "id = " << res->getInt(1); // getInt(1) returns the first column  // ... or column names for accessing results.  // The latter is recommended.  cout << ", label = '" << res->getString("label") << "'" << endl;}delete res;delete stmt;delete con;
Note

Note in the preceding code snippet that column indexing starts from 1.

Note that you have to free sql::Statement, sql::Connection and sql::ResultSet objects explicitly using delete.

The usage of cursors is demonstrated in the examples contained in the download package.

22.4.5.4. MySQL Connector/C++ Using Prepared Statements

If you are not familiar with Prepared Statements on MySQL have an extra look at the source code comments and explanations in the file examples/prepared_statement.cpp.

sql::PreparedStatement is created by passing an SQL query to sql::Connection::prepareStatement(). As sql::PreparedStatement is derived from sql::Statement, you will feel familiar with the API once you have learned how to use (simple) statements (sql::Statement). For example, the syntax for fetching results is identical.

// ...sql::Connection*con;sql::PreparedStatement*prep_stmt// ...prep_stmt = con->prepareStatement("INSERT INTO test(id, label) VALUES (?, ?)");prep_stmt->setInt(1, 1);prep_stmt->setString(2, "a");prep_stmt->execute();prep_stmt->setInt(1, 2);prep_stmt->setString(2, "b");prep_stmt->execute();delete prep_stmt;delete con;

As usual, you have to free sql::PreparedStatement and sql::Connection objects explicitly.

22.4.5.5. MySQL Connector/C++ Complete Example 1

The following code shows a complete example of how to use MySQL Connector/C++:

/* Copyright 2008, 2010, Oracle and/or its affiliates. All rights reserved.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; version 2 of the License.There are special exceptions to the terms and conditions of the GPLas it is applied to this software. View the full text of theexception in file EXCEPTIONS-CONNECTOR-C++ in the directory of thissoftware distribution.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*//* Standard C++ includes */#include <stdlib.h>#include <iostream>/*  Include directly the different  headers from cppconn/ and mysql_driver.h + mysql_util.h  (and mysql_connection.h). This will reduce your build time!*/#include "mysql_connection.h"#include <cppconn/driver.h>#include <cppconn/exception.h>#include <cppconn/resultset.h>#include <cppconn/statement.h>using namespace std;int main(void){cout << endl;cout << "Running 'SELECT 'Hello World!' »   AS _message'..." << endl;try {  sql::Driver *driver;  sql::Connection *con;  sql::Statement *stmt;  sql::ResultSet *res;  /* Create a connection */  driver = get_driver_instance();  con = driver->connect("tcp://127.0.0.1:3306", "root", "root");  /* Connect to the MySQL test database */  con->setSchema("test");  stmt = con->createStatement();  res = stmt->executeQuery("SELECT 'Hello World!' AS _message");  while (res->next()) { cout << "\t... MySQL replies: "; /* Access column data by alias or column name */ cout << res->getString("_message") << endl; cout << "\t... MySQL says it again: "; /* Access column fata by numeric offset, 1 is the first column */ cout << res->getString(1) << endl;  }  delete res;  delete stmt;  delete con;} catch (sql::SQLException &e) {  cout << "# ERR: SQLException in " << __FILE__;  cout << "(" << __FUNCTION__ << ") on line " » << __LINE__ << endl;  cout << "# ERR: " << e.what();  cout << " (MySQL error code: " << e.getErrorCode();  cout << ", SQLState: " << e.getSQLState() << " )" << endl;}cout << endl;return EXIT_SUCCESS;}

22.4.5.6. MySQL Connector/C++ Complete Example 2

The following code shows a complete example of how to use MySQL Connector/C++:

/* Copyright 2008, 2010, Oracle and/or its affiliates. All rights reserved.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; version 2 of the License.There are special exceptions to the terms and conditions of the GPLas it is applied to this software. View the full text of theexception in file EXCEPTIONS-CONNECTOR-C++ in the directory of thissoftware distribution.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*//* Standard C++ includes */#include <stdlib.h>#include <iostream>/*  Include directly the different  headers from cppconn/ and mysql_driver.h + mysql_util.h  (and mysql_connection.h). This will reduce your build time!*/#include "mysql_connection.h"#include <cppconn/driver.h>#include <cppconn/exception.h>#include <cppconn/resultset.h>#include <cppconn/statement.h>#include <cppconn/prepared_statement.h>using namespace std;int main(void){cout << endl;cout << "Let's have MySQL count from 10 to 1..." << endl;try {  sql::Driver *driver;  sql::Connection *con;  sql::Statement *stmt;  sql::ResultSet *res;  sql::PreparedStatement *pstmt;  /* Create a connection */  driver = get_driver_instance();  con = driver->connect("tcp://127.0.0.1:3306", "root", "root");  /* Connect to the MySQL test database */  con->setSchema("test");  stmt = con->createStatement();  stmt->execute("DROP TABLE IF EXISTS test");  stmt->execute("CREATE TABLE test(id INT)");  delete stmt;  /* '?' is the supported placeholder syntax */  pstmt = con->prepareStatement("INSERT INTO test(id) VALUES (?)");  for (int i = 1; i <= 10; i++) { pstmt->setInt(1, i); pstmt->executeUpdate();  }  delete pstmt;  /* Select in ascending order */  pstmt = con->prepareStatement("SELECT id FROM test ORDER BY id ASC");  res = pstmt->executeQuery();  /* Fetch in reverse = descending order! */  res->afterLast();  while (res->previous()) cout << "\t... MySQL counts: " << res->getInt("id") << endl;  delete res;  delete pstmt;  delete con;} catch (sql::SQLException &e) {  cout << "# ERR: SQLException in " << __FILE__;  cout << "(" << __FUNCTION__ << ") on line " » << __LINE__ << endl;  cout << "# ERR: " << e.what();  cout << " (MySQL error code: " << e.getErrorCode();  cout << ", SQLState: " << e.getSQLState() << » " )" << endl;}cout << endl;return EXIT_SUCCESS;}

22.4.6. MySQL Connector/C++ Tutorials

Here are some tutorials on using MySQL Connector/C++. Also consult the examples in Section 22.4.5, "MySQL Connector/C++ Getting Started: Usage Examples".

Setting up the World database for use in the tutorials

These tutorials refer to tables and sample data from the World database, which you can download from the MySQL Documentation page. Look for the section called "Example Databases".

Tutorial framework code

These examples all use the following framework, to avoid repeating code:

#include <stdlib.h>#include <iostream>#include <sstream>#include <stdexcept>#include "mysql_connection.h"#include <cppconn/driver.h>#include <cppconn/exception.h>#include <cppconn/resultset.h>#include <cppconn/statement.h>#include <cppconn/prepared_statement.h>#define EXAMPLE_HOST "localhost"#define EXAMPLE_USER "root"#define EXAMPLE_PASS ""#define EXAMPLE_DB "world"using namespace std;int main(int argc, const char **argv){ string url(argc >= 2 ? argv[1] : EXAMPLE_HOST); const string user(argc >= 3 ? argv[2] : EXAMPLE_USER); const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS); const string database(argc >= 5 ? argv[4] : EXAMPLE_DB); cout << "Connector/C++ tutorial framework..." << endl; cout << endl; try {/* INSERT TUTORIAL CODE HERE! */ } catch (sql::SQLException &e) { /*  The MySQL Connector/C++ throws three different exceptions:  - sql::MethodNotImplementedException (derived from sql::SQLException)  - sql::InvalidArgumentException (derived from sql::SQLException)  - sql::SQLException (derived from std::runtime_error) */ cout << "# ERR: SQLException in " << __FILE__; cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl; /* Use what() (derived from std::runtime_error) to fetch the error message */ cout << "# ERR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << " )" << endl; return EXIT_FAILURE; } cout << "Done." << endl; return EXIT_SUCCESS;}

To compile and run the framework

First, copy and paste the framework code to a file such as frmwk.cpp. Edit the #define statements to reflect your connection details (server, user, password, database).

To compile the framework, for example on Mac OS X, type:

shell> g++ -o frmwk -I/usr/local/include -I/usr/local/include/cppconn-lmysqlcppconn frmwk.cpp

To run the framework, enter the following:

shell> ./frmwk

You will see a simple message. You are now ready to continue to the tutorials.

22.4.6.1. Tutorial: Calling Stored Procedures with Statements in MySQL Connector/C++

Stored procedures can be called using both Statements and Prepared Statements. This tutorial looks at calling stored procedures using Statements. The following tutorial Section 22.4.6.2, "Tutorial: Calling Stored Procedures with Prepared Statements in MySQL Connector/C++" will cover the use of Prepared Statements.

You can construct and call various combinations of stored procedures:

  1. A stored procedure that does not return any result. For example, such a stored procedure can log non-critical information, or change database data in a straightforward way.

  2. A stored procedure that returns an output parameter. For example, such a procedure can indicate success or failure, query a single item of data, or combine multiple data items into a single result.

  3. A stored procedure that returns a result set. The procedure can execute a query that matches an arbitrary number of table rows. Your application loops through the result set to display, transform, or otherwise process each item.

The following stored procedures illustrate each of these scenarios.

The following routine adds a country into the World database, but does not return a result. This corresponds to Scenario 1 above.

CREATE PROCEDURE add_country (IN country_code CHAR(3), IN country_name CHAR(52),IN continent_name CHAR(30))BEGIN   INSERT INTO Country(Code, Name, Continent) VALUES (country_code, country_name, continent_name);END

The next routine returns the population of a specified country, and corresponds to Scenario 2 above:

CREATE PROCEDURE get_pop (IN country_name CHAR(52), OUT country_pop INT(11))BEGIN   SELECT Population INTO country_pop FROM Country WHERE Name = country_name;END

The next routine is an example of a procedure returning a result set containing multiple records. This routine corresponds to Scenario 3 above.

CREATE PROCEDURE get_data ()BEGIN SELECT Code, Name, Population, Continent FROM Country WHERE Continent = "Oceania" AND Population < 10000; SELECT Code, Name, Population, Continent FROM Country WHERE Continent = "Europe" AND Population < 10000; SELECT Code, Name, Population, Continent FROM Country WHERE Continent = "North America" AND Population < 10000;END

Enter and test the stored procedures to ensure no errors have been introduced. You are now ready to start writing applications using Connector/C++ that call stored procedures.

Scenario 1 - Stored procedure does not return a result set

The first case illustrates Scenario 1, calling a Stored procedure that does not return a result set.

  1. Make a copy of the tutorial framework code.

  2. Insert the following code into the framework at the correct location (denoted by an INSERT HERE comment in the framework).

    sql::Driver* driver = get_driver_instance();std::auto_ptr<sql::Connection> con(driver->connect(url, user, pass));con->setSchema(database);std::auto_ptr<sql::Statement> stmt(con->createStatement());// We don't need to check the return value explicitly, if it indicates// an error Connector/C++ will generate an exception.stmt->execute("CALL add_country(\"ATL\", \"Atlantis\", \"North America\")"); 
  3. Compile the program using the following command:

    shell> g++ -o sp_scenario1 -I/usr/local/include/cppconn/ -lmysqlcppconn sp_scenario1.cpp
  4. Run the program by typing:

    shell> ./sp_scenario1
  5. Using the mysql Command Line Client, or other suitable tool, check the World database to determine that it has been updated correctly. You can use a query such as:

    SELECT Code, Name, Continent FROM Country WHERE Code="ATL";

The code in this case simply creates a statement and then invokes the execute method on it, passing the call to the stored procedure as a parameter. The stored procedure itself does not return a value, although it is important to note there will always be a return value from the call - this is simply the call status. MySQL Connector/C++ handles this status for you, so you do not need code to handle it explicitly. If the call fails for some reason, an exception will be raised, and this will be handled by the catch statement in the code.

Scenario 2 - Stored procedure returns an output parameter

You will now see how to handle a stored procedure that returns an output parameter.

  1. Enter the following code into the tutorial framework code:

    sql::Driver* driver = get_driver_instance();std::auto_ptr<sql::Connection> con(driver->connect(url, user, pass));con->setSchema(database);std::auto_ptr<sql::Statement> stmt(con->createStatement());stmt->execute("CALL get_pop(\"Uganda\", @pop)");std::auto_ptr<sql::ResultSet> res(stmt->executeQuery("SELECT @pop AS _reply"));while (res->next())   cout << "Population of Uganda: " << res->getString("_reply") << endl;stmt->execute("CALL get_pop_continent(\"Asia\", @pop)");res.reset(stmt->executeQuery("SELECT @pop AS _reply"));while (res->next()) cout << "Population of Asia: " << res->getString("_reply") << endl;stmt->execute("CALL get_world_pop(@pop)");res.reset(stmt->executeQuery("SELECT @pop AS _reply"));while (res->next()) cout << "Population of World: " << res->getString("_reply") << endl;
  2. Compile the program using the following command:

    shell> g++ -o sp_scenario2 -I/usr/local/include/cppconn/ -lmysqlcppconn sp_scenario2.cpp
  3. Run the program by typing:

    shell> ./sp_scenario2

    Note the output generated by the program.

In this scenario, the stored procedure sets an output parameter. This is not returned as such, but needs to be obtained using a query. If running the SQL statements directly, this might be similar to the following:

CALL get_world_pop(@pop);SELECT @pop;

In the C++ code, a similar sequence is carried out. First, the CALL is executed as seen earlier. To obtain the output parameter, an additional query must be executed. This query results in a ResultSet that can then be processed in a while loop. The simplest way to retrieve the data in this case is to use a getString method on the ResultSet, passing the name of the variable to access. In this example _reply is used as a placeholder for the variable and therefore is used as the key to access the correct element of the result dictionary.

Scenario 3 - Stored procedure returns a Result Set

You will now see how to handle a stored procedure that returns a result set.

  1. Enter the following code into the tutorial framework code:

    sql::Driver* driver = get_driver_instance();std::auto_ptr<sql::Connection> con(driver->connect(url, user, pass));con->setSchema(database);std::auto_ptr<sql::Statement> stmt(con->createStatement());stmt->execute("CALL get_stats()");std::auto_ptr< sql::ResultSet > res;do {   res.reset(stmt->getResultSet());   while (res->next()) {  cout << "Result: " << res->getString(1) << endl;   }} while (stmt->getMoreResults());
  2. Compile the program using the following command:

    shell> g++ -o sp_scenario3 -I/usr/local/include/cppconn/ -lmysqlcppconn sp_scenario3.cpp
  3. Run the program by typing:

    shell> ./sp_scenario3

    Note the output generated by the program.

The code is similar to the examples you have previously seen. The code of particular interest in this case is:

do {   res.reset(stmt->getResultSet());   while (res->next()) {  cout << "Name: " << res->getString("Name") << " Population: " << res->getInt("Population")   << endl;   }} while (stmt->getMoreResults());

The CALL is executed as before, with the results being returned into multiple ResultSets. This is because the Stored Procedure in this case uses multiple SELECT statements. In this example, the output shows that three Result Sets are processed, because there are three SELECT statements in the Stored Procedure. All of the Result Sets have more than one row.

The results are processed using the pattern:

do {   Get Result Set   while (Get Result) {  Process Result   }} while (Get More Result Sets);
Note

This pattern would be used even if the Stored Procedure carried out a single SELECT and you knew there was only one result set. This is a requirement of the underlying protocol.

22.4.6.2. Tutorial: Calling Stored Procedures with Prepared Statements in MySQL Connector/C++

Before working through this tutorial, it is recommended you first work through the previous tutorial Section 22.4.6.1, "Tutorial: Calling Stored Procedures with Statements in MySQL Connector/C++".

Scenario 1 - Using a Prepared Statement to prepare a Stored Procedure that does not return a result set

  1. Add the following code to the try block of the tutorial framework:

    vector<string> code_vector;code_vector.push_back("SLD");code_vector.push_back("DSN");code_vector.push_back("ATL");vector<string> name_vector;name_vector.push_back("Sealand");name_vector.push_back("Disneyland");name_vector.push_back("Atlantis");vector<string> cont_vector;cont_vector.push_back("Europe");cont_vector.push_back("North America");cont_vector.push_back("Oceania");sql::Driver * driver = get_driver_instance();std::auto_ptr< sql::Connection > con(driver->connect(url, user, pass));con->setSchema(database);std::auto_ptr< sql::PreparedStatement >  pstmt;pstmt.reset(con->prepareStatement("CALL add_country(?,?,?)"));for (int i=0; i<3; i++){   pstmt->setString(1,code_vector[i]);   pstmt->setString(2,name_vector[i]);   pstmt->setString(3,cont_vector[i]);   pstmt->execute(); }

    Also, add #include <vector> to the top of your code, because vectors are used to store sample data.

  2. Compile the code using the following command:

    g++ -o ps_scenario1 -I/usr/local/include/cppconn/ -lmysqlcppconn ps_scenario1.cpp
  3. Run the code using the command:

    ./ps_scenario1
  4. You can test the database has been updated correctly by using a query such as:

    SELECT Code, Name, Continent FROM Country WHERE Code = "DSN" OR Code="ATL" OR Code="SLD";

The code is relatively simple, as no processing is required to handle Result Sets. The procedure call, CALL add_country(?,?,?), is made using placeholders for input parameters denoted by '?'. These placeholders are replaced by values using the Prepared Statement's setString method in this case. The for loop is set up to iterate 3 times, as there are three data sets in this example. The same Prepared Statement is executed three times, each time with different input parameters.

Scenario 2 - Using a Prepared Statement to prepare a Stored Procedure that uses an output parameter

In this scenario a different Stored Procedure is going to be used compared to the one used in the tutorial Section 22.4.6.1, "Tutorial: Calling Stored Procedures with Statements in MySQL Connector/C++". This is to illustrate passing an input parameter as well as fetching an output parameter. The stored routine is as follows:

CREATE PROCEDURE get_pop_continent (IN continent_name CHAR(30), OUT continent_pop INT(11))BEGIN SELECT SUM(Population) INTO continent_pop FROM Country WHERE Continent = continent_name;END
  1. Copy the following code into the try block of the tutorial framework code:

    vector<string> cont_vector;cont_vector.push_back("Europe");cont_vector.push_back("North America");cont_vector.push_back("Oceania");sql::Driver * driver = get_driver_instance();std::auto_ptr< sql::Connection > con(driver->connect(url, user, pass));con->setSchema(database); std::auto_ptr< sql::Statement > stmt(con->createStatement());std::auto_ptr< sql::PreparedStatement >  pstmt;std::auto_ptr< sql::ResultSet > res;pstmt.reset(con->prepareStatement("CALL get_pop_continent(?,@pop)"));for (int i=0; i<3; i++){   pstmt->setString(1,cont_vector[i]);   pstmt->execute();   res.reset(stmt->executeQuery("SELECT @pop AS _population"));   while (res->next())  cout << "Population of " << cont_vector[i] << " is "  << res->getString("_population") << endl;}

    You will also need to add the line #include <vector> to the top of the code, as vectors are used in this example.

  2. Compile the code using:

    shell> g++ -o ps_scenario2 -I/usr/local/include/cppconn/ -lmysqlcppconn ps_scenario2.cpp
  3. Run the code using:

    shell> ./ps_scenario2
  4. Make a note of the output.

In this scenario a Prepared Statement is created that calls the Stored Procedure get_pop_continent. This procedure takes an input parameter, and also returns an output parameter. The approach used is to create another statement that can be used to fetch the output parameter using a SELECT query. Note that when the Prepared Statement is created, the input parameter to the Stored Procedure is denoted by '?'. Prior to execution of Prepared Statement it is necessary to replace this placeholder by an actual value. This is done using methods such as setString and setInt, for example:

pstmt->setString(1,cont_vector[i]);

Although for the query used to obtain the output parameter a single result set is expected, it is important to use the while loop to catch more than one result, to avoid the possibility of the connection becoming unstable.

Scenario 3 - Using a Prepared Statement to prepare a Stored Procedure that returns multiple Result Sets

Note

Note this scenario is not supported on versions of MySQL prior to 5.5.3. This is due to a limitation in the client/server protocol.

  1. Enter the following code into the try block of the tutorial framework:

    sql::Driver * driver = get_driver_instance();std::auto_ptr< sql::Connection > con(driver->connect(url, user, pass));con->setSchema(database); std::auto_ptr< sql::PreparedStatement >  pstmt;std::auto_ptr< sql::ResultSet > res;pstmt.reset(con->prepareStatement("CALL get_data()"));res.reset(pstmt->executeQuery());do {   res.reset(pstmt->getResultSet());   while (res->next()) {  cout << "Name: " << res->getString("Name") << " Population: " << res->getInt("Population")   << endl;   }} while (pstmt->getMoreResults());
  2. Compile the code using the following command:

    shell> g++ -o ps_scenario3 -I/usr/local/include/cppconn/ -lmysqlcppconn ps_scenario3.cpp
  3. Run the program using the command:

    shell> ./ps_scenario3
  4. Make a note of the output generated.

The code executes the Stored Procedure using a Prepared Statement. The standard do-while construct is used to ensure that all Result Sets are fetched. In this case the returned values are fetched from the Result Sets using the getInt and getString methods.

22.4.7. MySQL Connector/C++ Debug Tracing

Although a debugger can be used to debug your application, you may find it beneficial to turn on the debug traces of the connector. Some problems happen randomly which makes them difficult to debug using a debugger. In such cases debug traces and protocol files are more useful because they allow you to trace the activities of all instances of your program.

DTrace is a very powerful technology to trace any application without having to develop an extra trace module for your application. Unfortunately, DTrace is currently only available on Solaris, MacOS 10.5, and FreeBSD.

The MySQL Connector/C++ can write two trace files:

  1. Trace file generated by the MySQL Client Library

  2. Trace file generated internally by MySQL Connector/C++

The first trace file can be generated by the underlying MySQL Client Library (libmysql). To enable this trace, the connector will call the C-API function mysql_debug() internally. As only debug versions of the MySQL Client Library are capable of writing a trace file, compile MySQL Connector/C++ against a debug version of the library if you want to utilize this trace. The trace shows the internal function calls and the addresses of internal objects as shown below:

>mysql_stmt_init| >_mymalloc| | enter: Size: 816| | exit: ptr: 0x68e7b8| <_mymalloc | >init_alloc_root| | enter: root: 0x68e7b8| | >_mymalloc| | | enter: Size: 2064| | | exit: ptr: 0x68eb28[...]

The second trace is the MySQL Connector/C++ internal trace. It is available with debug and nondebug builds of the connector as long as you have enabled the tracing module at compile time using cmake -DMYSQLCPPCONN_TRACE_ENABLE:BOOL=1. By default, the tracing functionality is not available and calls to trace functions are removed by the preprocessor.

Compiling the connector with tracing functionality enabled will cause two additional tracing function calls per each connector function call. Run your own benchmark to find out how much this will impact the performance of your application.

A simple test using a loop running 30,000 INSERT SQL statements showed no significant real-time impact. The two variants of this application using a trace enabled and trace disabled version of the connector performed equally well. The run time measured in real-time was not significantly impacted as long as writing a debug trace was not enabled. However, there will be a difference in the time spent in the application. When writing a debug trace the IO subsystem may become a bottleneck.

In summary, use connector builds with tracing enabled carefully. Trace enabled versions may cause higher CPU usage even if the overall run time of your application is not impacted significantly.

|  INF: Tracing enabled<MySQL_Connection::setClientOption>MySQL_Prepared_Statement::setInt|  INF: this=0x69a2e0|  >MySQL_Prepared_Statement::checkClosed|  <MySQL_Prepared_Statement::checkClosed| <MySQL_Prepared_Statement::setInt[...]

The example from examples/debug_output.cpp demonstrates how to activate the debug traces in your program. Currently they can only be activated through API calls. The traces are controlled on a per-connection basis. You can use the setClientOptions() method of a connection object to activate and deactivate the generation of a trace. The MySQL Client Library trace is always written into a file, whereas the connector's protocol messages are printed to standard out.

sql::Driver *driver;int on_off = 1;/* Using the Driver to create a connection */driver = get_driver_instance();std::auto_ptr< sql::Connection > con(driver->connect(host, user, pass));/*Activate debug trace of the MySQL Client Library (C-API)Only available with a debug build of the MySQL Client Library!*/con->setClientOption("libmysql_debug", "d:t:O,client.trace");/*Tracing is available if you have compiled the driver usingcmake -DMYSQLCPPCONN_TRACE_ENABLE:BOOL=1*/con->setClientOption("client_trace", &on_off);

22.4.8. MySQL Connector/C++ Usage Notes

See the JDBC overview for information on JDBC 4.0. Please also check the examples/ directory of the download package.

  • DatabaseMetaData::supportsBatchUpdates() returns true because MySQL supports batch updates in general. However, no API calls for batch updates are provided by the MySQL Connector/C++ API.

  • Two non-JDBC methods let you fetch and set unsigned integers: getUInt64() and getUInt(). These are available for ResultSet and Prepared_Statement:

    • ResultSet::getUInt64()

    • ResultSet::getUInt()

    • Prepared_Statement::setUInt64()

    • Prepared_Statement::setUInt()

    The corresponding getLong() and setLong() methods have been removed.

  • The method DatabaseMetaData::getColumns() has 23 columns in its result set, rather than the 22 columns defined by JDBC. The first 22 columns are as described in the JDBC documentation, but column 23 is new:

    23. IS_AUTOINCREMENT: String which is "YES" if the column is an auto-increment column. Otherwise the string contains "NO".

  • MySQL Connector/C++ may return different metadata for the same column.

    When you have any column that accepts a charset and a collation in its specification and you specify a binary collation, such as:

     CHAR(250) CHARACTER SET 'latin1' COLLATE 'latin1_bin'

    The server sets the BINARY flag in the result set metadata of this column. The method ResultSetMetadata::getColumnTypeName() uses the metadata and will report, due to the BINARY flag, that the column type name is BINARY. This is illustrated below:

    mysql> create table varbin(a varchar(20) character set utf8 collate utf8_bin);Query OK, 0 rows affected (0.00 sec)mysql> select * from varbin;Field   1:  `a`Catalog: `def`Database:   `test`Table:  `varbin`Org_table:  `varbin`Type:   VAR_STRINGCollation:  latin1_swedish_ci (8)Length: 20Max_length: 0Decimals:   0Flags:  BINARY0 rows in set (0.00 sec)mysql> select * from information_schema.columns where table_name='varbin'\G*************************** 1. row ***************************   TABLE_CATALOG: NULL TABLE_SCHEMA: test  TABLE_NAME: varbin COLUMN_NAME: a ORDINAL_POSITION: 1  COLUMN_DEFAULT: NULL IS_NULLABLE: YES   DATA_TYPE: varcharCHARACTER_MAXIMUM_LENGTH: 20  CHARACTER_OCTET_LENGTH: 60   NUMERIC_PRECISION: NULL   NUMERIC_SCALE: NULL  CHARACTER_SET_NAME: utf8  COLLATION_NAME: utf8_bin COLUMN_TYPE: varchar(20)  COLUMN_KEY:   EXTRA:  PRIVILEGES: select,insert,update,references  COLUMN_COMMENT:1 row in set (0.01 sec)

    However, INFORMATION_SCHEMA gives no hint in its COLUMNS table that metadata will contain the BINARY flag. DatabaseMetaData::getColumns() uses INFORMATION_SCHEMA. It will report the type name CHAR for the same column. Note, a different type code is also returned.

  • The MySQL Connector/C++ class sql::DataType defines the following JDBC standard data types: UNKNOWN, BIT, TINYINT, SMALLINT, MEDIUMINT, INTEGER, BIGINT, REAL, DOUBLE, DECIMAL, NUMERIC, CHAR, BINARY, VARCHAR, VARBINARY, LONGVARCHAR, LONGVARBINARY, TIMESTAMP, DATE, TIME, GEOMETRY, ENUM, SET, SQLNULL.

    However, the following JDBC standard data types are not supported by MySQL Connector/C++: ARRAY, BLOB, CLOB, DISTINCT, FLOAT, OTHER, REF, STRUCT.

  • When inserting or updating BLOB or TEXT columns, MySQL Connector/C++ developers are advised not to use setString(). Instead, use the dedicated API function setBlob().

    The use of setString() can cause a Packet too large error message. The error will occur if the length of the string passed to the connector using setString() exceeds max_allowed_packet (minus a few bytes reserved in the protocol for control purposes). This situation is not handled in MySQL Connector/C++, as this could lead to security issues, such as extremely large memory allocation requests due to malevolently long strings.

    However, if setBlob() is used, this problem does not arise. This is because setBlob() takes a streaming approach based on std::istream. When sending the data from the stream to MySQL Server, MySQL Connector/C++ will split the stream into chunks appropriate for MySQL Server and observe the max_allowed_packet setting currently being used.

    Caution

    When using setString() it is not possible to set max_allowed_packet to a value large enough for the string, prior to passing it to MySQL Connector/C++. That configuration option cannot be changed within a session.

    This difference with the JDBC specification ensures that MySQL Connector/C++ is not vulnerable to memory flooding attacks.

  • In general, MySQL Connector/C++ works with MySQL 5.0, but it is not completely supported. Some methods may not be available when connecting to MySQL 5.0. This is because the Information Schema is used to obtain the requested information. There are no plans to improve the support for 5.0 because the current GA version of MySQL Server is 5.5. As a new product, MySQL Connector/C++ is primarily targeted at the MySQL Server GA version that was available on its release.

    The following methods will throw a sql::MethodNotImplemented exception when you connect to MySQL earlier than 5.1.0:

    • DatabaseMetadata::getCrossReference()

    • DatabaseMetadata::getExportedKeys()

  • MySQL Connector/C++ includes a method Connection::getClientOption() which is not included in the JDBC API specification. The prototype is:

    void getClientOption(const std::string & optionName, void * optionValue)

    The method can be used to check the value of connection properties set when establishing a database connection. The values are returned through the optionValue argument passed to the method with the type void *.

    Currently, getClientOption() supports fetching the optionValue of the following options:

    • metadataUseInfoSchema

    • defaultStatementResultType

    • defaultPreparedStatementResultType

    In the case of both defaultStatementResultType and defaultPreparedStatementResultType, interpret the optionValue argument as an integer upon return.

    The connection property can be either set when establishing the connection through the connection property map or using void Connection::setClientOption(const std::string & optionName, const void * optionValue) where optionName is assigned the value metadataUseInfoSchema.

    Some examples are given below:

    int defaultStmtResType;int defaultPStmtResType;conn->getClientOption("defaultStatementResultType", (void *) &defaultStmtResType);conn->getClientOption("defaultPreparedStatementResultType", (void *) &defaultPStmtResType);bool isInfoSchemaUsed;conn->getClientOption("metadataUseInfoSchema", (void *) &isInfoSchemaUsed);
  • MySQL Connector/C++ also supports the following methods not found in the JDBC API standard:

    std::string MySQL_Connection::getSessionVariable(const std::string & varname)
    void MySQL_Connection::setSessionVariable(const std::string & varname, const std::string & value)

    Note that both methods are members of the MySQL_Connection class. The methods get and set MySQL session variables.

    setSessionVariable() is equivalent to executing:

    SET SESSION <varname> = <value>

    getSessionVariable() is equivalent to executing the following and fetching the first return value:

    SHOW SESSION VARIABLES LIKE "<varname>"

    You can use "%" and other placeholders in <varname>, if the underlying MySQL server supports this.

  • Fetching the value of a column can sometimes return different values depending on whether the call is made from a Statement or Prepared Statement. This is because the protocol used to communicate with the server differs depending on whether a Statement or Prepared Statement is used.

    To illustrate this, consider the case where a column has been defined as of type BIGINT. The most negative BIGINT value is then inserted into the column. If a Statement and Prepared Statement are created that perform a GetUInt64() call, then the results will be different in each case. The Statement returns the maximum positive value for BIGINT. The Prepared Statement returns 0.

    The reason for the different results is due to the fact that Statements use a text protocol, and Prepared Statements use a binary protocol. With the binary protocol in this case, a binary value is returned from the server that can be interpreted as an int64. In the above scenario a very large negative value was fetched with GetUInt64(), which fetches unsigned integers. As the large negative value cannot be sensibly converted to an unsigned value 0 is returned.

    In the case of the Statement, which uses the text protocol, values are returned from the server as strings, and then converted as required. When a string value is returned from the server in the above scenario, the large negative value must be converted by the runtime library function strtoul(), which GetUInt64() calls. The behavior of strtoul() is dependent upon the specific runtime and host operating system, so the results can be variable. In the case given a large positive value was actually returned.

    Although it is very rare, there are some cases where Statements and Prepared Statements can return different values unexpectedly, but this usually only happens in extreme cases such as the one mentioned.

  • The JDBC documentation lists many fields for the DatabaseMetaData class. JDBC also appears to define certain values for those fields. However, MySQL Connector/C++ does not define certain values for those fields. Internally enumerations are used and the compiler determines the values to assign to a field.

    To compare a value with the field, use code such as the following, rather than making assumptions about specific values for the attribute:

    // dbmeta is an instance of DatabaseMetaDataif (myvalue == dbmeta->attributeNoNulls) { ...}

    Usually myvalue will be a column from a result set holding metadata information. MySQL Connector/C++ does not guarantee that attributeNoNulls is 0. It can be any value.

  • When programming Stored Procedures, JDBC has available an extra class, an extra abstraction layer for callable statements, the CallableStatement class. As this class is not present in MySQL Connector/C++, use the methods from the Statement and Prepared Statement classes to run a Stored Procedure using CALL.

22.4.9. MySQL Connector/C++ Known Bugs and Issues

Note

Please report bugs through MySQL Bug System .

Known bugs:

None.

Known issues:

  • When linking against a static library for 1.0.3 on Windows, define CPPDBC_PUBLIC_FUNC either in the compiler options (preferable) or with /D "CPPCONN_PUBLIC_FUNC=". You can also explicitly define it in your code by placing #define CPPCONN_PUBLIC_FUNC before the header inclusions.

  • Generally speaking, C++ library binaries are less portable than C library binaries. Issues can be caused by name mangling, different Standard Template Library (STL) versions and using different compilers and linkers for linking against the libraries than were used for building the library itself.

    Even a small change in the compiler version can, but does not have to, cause problems. If you obtain error messages, that you suspect are related to binary incompatibilities, build MySQL Connector/C++ from source, using the same compiler and linker that you will use to build and link your application.

    Due to the variations between Linux distributions, compiler and linker versions and STL versions, it is not possible to provide binaries for each and every possible configuration. However, the MySQL Connector/C++ binary distributions contain a README file that describes the environment and settings used to build the binary versions of the libraries.

  • To avoid potential crashes the build configuration of MySQL Connector/C++ should match the build configuration of the application using it. For example, do not use the release build of MySQL Connector/C++ with a debug build of the client application.

For release notes detailing the changes in each release of Connector/C++, see MySQL Connector/C++ Release Notes.

22.4.10. MySQL Connector/C++ Feature requests

You can suggest new features in the first instance by joining the mailing list or forum and talking with the developers directly. See Section 22.4.11, "MySQL Connector/C++ Support"

The following feature requests are currently being worked on:

  • C++ references for Statements, ResultSets, and exceptions, are being considered, instead of pointers to heap memory. This reduces the exception handling burden for the programmer.

  • Adopt STL (suggestions are welcome).

  • JDBC compliance: data type interfaces and support through ResultSet:getType() and PreparedStatement:bind(). Introduce sql::Blob, sql::Clob, sql::Date, sql::Time, sql::Timestamp, sql::URL. Support get|setBlob(), get|setClob(), get|setDate(), get|setTime(), get|setTimestamp(), get|setURL()

  • Add support for all C-API connection options. Improved support for mysql_options.

  • Add connect method which supports passing options using HashMaps.

  • Create Windows installer.

22.4.11. MySQL Connector/C++ Support

For general discussion of the MySQL Connector/C++ please use the C/C++ community forum or join the MySQL Connector/C++ mailing list.

Bugs can be reported at the MySQL bug Web site.

For release notes detailing the changes in each release of MySQL Connector/C++, see MySQL Connector/C++ Release Notes.

For Licensing questions, and to purchase MySQL Products and Services, please see http://www.mysql.com/buy-mysql/

22.5. MySQL Connector/C

What is MySQL Connector/C?

MySQL Connector/C is a C client library for client/server communication. It is a standalone replacement for the MySQL Client Library shipped with the MySQL Server.

Why have a replacement for MySQL Client Library?

There is no need to compile or install the MySQL Server package if you need only the client library.

MySQL Connector/C does not rely on the MySQL Server release cycle, so bug fixes and new features can be distributed independently of MySQL Server releases.

MySQL Connector/C API documentation is available here Section 22.8.3, "C API Function Descriptions".

For release notes detailing the changes in each release of MySQL Connector/C, see MySQL Connector/C Release Notes.

Supported platforms include:

  • Windows

  • Windows x64

  • Linux

  • Solaris

  • FreeBSD

  • Mac OS X

  • HP-UX

  • IBM AIX

22.5.1. Building MySQL Connector/C from the Source Code

Obtaining the Source Code

You can download a tar file containing the source code from the MySQL Developers site. Select the source code package from the drop down list.

The source code for development releases of the connector can be found at http://launchpad.net/libmysql on the Launchpad site.

The source code for the 1.0 branch is also available on the Launchpad site.

To get the code from the Launchpad site, you must have Bazaar installed. Use the command bzr branch lp:libmysql.

Building on Unix

Examples of supported Unix or Unix-like operating systems include:

  • Solaris

  • Linux

  • HP-UX

  • AIX

  • OS X

Compiler Tools

Ideally, the native compiler tool set for the target platform is used for compilation. For example, this would be SunStudio for Solaris or aCC for HP-UX. However, the GNU tool-chain can be used across all platforms.

You also need CMake 2.6 or newer, which is available online.

To Build

Change location to the top-level MySQL Connector/C source directory and use the following procedure:

  1. To generate the Makefile, enter this command:

    shell> cmake -G "Unix Makefiles"

    Or, for a Debug build:

    shell> cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug
  2. Build the project:

    shell> make

To Install

By default, make install installs the MySQL Connector/C files in the /usr/local directory. To change this location, specify another directory when generating the Makefile:

shell> cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/mypath

Now, as root, enter the following command to install the MySQL Connector/C libraries and tools:

root-shell> make install

At this point, all of the MySQL Connector/C files will be in place.

Building on Microsoft Windows

Older versions of Microsoft Windows are not supported. Supported versions are Windows 2000, Windows XP, Windows Vista, Windows Server 2003, or Windows Server 2008.

Compiler Tools

Microsoft Visual Studio 8 or 9 is recommended. The Express Edition of Visual Studio and other compilers might work, but are untested.

You also need CMake 2.6 or newer, which is available online.

To Build

  1. Set the environment variables for the Visual Studio toolchain. Visual Studio includes a batch file to set these for you, and installs a shortcut in the Start menu to open a command prompt with these variables set.

  2. Change location to the top-level MySQL Connector/C source directory.

    To build MySQL Connector/C using the CMake command-line tool, enter the following command a command prompt window:

    shell> cmake -G "Visual Studio 9 2008"

    The result is a project file, libmysql.sln, that you can either open with Visual Studio, or build from the command line with either of these commands:

    shell> devenv.com libmysql.sln /build Release
    shell> devenv.com libmysql.sln /build RelWithDebInfo

    For other versions of Visual Studio or nmake based build, run the following command:

    shell> cmake --help

    to check the supported generators.

    To compile the Debug build, you must run set the CMake build type so the correct external library versions are used:

    shell> cmake -G "Visual Studio 9 2008" -DCMAKE_BUILD_TYPE=Debug

    Followed by:

    shell> devenv.com libmysql.sln /build Debug

To Install

To create a install package you can choose between two packaging formats:

  • Zip package

    To create a Zip package, run the cpack command from the top-level MySQL Connector/C source directory.

  • MSI Install package

    The required tools include Windows XML Installer toolset (WIX), which is available online.

    To create the MSI install package, change location to the subdirectory win of the MySQL Connector/C source tree and generate the Makefile:

    shell> cmake -G "NMake Makefiles"

    Create the MSI install package by invoking nmake:

    shell> nmake

Other Build Options

The following options can be used when building the MySQL Connector/C source code:

Table 22.28. Build Options for MySQL Connector/C

Build OptionDescription
-DWITH_OPENSSL=1Enables dynamic linking to the system OpenSSL library.
-DWITH_EXTERNAL_ZLIB=1Enables dynamic linking to the system Zlib library.

22.5.2. Testing MySQL Connector/C

To test MySQL Connector/C, you need a running MySQL server instance. Before you run the test suite, specify the following environment variables:

  • MYSQL_TEST_HOST: The host where the MySQL server is running (default localhost)

  • MYSQL_TEST_USER: The user name of the MySQL account to use

  • MYSQL_TEST_PASSWD: The password of the MySQL account to use

  • MYSQL_TEST_PORT: The port to connect to

  • MYSQL_TEST_SOCKET: The socket file to connect to

  • MYSQL_TEST_DB: The default database to use (default test)

To run the test suite, execute ctest from the command line:

shell> ctest

22.5.3. MySQL Connector/C FAQ

Questions

  • 23.5.3.1: What is the "MySQL Native C API"? What are its typical benefits and use cases?

  • 23.5.3.2: What is "libmysql"?

  • 23.5.3.3: What is "libmysqld"?

  • 23.5.3.4: What is "MySQL Connector/C"?

  • 23.5.3.5: What is the difference between "Native C API", "libmysql", "libmysqld" and "MySQL Connector/C"?

  • 23.5.3.6: Does MySQL Connector/C replace any of "Native C API", "libmysql" and "libmysqld"?

Questions and Answers

23.5.3.1: What is the "MySQL Native C API"? What are its typical benefits and use cases?

MySQL Connector/C, also known as libmysql, or MySQL Native C API, is a standalone, C-based API and library that you can use in C applications to connect to the MySQL Server. It implements the same MySQL client API that has been in use for a decade.

It is also used as the foundation for drivers for standard database APIs such as ODBC, Perl DBI, and Python DB API.

23.5.3.2: What is "libmysql"?

libmysql is the name of the library that MySQL Connector/C provides.

23.5.3.3: What is "libmysqld"?

libmysqld is an embedded database server with the same API as MySQL Connector/C. It is included with the MySQL Server distribution.

23.5.3.4: What is "MySQL Connector/C"?

MySQL Connector/C is a standalone distribution of the libmysql library, which was previously only available as part of the MySQL Server distribution. The version of libmysql included with MySQL Connector/C and the version bundled with the server are functionally equivalent, but the cross-platform build system for MySQL Connector/C uses CMake.

23.5.3.5: What is the difference between "Native C API", "libmysql", "libmysqld" and "MySQL Connector/C"?

MySQL Connector/C and libmysql are the "native C API for MySQL", and all three terms can be used interchangeably. "libmysqld" is the embedded version of the MySQL Server, and is included in the server distribution.

23.5.3.6: Does MySQL Connector/C replace any of "Native C API", "libmysql" and "libmysqld"?

MySQL Connector/C contains libmysql, and implements a native C API. It does not include libmysqld, which can be found with the MySQL server distribution.

22.6. MySQL Connector/Python

MySQL Connector/Python allows Python programs to access MySQL databases, using an API that is compliant with the Python DB API version 2.0. It is written in pure Python and does not have any dependencies except for the Python Standard Library.

MySQL Connector/Python includes support for:

  • Almost all features provided by MySQL Server up to and including MySQL Server version 5.5.

  • Converting parameter values back and forth between Python and MySQL data types, for example Python datetime and MySQL DATETIME. You can turn automatic conversion on for convenience, or off for optimal performance.

  • All MySQL extensions to standard SQL syntax.

  • Protocol compression, which enables compressing the data stream between the client and server.

  • Connections using TCP/IP sockets and on Unix using Unix sockets.

  • Secure TCP/IP connections using SSL.

  • Self-contained driver. Connector/Python does not require the MySQL client library or any Python modules outside the standard library.

MySQL Connector/Python supports from Python version 2.4 through 2.7, and Python 3.1 and later. Note that Connector/Python does not support the old MySQL Server authentication methods, which means that MySQL versions prior to 4.1 will not work.

For release notes detailing the changes in each release of Connector/Python, see MySQL Connector/Python Release Notes.

22.6.1. Guidelines for Python Developers

The following guidelines cover aspects of developing MySQL applications that might not be immediately obvious to developers coming from a Python background:

  • For security, do not hardcode the values needed to connect and log into the database in your main script. Python has the convention of a config.py module, where you can keep such values separate from the rest of your code.

  • Python scripts often build up and tear down large data structures in memory, up to the limits of available RAM. Because MySQL often deals with data sets that are many times larger than available memory, techniques that optimize storage space and disk I/O are especially important. For example, in MySQL tables, you typically use numeric IDs rather than string-based dictionary keys, so that the key values are compact and have a predictable length. This is especially important for columns that make up the primary key for an InnoDB table, because those column values are duplicated within each secondary index.

  • Any application that accepts input must expect to handle bad data.

    The bad data might be accidental, such as out-of-range values or misformatted strings. The application can use server-side checks such as unique constraints and NOT NULL constraints, to keep the bad data from ever reaching the database. On the client side, use techniques such as exception handlers to report any problems and take corrective action.

    The bad data might also be deliberate, representing a "SQL injection" attack. For example, input values might contain quotation marks, semicolons, % and _ wildcard characters and other characters significant in SQL statements. Validate input values to make sure they have only the expected characters. Escape any special characters that could change the intended behavior when substituted into a SQL statement. Never concatenate a user input value into a SQL statement without doing validation and escaping first. Even when accepting input generated by some other program, expect that the other program could also be hacked and be sending you incorrect or malicious data.

  • Because the result sets from SQL queries can be very large, use the appropriate method to retrieve items from the result set as you loop through them. fetchone() retrieves a single item, when you know the result set contains a single row. fetchall() retrieves all the items, when you know the result set contains a limited number of rows that can fit comfortably into memory. fetchmany() is the general-purpose method when you cannot predict the size of the result set: you keep calling it and looping through the returned items, until there are no more results to process.

  • Since Python already has convenient modules such as pickle and cPickle to read and write data structures on disk, the data that you choose store in MySQL instead is likely to have special characteristics:

    • Too large to all fit in memory at one time. You use SELECT statements to query only the precise items you need, and aggregate functions to perform calculations across multiple items. You configure the innodb_buffer_pool_size option within the MySQL server to dedicate a certain amount of RAM for caching query results.

    • Too complex to be represented by a single data structure. You divide the data between different SQL tables. You can recombine data from multiple tables by using a join query. You make sure that related data is kept in sync between different tables by setting up foreign key relationships.

    • Updated frequently, perhaps by multiple users simultaneously. The updates might only affect a small portion of the data, making it wasteful to write the whole structure each time. You use the SQL INSERT, UPDATE, and DELETE statements to update different items concurrently, writing only the changed values to disk. You use InnoDB tables and transactions to keep write operations from conflicting with each other, and to return consistent query results even as the underlying data is being updated.

  • Building in MySQL best practices for performance can help your application to scale without requiring major rewrites and architectural changes. See Chapter 8, Optimization for best practices for MySQL performance. It offers guidelines and tips for SQL tuning, database design, and server configuration.

  • You can avoid reinventing the wheel by learning the MySQL SQL statements for common operations: operators to use in queries, techniques for bulk loading data, and so on. Some statements and clauses are extensions to the basic ones defined by the SQL standard. See Section 13.2, "Data Manipulation Statements", Section 13.1, "Data Definition Statements", and Section 13.2.9, "SELECT Syntax" for the main classes of statements.

  • Issuing SQL statements from Python typically involves declaring very long, possibly multi-line string literals. Because string literals within the SQL statements could be enclosed by single quotation, double quotation marks, or contain either of those characters, for simplicity you can use Python's triple-quoting mechanism to enclose the entire statement. For example:

    '''It doesn't matter if this string contains 'single'or "double" quotes, as long as there aren't 3 in arow.'''

    You can use either of the ' or " characters for triple-quoting multi-line string literals.

  • Many of the secrets to a fast, scalable MySQL application involve using the right syntax at the very start of your setup procedure, in the CREATE TABLE statements. For example, Oracle recommends the ENGINE=INNODB clause for most tables, and makes it the default in MySQL 5.5 and up. Using InnoDB tables enables transactional behavior that helps scalability of read-write workloads and offers automatic crash recovery. A follow-on recommendation is to declare a numeric primary key for each table, which offers the fastest way to look up values and can act as a pointer to associated values in other tables (a foreign key). Also within the CREATE TABLE statement, using the most compact column data types that meet your application requirements helps performance and scalability, as the database server moves large amounts of data back and forth between memory and disk.

22.6.2. Connector/Python Versions

MySQL Connector/Python v1.0.x series went going through a series of beta releases, leading to the first generally available (GA) version 1.0.7. Any development releases prior to general availability are not supported now that the GA version is released.

The following table summarizes the available Connector/Python versions:

Table 22.29. Connector/Python Version Reference

Connector/Python VersionMySQL Server VersionsPython VersionsSupport Status for Connector
1.05.6, 5.5 (5.1, 5.0, 4.1)2.7, 2.6 (2.5, 2.4); 3.1 and laterRecommended version

Note

MySQL server and Python versions within brackets are known to work with Connector/Python, but are not officially supported. Bugs might not get fixed for those versions.

22.6.3. Connector/Python Installation

Connector/Python runs on any platform where Python is installed. Python comes pre-installed on almost any Linux distribution or UNIX-like system such as Apple Mac OS X and FreeBSD. On Microsoft Windows systems, you can install Python using the installer found on the Python Download website.

Connector/Python is a pure Python implementation of the MySQL Client/Server protocol, meaning it does not require any other MySQL client libraries or other components. It also has no third-party dependencies. If you need SSL support, verify that your Python installation has been compiled using the OpenSSL libraries.

The installation of Connector/Python is similar on every platform and follows the standard Python Distribution Utilities or Distutils. Some platforms have specific packaging, for example RPM, and, when made available, the installation of these will be covered in this manual.

Python terminology regarding distributions:

  • Source Distribution is a distribution that contains only source files and is generally platform independent.

  • Built Distribution can be regarded as a binary package. It contains both sources and platform-independent bytecode.

22.6.3.1. Installing Connector/Python Source Distribution on Linux, UNIX, or OS X

On UNIX-like systems such as Linux distributions, Solaris, Apple Mac OS X, and FreeBSD, you can download Connector/Python as a tar archive from http://dev.mysql.com/downloads/connector/python/.

To install Connector/Python from the .tar.gz file, download the latest version and follow these steps:

shell> gunzip mysql-connector-python-1.0.6b1.tar.gzshell> tar xf mysql-connector-python-1.0.6b1.tarshell> cd mysql-connector-python-1.0.6b1shell> sudo python setup.py install

On UNIX-like systems, Connector/Python gets installed in the default location /prefix/lib/pythonX.Y/site-packages/, where prefix is the location where Python was installed and X.Y is the version of Python. See How installation works in the Python manual.

If you are not sure where Connector/Python was installed, do the following to retrieve the location:

shell> python>>> from distutils.sysconfig import get_python_lib>>> print get_python_lib() # Python v2.x/Library/Python/2.7/site-packages>>> print(get_python_lib())   # Python v3.x/Library/Frameworks/Python.framework/Versions/3.1/lib/python3.1/site-packages
Note

The above example shows the default installation location on Mac OS X 10.7.

22.6.3.2. Installing Connector/Python Source Distribution on Microsoft Windows

On Microsoft Windows systems, you can download Connector/Python as a zip archive from http://dev.mysql.com/downloads/connector/python/.

Make sure that the Python executable is available in the Windows %PATH% setting. For more information about installation and configuration of Python on Windows, see the section Using Python on Windows in the Python documentation.

To install Connector/Python from the .zip file, download the latest version and follow these steps:

  1. Unpack the downloaded zip archive into a directory of your choice. For example, into the folder C:\mysql-connector\. Use the appropriate unzip command for your system, for example, unzip, pkunzip, and so on.

  2. Start a console window (or a DOS window) and change to the folder where you unpacked the Connector/Python zip archive.

    shell> cd C:\mysql-connector\
  3. Once inside the Connector/Python folder, do the following:

    shell> python setup.py install

On Windows, Connector/Python gets installed in the default location C:\PythonX.Y\Lib\site-packages\ where X.Y is the Python version you used to install the connector.

If you are not sure where Connector/Python ended up, do the following to retrieve the location where packages get installed:

shell> python>>> from distutils.sysconfig import get_python_lib>>> print get_python_lib() # Python v2.x>>> print(get_python_lib())   # Python v3.x

22.6.3.3. Verifying Your Connector/Python Installation

To test that your Connector/Python installation is working and is able to connect to a MySQL database server, you can run a very simple program where you substitute the login credentials and host information of the MySQL server. See Section 22.6.4.1, "Connecting to MySQL Using Connector/Python" for an example.

22.6.4. Connector/Python Coding Examples

These coding examples illustrate how to develop Python applications and scripts which connect to a MySQL Server using MySQL Connector/Python.

22.6.4.1. Connecting to MySQL Using Connector/Python

The connect() constructor is used for creating a connection to the MySQL server and returns a MySQLConnection object.

The following example shows how to connect to the MySQL server:

import mysql.connectorcnx = mysql.connector.connect(user='scott', password='tiger',  host='127.0.0.1',  database='employees')cnx.close()

See Section 22.6.6, "Connector/Python Connection Arguments" for all possible connection arguments.

It is also possible to create connection objects using the connection.MySQLConnection() class. Both methods, using the connect() constructor, or the class directly, are valid and functionally equal, but using connector() is preferred and will be used in most examples in this manual.

To handle connection errors, use the try statement and catch all errors using the errors.Error exception:

import mysql.connectorfrom mysql.connector import errorcodetry:  cnx = mysql.connector.connect(user='scott', database='testt')except mysql.connector.Error as err:  if err.errno == errorcode.ER_ACCESS_DENIED_ERROR: print("Something is wrong your username or password")  elif err.errno == errorcode.ER_BAD_DB_ERROR: print("Database does not exists")  else: print(err)else:  cnx.close()

If you have lots of connection arguments, it's best to keep them in a dictionary and use the **-operator. Here is an example:

import mysql.connectorconfig = {  'user': 'scott',  'password': 'tiger',  'host': '127.0.0.1',  'database': 'employees',  'raise_on_warnings': True,}cnx = mysql.connector.connect(**config)cnx.close()

22.6.4.2. Creating Tables Using Connector/Python

All DDL (Data Definition Language) statements are executed using a handle structure known as a cursor. The following examples show how to create the tables of the employees database. You will need them for the other examples.

In a MySQL server, tables are very long-lived objects, and are often accessed by multiple applications written in different languages. You might typically work with tables that are already set up, rather than creating them within your own application. Avoid setting up and dropping tables over and over again, as that is an expensive operation. The exception is temporary tables, which can be created and dropped quickly within an application.

from __future__ import print_functionimport mysql.connectorfrom mysql.connector import errorcodeDB_NAME = 'employees'TABLES = {}TABLES['employees'] = ( "CREATE TABLE `employees` (" "  `emp_no` int(11) NOT NULL AUTO_INCREMENT," "  `birth_date` date NOT NULL," "  `first_name` varchar(14) NOT NULL," "  `last_name` varchar(16) NOT NULL," "  `gender` enum('M','F') NOT NULL," "  `hire_date` date NOT NULL," "  PRIMARY KEY (`emp_no`)" ") ENGINE=InnoDB")TABLES['departments'] = ( "CREATE TABLE `departments` (" "  `dept_no` char(4) NOT NULL," "  `dept_name` varchar(40) NOT NULL," "  PRIMARY KEY (`dept_no`), UNIQUE KEY `dept_name` (`dept_name`)" ") ENGINE=InnoDB")TABLES['salaries'] = ( "CREATE TABLE `salaries` (" "  `emp_no` int(11) NOT NULL," "  `salary` int(11) NOT NULL," "  `from_date` date NOT NULL," "  `to_date` date NOT NULL," "  PRIMARY KEY (`emp_no`,`from_date`), KEY `emp_no` (`emp_no`)," "  CONSTRAINT `salaries_ibfk_1` FOREIGN KEY (`emp_no`) " " REFERENCES `employees` (`emp_no`) ON DELETE CASCADE" ") ENGINE=InnoDB")TABLES['dept_emp'] = ( "CREATE TABLE `dept_emp` (" "  `emp_no` int(11) NOT NULL," "  `dept_no` char(4) NOT NULL," "  `from_date` date NOT NULL," "  `to_date` date NOT NULL," "  PRIMARY KEY (`emp_no`,`dept_no`), KEY `emp_no` (`emp_no`)," "  KEY `dept_no` (`dept_no`)," "  CONSTRAINT `dept_emp_ibfk_1` FOREIGN KEY (`emp_no`) " " REFERENCES `employees` (`emp_no`) ON DELETE CASCADE," "  CONSTRAINT `dept_emp_ibfk_2` FOREIGN KEY (`dept_no`) " " REFERENCES `departments` (`dept_no`) ON DELETE CASCADE" ") ENGINE=InnoDB")TABLES['dept_manager'] = ( "  CREATE TABLE `dept_manager` (" "  `dept_no` char(4) NOT NULL," "  `emp_no` int(11) NOT NULL," "  `from_date` date NOT NULL," "  `to_date` date NOT NULL," "  PRIMARY KEY (`emp_no`,`dept_no`)," "  KEY `emp_no` (`emp_no`)," "  KEY `dept_no` (`dept_no`)," "  CONSTRAINT `dept_manager_ibfk_1` FOREIGN KEY (`emp_no`) " " REFERENCES `employees` (`emp_no`) ON DELETE CASCADE," "  CONSTRAINT `dept_manager_ibfk_2` FOREIGN KEY (`dept_no`) " " REFERENCES `departments` (`dept_no`) ON DELETE CASCADE" ") ENGINE=InnoDB")TABLES['titles'] = ( "CREATE TABLE `titles` (" "  `emp_no` int(11) NOT NULL," "  `title` varchar(50) NOT NULL," "  `from_date` date NOT NULL," "  `to_date` date DEFAULT NULL," "  PRIMARY KEY (`emp_no`,`title`,`from_date`), KEY `emp_no` (`emp_no`)," "  CONSTRAINT `titles_ibfk_1` FOREIGN KEY (`emp_no`)" " REFERENCES `employees` (`emp_no`) ON DELETE CASCADE" ") ENGINE=InnoDB")

The above code shows how we are storing the CREATE statements in a Python dictionary called TABLES. We also define the database in a global variable called DB_NAME, which allows you to easily use a different schema.

cnx = mysql.connector.connect(user='scott')cursor = cnx.cursor()

A single MySQL server can contain multiple databases. Typically, you specify the database to switch to when connecting to the MySQL server. This example does not connect to the database upon connection, so that it can make sure the database exists, and create it if not.

def create_database(cursor): try: cursor.execute( "CREATE DATABASE {} DEFAULT CHARACTER SET 'utf8'".format(DB_NAME)) except mysql.connector.Error as err: print("Failed creating database: {}".format(err)) exit(1)try: cnx.database = DB_NAME except mysql.connector.Error as err: if err.errno == errorcode.ER_BAD_DB_ERROR: create_database(cursor) cnx.database = DB_NAME else: print(err) exit(1)

We first try to change to a particular database using the database property of the connection object cnx. If there is an error, we examine the error number to check if the database does not exist. If so, we call the create_database function to create it for us.

On any other error, the application exits and displays the error message.

for name, ddl in TABLES.iteritems(): try: print("Creating table {}: ".format(name), end='') cursor.execute(ddl) except mysql.connector.Error as err: if err.errno == errorcode.ER_TABLE_EXISTS_ERROR: print("already exists.") else: print(err.errmsg) else: print("OK")cursor.close()cnx.close()

After we succesfully created or changed to the target database, we create the tables by iterating over the items of the TABLES dictionary.

We handle the error when the table already exists by simply notifying the user that it was already there. Other errors are printed, but we simply continue creating tables. (We show how to handle the "table already exists" condition for illustration purposes. In a real application, we would typically avoid the error condition entirely by using the IF NOT EXISTS clause of the CREATE TABLE statement.)

The output would be something like this:

Creating table employees: already exists.Creating table salaries: already exists.Creating table titles: OKCreating table departments: already exists.Creating table dept_manager: already exists.Creating table dept_emp: already exists.

To populate the employees tables, use the dump files of the Employee Sample Database. Note that you only need the data dump files that you will find in an archive named like employees_db-dump-files-1.0.5.tar.bz2. After downloading the dump files, do the following from the command line, adding connection options to the mysql commands if necessary:

shell> tar xzf employees_db-dump-files-1.0.5.tar.bz2shell> cd employees_dbshell> mysql employees < load_employees.dumpshell> mysql employees < load_titles.dumpshell> mysql employees < load_departments.dumpshell> mysql employees < load_salaries.dumpshell> mysql employees < load_dept_emp.dumpshell> mysql employees < load_dept_manager.dump

22.6.4.3. Inserting Data Using Connector/Python

Inserting or updating data is also done using the handler structure known as a cursor. When you use a transactional storage engine such as InnoDB (which is the default in MySQL 5.5 and later), you must commit the data after a sequence of INSERT, DELETE, and UPDATE statements.

In this example we show how to insert new data. The second INSERT depends on the value of the newly created primary key of the first. We are also demonstrating how to use extended formats. The task is to add a new employee starting to work tomorrow with a salary set to 50000.

Note

The following example uses tables created in the example Section 22.6.4.2, "Creating Tables Using Connector/Python". The AUTO_INCREMENT column option for the primary key of the employees table is important to ensure reliable, easily searchable data.

from __future__ import print_functionfrom datetime import date, datetime, timedeltaimport mysql.connectorcnx = mysql.connector.connect(user='scott', database='employees')cursor = cnx.cursor()tomorrow = datetime.now().date() + timedelta(days=1)add_employee = ("INSERT INTO employees "   "(first_name, last_name, hire_date, gender, birth_date) "   "VALUES (%s, %s, %s, %s, %s)")add_salary = ("INSERT INTO salaries "  "(emp_no, salary, from_date, to_date) "  "VALUES (%(emp_no)s, %(salary)s, %(from_date)s, %(to_date)s)")data_employee = ('Geert', 'Vanderkelen', tomorrow, 'M', date(1977, 6, 14))# Insert new employeecursor.execute(add_employee, data_employee)emp_no = cursor.lastrowid# Insert salary informationdata_salary = {  'emp_no': emp_no,  'salary': 50000,  'from_date': tomorrow,  'to_date': date(9999, 1, 1),}cursor.execute(add_salary, data_salary)# Make sure data is committed to the databasecnx.commit()cursor.close()cnx.close()

We first open a connection to the MySQL server and store the connection object in the variable cnx. We then create a new cursor, by default a MySQLCursor object, using the connection's cursor() method.

We could calculate tomorrow by calling a database function, but for clarity we do it in Python using the datetime module.

Both INSERT statements are stored in the variables called add_employee and add_salary. Note that the second INSERT statement uses extended Python format codes.

The information of the new employee is stored in the tuple data_employee. The query to insert the new employee is executed and we retrieve the newly inserted value for the column emp_no using the lastrowid property of the cursor object.

Next, we insert the new salary for the new employee. We are using the emp_no variable in the directory holding the data. This directory is passed to the execute() method of the cursor object.

Since by default Connector/Python turns autocommit off, and MySQL 5.5 and later uses transactional InnoDB tables by default, it is necessary to commit your changes using the connection's commit() method. You could also roll back using the rollback() method.

22.6.4.4. Querying Data Using Connector/Python

The following example shows how to query data using a cursor created using the connection's cursor() method. The data returned is formatted and printed on the console.

The task is to select all employees hired in the year 1999 and print their names with their hire date to the console.

import datetimeimport mysql.connectorcnx = mysql.connector.connect(user='scott', database='employees')cursor = cnx.cursor()query = ("SELECT first_name, last_name, hire_date FROM employees " "WHERE hire_date BETWEEN %s AND %s")hire_start = datetime.date(1999, 1, 1)hire_end = datetime.date(1999, 12, 31)cursor.execute(query, (hire_start, hire_end))for (first_name, last_name, hire_date) in cursor:  print("{}, {} was hired on {:%d %b %Y}".format( last_name, first_name, hire_date))cursor.close()cnx.close()

We first open a connection to the MySQL server and store the connection object in the variable cnx. We then create a new cursor, by default a MySQLCursor object, using the connection's cursor() method.

In the preceding example, we store the SELECT statement in the variable query. Note that we are using unquoted %s-markers where dates should have been. Connector/Python converts hire_start and hire_end from Python types to a data type that MySQL understands and adds the required quotes. In this case, it replaces the first %s with '1999-01-01', and the second with '1999-12-31'.

We then execute the operation stored in the query variable using the execute() method. The data used to replace the %s-markers in the query is passed as a tuple: (hire_start, hire_end).

After executing the query, the MySQL server is ready to send the data. The result set could be zero rows, one row, or 100 million rows. Depending on the expected volume, you can use different techniques to process this result set. In this example, we use the cursor object as an iterator. The first column in the row will be stored in the variable first_name, the second in last_name, and the third in hire_date.

We print the result, formatting the output using Python's built-in format() function. Note that hire_date was converted automatically by Connector/Python to a Python datetime.date object. This means that we can easily format the date in a more human-readable form.

The output should be something like this:

..Wilharm, LiMin was hired on 16 Dec 1999Wielonsky, Lalit was hired on 16 Dec 1999Kamble, Dannz was hired on 18 Dec 1999DuBourdieux, Zhongwei was hired on 19 Dec 1999Fujisawa, Rosita was hired on 20 Dec 1999..

22.6.5. Connector/Python Tutorials

These tutorials illustrate how to develop Python applications and scripts that connect to a MySQL database server using MySQL Connector/Python.

22.6.5.1. Tutorial: Raise employee's salary using a buffering cursor

The following example script will give a long-overdue raise effective tomorrow to all employees who joined in the year 2000 and are still with the company.

We are using buffered cursors to iterate through the selected employees. This way we do not have to fetch the rows in a new variables, but can instead use the cursor as an iterator.

Note that the script is an example; there are other ways of doing this simple task.

from __future__ import print_functionfrom decimal import Decimalfrom datetime import datetime, date, timedeltaimport mysql.connector# Connect with the MySQL Servercnx = mysql.connector.connect(user='scott', database='employees')# Get two buffered cursorscurA = cnx.cursor(buffered=True)curB = cnx.cursor(buffered=True)# Query to get employees who joined in a period defined by two datesquery = (  "SELECT s.emp_no, salary, from_date, to_date FROM employees AS e "  "LEFT JOIN salaries AS s USING (emp_no) "  "WHERE to_date = DATE('9999-01-01')"  "AND e.hire_date BETWEEN DATE(%s) AND DATE(%s)")# UPDATE and INSERT statements for the old and new salaryupdate_old_salary = (  "UPDATE salaries SET to_date = %s "  "WHERE emp_no = %s AND from_date = %s")insert_new_salary = (  "INSERT INTO salaries (emp_no, from_date, to_date, salary) "  "VALUES (%s, %s, %s, %s)")# Select the employes getting a raisecurA.execute(query, (date(2000, 1, 1), date(2001, 1, 1)))# Iterate through the result of curAfor (emp_no, salary, from_date, to_date) in curA:  # Update the old and insert the new salary  new_salary = int(round(salary * Decimal('1.15')))  curB.execute(update_old_salary, (tomorrow, emp_no, from_date))  curB.execute(insert_new_salary,   (emp_no, tomorrow, date(9999, 1, 1,), new_salary))  # Commit the changes  cnx.commit()cnx.close()

22.6.6. Connector/Python Connection Arguments

The following lists the arguments which can be used to initiate a connection with the MySQL server using either:

  • Function mysql.connector.connect()

  • Class mysql.connector.MySQLConnection()

Table 22.30. Connection Arguments for Connector/Python

Argument NameDefaultDescription
user (username*) The username used to authenticate with the MySQL Server.
password (passwd*) The password to authenticate the user with the MySQL Server.
database (db*) Database name to use when connecting with the MySQL Server.
host127.0.0.1Hostname or IP address of the MySQL Server.
port3306TCP/IP port of the MySQL Server. Must be an integer.
unix_socket The location of the Unix socket file.
use_unicodeTrueWhether to use Unicode or not.
charsetutf8Which MySQL character set to use.
collationutf8_general_ciWhich MySQL collation to use.
autocommitFalseWhether to autocommit transactions.
time_zone Set the time_zone session variable at connection.
sql_mode Set the sql_mode session variable at connection.
get_warningsFalseWhether to fetch warnings.
raise_on_warningsFalseWhether to raise an exception on warnings.
connection_timeout (connect_timeout*) Timeout for the TCP and Unix socket connections.
client_flags MySQL client flags.
bufferedFalseWhether cursor object fetches the result immediately after executing query.
rawFalseWhether MySQL results are returned as-is, rather than converted toPython types.
ssl_ca File containing the SSL certificate authority.
ssl_cert File containing the SSL certificate file.
ssl_key File containing the SSL key.
dsn Not supported (raises NotSupportedError when used).

* Synonymous argument name, available only for compatibility with other Python MySQL drivers. Oracle recommends not to use these alternative names.

Authentication with MySQL will use username and password. Note that MySQL Connector/Python does not support the old, insecure password protocols of MySQL versions prior to 4.1.

When the database parameter is given, the current database is set to the given value. To later change the database, execute the MySQL USE command or set the database property of the MySQLConnection instance.

By default, Connector/Python tries to connect to a MySQL server running on localhost using TCP/IP. The host argument defaults to IP address 127.0.0.1 and port to 3306. Unix sockets are supported by setting unix_socket. Named pipes on the Windows platform are not supported.

Strings coming from MySQL are by default returned as Python Unicode literals. To change this behavior, set use_unicode to False. You can change the character setting for the client connection through the charset argument. To change the character set after connecting to MySQL, set the charset property of the MySQLConnection instance. This technique is preferred over using the MySQL SET NAMES statement directly. Similar to the charset property, you can set the collation for the current MySQL session.

Transactions are not automatically committed; call the commit() method of the MySQLConnection instance within your application after doing a set of related insert, update, and delete operations. For data consistency and high throughput for write operations, it is best to leave the autocommit configuration option turned off when using InnoDB or other transactional tables.

The time zone can be set per connection using the time_zone argument. This is useful if the MySQL server is set, for example, to UTC and TIMESTAMP values should be returned by MySQL converted to the PST time zone.

MySQL supports so called SQL Modes. which will change the behavior of the server globally or per connection. For example, to have warnings raised as errors, set sql_mode to TRADITIONAL. For more information, see Section 5.1.7, "Server SQL Modes".

Warnings generated by queries are fetched automatically when get_warnings is set to True. You can also immediately raise an exception by setting raise_on_warnings to True. Consider using the MySQL sql_mode setting for turning warnings into errors.

To set a timeout value for connections, use connection_timeout.

MySQL uses client flags to enable or disable features. Using the client_flags argument, you have control of what is set. To find out what flags are available, use the following:

from mysql.connector.constants import ClientFlagprint '\n'.join(ClientFlag.get_full_info())

If client_flags is not specified (that is, it is zero), defaults are used for MySQL v4.1 and later. If you specify an integer greater than 0, make sure all flags are set. A better way to set and unset flags is to use a list. For example, to set FOUND_ROWS, but disable the default LONG_FLAG:

flags = [ClientFlag.FOUND_ROWS, -ClientFlag.LONG_FLAG]mysql.connector.connect(client_flags=flags)

By default, MySQL Connector/Python does not buffer or pre-fetch results. This means that after a query is executed, your program is responsible of fetching the data. This avoids using excessive memory when queries return large result sets. If you know that the result set is small enough to handle all at once, fetching the results immediately by setting buffered to True. It is also possible to set this per cursor (see cursor manual).

MySQL types will be converted automatically to Python types. For example, a DATETIME column becomes a datetime.datetime object. When conversion should be done differently, for example to get better performance, set raw to True.

Using SSL connections is possible when your Python installation supports SSL, that is, when it is compiled against the OpenSSL libraries. When you provide the arguments ssl_ca, ssl_key and ssl_cert, the connection switches to SSL. You can use this in combination with the compressed argument set to True.

passwd, db and connect_timeout are valid for compatibility with other MySQL interfaces and are respectively the same as password, database and connection_timeout. The latter take precedence. Data source name syntax or dsn is not used; if specified, it raises a NotSupportedError exception.

22.6.7. Connector/Python API Reference

This section contains the public API reference of Connector/Python. Although valid for both Python 2 and Python 3, examples should be considered working for Python 2.7, and Python 3.1 and greater.

The following overview shows the mysql.connector package with its modules. Currently, only the most useful modules, classes and functions for end users are documented.

mysql.connector  errorcode  errors  connection  constants  conversion  cursor  dbapi  locales eng  client_error  protocol  utils

22.6.7.1. Errors and Exceptions

The mysql.connector.errors module defines exception classes for errors and warnings raised by MySQL Connector/Python. Most classes defined in this module are available when you import mysql.connector.

The exception classes defined in this module follow mostly the Python Database Specification v2.0 (PEP-249). For some MySQL client or server errors it is not always clear which exception to raise. It is good to discuss whether an error should be reclassified by opening a bug report.

MySQL Server errors are mapped with Python exception based on their SQLState (see Section C.3, "Server Error Codes and Messages"). The following list shows the SQLState classes and the exception Connector/Python will raise. It is, however, possible to redefine which exception is raised for each server error. Note that the default exception is DatabaseError.

  • 02: DataError

  • 07: DatabaseError

  • 08: OperationalError

  • 0A: NotSupportedError

  • 21: DataError

  • 22: DataError

  • 23: IntegrityError

  • 24: ProgrammingError

  • 25: ProgrammingError

  • 26: ProgrammingError

  • 27: ProgrammingError

  • 28: ProgrammingError

  • 2A: ProgrammingError

  • 2B: DatabaseError

  • 2C: ProgrammingError

  • 2D: DatabaseError

  • 2E: DatabaseError

  • 33: DatabaseError

  • 34: ProgrammingError

  • 35: ProgrammingError

  • 37: ProgrammingError

  • 3C: ProgrammingError

  • 3D: ProgrammingError

  • 3F: ProgrammingError

  • 40: InternalError

  • 42: ProgrammingError

  • 44: InternalError

  • HZ: OperationalError

  • XA: IntegrityError

  • 0K: OperationalError

  • HY: DatabaseError

22.6.7.1.1. Module errorcode

This module contains both MySQL server and client error codes defined as module attributes with the error number as value. Using error codes instead of error numbers could make reading the source code a bit easier.

>>> from mysql.connector import errorcode>>> errorcode.ER_BAD_TABLE_ERROR1051

See Section C.3, "Server Error Codes and Messages" and Section C.4, "Client Error Codes and Messages".

22.6.7.1.2. Exception errors.Error

This exception is the base class for all other exceptions in the errors module. It can be used to catch all errors in a single except statement.

The following example shows how we could catch syntax errors:

import mysql.connectortry:  cnx = mysql.connector.connect(user='scott', database='employees')  cursor = cnx.cursor()  cursor.execute("SELECT * FORM employees")   # Syntax error in query  cnx.close()except mysql.connector.Error as err:  print("Something went wrong: {}".format(err))

Initializing the exception supports a few optional arguments, namely msg, errno, values and sqlstate. All of them are optional and default to None. errors.Error isinternally used by Connector/Python to raise MySQL client and server errors and should not be used by your application to raise exceptions.

The following examples show the result when using no or a combination of the arguments:

>>> from mysql.connector.errors import Error>>> str(Error())'Unknown error'>>> str(Error("Oops! There was an error."))'Oops! There was an error.'>>> str(Error(errno=2006))'2006: MySQL server has gone away'>>> str(Error(errno=2002, values=('/tmp/mysql.sock', 2)))"2002: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)">>> str(Error(errno=1146, sqlstate='42S02', msg="Table 'test.spam' doesn't exist"))"1146 (42S02): Table 'test.spam' doesn't exist"

The example which uses error number 1146 is used when Connector/Python receives an error packet from the MySQL Server. The information is parsed and passed to the Error exception as shown.

Each exception subclassing from Error can be initialized using the above mentioned arguments. Additionally, each instance has the attributes errno, msg and sqlstate which can be used in your code.

The following example shows how to handle errors when dropping a table which does not exists (when you do not want to use the IF EXISTS clause):

import mysql.connectorfrom mysql.connector import errorcodecnx = mysql.connector.connect(user='scott', database='test')try:  cur.execute("DROP TABLE spam")except mysql.connector.Error as err:  if err.errno == errorcode.ER_BAD_TABLE_ERROR: print("Creating table spam")  else: raise

errors.Error is a subclass of the Python StandardError.

22.6.7.1.3. Exception errors.Warning

This exception is used for reporting important warnings, however, Connector/Python does not use it. It is included to be compliant with the Python Database Specification v2.0 (PEP-249).

Consider using either more strict Server SQL Modes or the raise_on_warnings connection argument to make Connector/Python raise errors when your queries produce warnings.

errors.Warning is a subclass of the Python StandardError.

22.6.7.1.4. Exception errors.InterfaceError

This exception is raised for errors originating from Connector/Python itself, not related to the MySQL server.

errors.InterfaceError is a subclass of errors.Error.

22.6.7.1.5. Exception errors.DatabaseError

This exception is the default for any MySQL error which does not fit the other exceptions.

errors.DatabaseError is a subclass of errors.Error.

22.6.7.1.6. Exception errors.InternalError

This exception is raised when the MySQL server encounters an internal error, for example, when a deadlock occurred.

errors.InternalError is a subclass of errors.DatabaseError.

22.6.7.1.7. Exception errors.OperationalError

This exception is raised for errors which are related to MySQL's operations. For example, to many connections, a hostname could not be resolved, bad handshake, server is shutting down, communication errors, and so on.

errors.OperationalError is a subclass of errors.DatabaseError.

22.6.7.1.8. Exception errors.ProgrammingError

This exception is raised on programming errors, for example when you have a syntax error in your SQL or a table was not found.

The following example shows how to handle syntax errors:

try:  cursor.execute("CREATE DESK t1 (id int, PRIMARY KEY (id))")except mysql.connector.ProgrammingError as err:  if err.errno == errorcode.ER_SYNTAX_ERROR: print("Check your syntax!")  else: print("Error: {}".format(err))

errors.ProgrammingError is a subclass of errors.DatabaseError.

22.6.7.1.9. Exception errors.IntegrityError

This exception is raised when the relational integrity of the data is affected. For example, a duplicate key was inserted or a foreign key constraint would fail.

The following example shows a duplicate key error raised as IntegrityError:

cursor.execute("CREATE TABLE t1 (id int, PRIMARY KEY (id))")try:  cursor.execute("INSERT INTO t1 (id) VALUES (1)")  cursor.execute("INSERT INTO t1 (id) VALUES (1)")except mysql.connector.IntegrityError as err:  print("Error: {}".format(err))

errors.IntegrityError is a subclass of errors.DatabaseError.

22.6.7.1.10. Exception errors.DataError

This exception is raised when there were problems with the data. Examples are a column set to NULL when it can not, out of range values for a column, division by zero, column count does not match value count, and so on.

errors.DataError is a subclass of errors.DatabaseError.

22.6.7.1.11. Exception errors.NotSupportedError

This exception is raised is case some feature was used but not supported by the version of MySQL which returned the error. It is also raised when using functions or statements which are not supported by stored routines.

errors.NotSupportedError is a subclass of errors.DatabaseError.

22.6.7.1.12. Function errors.custom_error_exception(error=None,exception=None)

This function defines custom exceptions for MySQL server errors and returns current customizations.

If error is a MySQL Server error number, then you have to pass also the exception class. The error argument can also be a dictionary in which case the key is the server error number, and value the class of the exception to be raised.

To reset the customizations, simply supply an empty dictionary.

import mysql.connectorfrom mysql.connector import errorcode# Server error 1028 should raise a DatabaseErrormysql.connector.custom_error_exception(1028, mysql.connector.DatabaseError)# Or using a dictionary:mysql.connector.custom_error_exception({  1028: mysql.connector.DatabaseError,  1029: mysql.connector.OperationalError,})# To reset, pass an empty dictionary:mysql.connector.custom_error_exception({})

22.6.7.2. Class connection.MySQLConnection

The MySQLConnection class is used to open and manage a connection to a MySQL server. It also used to send commands and SQL queries and read result.

22.6.7.2.1. Constructor connection.MySQLConnection(**kwargs)

The MySQLConnection constructor initializes the attributes and when at least one argument is passed, it tries to connect with the MySQL server.

For a complete list or arguments, see Section 22.6.6, "Connector/Python Connection Arguments".

22.6.7.2.2. Method MySQLConnection.close()

See disconnect().

Returns a tuple.

22.6.7.2.3. Method MySQLConnection.config(**kwargs)

Allows to configure a MySQLConnection instance after it was instantiated. See Section 22.6.6, "Connector/Python Connection Arguments" for a complete list of possible arguments.

You could use the config() method to change, for example, the username and call reconnect().

cnx = MySQLConnection(user='joe', database='test')# Connected as 'joe'cnx.config(user='jane')cnx.reconnect()# Now connected as 'jane'
22.6.7.2.4. Method MySQLConnection.connect(**kwargs)

This method sets up the connection to the MySQL server. If no arguments are given, it uses the already configured or default values. See Section 22.6.6, "Connector/Python Connection Arguments" for a complete list of possible arguments.

22.6.7.2.5. Method MySQLConnection.commit()

This method sends the COMMIT command to the MySQL server, committing the current transaction. Since by default, Connector/Python does not auto commit, it is important to call this method after every transaction which updates data for tables using transactional storage engines.

See the rollback() method for rolling back transactions.

>>> cursor.execute("INSERT INTO employees (first_name) VALUES (%s)", ('Jane'))>>> cnx.commit()
22.6.7.2.6. Method MySQLConnection.cursor(buffered=None, raw=None,cursor_class=None)

This method returns a MySQLCursor() object, or a subclass of it depending the passed arguments.

When buffered is True, the cursor will fetch all rows after the operation is executed. This is useful when queries return small result sets. Setting raw will skip the conversion from MySQL data types to Python types when fetching rows. Raw is usually used when you want to have more performance and/or you want to do the conversion yourself.

The cursor_class argument can be used to pass a class to use for instantiating a new cursor. It has to be a subclass of cursor.CursorBase.

The returned object depends on the combination of the buffered and raw arguments.

  • If not buffered and not raw: cursor.MySQLCursor

  • If buffered and not raw: cursor.MySQLCursorBuffered

  • If buffered and raw: cursor.MySQLCursorBufferedRaw

  • If not buffered and raw: cursor.MySQLCursorRaw

Returns a CursorBase instance.

22.6.7.2.7. Method MySQLConnection.cmd_change_user(username='',password='', database='', charset=33)

Changes the user using username and password. It also causes the specified database to become the default (current) database. It is also possible to change the character set using the charset argument.

Returns a dictionary containing the OK packet information.

22.6.7.2.8. Method MySQLConnection.cmd_debug()

Instructs the server to write some debug information to the log. For this to work, the connected user must have the SUPER privilege.

Returns a dictionary containing the OK packet information.

22.6.7.2.9. Method MySQLConnection.cmd_init_db(database)

This method makes specified database the default (current) database. In subsequent queries, this database is the default for table references that do not include an explicit database specifier.

Returns a dictionary containing the OK packet information.

22.6.7.2.10. Method MySQLConnection.cmd_ping()

Checks whether the connection to the server is working.

This method is not to be used directly. Use ping() or is_connected() instead.

Returns a dictionary containing the OK packet information.

22.6.7.2.11. Method MySQLConnection.cmd_process_info()

This method raises the NotSupportedError exception. Instead, use the SHOW PROCESSLIST statement or query the tables found in the database INFORMATION_SCHEMA.

22.6.7.2.12. Method MySQLConnection.cmd_process_kill(mysql_pid)

Asks the server to kill the thread specified by mysql_pid. Although still available, it's better to use the SQL KILL command.

Returns a dictionary containing the OK packet information.

The following two lines do the same:

>>> cnx.cmd_process_kill(123)>>> cnx.cmd_query('KILL 123')
22.6.7.2.13. Method MySQLConnection.cmd_quit()

This method sends the QUIT command to the MySQL server, closing the current connection. Since there is no response from the MySQL, the packet that was sent is returned.

22.6.7.2.14. Method MySQLConnection.cmd_query(statement)

This method sends the given statement to the MySQL server and returns a result. If you need to send multiple statements, you have to use the cmd_query_iter() method.

The returned dictionary contains information depending on what kind of query was executed. If the query is a SELECT statement, the result contains information about columns. Other statements return a dictionary containing OK or EOF packet information.

Errors received from the MySQL server are raised as exceptions. An InterfaceError is raised when multiple results are found.

Returns a dictionary.

22.6.7.2.15. Method MySQLConnection.cmd_query_iter(statement)

Similar to the cmd_query() method, but returns a generator object to iterate through results. Use cmd_query_iter() when sending multiple statements, and separate the statements with semicolons.

The following example shows how to iterate through the results after sending multiple statements:

statement = 'SELECT 1; INSERT INTO t1 VALUES (); SELECT 2'for result in cnx.cmd_query(statement, iterate=True):  if 'columns' in result: columns = result['columns'] rows = cnx.get_rows()  else: # do something useful with INSERT result

Returns a generator object.

22.6.7.2.16. Method MySQLConnection.cmd_refresh(options)

This method flushes tables or caches, or resets replication server information. The connected user must have the RELOAD privilege.

The options argument should be a bitwise value using constants from the class constants.RefreshOption.

See Section 22.6.7.9, "Class constants.RefreshOption" for a list of options.

Example:

>>> from mysql.connector import RefreshOption>>> refresh = RefreshOption.LOG | RefreshOption.THREADS>>> cnx.cmd_refresh(refresh)
22.6.7.2.17. Method MySQLConnection.cmd_shutdown()

Asks the database server to shut down. The connected user must have the SHUTDOWN privilege.

Returns a dictionary containing the OK packet information.

22.6.7.2.18. Method MySQLConnection.cmd_statistics()

Returns a dictionary containing information about the MySQL server including uptime in seconds and the number of running threads, questions, reloads, and open tables.

22.6.7.2.19. Method MySQLConnection.disconnect()

This method tries to send the QUIT command and close the socket. It does not raise any exceptions.

MySQLConnection.close() is a synonymous method name and more commonly used.

22.6.7.2.20. Method MySQLConnection.get_rows(count=None)

This method retrieves all or remaining rows of a query result set, returning a tuple containing the rows as sequence and the EOF packet information. The count argument can be used to get a given amount of rows. If count is not specified or is None, all rows are retrieved.

The tuple returned by get_rows() consists of:

  • A list of tuples containing the row data as byte objects, or an empty list when no rows are available.

  • EOF packet information as a dictionary containing status_flag and warning_count.

An InterfaceError is raised when all rows have been retrieved.

The get_rows() method is used by MySQLCursor to fetch rows.

Returns a tuple.

22.6.7.2.21. Method MySQLConnection.get_row()

This method retrieves the next row of a query result set, returning a tuple.

The tuple returned by get_row() consists of:

  • The row as a tuple containing byte objects, or None when no more rows are available.

  • EOF packet information as a dictionary containing status_flag and warning_count, or None when the row returned is not the last row.

The get_row() method is used by MySQLCursor to fetch rows.

22.6.7.2.22. Method MySQLConnection.get_server_info()

This method returns the MySQL server information verbatim, for example '5.5.24-log', or None when not connected.

Returns a string or None.

22.6.7.2.23. Method MySQLConnection.get_server_version()

This method returns the MySQL server version as a tuple, or None when not connected.

Returns a tuple or None.

22.6.7.2.24. Method MySQLConnection.is_connected()

Reports whether the connection to MySQL Server is available.

This method checks whether the connection to MySQL is available using the ping() method, but unlike ping(), is_connected() returns True when the connection is available, False otherwise.

Returns True or False.

22.6.7.2.25. Method MySQLConnection.isset_client_flag(flag)

This method returns True if the client flag was set, False otherwise.

Returns True or False.

22.6.7.2.26. Method MySQLConnection.ping(attempts=1, delay=0)

Check whether the connection to the MySQL server is still available.

When reconnect is set to True, one or more attempts are made to try to reconnect to the MySQL server using the reconnect() method. Use the delay argument (seconds) if you want to wait between each retry.

When the connection is not available, an InterfaceError is raised. Use the is_connected() method to check the connection without raising an error.

Raises InterfaceError on errors.

22.6.7.2.27. Method MySQLConnection.reconnect(attempts=1, delay=0)

Attempt to reconnect with the MySQL server.

The argument attempts specifies the number of times a reconnect is tried. The delay argument is the number of seconds to wait between each retry.

You might set the number of attempts higher and use a longer delay when you expect the MySQL server to be down for maintenance, or when you expect the network to be temporarily unavailable.

22.6.7.2.28. Method MySQLConnection.rollback()

This method sends the ROLLBACK command to the MySQL server, undoing all data changes from the current transaction. Since by default, Connector/Python does not auto commit, it is possible to cancel transactions when using transactional storage engines such as InnoDB.

See the commit() method for committing transactions.

>>> cursor.execute("INSERT INTO employees (first_name) VALUES (%s)", ('Jane'))>>> cnx.rollback()
22.6.7.2.29. Method MySQLConnection.set_charset_collation(charset=None,collation=None)

This method sets the character set and collation to be used for the current connection. The charset argument can be either the name of a character set, or the numerical equivalent as defined in constants.CharacterSet.

When collation is None, the default will be looked up and used.

The charset argument then be either:

In the following example, we set the character set to latin1 and the collation will be set to the default latin1_swedish_ci:

>>> cnx = mysql.connector.connect(user='scott')>>> cnx.set_charset('latin1')

Specify a specific collation as follows:

>>> cnx = mysql.connector.connect(user='scott')>>> cnx.set_charset('latin1', 'latin1_general_ci')
22.6.7.2.30. Method MySQLConnection.set_client_flags(flags)

This method sets the client flags which are used when connecting with the MySQL server and returns the new value. The flags argument can be either an integer or a sequence of valid client flag values (see Section 22.6.7.5, "Class constants.ClientFlag").

If flags is a sequence, each item in the sequence will set the flag when the value is positive or unset it when negative. For example, to unset LONG_FLAG and set the FOUND_ROWS flags:

>>> from mysql.connector.constants import ClientFlag>>> cnx.set_client_flags([ClientFlag.FOUND_ROWS, -ClientFlag.LONG_FLAG])>>> cnx.reconnect()

Note that client flags are only set or used when connecting with the MySQL server. It is therefor necessary to reconnect after making changes.

Returns an integer.

22.6.7.2.31. Property MySQLConnection.autocommit

This property is used to toggle the auto commit feature of MySQL and retrieve the current state. When the value evaluates to True, auto commit will be turned, otherwise it is turned off.

Note that auto commit is disabled by default when connecting through Connector/Python. This can be toggled using the connection parameter autocommit.

When the auto commit is turned off, you have to commit transactions when using transactional storage engines such as InnoDB or NDBCluster.

>>> cnx.autocommitFalse>>> cnx.autocommit = True>>> cnx.autocommitTrue

Returns True or False.

22.6.7.2.32. Property MySQLConnection.charset_name

This property returns which character set is used for the connection whether it is connected or not.

Returns a string.

22.6.7.2.33. Property MySQLConnection.collation_name

This property returns which collation is used for the connection whether it is connected or not.

Returns a string.

22.6.7.2.34. Property MySQLConnection.connection_id

This property returns the connection ID (thread ID or session ID) for the current connection or None when not connected.

Returns a integer or None.

22.6.7.2.35. Property MySQLConnection.database

This property is used to set current (active) database executing the USE command. The property can also be used to retrieve the current database name.

>>> cnx.database = 'test'>>> cnx.database = 'mysql'>>> cnx.databaseu'mysql'

Returns a string.

22.6.7.2.36. Property MySQLConnection.get_warnings

This property is used to toggle whether warnings should be fetched automatically or not. It accepts True or False (default).

Fetching warnings automatically could be useful when debugging queries. Cursors will make warnings available through the method MySQLCursor.fetchwarnings().

>>> cnx.get_warnings = True>>> cursor.execute('SELECT "a"+1')>>> cursor.fetchall()[(1.0,)]>>> cursor.fetchwarnings()[(u'Warning', 1292, u"Truncated incorrect DOUBLE value: 'a'")]

Returns True or False.

22.6.7.2.37. Property MySQLConnection.raise_on_warnings

This property is used to toggle whether warnings should raise exceptions or not. It accepts True or False (default).

Toggling raise_on_warnings will also toggle get_warnings since warnings need to be fetched so they can be raised as exceptions.

Note that you might always want to check setting SQL Mode if you would like to have the MySQL server directly report warnings as errors. It is also good to use transactional engines so transactions can be rolled back when catching the exception.

Result sets needs to be fetched completely before any exception can be raised. The following example shows the execution of a query which produces a warning

>>> cnx.raise_on_warnings = True>>> cursor.execute('SELECT "a"+1')>>> cursor.fetchall()..mysql.connector.errors.DataError: 1292: Truncated incorrect DOUBLE value: 'a'

Returns True or False.

22.6.7.2.38. Property MySQLConnection.server_host

This read-only property returns the hostname or IP address used for connecting with the MySQL server.

Returns a string.

22.6.7.2.39. Property MySQLConnection.server_port

This read-only property returns the TCP/IP port used for connecting with the MySQL server.

Returns a integer.

22.6.7.2.40. Property MySQLConnection.sql_mode

This property is used to retrieve and set the SQL Modes for the current. The value should be list of different modes separated by comma (","), or a sequence of modes, preferably using the constants.SQLMode class.

To unset all modes, pass an empty string or an empty sequence.

>>> cnx.sql_mode = 'TRADITIONAL,NO_ENGINE_SUBSTITUTION'>>> cnx.sql_mode.split(',')[u'STRICT_TRANS_TABLES', u'STRICT_ALL_TABLES', u'NO_ZERO_IN_DATE',u'NO_ZERO_DATE', u'ERROR_FOR_DIVISION_BY_ZERO', u'TRADITIONAL', u'NO_AUTO_CREATE_USER', u'NO_ENGINE_SUBSTITUTION']>>> from mysql.connector.constants import SQLMode>>> cnx.sql_mode = [ SQLMode.NO_ZERO_DATE, SQLMode.REAL_AS_FLOAT]>>> cnx.sql_modeu'REAL_AS_FLOAT,NO_ZERO_DATE'

Returns a string.

22.6.7.2.41. Property MySQLConnection.time_zone

This property is used to set the time zone session variable for the current connection and retrieve it.

>>> cnx.time_zone = '+00:00'>>> cur.execute('SELECT NOW()') ; cur.fetchone()(datetime.datetime(2012, 6, 15, 11, 24, 36),)>>> cnx.time_zone = '-09:00'>>> cur.execute('SELECT NOW()') ; cur.fetchone()(datetime.datetime(2012, 6, 15, 2, 24, 44),)>>> cnx.time_zoneu'-09:00'

Returns a string.

22.6.7.2.42. Property MySQLConnection.unix_socket

This read-only property returns the UNIX socket user for connecting with the MySQL server.

Returns a string.

22.6.7.2.43. Property MySQLConnection.user

This read-only property returns the username used for connecting with the MySQL server.

Returns a string.

22.6.7.3. Class cursor.MySQLCursor

The MySQLCursor class is used to instantiate object which can execute operation such as SQL queries. They interact with the MySQL server using a MySQLConnection object.

22.6.7.3.1. Constructor cursor.MySQLCursor

The constructor initializes the instance with the optional connection, which should be an instance of MySQLConnection.

In most cases, the MySQLConnection method cursor() is used to instantiate a MySQLCursor object.

22.6.7.3.2. Method MySQLCursor.callproc(procname, args=())

This method calls a stored procedure with the given name. The args sequence of parameters must contain one entry for each argument that the routine expects. The result is returned as modified copy of the input sequence. Input parameters are left untouched, output and input/output parameters replaced with possibly new values.

Result set provided by the stored procedure are automatically fetched and stored as MySQLBufferedCursor instances. See stored_results() for more information.

The following example shows how to execute a stored procedure which takes two parameters, multiplies the values and returns the product:

# Definition of the multiply stored procedure:# CREATE PROCEDURE multiply(IN pFac1 INT, IN pFac2 INT, OUT pProd INT)# BEGIN#  SET pProd := pFac1 * pFac2;# END>>> args = (5, 5, 0) # 0 is to hold value of the OUT parameter pProd>>> cursor.callproc('multiply', args)('5', '5', 25L)
22.6.7.3.3. Method MySQLCursor.close()

This method will close the MySQL cursor, resetting all results and removing the connection.

Use close() every time you are done using the cursor.

22.6.7.3.4. Method MySQLCursor.execute(operation, params=None,multi=False)

This method prepare the given database operation (query or command). The parameters found in the tuple or dictionary params will be bound to the variables in the operation. Variables are specified using %s markers or named markers %(name)s.

For example, insert information about a new employee and selecting again the data of this person:

insert = ("INSERT INTO employees (emp_no, first_name, last_name, hire_date) ""VALUES (%s, %s, %s, %s)")data = (2, 'Jane', 'Doe', datetime.date(2012, 3, 23))cursor.execute(insert, data)select = "SELECT * FROM employees WHERE emp_no = %(emp_no)s"cursor.execute(select, { 'emp_no': 2 })

Note that the data is converted from Python object to something MySQL understand. In the above example, the datetime.date() instance is converted to '2012-03-23' in the above example.

When multi is set to True, execute() will be able to execute multiple statements. It will return an iterator which makes it possible to go through all results for each statement. Note that using parameters is not working well in this case, and it's usually a good idea to execute each statement on its own.

In the following example we select and insert data in one operation and display the result:

operation = 'SELECT 1; INSERT INTO t1 VALUES (); SELECT 2'for result in cursor.execute(operation):  if result.with_rows: print("Statement '{}' has following rows:".format(  result.statement)) print(result.fetchall())  else: print("Affected row(s) by query '{}' was {}".format(  result.statement, result.rowcount))

If the connection was configured to fetch warnings, warnings generated by the operation will be available through the method MySQLCursor.fetchwarnings().

Returns an iterator when multi is True.

22.6.7.3.5. Method MySQLCursor.executemany(operation, seq_params)

This method prepares a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_params.

The executemany() is simply iterating through the sequence of parameters calling the execute() method. Inserting data, however, is optimized by batching them using the multiple rows syntax.

In the following example we are inserting 3 records:

data = [  ('Jane', date(2005, 2, 12)),  ('Joe', date(2006, 5, 23)),  ('John', date(2010, 10, 3)),]stmt = "INSERT INTO employees (first_name, hire_date) VALUES (%s, %s)"cursor.executemany(stmt, data)

In the above example, the INSERT statement sent to MySQL would be as follows: INSERT INTO employees (first_name, hire_date) VALUES ('Jane', '2005-02-12'), ('Joe', '2006-05-23'), ('John', '2010-10-03').

Note that it is not possible to execute multiple statements using the executemany() method. Doing so will raise an InternalError exception.

22.6.7.3.6. Method MySQLCursor.fetchall()

The method fetches all or remaining rows of a query result set, returning a list of tuples. An empty list is returned when no rows are (anymore) available.

The following examples shows how to retrieve the first 2 rows of a result set, and then retrieve the remaining rows:

>>> cursor.execute("SELECT * FROM employees ORDER BY emp_no")>>> head_rows = cursor.fetchmany(size=2)>>> remaining_rows = cursor.fetchall()

Note that you have to fetch all rows before being able to execute new queries using the same connection.

Returns a list of tuples or empty list when no rows available.

22.6.7.3.7. Method MySQLCursor.fetchmany(size=1)

This method fetches the next set of rows of a query results, returning a list of tuples. An empty list is returned when no more rows are available.

The number of rows returned can be specified using the size argument, which defaults to one. Fewer rows might be returned, when there are not more rows available than specified by the argument.

Note that you have to fetch all rows before being able to execute new queries using the same connection.

Returns a list of tuples or empty list when no rows available.

22.6.7.3.8. Method MySQLCursor.fetchone()

This method retrieves the next row of a query result set, returning a single sequence, or None when no more data is available.The returned tuple consists of data returned by the MySQL server converted to Python objects.

The fetchone() method is used by fetchmany() and fetchall(). It is also used when using the MySQLCursor instance as an iterator.

The following examples show how to iterate through the result of a query using fetchone():

# Using a while-loopcursor.execute("SELECT * FROM employees")row = cursor.fetchone()while row is not None:  print(row)  row = cursor.fetchone()# Using the cursor as iterator cursor.execute("SELECT * FROM employees")for row in cursor:  print(row)

Note that you have to fetch all rows before being able to execute new queries using the same connection.

Returns a tuple or None.

22.6.7.3.9. Method MySQLCursor.fetchwarnings()

This method returns a list of tuples containing warnings generated by previously executed statement. Use the connection's get_warnings property to toggle whether warnings has to be fetched.

The following example shows a SELECT statement which generated a warning:

>>> cnx.get_warnings = True>>> cursor.execute('SELECT "a"+1')>>> cursor.fetchall()[(1.0,)]>>> cursor.fetchwarnings()[(u'Warning', 1292, u"Truncated incorrect DOUBLE value: 'a'")]

It is also possible to raise errors when warnings are found. See the MySQLConnection property raise_on_warnings.

Returns a list of tuples.

22.6.7.3.10. Method MySQLCursor.stored_results()

This method returns an list iterator object which can be used to go through result sets provided by stored procedures after calling them using the callproc() method.

In the following example we execute a stored procedure which will provide two result sets. We use stored_results() to retrieve them:

>>> cursor.callproc('sp1')()>>> for result in cursor.stored_results():... print result.fetchall()... [(1,)][(2,)]

Note that the result sets stay available until you executed another operation or call another stored procedure.

Returns a listiterator.

22.6.7.3.11. Property MySQLCursor.column_names

This read-only property returns the column names of a result set as sequence of (unicode) strings.

The following example shows how you can create a dictionary out of a tuple containing data with keys using column_names:

cursor.execute("SELECT last_name, first_name, hire_date "  "FROM employees WHERE emp_no = %s", (123,))row = dict(zip(cursor.column_names, cursor.fetchone())print("{last_name}, {first_name}: {hire_date}".format(row))

Returns a tuple.

22.6.7.3.12. Property MySQLCursor.statement

This read-only property returns the last executed statement. In case multiple statements where executed, it will show the actual statement.

The statement property might be useful for debugging and showing what was send to the MySQL server.

Returns a string.

22.6.7.3.13. Property MySQLCursor.with_rows

This read-only property will return True when the result of the executed operation provides rows.

The with_rows property is useful when executing multiple statements and you need to fetch rows. In the following example we only report the affected rows by the UPDATE statement:

import mysql.connectorcnx = mysql.connector.connect(user='scott', database='test')cursor = cnx.cursor()operation = 'SELECT 1; UPDATE t1 SET c1 = 2; SELECT 2'for result in cursor.execute(operation, multi=True):  if result.with_rows: result.fetchall()  else: print("Updated row(s): {}".format(result.rowcount))

22.6.7.4. Class cursor.MySQLCursorBuffered

This class is inheriting from cursor.MySQLCursor and if needed automatically retrieves rows after an operation has been executed.

MySQLCursorBuffered can be useful in situations where two queries, with small result sets, need to be combined or computed with each other.

You can either use the buffered argument when using the connection's cursor() method, or you can use the buffered connection option to make all created cursors by default buffering.

import mysql.connectorcnx = mysql.connector.connect()# Only this particular cursor will be buffering resultscursor.cursor(buffered=True)# All cursors by default bufferingcnx = mysql.connector.connect(buffered=True)

See Section 22.6.5.1, "Tutorial: Raise employee's salary using a buffering cursor" for a practical use case.

22.6.7.5. Class constants.ClientFlag

This class provides constants defining MySQL client flags which can be used upon connection to configure the session. The ClientFlag class is available when importing mysql.connector.

>>> import mysql.connector>>> mysql.connector.ClientFlag.FOUND_ROWS2

See Section 22.6.7.2.30, "Method MySQLConnection.set_client_flags(flags)" and the connection argument client_flag.

Note that the ClientFlag class can not be instantiated.

22.6.7.6. Class constants.FieldType

This class provides all supported MySQL field or data types. They can be useful when dealing with raw data or defining your own converters. The field type is stored with every cursor in the description for each column.

The following example shows how you can print the name of the data types for each of the columns in the result set.

from __future__ import print_functionimport mysql.connectorfrom mysql.connector import FieldTypecnx = mysql.connector.connect(user='scott', database='test')cursor = cnx.cursor()cursor.execute(  "SELECT DATE(NOW()) AS `c1`, TIME(NOW()) AS `c2`, "  "NOW() AS `c3`, 'a string' AS `c4`, 42 AS `c5`")rows = cursor.fetchall()for desc in cursor.description:  colname = desc[0]  coltype = desc[1]  print("Column {} has type {}".format( colname, FieldType.get_info(coltype)))cursor.close()cnx.close()

Note that the FieldType class can not be instantiated.

22.6.7.7. Class constants.SQLMode

This class provides all known MySQL Server SQL Modes. It is mostly used when setting the SQL modes at connection time using the connection's property sql_mode. See Section 22.6.7.2.40, "Property MySQLConnection.sql_mode".

Note that the SQLMode class can not be instantiated.

22.6.7.8. Class constants.CharacterSet

This class provides all known MySQL characters sets and their default collations. See Section 22.6.7.2.29, "Method MySQLConnection.set_charset_collation(charset=None, collation=None)" for examples.

Note that the CharacterSet class can not be instantiated.

22.6.7.9. Class constants.RefreshOption

  • RefreshOption.GRANT

    Refresh the grant tables, like FLUSH PRIVILEGES.

  • RefreshOption.LOG

    Flush the logs, like FLUSH LOGS.

  • RefreshOption.TABLES

    Flush the table cache, like FLUSH TABLES.

  • RefreshOption.HOSTS

    Flush the host cache, like FLUSH HOSTS.

  • RefreshOption.STATUS

    Reset status variables, like FLUSH STATUS.

  • RefreshOption.THREADS

    Flush the thread cache.

  • RefreshOption.SLAVE

    On a slave replication server, reset the master server information and restart the slave, like RESET SLAVE.

  • RefreshOption.MASTER

    On a master replication server, remove the binary log files listed in the binary log index and truncate the index file, like RESET MASTER.

22.6.8. Connector/Python FAQ

Frequently asked questions.

22.7. libmysqld, the Embedded MySQL Server Library

The embedded MySQL server library makes it possible to run a full-featured MySQL server inside a client application. The main benefits are increased speed and more simple management for embedded applications.

The embedded server library is based on the client/server version of MySQL, which is written in C/C++. Consequently, the embedded server also is written in C/C++. There is no embedded server available in other languages.

The API is identical for the embedded MySQL version and the client/server version. To change an old threaded application to use the embedded library, you normally only have to add calls to the following functions.

FunctionWhen to Call
mysql_library_init()Should be called before any other MySQL function is called, preferablyearly in the main() function.
mysql_library_end()Should be called before your program exits.
mysql_thread_init()Should be called in each thread you create that accesses MySQL.
mysql_thread_end()Should be called before calling pthread_exit()

Then you must link your code with libmysqld.a instead of libmysqlclient.a. To ensure binary compatibility between your application and the server library, be sure to compile your application against headers for the same series of MySQL that was used to compile the server library. For example, if libmysqld was compiled against MySQL 4.1 headers, do not compile your application against MySQL 5.1 headers, or vice versa.

The mysql_library_xxx() functions are also included in libmysqlclient.a to enable you to change between the embedded and the client/server version by just linking your application with the right library. See Section 22.8.3.40, "mysql_library_init()".

One difference between the embedded server and the standalone server is that for the embedded server, authentication for connections is disabled by default. To use authentication for the embedded server, define the HAVE_EMBEDDED_PRIVILEGE_CONTROL compiler flag when you invoke CMake to configure your MySQL distribution. See Section 2.10.4, "MySQL Source-Configuration Options".

22.7.1. Compiling Programs with libmysqld

In precompiled binary MySQL distributions that include libmysqld, the embedded server library, MySQL builds the library using the appropriate vendor compiler if there is one.

To get a libmysqld library if you build MySQL from source yourself, you should configure MySQL with the -DWITH_EMBEDDED_SERVER=1 option. See Section 2.10.4, "MySQL Source-Configuration Options".

When you link your program with libmysqld, you must also include the system-specific pthread libraries and some libraries that the MySQL server uses. You can get the full list of libraries by executing mysql_config --libmysqld-libs.

The correct flags for compiling and linking a threaded program must be used, even if you do not directly call any thread functions in your code.

To compile a C program to include the necessary files to embed the MySQL server library into an executable version of a program, the compiler will need to know where to find various files and need instructions on how to compile the program. The following example shows how a program could be compiled from the command line, assuming that you are using gcc, use the GNU C compiler:

gcc mysql_test.c -o mysql_test -lz \`/usr/local/mysql/bin/mysql_config --include --libmysqld-libs`

Immediately following the gcc command is the name of the C program source file. After it, the -o option is given to indicate that the file name that follows is the name that the compiler is to give to the output file, the compiled program. The next line of code tells the compiler to obtain the location of the include files and libraries and other settings for the system on which it is compiled. Because of a problem with mysql_config, the option -lz (for compression) is added here. The mysql_config command is contained in backticks, not single quotation marks.

On some non-gcc platforms, the embedded library depends on C++ runtime libraries and linking against the embedded library might result in missing-symbol errors. To solve this, link using a C++ compiler or explicitly list the required libraries on the link command line.

22.7.2. Restrictions When Using the Embedded MySQL Server

The embedded server has the following limitations:

  • No user-defined functions (UDFs).

  • No stack trace on core dump.

  • You cannot set this up as a master or a slave (no replication).

  • Very large result sets may be unusable on low memory systems.

  • You cannot connect to an embedded server from an outside process with sockets or TCP/IP. However, you can connect to an intermediate application, which in turn can connect to an embedded server on the behalf of a remote client or outside process.

  • InnoDB is not reentrant in the embedded server and cannot be used for multiple connections, either successively or simultaneously.

  • The Event Scheduler is not available. Because of this, the event_scheduler system variable is disabled.

Some of these limitations can be changed by editing the mysql_embed.h include file and recompiling MySQL.

22.7.3. Options with the Embedded Server

Any options that may be given with the mysqld server daemon, may be used with an embedded server library. Server options may be given in an array as an argument to the mysql_library_init(), which initializes the server. They also may be given in an option file like my.cnf. To specify an option file for a C program, use the --defaults-file option as one of the elements of the second argument of the mysql_library_init() function. See Section 22.8.3.40, "mysql_library_init()", for more information on the mysql_library_init() function.

Using option files can make it easier to switch between a client/server application and one where MySQL is embedded. Put common options under the [server] group. These are read by both MySQL versions. Client/server-specific options should go under the [mysqld] section. Put options specific to the embedded MySQL server library in the [embedded] section. Options specific to applications go under section labeled [ApplicationName_SERVER]. See Section 4.2.3.3, "Using Option Files".

22.7.4. Embedded Server Examples

These two example programs should work without any changes on a Linux or FreeBSD system. For other operating systems, minor changes are needed, mostly with file paths. These examples are designed to give enough details for you to understand the problem, without the clutter that is a necessary part of a real application. The first example is very straightforward. The second example is a little more advanced with some error checking. The first is followed by a command-line entry for compiling the program. The second is followed by a GNUmake file that may be used for compiling instead.

Example 1

test1_libmysqld.c

#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include "mysql.h"MYSQL *mysql;MYSQL_RES *results;MYSQL_ROW record;static char *server_options[] = \   { "mysql_test", "--defaults-file=my.cnf", NULL };int num_elements = (sizeof(server_options) / sizeof(char *)) - 1;static char *server_groups[] = { "libmysqld_server", "libmysqld_client", NULL };int main(void){   mysql_library_init(num_elements, server_options, server_groups);   mysql = mysql_init(NULL);   mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "libmysqld_client");   mysql_options(mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);   mysql_real_connect(mysql, NULL,NULL,NULL, "database1", 0,NULL,0);   mysql_query(mysql, "SELECT column1, column2 FROM table1");   results = mysql_store_result(mysql);   while((record = mysql_fetch_row(results))) {  printf("%s - %s \n", record[0], record[1]);   }   mysql_free_result(results);   mysql_close(mysql);   mysql_library_end();   return 0;}

Here is the command line for compiling the above program:

gcc test1_libmysqld.c -o test1_libmysqld -lz \ `/usr/local/mysql/bin/mysql_config --include --libmysqld-libs`

Example 2

To try the example, create an test2_libmysqld directory at the same level as the MySQL source directory. Save the test2_libmysqld.c source and the GNUmakefile in the directory, and run GNU make from inside the test2_libmysqld directory.

test2_libmysqld.c

/* * A simple example client, using the embedded MySQL server library*/#include <mysql.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>MYSQL *db_connect(const char *dbname);void db_disconnect(MYSQL *db);void db_do_query(MYSQL *db, const char *query);const char *server_groups[] = {  "test2_libmysqld_SERVER", "embedded", "server", NULL};intmain(int argc, char **argv){  MYSQL *one, *two;  /* mysql_library_init() must be called before any other mysql   * functions.   *   * You can use mysql_library_init(0, NULL, NULL), and it   * initializes the server using groups = {   *   "server", "embedded", NULL   *  }.   *   * In your $HOME/.my.cnf file, you probably want to put:[test2_libmysqld_SERVER]language = /path/to/source/of/mysql/sql/share/english   * You could, of course, modify argc and argv before passing   * them to this function.  Or you could create new ones in any   * way you like.  But all of the arguments in argv (except for   * argv[0], which is the program name) should be valid options   * for the MySQL server.   *   * If you link this client against the normal mysqlclient   * library, this function is just a stub that does nothing.   */  mysql_library_init(argc, argv, (char **)server_groups);  one = db_connect("test");  two = db_connect(NULL);  db_do_query(one, "SHOW TABLE STATUS");  db_do_query(two, "SHOW DATABASES");  mysql_close(two);  mysql_close(one);  /* This must be called after all other mysql functions */  mysql_library_end();  exit(EXIT_SUCCESS);}static voiddie(MYSQL *db, char *fmt, ...){  va_list ap;  va_start(ap, fmt);  vfprintf(stderr, fmt, ap);  va_end(ap);  (void)putc('\n', stderr);  if (db) db_disconnect(db);  exit(EXIT_FAILURE);}MYSQL *db_connect(const char *dbname){  MYSQL *db = mysql_init(NULL);  if (!db) die(db, "mysql_init failed: no memory");  /*   * Notice that the client and server use separate group names.   * This is critical, because the server does not accept the   * client's options, and vice versa.   */  mysql_options(db, MYSQL_READ_DEFAULT_GROUP, "test2_libmysqld_CLIENT");  if (!mysql_real_connect(db, NULL, NULL, NULL, dbname, 0, NULL, 0)) die(db, "mysql_real_connect failed: %s", mysql_error(db));  return db;}voiddb_disconnect(MYSQL *db){  mysql_close(db);}voiddb_do_query(MYSQL *db, const char *query){  if (mysql_query(db, query) != 0) goto err;  if (mysql_field_count(db) > 0)  { MYSQL_RES   *res; MYSQL_ROW row, end_row; int num_fields; if (!(res = mysql_store_result(db)))  goto err; num_fields = mysql_num_fields(res); while ((row = mysql_fetch_row(res))) {  (void)fputs(">> ", stdout);  for (end_row = row + num_fields; row < end_row; ++row) (void)printf("%s\t", row ? (char*)*row : "NULL");  (void)fputc('\n', stdout); } (void)fputc('\n', stdout); mysql_free_result(res);  }  else (void)printf("Affected rows: %lld\n", mysql_affected_rows(db));  return;err:  die(db, "db_do_query failed: %s [%s]", mysql_error(db), query);}

GNUmakefile

# This assumes the MySQL software is installed in /usr/local/mysqlinc  := /usr/local/mysql/include/mysqllib  := /usr/local/mysql/lib# If you have not installed the MySQL software yet, try this instead#inc  := $(HOME)/mysql-5.5/include#lib  := $(HOME)/mysql-5.5/libmysqldCC   := gccCPPFLAGS := -I$(inc) -D_THREAD_SAFE -D_REENTRANTCFLAGS   := -g -W -WallLDFLAGS  := -static# You can change -lmysqld to -lmysqlclient to use the# client/server libraryLDLIBS = -L$(lib) -lmysqld -lz -lm -ldl -lcryptifneq (,$(shell grep FreeBSD /COPYRIGHT 2>/dev/null))# FreeBSDLDFLAGS += -pthreadelse# Assume LinuxLDLIBS += -lpthreadendif# This works for simple one-file test programssources := $(wildcard *.c)objects := $(patsubst %c,%o,$(sources))targets := $(basename $(sources))all: $(targets)clean: rm -f $(targets) $(objects) *.core
Copyright © 1997, 2013, Oracle and/or its affiliates. All rights reserved. Legal Notices
(Sebelumnya) 22.3. MySQL Connector/J22.8. MySQL C API (Berikutnya)