ADO
ADO
Welcome to our homepage about client programming to interact with Microsoft SQL Server, and with Azure
SQL Database in the cloud. This article provides the following information:
Lists and describes the available language and driver combinations.
Information is given for the operating systems of Linux (Ubuntu and others), macOS, and Windows.
Provides links to the detailed documentation for each combination.
Displays the areas and subareas of the hierarchical documentation for certain languages, where appropriate.
Azure SQL Database
In any given language, the code that connects to SQL Server is almost identical to the code for connecting to
Azure SQL Database.
For details about the connection strings for connecting to Azure SQL Database, see:
Use .NET Core (C#) to query an Azure SQL database.
Other Azure SQL Database articles that are nearby the preceding article in the table of contents, about other
languages. For instance, see Use PHP to query an Azure SQL database.
Build-an-app webpages
Our Build-an-app webpages present code examples, along with configuration information, in an alternative
format. For more information, see later in this article the section labeled Build-an-app website.
C# using ADO.NET
The .NET managed languages, such as C# and Visual Basic, are the most common users of ADO.NET. ADO.NET is
a casual name for a subset of .NET Framework classes.
Code examples
Proof of concept connecting to SQL using ADO.NET A small code example focused on connecting and querying
SQL Server.
Connect resiliently to SQL with ADO.NET Retry logic in a code example, because connections can
occasionally experience moments of connectivity loss.
Azure SQL Database: Demonstration of how to use .NET Azure SQL Database example.
Core on Windows/Linux/macOS to create a C# program, to
connect and query
Build-an-app: C#, ADO.NET, Windows Configuration information, along with code examples.
Documentation
Namespace: Microsoft.Data.SqlClient The set of classes used for Microsoft .NET Data Provider for
SQL Server
C# code examples:
Getting Started with Entity Framework Core
Getting started with EF Core on .NET Framework with an
Existing Database
VERSIO N DESC RIP T IO N
EF and related technologies are powerful, and are a lot to learn for the developer who wants to master the entire
area.
Code examples Code examples that teach about data types, result sets, and
large data.
Connection URL Sample Describes how to use a connection URL to connect to SQL
Server. Then use it to use an SQL statement to retrieve data.
Data Source Sample Describes how to use a data source to connect to SQL
Server. Then use a stored procedure to retrieve data.
Use Java to query an Azure SQL database Azure SQL Database example.
Create Java apps using SQL Server on Ubuntu Configuration information, along with code examples.
Documentation
The JDBC documentation includes the following major areas:
Programming Guide for JDBC SQL Driver Configuration information, along with code examples.
Node.js
With Node.js you can connect to SQL Server from Windows, Linux, or macOS. The root of our Node.js
documentation is here.
The Node.js connection driver for SQL Server is implemented in JavaScript. The driver uses the TDS protocol,
which is supported by all modern versions of SQL Server. The driver is an open-source project, available on
GitHub.
Code examples
Proof of concept connecting to SQL using Node.js Bare bones source code for connecting to SQL Server, and
executing a query.
Azure SQL database: Use Node.js to query Example for Azure SQL Database in the cloud.
Create Node.js apps to use SQL Server on macOS Configuration information, along with code examples.
Open database connectivity (ODBC) was developed in the 1990s, and it predates .NET Framework. ODBC is
designed to be independent of any particular database system, and independent of operating system.
Over the years numerous ODBC drivers have been created and released by groups within and outside of
Microsoft. The range of drivers involve several client programming languages. The list of data targets goes well
beyond SQL Server.
Some other connectivity drivers use ODBC internally.
Code example
C++ code example, using ODBC
Documentation outline
The ODBC content in this section focuses on accessing either SQL Server or Azure SQL Database, from C++. The
following table lists an approximate outline of the major documentation for ODBC.
A REA SUB A REA DESC RIP T IO N
PHP
You can use PHP to interact with SQL Server. The root of our PHP documentation is here.
Code examples
Proof of concept connecting to SQL using PHP A small code example focused on connecting and querying
SQL Server.
Connect resiliently to SQL with PHP Retry logic in a code example, because connections through
the Internet and the cloud can occasionally experience
moments of connectivity loss.
Azure SQL database: Use PHP to query Azure SQL Database example.
EXA M P L E DESC RIP T IO N
Create PHP apps to use SQL Server on RHEL Configuration information, along with code examples.
Python
You can use Python to interact with SQL Server.
Code examples
Proof of concept connecting to SQL with Python using A small code example focused on connecting and querying
pyodbc SQL Server.
Azure SQL database: Use Python to query Azure SQL Database example.
Create PHP apps to use SQL Server on SLES Configuration information, along with code examples.
Documentation
pymssql driver Microsoft does not maintain or test the pymssql driver.
Ruby
You can use Ruby to interact with SQL Server. The root of our Ruby documentation is here.
Code examples
EXA M P L E DESC RIP T IO N
Proof of concept connecting to SQL with Ruby A small code example focused on connecting and querying
SQL Server.
Azure SQL database: Use Ruby to query Azure SQL Database example.
Create Ruby apps to use SQL Server on macOS Configuration information, along with code examples.
This article provides download links to connection modules or drivers that your client programs can use for
interacting with Microsoft SQL Server, and with its twin in the cloud Azure SQL Database. Drivers are available
for a variety of programming languages, running on the following operating systems:
Linux
macOS
Windows
OOP-to-relational mismatch:
Relational: Client programs that are written in an object-oriented programming (OOP) language often use SQL
drivers, which return queried data in a format that is more relational than object oriented. C# using ADO.NET is
one example. The OOP-relational format mismatch sometimes makes the OOP code harder to write and
understand.
ORM: Other drivers or frameworks return queried data in the OOP format, avoiding the mismatch. These drivers
work by expecting that classes have been defined to match the data columns of particular SQL tables. The driver
then performs the object-relational mapping (ORM) to return queried data as an instance of a class. Microsoft's
Entity Framework (EF) for C#, and Hibernate for Java, are two examples.
The present article devotes separate sections to these two kinds of connection drivers.
C# ADO.NET
Microsoft.Data.SqlClient
C++ ODBC
OLE DB
Java JDBC
PHP PHP
L A N GUA GE O RM DRIVER DO W N LO A D
Python Django
Build-an-app webpages
https://aka.ms/sqldev takes you to a set of Build-an-app webpages. The webpages provide information about
numerous combinations of programming language, operating system, and SQL connection driver. Among the
information provided by the Build-an-app webpages are the following items:
Details about how to get started from the very beginning, for each combination of language + operating
system + driver.
Instructions for installing the latest SQL connection drivers.
Code examples for each of the following items:
Object-relational code examples.
ORM code examples.
Columnstore index demonstrations for much faster performance.
First page, of Build-an-app webpages:
Menu for Java - Ubuntu, of Build-an-app webpages
Related links
Code examples for connecting to Azure SQL Database in the cloud, with Java and other languages.
Driver feature support matrix for Microsoft SQL
Server
4/27/2022 • 3 minutes to read • Edit Online
If you're planning to use a feature in Microsoft SQL Server, it might not be available in all drivers. Some reasons
a feature might not be in a particular driver include:
The feature doesn't apply to the driver technology.
The feature is new and hasn't been implemented across all drivers yet.
The feature isn't in demand in a particular driver.
Other features are being implemented first.
We wish all drivers supported every feature and spend effort to ensure feature parity across drivers. However
that isn't always possible. To help you choose the appropriate driver for your needs, here's a list of popular
features and the drivers that implement them.
.NET
ODBC
OLE DB
JDBC
PHP
Node.js / JavaScript
Python
O DB C DRIVER F O R O DB C DRIVER F O R
SQ L SERVER O N SQ L SERVER O N JDB C DRIVER F O R O L E DB DRIVER F O R
F EAT URE W IN DO W S L IN UX A N D M A C O S SQ L SERVER SQ L SERVER
Azure Active Yes (v13.1+) Yes (v13.1+) Yes (v6.0+) Yes (v18.2+)
Directory Access
Token authentication
Azure Active Yes (v13.1+) Yes (v13.1+) Yes (v6.0+) Yes (v18.2+)
Directory Password
authentication
O DB C DRIVER F O R O DB C DRIVER F O R
SQ L SERVER O N SQ L SERVER O N JDB C DRIVER F O R O L E DB DRIVER F O R
F EAT URE W IN DO W S L IN UX A N D M A C O S SQ L SERVER SQ L SERVER
Azure Active Yes (v13.1+) Yes (v17.6+) Yes (v6.0+) Yes (v18.2+)
Directory Integrated
authentication
Azure Active Yes (v17.3+) Yes (v17.3+) Yes (v7.2+) Yes (v18.3+)
Directory Managed
Identity
authentication
Azure Active Yes (v17.7+) Yes (v17.7+) Yes (v9.2+) Yes (v18.5+)
Directory Service
Principal
authentication
Data Discovery and Yes (v17.2+) Yes (v17.2+) Yes (v7.0+) Yes (v18.5+)
Classification
metadata
Transparent Network Yes (v13.0+) Yes (v13.1+) Yes (v6.0+) Yes (v18.4+)
IP Resolution
DRIVERS F O R P H P DRIVERS F O R P H P
F O R SQ L SERVER O N F O R SQ L SERVER O N
F EAT URE W IN DO W S 1 L IN UX A N D M A C O S 1 T EDIO US ( N O DE. JS) P Y O DB C ( P Y T H O N ) 1
1 Since these drivers rely on the Microsoft ODBC Driver for SQL Server, a version of that driver that supports the
feature must also be used.
2
2 Only on Windows.
Get help
Ideas for SQL: Have suggestions for improving SQL Server?
Microsoft Q & A (SQL Server)
DBA Stack Exchange (tag sql-server): Ask SQL Server questions
Stack Overflow (tag sql-server): Answers to SQL development questions
Reddit: General discussion about SQL Server
Microsoft SQL Server License Terms and Information
Support options for business users
Contact Microsoft
Additional SQL Server help and feedback
This page describes Microsoft's historical data connection technologies for connecting to SQL Server.
ODBC
There are three distinct generations of Microsoft ODBC drivers for SQL Server. The first "SQL Server" ODBC
driver still ships as part of Windows Data Access Components. This driver isn't recommended for new
development. Starting in SQL Server 2005, the SQL Server Native Client includes an ODBC interface and is the
ODBC driver that shipped with SQL Server 2005 through SQL Server 2012. This driver also isn't recommended
for new development. After SQL Server 2012, the Microsoft ODBC Driver for SQL Server is the driver that is
updated with the most recent server features going forward.
SQL Server Native Client
SQL Server Native Client is a stand-alone library that is used for both OLE DB and ODBC. SQL Server Native
Client (often abbreviated SNAC) was included in SQL Server 2005 through 2012. SQL Server Native Client can
be used for applications that need to take advantage of new features introduced in SQL Server 2005 through
SQL Server 2012. (Microsoft/Windows Data Access Components aren't updated for these new features in SQL
Server.) For new features beyond SQL Server 2012, SQL Server Native Client won't be updated. Switch to the
Microsoft ODBC Driver for SQL Server or the Microsoft OLE DB Driver for SQL Server if you want to take
advantage of new SQL Server features going forward.
For complete documentation of the SQL Server Native Client, see the SQL Server Native Client documentation.
Microsoft ODBC Driver for SQL Server
After SQL Server 2012, the primary ODBC driver for SQL Server has been developed and released as the
Microsoft ODBC Driver for SQL Server. For more information, see the Microsoft ODBC Driver for SQL Server
documentation.
OLE DB
There are three distinct generations of Microsoft OLE DB providers for SQL Server. The first "Microsoft OLE DB
Provider for SQL Server" (SQLOLEDB) still ships as part of Windows Data Access Components. This provider
won't be updated with new features and it isn't recommended to use this driver for new development. Starting
in SQL Server 2005, the SQL Server Native Client includes an OLE DB provider interface (SQLNCLI) and is the
OLE DB provider that shipped with SQL Server 2005 through SQL Server 2017. It was announced as deprecated
in 2011 and it isn't recommended to use this driver for new development. In 2017, OLE DB data access
technology was later undeprecated and a new planned release was announced for 2018. The new OLE DB
provider is called the "Microsoft OLE DB Driver for SQL Server" (MSOLEDBSQL) and is currently maintained and
supported.
ADO.NET
ADO.NET is a set of classes that defines an interface for accessing any kind of data source, both relational and
non-relational. ADO.NET was introduced with the Microsoft .NET Framework and continues to be improved and
maintained in .NET. The SqlClient library is an ADO.NET data provider that provides connectivity to SQL Server
and Azure SQL data sources.
System.Data.SqlClient
System.Data.SqlClient is included as part of .NET Framework and .NET Core. Up until 2019, it was receiving
regular feature updates. With the announcements of the future of .NET Core, .NET Framework, and .NET in
general, development of SqlClient needed to shift to a package outside of .NET. System.Data.SqlClient is still
supported but isn't receiving feature updates and isn't recommended for new development.
Microsoft.Data.SqlClient
Introduced in 2019, the Microsoft SqlClient Data Provider for SQL Server is an ADO.NET data provider
supporting applications that target .NET Framework, .NET Core, and .NET Standard. For more information about
the Microsoft.Data.SqlClient namespace, see Microsoft ADO.NET for SQL Server.
JDBC
Microsoft JDBC Driver for SQL Server
Introduced in 2000, the Microsoft JDBC Driver for SQL Server continues to be improved and maintained. It was
open-sourced in 2016. For the latest information, including how to download the driver, see Overview of the
JDBC Driver.
PHP
Microsoft Drivers for PHP for SQL Server
Introduced in 2009 as an open-source project, the Microsoft Drivers for PHP for SQL Server continue to be
improved and maintained. For the latest information, including how to download the PHP driver, see Microsoft
Drivers for PHP for SQL Server.
Node.js
Microsoft Driver for Node.js for SQL Server
The Microsoft Driver for Node.js for SQL Server allows Node.js applications on Microsoft Windows and
Microsoft Azure to access Microsoft SQL Server and Microsoft Azure SQL Database. Development efforts are no
longer being focused on this driver. It isn't recommended to create new applications using the Microsoft Driver
for Node.js for SQL Server.
For more information about the Microsoft Driver for Node.js for SQL Server, see WindowsAzure / node-
sqlserver.
Tedious
Microsoft currently contributes to and supports the open-source tedious module in Node.js for connectivity to
SQL Server using JavaScript. For more information, see Node.js Driver for SQL Server.
IMPORTANT
Please read the 2007 Office System End User License Agreement for specific usage limitations.
NOTE
SQL Server applications can also access the 2007 Office System, and earlier, files from SQL Server heterogeneous
data connectivity and Integrations Services capabilities as well, via the 2007 Office System Driver. Additionally, 64-
bit SQL Server applications can access to 32-bit Jet and 2007 Office System files by using 32-bit SQL Server
Integration Services (SSIS) on 64-bit Windows.
Microsoft OLE DB Provider for Data Shaping (MSDADS): With MSDADS, you can create
hierarchical relationships between keys, fields, or rowsets in an application. No major feature
enhancements have been made since MDAC 2.1. This Provider has been deprecated. Microsoft
recommends that you use XML, instead of MSDADS.
Oracle ODBC and Oracle OLE DB: The Microsoft Oracle ODBC Driver (Oracle ODBC) and Microsoft
OLE DB Provider for Oracle (Oracle OLE DB) provide access to Oracle database servers. They're built by
using Oracle Call Interface (OCI) version 7 and provide full support for Oracle 7. Also, it uses Oracle 7
emulation to provide limited support for Oracle 8 databases. Oracle no longer supports applications that
use OCI version 7 calls. These technologies are deprecated. If you're using Oracle data sources, you
should migrate to Oracle-supplied driver and provider.
Remote Data Ser vices (RDS): RDS is a proprietary Microsoft mechanism for accessing remote ADO
Recordset objects across the Internet or an Intranet. RDS is deprecated; no major feature enhancements
have been made to RDS since MDAC 2.1. Microsoft has released the .NET Framework, which has
extensive SOAP capabilities and replaces RDS components. All RDS server components will be removed
from the operating system after Windows 7.
Jet Replication Objects (JRO): JRO is deprecated. JRO is used within ADO with Jet (.mdb) databases to
create and compress Jet Databases (.mdb's) and perform Jet Replication Management. MDAC 2.7 will be
its last release. JRO won't be available on the 64-bit Windows operating system. JRO isn't supported in
the Microsoft Access 2007 file format (.accdb).
16-bit ODBC Suppor t: If you're using 16-bit applications, you should migrate to a 32-bit application.
16-bit functionality is deprecated and is being removed from 64-bit operating systems. For more
information, see Knowledge base article 896458.
OLEDB Simple Provider (MSDAOSP): OLEDB Simple Provider offers a framework for quickly building
OLE DB providers over simple data. MSDAOSP is deprecated.
ODBC Cursor Librar y: ODBC Cursor Library (ODBCCR32.dll) provides limited client-side data cursors.
ODBC Cursor Library has been deprecated; your application can use server-side cursor implementations
as a replacement.
OLE DB Out-of-Process Interface Remoting: OLEDB Interface remoting (msdaps.dll) was an attempt
to allow OLE DB providers to run out of process. OLEDB Out-of-Process Interface remoting is deprecated.
AppleTalk and Banyan Vines SQL Network Libraries: The Banyan Vines, AppleTalk, ServerNet,
IPX/SPX, Giganet, and RPC SQL network libraries are deprecated. If you're using any of these
technologies, you should modify your applications to use one of the other network libraries, such as
TCP/IP and Named Pipe.
MDAC/WDAC Releases
Here's a list of the supportability scenarios of past MDAC/WDAC releases, starting with the earliest.
MDAC 1.5, MDAC 2.0, and MDAC 2.1: These versions of MDAC were independent releases that were
released through the Microsoft Windows NT Option Pack, the Microsoft Windows Platform SDK, or the
MDAC Web site. These versions of MDAC are no longer supported.
MDAC 2.5: This version of MDAC was included with the Windows 2000 operating system. Service packs
of MDAC 2.5 were included with corresponding Windows 2000 service packs.
MDAC 2.6: MDAC 2.6 RTM, SP1, and SP2 were included with Microsoft SQL Server 2000 RTM, SP1, and
SP2, respectively. Additionally, these MDAC service packs were released to the MDAC Web site following
the Microsoft SQL Server 2000 service-pack release schedule. You can install this version of MDAC and
its service packs on Windows 2000, Windows Millennium Edition, Windows NT, Windows 95, and
Windows 98 platforms. This version of MDAC no longer is supported.
MDAC 2.7: This version of MDAC was included with the Microsoft Windows XP RTM and SP1 operating
systems. You can install this version of MDAC and its service packs on Windows 2000, Windows
Millennium, Windows NT, and Windows 98 platforms. You can install this version on the Windows XP
platform only through the operating system or its services packs. This version of MDAC no longer is
supported.
MDAC 2.8: This version of MDAC was included with Windows Server 2003 and Windows XP SP2 and
later. You also can install this version of MDAC and its service packs on Windows 2000.
The 32-bit version of MDAC 2.8 also was released to the MDAC Web site at the same time that
Windows Server 2003 was released to the customer.
The 64-bit version of MDAC 2.8 was released with the 64-bit version of Windows Server 2003 and
Windows XP.
Windows Data Access Components (WDAC): MDAC changed its name to WDAC - "Windows Data
Access Components" starting with Windows Vista and Windows Server 2008. WDAC is included as part
of the operating system and isn't available separately for redistribution. Serviceability for WDAC is
subject to the life cycle of the operating system.
32-bit and 64-bit versions of WDAC are released with the 32-bit and 64-bit versions of the Windows
operating systems, respectively.
Get help
Ideas for SQL: Have suggestions for improving SQL Server?
Microsoft Q & A (SQL Server)
DBA Stack Exchange (tag sql-server): Ask SQL Server questions
Stack Overflow (tag sql-server): Answers to SQL development questions
Reddit: General discussion about SQL Server
Microsoft SQL Server License Terms and Information
Support options for business users
Contact Microsoft
Additional SQL Server help and feedback
Use Microsoft's SQL data platform to create data-centric solutions across mobile devices and desktops for web
servers, enterprise servers, and the cloud.
Download ADO.NET
ADO.NET is the core data access technology for .NET languages. Use the Microsoft.Data.SqlClient namespace to
access SQL Server, or providers from other suppliers to access their stores. Use System.Data.Odbc or
System.Data.Oledb to access data from .NET languages using other data access technologies. Use
System.Data.Dataset when you need an offline data cache in client applications. It also provides local persistence
and XML capabilities that can be useful in web services.
Getting started
Step 1: Configure development environment for ADO.NET development
Step 2: Create a SQL database for ADO.NET development
Step 3: Proof of concept connecting to SQL using ADO.NET
Step 4: Connect resiliently to SQL with ADO.NET
Documentation
ADO.NET Overview
Getting started with the SqlClient driver
Overview of the SqlClient driver
Data type mappings in ADO.NET
Retrieving and modifying data in ADO.NET
SQL Server and ADO.NET
Community
ADO.NET Managed Providers Forum
ADO.NET DataSet Forum
More samples
ADO.NET Code Examples
Getting Started with .NET Framework on Windows
Getting Started with .NET Core on macOS
Getting Started with .NET Core on Ubuntu
Getting Started with .NET Core on Red Hat Enterprise Linux (RHEL)
Getting started with the SqlClient driver
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Step 1: Configure development environment for ADO.NET development
Step 2: Create a SQL database for ADO.NET development
Step 3: Proof of concept connecting to SQL using ADO.NET
Step 4: Connect resiliently to SQL with ADO.NET
Step 1: Configure development environment for
ADO.NET development
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Next article: Step 2: Create a SQL database for ADO.NET development
Download ADO.NET
The samples in this section only work with the AdventureWorks schema, on either Microsoft SQL Server or
Azure SQL Database.
Sequential articles
Previous: Step 1: Configure development environment for ADO.NET development
Next: Step 3: Proof of concept connecting to SQL using ADO.NET
Step 3: Proof of concept connecting to SQL using
ADO.NET
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Previous article: Step 2: Create a SQL database for ADO.NET development
Next article: Step 4: Connect resiliently to SQL with ADO.NET
This C# code example should be considered a proof of concept only. The sample code is simplified for clarity,
and does not necessarily represent best practices recommended by Microsoft.
Step 1: Connect
The method SqlConnection.Open is used to connect to your SQL database.
using System;
using QC = Microsoft.Data.SqlClient;
namespace ProofOfConcept_SQL_CSharp
{
public class Program
{
static public void Main()
{
using (var connection = new QC.SqlConnection(
"Server=tcp:YOUR_SERVER_NAME_HERE.database.windows.net,1433;" +
"Database=AdventureWorksLT;User ID=YOUR_LOGIN_NAME_HERE;" +
"Password=YOUR_PASSWORD_HERE;Encrypt=True;" +
"TrustServerCertificate=False;Connection Timeout=30;"
))
{
connection.Open();
Console.WriteLine("Connected successfully.");
using System;
using DT = System.Data;
using QC = Microsoft.Data.SqlClient;
namespace ProofOfConcept_SQL_CSharp
{
public class Program
{
static public void Main()
{
using (var connection = new QC.SqlConnection(
"Server=tcp:YOUR_SERVER_NAME_HERE.database.windows.net,1433;" +
"Database=AdventureWorksLT;User ID=YOUR_LOGIN_NAME_HERE;" +
"Password=YOUR_PASSWORD_HERE;Encrypt=True;" +
"TrustServerCertificate=False;Connection Timeout=30;"
))
{
connection.Open();
Console.WriteLine("Connected successfully.");
Program.SelectRows(connection);
while (reader.Read())
{
Console.WriteLine("{0}\t{1}\t{2}",
reader.GetInt32(0),
reader.GetInt32(1),
reader.GetString(2));
}
}
}
}
}
/**** Actual output:
Connected successfully.
1 29736 Action Bicycle Specialists
1 29638 Aerobic Exercise Company
1 29546 Bulk Discount Store
1 29741 Central Bicycle Specialists
1 29612 Channel Outlet
Press any key to finish...
****/
using System;
using DT = System.Data;
using QC = Microsoft.Data.SqlClient;
namespace ProofOfConcept_SQL_CSharp
{
public class Program
{
static public void Main()
{
using (var connection = new QC.SqlConnection(
"Server=tcp:YOUR_SERVER_NAME_HERE.database.windows.net,1433;" +
"Database=AdventureWorksLT;User ID=YOUR_LOGIN_NAME_HERE;" +
"Password=YOUR_PASSWORD_HERE;Encrypt=True;" +
"TrustServerCertificate=False;Connection Timeout=30;"
))
{
connection.Open();
Console.WriteLine("Connected successfully.");
Program.InsertRows(connection);
Download ADO.NET
Previous article: Step 3: Proof of concept connecting to SQL using ADO.NET
This topic provides a C# code sample that demonstrates custom retry logic. The retry logic provides reliability.
The retry logic is designed to gracefully process temporary errors or transient faults which tend to go away if
the program waits several seconds and retries.
Sources of transient faults include:
A brief failure of the networking that supports the Internet.
A cloud system might be load balancing its resources at the moment your query was sent.
The ADO.NET classes for connecting to your local Microsoft SQL Server can also connect to Azure SQL Database.
However, by themselves the ADO.NET classes cannot provide all the robustness and reliability necessary in
production use. Your client program can encounter transient faults from which it should silently and gracefully
recover and continue on its own.
using System; // C#
using CG = System.Collections.Generic;
using QC = Microsoft.Data.SqlClient;
using TD = System.Threading;
namespace RetryAdo2
{
public class Program
{
static public int Main(string[] args)
{
bool succeeded = false;
int totalNumberOfTimesToTry = 4;
int retryIntervalSeconds = 10;
if (succeeded == true)
{
return 0;
}
else
{
Console.WriteLine("ERROR: Unable to access the database!");
return 1;
}
}
/// <summary>
/// Connects to the database, reads,
/// prints results to the console.
/// </summary>
static public void AccessDatabase()
{
//throw new TestSqlException(4060); //(7654321); // Uncomment for testing.
sqlConnection.Open();
var dataReader = dbCommand.ExecuteReader();
while (dataReader.Read())
{
Console.WriteLine("{0}\t{1}",
dataReader.GetString(0),
dataReader.GetString(1));
}
}
}
}
/// <summary>
/// You must edit the four 'my' string values.
/// </summary>
/// <returns>An ADO.NET connection string.</returns>
static private string GetSqlConnectionString()
{
// Prepare the connection string to Azure SQL Database.
// Prepare the connection string to Azure SQL Database.
var sqlConnectionSB = new QC.SqlConnectionStringBuilder();
return sqlConnectionSB.ToString();
}
/// <summary>
/// For testing retry logic, you can have method
/// AccessDatabase start by throwing a new
/// TestSqlException with a Number that does
/// or does not match a transient error number
/// present in TransientErrorNumbers.
/// </summary>
internal class TestSqlException : ApplicationException
{
internal TestSqlException(int testErrorNumber)
{ this.Number = testErrorNumber; }
database_firewall_rules_table 245575913
filestream_tombstone_2073058421 2073058421
filetable_updates_2105058535 2105058535
If you uncomment the throw statement, and recompile, the next run of Retr yAdo2.exe outputs something
similar to the following.
[C:\VS15\RetryAdo2\RetryAdo2\bin\Debug\]
>> RetryAdo2.exe
4060: transient occurred. (TESTING.)
Transient error encountered. Will begin attempt number 2 of 4 max...
4060: transient occurred. (TESTING.)
Transient error encountered. Will begin attempt number 3 of 4 max...
4060: transient occurred. (TESTING.)
Transient error encountered. Will begin attempt number 4 of 4 max...
4060: transient occurred. (TESTING.)
ERROR: Unable to access the database!
[C:\VS15\RetryAdo2\RetryAdo2\bin\Debug\]
>>
Next steps
To explore other best practicies and design guidelines, visit Connecting to SQL Database: Links, Best Practices
and Design Guidelines
Overview of the SqlClient driver
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
The Microsoft SqlClient Data Provider for SQL Server is a .NET Framework and .NET Core data provider. It's used
for connecting to a database, executing commands, and retrieving results.
The articles in this section provide a general overview of the SqlClient driver.
In this section
A RT IC L E DESC RIP T IO N
Download Microsoft SqlClient Data Provider for SQL Server Download page for ADO.NET and Microsoft SqlClient Data
Provider for SQL Server.
Enabling event tracing in SqlClient Describes how to use event tracing to debug and test the
driver.
AppContext switches in SqlClient Describes the AppContext switches supported by the driver.
SqlClient driver support lifecycle Page that contains product support lifecycle information.
Finding additional SqlClient driver information Page that contains useful information about the driver.
Next steps
SqlClient driver GitHub Repository
.NET API browser
Introduction to Microsoft.Data.SqlClient namespace
4/27/2022 • 27 minutes to read • Edit Online
Download ADO.NET
The Microsoft.Data.SqlClient namespace is essentially a new version of the System.Data.SqlClient namespace.
Microsoft.Data.SqlClient generally maintains the same API and backwards compatibility with
System.Data.SqlClient. To migrate from System.Data.SqlClient to Microsoft.Data.SqlClient, for most applications,
it's simple. Add a NuGet dependency on Microsoft.Data.SqlClient and update references and using statements
to Microsoft.Data.SqlClient.
There are a few differences in less-used APIs compared to System.Data.SqlClient that may affect some
applications. For those differences, see this useful porting cheat sheet.
API reference
The Microsoft.Data.SqlClient API details can be found in the .NET API Browser.
Once the .NET AppContext switch is enabled, a retry logic policy can be defined for SqlConnection and
SqlCommand independently, or together using various customization options.
New public APIs are introduced in SqlConnection and SqlCommand for registering a custom
SqlRetryLogicBaseProvider implementation:
public SqlConnection
{
public SqlRetryLogicBaseProvider RetryLogicProvider;
}
public SqlCommand
{
public SqlRetryLogicBaseProvider RetryLogicProvider;
}
using Microsoft.Data.SqlClient;
// It is not a good practice to do time-consuming tasks inside the retrying event which
blocks the running task.
// Use parallel programming patterns to mitigate it.
if (e.RetryCount == provider.RetryLogic.NumberOfTries - 1)
{
Console.WriteLine("This is the last chance to execute the command before throwing the
exception.");
Console.WriteLine("Press Enter when you're ready:");
Console.ReadLine();
Console.WriteLine("continue ...");
}
};
try
{
// Assume the database is being created and other services are going to connect to it.
RetryConnection(provider);
}
catch
{
// exception is thrown if connecting to the database isn't successful.
throw;
}
}
cnn.Close();
// It is not good practice to do time-consuming tasks inside the retrying event which blocks
the running task.
// Use parallel programming patterns to mitigate it.
if (e.RetryCount == provider.RetryLogic.NumberOfTries - 1)
{
Console.WriteLine("This is the last chance to execute the command before throwing the
exception.");
Console.WriteLine("Press Enter when you're ready:");
Console.ReadLine();
Console.WriteLine("continue ...");
}
};
try
{
// Assume the database is creating and other services are going to connect to it.
RetryCommand(provider);
}
catch
{
s_generalConnection.Close();
// exception is thrown if connecting to the database isn't successful.
throw;
}
s_generalConnection.Close();
}
private static void ExecuteCommand(SqlConnection cn, string command)
{
using var cmd = cn.CreateCommand();
cmd.CommandText = command;
cmd.ExecuteNonQuery();
}
New configuration sections have also been introduced to do the same registration from configuration files,
without having to modify existing code:
<section name="SqlConfigurableRetryLogicConnection"
type="Microsoft.Data.SqlClient.SqlConfigurableRetryConnectionSection,
Microsoft.Data.SqlClient"/>
<section name="SqlConfigurableRetryLogicCommand"
type="Microsoft.Data.SqlClient.SqlConfigurableRetryCommandSection, Microsoft.Data.SqlClient"/>
A simple example of using the new configuration sections in configuration files is below:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="SqlConfigurableRetryLogicConnection"
type="Microsoft.Data.SqlClient.SqlConfigurableRetryConnectionSection,
Microsoft.Data.SqlClient"/>
<section name="SqlConfigurableRetryLogicCommand"
type="Microsoft.Data.SqlClient.SqlConfigurableRetryCommandSection, Microsoft.Data.SqlClient"/>
<section name="AppContextSwitchOverrides"
type="Microsoft.Data.SqlClient.AppContextSwitchOverridesSection, Microsoft.Data.SqlClient"/>
</configSections>
Alternatively, applications can implement their own provider of the SqlRetryLogicBaseProvider base class, and
register it with SqlConnection / SqlCommand .
Event Counters
The following counters are now available for applications targeting .NET Core 3.1+ and .NET Standard 2.1+:
active-hard-connections Actual active connections currently The number of connections that are
made to servers currently open to database servers.
hard-connects Actual connection rate to servers The number of connections per second
that are being opened to database
servers.
hard-disconnects Actual disconnection rate from servers The number of disconnects per second
that are being made to database
servers.
soft-connects Rate of connections retrieved from the The number of connections per second
connection pool that are being consumed from the
connection pool.
soft-disconnects Rate of connections returned to the The number of connections per second
connection pool that are being returned to the
connection pool.
number-of-non-pooled- Number of connections not using The number of active connections that
connections connection pooling aren't pooled.
NAME DISP L AY N A M E DESC RIP T IO N
number-of-active-connection- Number of active unique connection The number of unique connection pool
pool-groups strings groups that are active. This counter is
controlled by the number of unique
connection strings that are found in
the AppDomain.
number-of-inactive-connection- Number of unique connection strings The number of unique connection pool
pool-groups waiting for pruning groups that are marked for pruning.
This counter is controlled by the
number of unique connection strings
that are found in the AppDomain.
number-of-active-connection- Number of active connection pools The total number of connection pools.
pools
number-of-reclaimed-connections Number of reclaimed connections from The number of connections that have
GC been reclaimed through garbage
collection where Close or Dispose
wasn't called by the application. Note
Not explicitly closing or disposing
connections hurts performance.
These counters can be used with .NET Core global CLI tools: dotnet-counters and dotnet-trace in Windows or
Linux and PerfView in Windows, using Microsoft.Data.SqlClient.EventSource as the provider name. For more
information, see Retrieve event counter values.
IP Address preference
A new connection property IPAddressPreference is introduced to specify the IP address family preference to the
driver when establishing TCP connections. If Transparent Network IP Resolution (in .NET Framework) or
Multi Subnet Failover is set to true , this setting has no effect. Below are the three accepted values for this
property:
IPv4First
This is the default preference value. The driver will use resolved IPv4 addresses first. If none of them
can be connected to successfully, it will try resolved IPv6 addresses.
IPv6First
The driver will use resolved IPv6 addresses first. If none of them can be connected to successfully, it
will try resolved IPv4 addresses.
UsePlatformDefault
The driver will try IP addresses in the order received from the DNS resolution response.
3.0 Target Platform Support
.NET Framework 4.6.1+ (Windows x86, Windows x64)
.NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
.NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
SUP P O RT A L WAY S
SUP P O RT A L WAY S EN C RY P T ED W IT H TA RGET M IC RO SO F T. DATA . SQ
EN C RY P T ED SEC URE EN C L AVE F RA M EW O RK L C L IEN T VERSIO N O P ERAT IN G SY ST EM
The following API enables customization of the Device Code Flow callback mechanism:
// For .NET Framework, .NET Core and .NET Standard targeted applications
public void SetAcquireAuthorizationCodeAsyncCallback(Func<Uri, Uri, CancellationToken, Task<Uri>>
acquireAuthorizationCodeAsyncCallback);
// For .NET Framework, .NET Core and .NET Standard targeted applications
public void ClearUserTokenCache();
}
Usage:
// Inheritance
internal class SqlClientAuthenticationProviderConfigurationSection :
SqlAuthenticationProviderConfigurationSection
{ ... }
Usage:
<configuration>
<configSections>
<section name="SqlClientAuthenticationProviders"
type="Microsoft.Data.SqlClient.SqlClientAuthenticationProviderConfigurationSection,
Microsoft.Data.SqlClient" />
</configSections>
<SqlClientAuthenticationProviders applicationClientId ="<GUID>" />
</configuration>
<!--or-->
<configuration>
<configSections>
<section name="SqlAuthenticationProviders"
type="Microsoft.Data.SqlClient.SqlAuthenticationProviderConfigurationSection,
Microsoft.Data.SqlClient" />
</configSections>
<SqlAuthenticationProviders applicationClientId ="<GUID>" />
</configuration>
Microsoft.Data.SqlClient.EventSource
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true);
See AppContext Switches in SqlClient for a full list of available switches in the driver.
Enabling decimal truncation behavior
The decimal data scale will be rounded by the driver by default as is done by SQL Server. For backwards
compatibility, you can set the AppContext switch
"Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal" to true .
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal", true);
NOTE
Note that this override can only be applied to SqlConnection.Open() and not SqlConnection.OpenAsync().
namespace Microsoft.Data.SqlClient.DataClassification
{
public class ColumnSensitivity
{
public
System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.Data.SqlClient.DataClassification.SensitivityPro
perty> SensitivityProperties
}
public class InformationType
{
public string Id
public string Name
}
public class Label
{
public string Id
public string Name
}
public class SensitivityClassification
{
public
System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.Data.SqlClient.DataClassification.ColumnSensitiv
ity> ColumnSensitivities
public
System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.Data.SqlClient.DataClassification.InformationTyp
e> InformationTypes
public
System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.Data.SqlClient.DataClassification.Label> Labels
}
public class SensitivityProperty
{
public Microsoft.Data.SqlClient.DataClassification.InformationType InformationType
public Microsoft.Data.SqlClient.DataClassification.Label Label
}
}
UTF -8 support
UTF-8 support doesn't require any application code changes. These SqlClient changes optimize client-server
communication when the server supports UTF-8 and the underlying column collation is UTF-8. See the UTF-8
section under What's new in SQL Server 2019.
Always encrypted with secure enclaves
In general, existing documentation that uses System.Data.SqlClient on .NET Framework and built-in column
master key store providers should now work with .NET Core, too.
Develop using Always Encrypted with .NET Framework Data Provider
Always Encrypted: Protect sensitive data and store encryption keys in the Windows certificate store
Authentication
Different authentication modes can be specified by using the Authentication connection string option. For more
information, see the documentation for SqlAuthenticationMethod.
NOTE
Custom key store providers, like the Azure Key Vault provider, will need to be updated to support
Microsoft.Data.SqlClient. Similarly, enclave providers will also need to be updated to support Microsoft.Data.SqlClient.
Always Encrypted is only supported against .NET Framework and .NET Core targets. It is not supported against .NET
Standard since .NET Standard is missing certain encryption dependencies.
The Microsoft.Data.SqlClient library is distributed as a NuGet package. Simply add a NuGet reference to
Microsoft.Data.SqlClient. NuGet packages are easily consumed directly from a .NET project without the need to
manually download anything. If you use Visual Studio for development, see Install and use a package. For other
ways to consume a NuGet package, see the NuGet documentation.
Download ADO.NET
Microsoft.Data.SqlClient library follows the latest .NET Core support policy for all releases.
View the .NET Core Support Policy
3.0 June 9, 2021 3.0.1 September 24, Current May 18, 2022
2021
1.1 November 20, 1.1.4 March 10, 2021 LTS November 21,
2019 2022
2.0 June 16, 2020 2.0.1 August 25, 2020 May 19, 2021
1.0 August 28, 2019 1.0.19269.1 September 26, 2019 May 20, 2020
3.x June 14, 2021 3.0.0 June 14, 2021 LTS June 15, 2024
Current releases
Current releases are supported for three months after a subsequent Current or LTS release.
Supported OS versions
Support for .NET Framework applications
Microsoft.Data.SqlClient supports all operating systems supported by .NET Framework v4.6.1 and above.
.NET Framework system requirements.
Support for .NET Core applications
Microsoft.Data.SqlClient supports all operating systems supported by .NET Core v3.1 and above.
.NET Core supported OS lifecycle policy.
NOTE
Globalization Invariant mode is currently not supported.
Enable event tracing in SqlClient
4/27/2022 • 4 minutes to read • Edit Online
Download ADO.NET
Event Tracing for Windows (ETW) is an efficient, kernel-level, tracing facility that lets you log driver-defined
events for debugging and testing purposes. SqlClient supports capturing ETW events at different informational
levels. To begin capturing event traces, client applications should listen for events from SqlClient's EventSource
implementation:
Microsoft.Data.SqlClient.EventSource
K EY W O RD N A M E VA L UE DESC RIP T IO N
Example
The following example enables event tracing for a data operation on the AdventureWorks sample database
and displays the events in the console window.
using System;
using System.Diagnostics.Tracing;
using Microsoft.Data.SqlClient;
// This listener class will listen for events from the SqlClientEventSource class.
// SqlClientEventSource is an implementation of the EventSource class which gives
// it the ability to create events.
public class SqlClientListener : EventListener
{
protected override void OnEventSourceCreated(EventSource eventSource)
{
// Only enable events from SqlClientEventSource.
if (eventSource.Name.Equals("Microsoft.Data.SqlClient.EventSource"))
{
// Use EventKeyWord 2 to capture basic application flow events.
// See the above table for all available keywords.
EnableEvents(eventSource, EventLevel.Informational, (EventKeywords)2);
}
}
class Program
{
public static void Main()
{
// Create a new event listener.
using (SqlClientListener listener = new SqlClientListener())
{
string connectionString = "Data Source=localhost; " +
"Initial Catalog=AdventureWorks; Integrated Security=true";
class Program
{
static string connectionString = @"Data Source = localhost; Initial Catalog = AdventureWorks;Integrated
Security=true;";
4. Use PerfView to open the myTrace.etl file specified in Step 1. The SNI tracing log can be found with
Microsoft.Data.SqlClient.EventSource/SNIScope and Microsoft.Data.SqlClient.EventSource/SNITrace
event names.
3. Start collection.
4. Run the native SNI tracing example to connect to SQL Server.
5. Stop collection from PerfView. It will take a while to generate PerfViewData.etl file according to
configuration in Step 2.
6. Open the etlfile in PerfView. The SNI tracing log can be found with
Microsoft.Data.SqlClient.EventSource/SNIScope and Microsoft.Data.SqlClient.EventSource/SNITrace
event names.
External resources
For more information, see the following resources.
EventListener Class Provides methods for enabling and disabling events from
event sources.
AppContext switches in Sqlclient
4/27/2022 • 3 minutes to read • Edit Online
Download ADO.NET
The AppContext class allows SqlClient to provide new functionality while continuing to support callers who
depend on the previous behavior. Users can opt out of a change in behavior by setting specific AppContext
switches.
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseSystemDefaultSecureProtocols", true);
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal", true);
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true);
This switch will toggle the driver's behavior to use a managed networking implementation in .NET Core 2.1+
and .NET Standard 2.0+ projects on Windows, eliminating all dependencies on native libraries for the
Microsoft.Data.SqlClient library. It is intended for testing and debugging purposes only.
NOTE
There are some known differences when compared to the native implementation. For example, the managed
implementation does not support non-domain Windows Authentication.
True True 1
True False 0
False True 1
False False 2
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.DisableTNIRByDefaultInConnectionString", true);
For more information about setting these properties, see the documentation for
SqlConnection.ConnectionString Property.
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseOneSecFloorInTimeoutCalculationDuringLogin",
false);
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking", false);
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.EnableRetryLogic", true);
For information on how to enable the switch by using a configuration file see Enable safety switch.
NOTE
Starting from Microsoft.Data.SqlClient v4.0, the App Context switch "Switch.Microsoft.Data.SqlClient.EnableRetryLogic" will
no longer be required to use the configurable retry logic feature. The feature is now supported in production. The default
behavior of the feature will continue to be a non-retry policy, which will need to be overridden by client applications to
enable retries.
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior", true);
AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning", true);
See also
AppContext Class
SqlClient troubleshooting guide
4/27/2022 • 6 minutes to read • Edit Online
Download ADO.NET
SNI is the native C++ library that SqlClient depends on for various network operations when running on
Windows. In .NET Framework applications that are built with the MSBuild Project SDK, native DLLs aren't
managed with restore commands. So a ".targets" file is included in the "Microsoft.Data.SqlClient.SNI" NuGet
package that defines the necessary "Copy" operations.
The included ".targets" file is auto-referenced when a direct dependency is made to the
"Microsoft.Data.SqlClient" library. In scenarios where a transitive (indirect) reference is made, this ".targets" file
should be manually referenced to ensure "Copy" operations can execute when necessary.
Recommended Solution: Make sure the ".targets" file is referenced in the application's ".csproj" file to ensure
"Copy" operations are executed.
These targets cover Microsoft's well-known and commonly used targets only. If an external tool or application
defines custom targets to copy binaries, new targets must be defined by tool maintainers to ensure native SNI
DLLs are copied along-side the Microsoft.Data.SqlClient.dll binaries and are available when executing client
applications.
Issues in .NET Core applications
Stacktrace observed:
SNI is the native C++ library that SqlClient depends on for various network operations when running on
Windows. Microsoft.Data.SqlClient doesn't manage loading/unloading of this library in .NET Core.
Recommended Solution: Ensure "Execute" permissions are granted on the filesystem where native runtime
libraries are loaded in the .NET Core process. If that doesn't solve the issue, you can file an issue in the
dotnet/runtime repository for further support.
Native SNI (pdb not found) errors
Stacktrace observed:
An assembly specified in the application dependencies manifest (sql2csv.deps.json) was not found:
package: 'Microsoft.Data.SqlClient.SNI.runtime', version: '2.0.0'
path: 'runtimes/win-x64/native/Microsoft.Data.SqlClient.SNI.pdb'
Possible reasons
TCP/Named Pipes Protocol isn't enabled on SQL Server
Recommended Solution: Enable the TCP/Named Pipes Protocol on the SQL Server instance from the
SQL Server Configuration Manager console.
Hostname not known
Recommended Solution: Ensure the hostname resolves to the Server's IP address from the client
where the connection is being initiated.
Login-phase errors
Stacktraces observed:
A connection was successfully established with the server, but then an error occurred during the login
process.
(provider: SSL Provider, error: 0 - The target principal name is incorrect.)
MinProtocol = TLSv1
CipherString = DEFAULT@SECLEVEL=1
NOTE
When connecting with Microsoft.Data.SqlClient v2.0+ from a Windows/Linux environment with TLS 1.0 or TLS 1.1,
a security warning message will be thrown if the target SQL Server and client cannot negotiate a minimum of TLS
version 1.2 when establishing the connection:
Security Warning: The negotiated <TLS1.0 | TLS1.1> is an insecure protocol and is supported for
backward compatibility only. The recommended protocol version is TLS 1.2 and later.
Contact Support
If this guide doesn't solve your connectivity issues, you may view existing issues in the dotnet/sqlclient
repository and open a new issue if needed.
Finding additional SqlClient driver information
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
For more information about the Microsoft SqlClient Data Provider for SQL Server development in general, see
the following online resources:
Remarks
RESO URC E DESC RIP T IO N
.NET API Browser This site contains .NET API information for
Microsoft.Data.SqlClient.
Microsoft SqlClient Data Provider for SQL Server GitHub This repository contains the source code for
Repository Microsoft.Data.SqlClient.
.NET Runtime GitHub Repository This repository contains the runtime library implementation
for .NET.
Next steps
Overview of the SqlClient driver
Data type mappings in ADO.NET
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
The ADO.NET is based on the common type system, which defines how types are declared, used, and managed
in the runtime. It consists of both value types and reference types, which all derive from the Object base type.
When working with a data source, the data type is inferred from the data provider if it is not explicitly specified.
For example, a DataSet object is independent of any specific data source. Data in a DataSet is retrieved from a
data source, and changes are persisted back to the data source by using a DataAdapter . This program flow
means that when a DataAdapter fills a DataTable in a DataSet with values from a data source, the resulting data
types of the columns in the DataTable are .NET Framework types, instead of types specific to the Microsoft
SqlClient Data Provider for SQL Server that is used to connect to the data source.
Likewise, when a DataReader returns a value from a data source, the resulting value is stored in a local variable
that has a .NET Framework type. For both the Fill operations of the DataAdapter and the Get methods of the
DataReader , the .NET Framework type is inferred from the value returned from the Microsoft SqlClient Data
Provider for SQL Server.
Instead of relying on the inferred data type, you can use the typed accessor methods of the DataReader when
you know the specific type of the value being returned. Typed accessor methods give you better performance by
returning a value as a specific .NET Framework type, which eliminates the need for additional type conversion.
NOTE
Null values for Microsoft SqlClient Data Provider for SQL Server data types are represented by DBNull.Value .
In This Section
SQL Server Data Type Mappings Lists inferred data type mappings and data accessor methods for
Microsoft.Data.SqlClient.
Floating-Point Numbers Describes issues that developers frequently encounter when working with floating-
point numbers.
See also
SQL Server data types and ADO.NET
Configuring parameters
Retrieving database schema information
Microsoft ADO.NET for SQL Server
SQL Server data type mappings
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
SQL Server and the .NET Framework are based on different type systems. For example, the .NET Framework
Decimal structure has a maximum scale of 28, whereas the SQL Server decimal and numeric data types have a
maximum scale of 38. To maintain data integrity when reading and writing data, the SqlDataReader exposes SQL
Server–specific typed accessor methods that return objects of System.Data.SqlTypes as well as accessor
methods that return .NET Framework types. Both SQL Server types and .NET Framework types are also
represented by enumerations in the DbType and SqlDbType classes, which you can use when specifying
SqlParameter data types.
The following table shows the inferred .NET Framework type, the DbType and SqlDbType enumerations, and the
accessor methods for the SqlDataReader.
(SQL Server
2008 and later)
(SQL Server
2008 and later)
Char[] GetChars
Char[] GetChars
Char[] GetChars
(SQL Server
2008 and later)
Char[] GetChars
See also
SQL Server data types and ADO.NET
SQL Server binary and large-value data
Configuring parameters
Data type mappings in ADO.NET
Floating-point numbers
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
This topic describes some of the issues that developers frequently encounter when they work with floating-point
numbers in the Microsoft SqlClient Data Provider for SQL Server. These issues are caused by the way that
computers store floating-point numbers, and are not specific to a particular provider such as
Microsoft.Data.SqlClient.
Floating-point pitfall
Floating-point numbers generally do not have an exact binary representation. Instead, the computer stores an
approximation of the number. At different times, different numbers of binary digits may be used to represent
the number. When a floating point number is converted from one representation to another representation, the
least significant digits of that number may vary slightly. Conversion typically occurs when the number is cast
from one type to another type. The variation occurs whether the conversion occurs within a database, between
types that represent database values, or between types. Because of these changes, numbers that would logically
be equal may have changes in their least-significant digits that cause them to have different values. The number
of digits of precision in the number may be larger or smaller than expected. When formatted as a string, the
number may not show the expected value.
Suggested workarounds
To minimize these effects, you should use the closest match between numeric types that is available to you. For
example, if you are working with SQL Server, the exact numeric value may change if you convert a Transact-SQL
value of real type to a value of float type. In the .NET, converting a Single to a Double may also produce
unexpected results. In both of these cases, a good strategy is to make all the values in the application use the
same numeric type. You can also use a fixed-precision decimal type, or cast floating-point numbers to a fixed-
precision decimal type before you work with them.
To work around problems with equality comparison, consider coding your application so that variations in the
least significant digits are ignored. For example, instead of comparing to see whether two numbers are equal,
subtract one number from the other number. If the difference is within an acceptable margin of rounding, your
application can treat the numbers as if they are the same.
See also
Microsoft ADO.NET for SQL Server
Retrieving and modifying data in ADO.NET
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
A primary function of any database application is connecting to a data source and retrieving the data that it
contains. The SqlClient data provider serves as a bridge between an application and a data source, allowing you
to execute commands as well as to retrieve data by using a DataReader or a DataAdapter . A key function of
any database application is the ability to update the data that is stored in the database. In the Microsoft SqlClient
Data Provider for SQL Server, updating data involves using the DataAdapter and DataSet, and Command
objects; and it may also involve using transactions.
In this section
Connecting to a data source
Describes how to establish a connection to a data source and how to work with connection events.
Connection strings
Contains topics describing various aspects of using connection strings, including connection string keywords,
security info, and storing and retrieving them.
Connection pooling
Describes connection pooling for the Microsoft SqlClient Data Provider for SQL Server.
Commands and Parameters
Contains topics describing how to create commands and command builders, configure parameters,
and how to execute commands to retrieve and modify data.
DataAdapters and DataReaders
Contains topics describing DataReaders, DataAdapters, parameters, handling DataAdapter events and performin
g batch operations.
Transactions and concurrency
Contains topics describing how to perform local transactions, distributed transactions, and work with optimistic
concurrency.
Retrieving database schema information
Describes how to obtain available databases or catalogs, tables and views in a database, constraints that exist for
tables, and other schema information from a data source.
DbProviderFactories
Describes the provider factory model and demonstrates how to use the base classes in the System.Data.Common
namespace.
Configurable retry logic in SqlClient
Describes how to use the configurable retr y logic feature when establishing a connection or executing a
command.
Retrieve identity or autonumber values
Provides an example of mapping the values generated for an identity column in a SQL Server table to a
column of an inserted row in a table. Discusses merging identity values in a DataTable .
Retrieve Binary Data
Describes how to retrieve binary data or large data structures using CommandBehavior . SequentialAccess to
modify the default behavior of a DataReader .
Modify data with stored procedures
Describes how to use stored procedure input parameters and output parameters to insert a row in a database,
returning a new identity value.
Data tracing in SqlClient
Describes how Microsoft SqlClient Data Provider for SQL Server provides built-in data tracing functionality.
Diagnostic counters in SqlClient
Describes diagnostic counters and available for Microsoft SqlClient Data Provider for SQL Server.
Asynchronous programming
Describes Microsoft SqlClient Data Provider for SQL Server support for asynchronous programming.
SqlClient streaming support
Discusses how to write applications that stream data from SQL Server without having it fully loaded in memory.
See also
Data type mappings in ADO.NET
SQL Server and ADO.NET
Microsoft ADO.NET for SQL Server
Connecting to a data source in ADO.NET
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
In the Microsoft SqlClient data provider, you use a Connection object to connect to a specific data source by
supplying necessary authentication information in a connection string. The Connection object you use depends
on the type of data source.
The Microsoft SqlClient Data Provider for SQL Server includes a SqlConnection type that is derived from a
DbConnection class.
In this section
Establishing the Connection
Describes how to use a Connection object to establish a connection to a data source.
Connection Events
Describes how to use an InfoMessage event to retrieve informational messages from a data source.
See also
Connection strings
Connection pooling
Commands and parameters
DataAdapters and DataReaders
Transactions and concurrency
Microsoft ADO.NET for SQL Server
Establishing connection
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
To connect to Microsoft SQL Server, use the SqlConnection object of the Microsoft SqlClient Data Provider for
SQL Server. For securely storing and retrieving connection strings, see Protecting Connection Information.
Closing connections
We recommend that you always close the connection when you are finished using it, so that the connection can
be returned to the pool. The Using block in Visual Basic or C# automatically disposes of the connection when
the code exits the block, even in the case of an unhandled exception. See using Statement and Using Statement
for more information.
You can also use the Close or Dispose methods of the connection object. Connections that are not explicitly
closed might not be added or returned to the pool. For example, a connection that has gone out of scope but
that has not been explicitly closed will only be returned to the connection pool if the maximum pool size has
been reached and the connection is still valid.
NOTE
Do not call Close or Dispose on a Connection , a DataReader , or any other managed object in the Finalize
method of your class. In a finalizer, only release unmanaged resources that your class owns directly. If your class does not
own any unmanaged resources, do not include a Finalize method in your class definition. For more information, see
Garbage Collection.
NOTE
Login and logout events will not be raised on the server when a connection is fetched from or returned to the connection
pool, because the connection is not actually closed when it is returned to the connection pool. For more information, see
SQL Server Connection Pooling (ADO.NET).
class Program1
{
static void Main()
{
string s = GetConnectionString();
OpenSqlConnection(s);
Console.ReadLine();
}
See also
Connecting to a data source
Connection strings
Microsoft ADO.NET for SQL Server
Connection events
4/27/2022 • 3 minutes to read • Edit Online
Download ADO.NET
The Microsoft SqlClient Data Provider for SQL Server has Connection objects with two events that you can use
to retrieve informational messages from a data source or to determine if the state of a Connection has
changed. The following table describes the events of the Connection object.
NOTE
An error with a severity level of 17 or above that causes the server to stop processing the command must be handled as
an exception. In this case, an exception is thrown regardless of how the error is handled in the InfoMessage event.
See also
Connecting to a data source
Microsoft ADO.NET for SQL Server
Connection strings in ADO.NET
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
A connection string contains initialization information that is passed as a parameter from a data provider to a
data source. The data provider receives the connection string as the value of the DbConnection.ConnectionString
property. The provider parses the connection string and ensures that the syntax is correct and that the keywords
are supported. Then the DbConnection.Open() method passes the parsed connection parameters to the data
source. The data source performs further validation and establishes a connection.
keyword1=value; keyword2=value;
Keywords are not case-sensitive. Values, however, may be case-sensitive, depending on the data source. Both
keywords and values may contain whitespace characters. Leading and trailing white space is ignored in
keywords and unquoted values.
If a value contains the semicolon, Unicode control characters, or leading or trailing white space, it must be
enclosed in single or double quotation marks. For example:
The enclosing character may not occur within the value it encloses. Therefore, a value containing single
quotation marks can be enclosed only in double quotation marks, and vice versa:
Keyword='double"quotation;mark';
Keyword="single'quotation;mark";
You can also escape the enclosing character by using two of them together:
Keyword="double""quotation";
Keyword='single''quotation';
The quotation marks themselves, as well as the equals sign, do not require escaping, so the following connection
strings are valid:
Since each value is read until the next semicolon or the end of string, the value in the latter example is a=b=c ,
and the final semicolon is optional.
All connection strings share the same basic syntax described above. The set of recognized keywords depends on
the provider. The Microsoft SqlClient data provider for SQL Server supports many keywords from older APIs,
but is generally more flexible and accepts synonyms for many of the common connection string keywords.
Typing mistakes can cause errors. For example, Integrated Security=true is valid, but IntegratedSecurity=true
causes an error.
Connection strings constructed manually at run time from invalidated user input are vulnerable to string-
injection attacks and jeopardize security at the data source. To address these problems, the
SqlConnectionStringBuilder class has been created. This connection string builder class exposes parameters as
strongly typed properties, and makes it possible to validate the connection string before it's sent to the data
source.
In this section
Connection String Builder
Demonstrates how to use the ConnectionStringBuilder class to construct valid connection strings at run time.
Connection Strings and Configuration Files
Demonstrates how to store and retrieve connection strings in configuration files.
Connection String Syntax
Describes how to configure provider-specific connection strings for SqlClient .
Protecting Connection Information
Demonstrates techniques for protecting information used to connect to a data source.
See also
Microsoft ADO.NET for SQL Server
Connection string builders
4/27/2022 • 3 minutes to read • Edit Online
Download ADO.NET
In earlier versions of ADO.NET, compile-time checking of connection strings with concatenated string values
didn't occur, so that at run time, an incorrect keyword generated an ArgumentException. The Microsoft SqlClient
Data Provider for SQL Server includes the connection string builder class
Microsoft.Data.SqlClient.SqlConnectionStringBuilder that inherits from DbConnectionStringBuilder.
The output shows that the SqlConnectionStringBuilder handled it correctly by escaping the extra value in double
quotation marks instead of appending it to the connection string as a new key/value pair.
Example
This example demonstrates retrieving a partial connection string from a configuration file and completing it by
setting the DataSource, UserID, and Password properties of the SqlConnectionStringBuilder. The configuration
file is defined as follows.
<connectionStrings>
<clear/>
<add name="partialConnectString"
connectionString="Initial Catalog=Northwind;"
providerName="Microsoft.Data.SqlClient" />
</connectionStrings>
NOTE
You must set a reference to the System.Configuration.dll in your project for the code to run.
if (null != settings)
{
// Retrieve the partial connection string.
string connectString = settings.ConnectionString;
Console.WriteLine("Original: {0}", connectString);
See also
Connection strings
Microsoft ADO.NET for SQL Server
Connection strings and configuration files
4/27/2022 • 10 minutes to read • Edit Online
Download ADO.NET
Embedding connection strings in your application's code can lead to security vulnerabilities and maintenance
problems. Unencrypted connection strings compiled into an application's source code can be viewed using the
Ildasm.exe (IL Disassembler) tool. Moreover, if the connection string ever changes, your application must be
recompiled. For these reasons, we recommend storing connection strings in an application configuration file.
NOTE
You can save part of a connection string in a configuration file and use the DbConnectionStringBuilder class to complete it
at run time. This is useful in scenarios where you do not know elements of the connection string ahead of time, or when
you do not want to save sensitive information in a configuration file. For more information, see Connection String
Builders.
<connectionStrings>
<add name="Name"
providerName="Microsoft.Data.SqlClient"
connectionString="Valid Connection String;" />
</connectionStrings>
In the main application configuration file, you use the configSource attribute to specify the fully qualified name
and location of the external file. This example refers to an external configuration file named connections.config .
NOTE
The machine.config file also contains a connectionStrings section, which contains connection strings used by Visual
Studio. When retrieving connection strings by provider name from the app.config file in a Windows application, the
connection strings in machine.config get loaded first, and then the entries from app.config . Adding clear immediately
after the connectionStrings element removes all inherited references from the data structure in memory, so that only
the connection strings defined in the local app.config file are considered.
NOTE
Accessing configuration files at run time requires granting permissions to the caller; the required permissions depend on
the type of application, configuration file, and location. For more information, see Using the Configuration Classes and
WebConfigurationManager for ASP.NET applications, and ConfigurationManager for Windows applications.
You can use the ConnectionStringSettingsCollection to retrieve connection strings from application
configuration files. It contains a collection of ConnectionStringSettings objects, each of which represents a single
entry in the connectionStrings section. Its properties map to connection string attributes, allowing you to
retrieve a connection string by specifying the name or the provider name.
P RO P ERT Y DESC RIP T IO N
NOTE
System.Configuration.dll is not included in all project types, and you may need to set a reference to it in order to use the
configuration classes. The name and location of a particular application configuration file varies by the type of application
and the hosting process.
using System.Configuration;
class Program
{
static void Main()
{
GetConnectionStrings();
Console.ReadLine();
}
if (settings != null)
{
foreach(ConnectionStringSettings cs in settings)
{
Console.WriteLine(cs.Name);
Console.WriteLine(cs.ProviderName);
Console.WriteLine(cs.ConnectionString);
}
}
}
}
return returnValue;
}
When the encrypted connection string is retrieved at run time, the .NET Framework uses the specified provider
to decrypt the CipherValue and make it available to your application. You do not need to write any additional
code to manage the decryption process.
Protected configuration providers
Protected configuration providers are registered in the configProtectedData section of the machine.config
file on the local computer, as shown in the following fragment, which shows the two protected configuration
providers supplied with the .NET Framework. The values shown here have been truncated for readability.
<configProtectedData defaultProvider="RsaProtectedConfigurationProvider">
<providers>
<add name="RsaProtectedConfigurationProvider"
type="System.Configuration.RsaProtectedConfigurationProvider" />
<add name="DataProtectionConfigurationProvider"
type="System.Configuration.DpapiProtectedConfigurationProvider" />
</providers>
</configProtectedData>
You can configure additional protected configuration providers by adding them to the machine.config file. You
can also create your own protected configuration provider by inheriting from the
ProtectedConfigurationProvider abstract base class. The following table describes the two configuration files
included with the .NET Framework.
Both providers offer strong encryption of data. However, if you are planning to use the same encrypted
configuration file on multiple servers, such as a Web farm, only the RsaProtectedConfigurationProvider enables
you to export the encryption keys used to encrypt the data and import them on another server. For more
information, see Importing and Exporting Protected Configuration RSA Key Containers.
Use the configuration classes
The System.Configuration namespace provides classes to work with configuration settings programmatically.
The ConfigurationManager class provides access to machine, application, and user configuration files. If you are
creating an ASP.NET application, you can use the WebConfigurationManager class, which provides the same
functionality while also allowing you to access settings that are unique to ASP.NET applications, such as those
found in <system.web> .
NOTE
The System.Security.Cryptography namespace contains classes that provide additional options for encrypting and
decrypting data. Use these classes if you require cryptographic services that are not available using protected
configuration. Some of these classes are wrappers for the unmanaged Microsoft CryptoAPI, while others are purely
managed implementations. For more information, see Cryptographic Services.
App.config example
This example demonstrates how to toggle encrypting the connectionStrings section in an app.config file for
a Windows application. In this example, the procedure takes the name of the application as an argument, for
example, "MyApplication.exe". The app.config file will then be encrypted and copied to the folder that contains
the executable under the name of "MyApplication.exe.config".
NOTE
The connection string can only be decrypted on the computer on which it was encrypted.
The code uses the OpenExeConfiguration method to open the app.config file for editing, and the GetSection
method returns the connectionStrings section. The code then checks the IsProtected property, calling the
ProtectSection to encrypt the section if it is not encrypted. The UnprotectSection method is invoked to decrypt
the section. The Save method completes the operation and saves the changes.
NOTE
You must set a reference to System.Configuration.dll in your project for the code to run.
static void ToggleConfigEncryption(string exeFile)
{
// Takes the executable file name without the
// .config extension.
try
{
// Open the configuration file and retrieve
// the connectionStrings section.
Configuration config = ConfigurationManager.
OpenExeConfiguration(exeConfigName);
ConnectionStringsSection section =
config.GetSection("connectionStrings")
as ConnectionStringsSection;
if (section.SectionInformation.IsProtected)
{
// Remove encryption.
section.SectionInformation.UnprotectSection();
}
else
{
// Encrypt the section.
section.SectionInformation.ProtectSection(
"DataProtectionConfigurationProvider");
}
// Save the current configuration.
config.Save();
Console.WriteLine("Protected={0}",
section.SectionInformation.IsProtected);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Web.config example
This example uses the OpenWebConfiguration method of the WebConfigurationManager . Note that in this case
you can supply the relative path to the Web.config file by using a tilde. The code requires a reference to the
System.Web.Configuration class.
static void ToggleWebEncrypt()
{
// Open the Web.config file.
Configuration config = WebConfigurationManager.
OpenWebConfiguration("~");
// Toggle encryption.
if (section.SectionInformation.IsProtected)
{
section.SectionInformation.UnprotectSection();
}
else
{
section.SectionInformation.ProtectSection(
"DataProtectionConfigurationProvider");
}
For more information about securing ASP.NET applications, see Securing ASP.NET web sites.
See also
Connection string builders
Protecting connection information
Using the configuration classes
Configuring apps
ASP.NET web site administration
Microsoft ADO.NET for SQL Server
Connection string syntax
4/27/2022 • 4 minutes to read • Edit Online
Download ADO.NET
The Microsoft.Data.SqlClient has a Connection object that inherits from DbConnection as well as a provider-
specific ConnectionString property. The specific connection string syntax for the SqlClient provider is
documented in its ConnectionString property. For more information on connection string syntax, see
ConnectionString.
Windows authentication
We recommend using Windows Authentication (sometimes referred to as integrated security) to connect to data
sources that support it. The following table shows the Windows Authentication syntax used with the Microsoft
SqlClient Data Provider for SQL Server.
P RO VIDER SY N TA X
-- or --
Integrated Security=SSPI;
IMPORTANT
The default setting for the Persist Security Info keyword is false . Setting it to true or yes allows security-
sensitive information, including the user ID and password, to be obtained from the connection after the connection has
been opened. Keep Persist Security Info set to false to ensure that an untrusted source does not have access to
sensitive connection string information.
When you connect to Azure SQL Database or to Azure Synapse Analytics and provide a login in the format
user@servername , make sure that the servername value in the login matches the value provided for Server= .
NOTE
Windows authentication takes precedence over SQL Server logins. If you specify both Integrated Security=true as well as
a user name and password, the user name and password will be ignored and Windows authentication will be used.
"Data Source=MySqlServer\MSSQL1;"
You can also set the DataSource property of the SqlConnectionStringBuilder to the instance name when
building a connection string. The DataSource property of a SqlConnection object is read-only.
Type system version changes
The Type System Version keyword in a SqlConnection.ConnectionString specifies the client-side representation
of SQL Server types. See SqlConnection.ConnectionString for more information about the Type System Version
keyword.
Use TrustServerCertificate
The TrustServerCertificate keyword is valid only when connecting to a SQL Server instance with a valid
certificate. When TrustServerCertificate is set to true , the transport layer will use TLS/SSL to encrypt the
channel and bypass walking the certificate chain to validate trust.
"TrustServerCertificate=true;"
NOTE
If TrustServerCertificate is set to true and encryption is turned on, the encryption level specified on the server will
be used even if Encrypt is set to false in the connection string. The connection will fail otherwise.
Enable encryption
To enable encryption when a certificate has not been provisioned on the server, the Trust Ser ver Cer tificate
connection property must be set. In this case, encryption will use a self-signed server certificate without
validation since no verifiable certificate has been provisioned on the server.
Application settings cannot reduce the level of security configured in SQL Server, but can optionally strengthen
it. An application can request encryption by setting the TrustServerCertificate and Encrypt keywords to true
, guaranteeing that encryption takes place even when a server certificate has not been provisioned. However, if
TrustServerCertificate is not enabled in the client configuration, a provisioned server certificate is still
required.
The following table describes all cases.
See also
Connection strings
Connecting to a data source
Microsoft ADO.NET for SQL Server
Protecting connection information
4/27/2022 • 3 minutes to read • Edit Online
Download ADO.NET
Protecting access to your data source is one of the most important goals when securing an application. A
connection string presents a potential vulnerability if it is not secured. Storing connection information in plain
text or persisting it in memory risks compromising your entire system. Connection strings embedded in your
source code can be read using the Ildasm.exe (IL Disassembler) to view Microsoft intermediate language (MSIL)
in a compiled assembly.
Security vulnerabilities involving connection strings can arise based on the type of authentication used, how
connection strings are persisted in memory and on disk, and the techniques used to construct them at run time.
<identity impersonate="true"
userName="MyDomain\UserAccount"
password="*****" />
The fixed identity account should be a low-privilege account that has been granted only necessary permissions
in the database. In addition, you should encrypt the configuration file so that the user name and password are
not exposed in clear text.
See also
Encrypting Configuration Information Using Protected Configuration
Microsoft ADO.NET for SQL Server
Connection pooling
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Connecting to a data source can be time consuming. To minimize the cost of opening connections, ADO.NET
uses an optimization technique called connection pooling, which minimizes the cost of repeatedly opening and
closing connections.
In this section
SQL Server Connection Pooling (ADO.NET)
Provides an overview of connection pooling and describes how connection pooling works in SQL Server.
See also
Retrieving and modifying data in ADO.NET
Microsoft ADO.NET for SQL Server
SQL Server connection pooling (ADO.NET)
4/27/2022 • 10 minutes to read • Edit Online
Download ADO.NET
Connecting to a database server typically consists of several time-consuming steps. A physical channel such as a
socket or a named pipe must be established, the initial handshake with the server must occur, the connection
string information must be parsed, the connection must be authenticated by the server, checks must be run for
enlisting in the current transaction, and so on.
In practice, most applications use only one or a few different configurations for connections. This means that
during application execution, many identical connections will be repeatedly opened and closed. To minimize the
cost of opening connections, Microsoft SqlClient Data Provider for SQL Server uses an optimization technique
called connection pooling.
Connection pooling reduces the number of times that new connections must be opened. The pooler maintains
ownership of the physical connection. It manages connections by keeping alive a set of active connections for
each given connection configuration. Whenever a user calls Open on a connection, the pooler looks for an
available connection in the pool. If a pooled connection is available, it returns it to the caller instead of opening a
new connection. When the application calls Close on the connection, the pooler returns it to the pooled set of
active connections instead of closing it. Once the connection is returned to the pool, it is ready to be reused on
the next Open call.
Only connections with the same configuration can be pooled. Microsoft SqlClient Data Provider for SQL Server
keeps several pools at the same time, one for each configuration. Connections are separated into pools by
connection string, and by Windows identity when integrated security is used. Connections are also pooled based
on whether they are enlisted in a transaction. When using ChangePassword, the SqlCredential instance affects
the connection pool. Different instances of SqlCredential will use different connection pools, even if the user ID
and password are the same.
Pooling connections can significantly enhance the performance and scalability of your application. By default,
connection pooling is enabled in the Microsoft SqlClient Data Provider for SQL Server. Unless you explicitly
disable it, the pooler optimizes the connections as they are opened and closed in your application. You can also
supply several connection string modifiers to control connection pooling behavior. For more information, see
"Controlling Connection Pooling with Connection String Keywords " later in this topic.
IMPORTANT
When connection pooling is enabled, and if a timeout error or other login error occurs, an exception will be thrown and
subsequent connection attempts will fail for the next 5 seconds, the " blocking period ". If the application attempts to
connect within the blocking period, the first exception will be thrown again. Subsequent failures after a blocking period
ends will result in a new blocking periods that is twice as long as the previous blocking period, up to a maximum of 1
minute.
NOTE
The " blocking period " mechanism doesn't apply to Azure SQL Server by default. This behavior can be changed by
modifying the PoolBlockingPeriod property in ConnectionString except for .NET Standard.
Pool creation and assignment
When a connection is first opened, a connection pool is created based on an exact matching algorithm that
associates the pool with the connection string in the connection. Each connection pool is associated with a
distinct connection string. When a new connection is opened, if the connection string is not an exact match to an
existing pool, a new pool is created.
NOTE
Connections are pooled per process, per application domain, per connection string and when integrated security is used,
per Windows identity. Connection strings must also be an exact match; keywords supplied in a different order for the
same connection will be pooled separately.
NOTE
If MinPoolSize is either not specified in the connection string or is specified as zero, the connections in the pool will be
closed after a period of inactivity. However, if the specified MinPoolSize is greater than zero, the connection pool is not
destroyed until the AppDomain is unloaded and the process ends. Maintenance of inactive or empty pools involves
minimal system overhead.
NOTE
The pool is automatically cleared when a fatal error occurs, such as a failover.
In the following C# example, three new SqlConnection objects are created, but only two connection pools are
required to manage them. Note that the first and second connection strings differ by the value assigned for
Initial Catalog .
Add connections
A connection pool is created for each unique connection string. When a pool is created, multiple connection
objects are created and added to the pool so that the minimum pool size requirement is satisfied. Connections
are added to the pool as needed, up to the maximum pool size specified (100 is the default ). Connections are
released back into the pool when they are closed or disposed.
When a SqlConnection object is requested, it is obtained from the pool if a usable connection is available. To be
usable, a connection must be unused, have a matching transaction context or be unassociated with any
transaction context, and have a valid link to the server.
The connection pooler satisfies requests for connections by reallocating connections as they are released back
into the pool. If the maximum pool size has been reached and no usable connection is available, the request is
queued. The pooler then tries to reclaim any connections until the time-out is reached (the default is 15
seconds ). If the pooler cannot satisfy the request before the connection times out, an exception is thrown.
Cau t i on
We strongly recommend that you always close the connection when you are finished using it so that the
connection will be returned to the pool. You can do this using either the Close or Dispose methods of the
Connection object, or by opening all connections inside a using statement in C#, or a Using statement in
Visual Basic. Connections that are not explicitly closed might not be added or returned to the pool. For more
information, see using Statement or How to: Dispose of a System Resource for Visual Basic.
NOTE
Do not call Close or Dispose on a Connection , a DataReader , or any other managed object in the Finalize
method of your class. In a finalizer, only release unmanaged resources that your class owns directly. If your class does not
own any unmanaged resources, do not include a Finalize method in your class definition. For more information, see
Garbage Collection.
For more info about the events associated with opening and closing connections, see Audit Login Event Class
and Audit Logout Event Class in the SQL Server documentation.
Remove connections
The connection pooler removes a connection from the pool after it has been idle for approximately 4-8 minutes,
or if the pooler detects that the connection with the server has been severed.
NOTE
A severed connection can be detected only after attempting to communicate with the server. If a connection is found that
is no longer connected to the server, it is marked as invalid. Invalid connections are removed from the connection pool
only when they are closed or reclaimed.
If a connection exists to a server that has disappeared, this connection can be drawn from the pool even if the
connection pooler has not detected the severed connection and marked it as invalid. This is the case because the
overhead of checking that the connection is still valid would eliminate the benefits of having a pooler by causing
another round trip to the server to occur. When this occurs, the first attempt to use the connection will detect
that the connection has been severed, and an exception is thrown.
NOTE
If there are connections being used at the time of the call, they are marked appropriately. When they are closed, they are
discarded instead of being returned to the pool.
Transaction support
Connections are drawn from the pool and assigned based on transaction context. Unless Enlist=false is
specified in the connection string, the connection pool makes sure that the connection is enlisted in the Current
context. When a connection is closed and returned to the pool with an enlisted System.Transactions transaction,
it is set aside in such a way that the next request for that connection pool with the same System.Transactions
transaction will return the same connection if it is available. If such a request is issued, and there are no pooled
connections available, a connection is drawn from the non-transacted part of the pool and enlisted. If no
connections are available in either area of the pool, a new connection is created and enlisted.
When a connection is closed, it is released back into the pool and into the appropriate subdivision based on its
transaction context. Therefore, you can close the connection without generating an error, even though a
distributed transaction is still pending. This allows you to commit or abort the distributed transaction later.
Pool fragmentation
Pool fragmentation is a common problem in many Web applications where the application can create a large
number of pools that are not freed until the process exits. This leaves a large number of connections open and
consuming memory, which results in poor performance.
Pool fragmentation due to integrated security
Connections are pooled according to the connection string plus the user identity. Therefore, if you use Basic
authentication or Windows Authentication on the Web site and an integrated security login, you get one pool
per user. Although this improves the performance of subsequent database requests for a single user, that user
cannot take advantage of connections made by other users. It also results in at least one connection per user to
the database server. This is a side effect of a particular Web application architecture that developers must weigh
against security and auditing requirements.
Pool fragmentation due to many databases
Many Internet service providers host several Web sites on a single server. They may use a single database to
confirm a Forms authentication login and then open a connection to a specific database for that user or group of
users. The connection to the authentication database is pooled and used by everyone. However, there is a
separate pool of connections to each database, which increase the number of connections to the server.
This is also a side-effect of the application design. There is a relatively simple way to avoid this side effect
without compromising security when you connect to SQL Server. Instead of connecting to a separate database
for each user or group, connect to the same database on the server and then execute the Transact-SQL USE
statement to change to the desired database.
The following code fragment demonstrates creating an initial connection to the master database and then
switching to the desired database specified in the databaseName string variable.
// Assume that connectionString connects to master.
using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand())
{
connection.Open();
command.Connection = connection;
command.Text = "USE DatabaseName";
command.ExecuteNonQuery();
}
See also
Connection pooling
SQL Server and ADO.NET - Diagnostic counters in SqlClient
Microsoft ADO.NET for SQL Server
Commands and parameters
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
After establishing a connection to a data source, you can execute commands and return results from the data
source using a DbCommand object. You can create a command using one of the command constructors for the
Microsoft SqlClient Data Provider for SQL Server. Constructors can take optional arguments, such as an SQL
statement to execute at the data source, a DbConnection object, or a DbTransaction object.
You can also configure those objects as properties of the command. You can also create a command for a
particular connection using the CreateCommand method of a DbConnection object. The SQL statement being
executed by the command can be configured using the CommandText property. The Microsoft SqlClient Data
Provider for SQL Server has the SqlCommand object.
In this section
Executing a Command
Describes the ADO.NET Command object and how to use it to execute queries and commands against a data
source.
Configuring parameters
Describes working with Command parameters, including direction, data types, and parameter syntax.
Generating commands with CommandBuilders
Describes how to use command builders to automatically generate INSERT, UPDATE, and DELETE commands for
a DataAdapter that has a single-table SELECT command.
Obtaining a single value from a database
Describes how to use the ExecuteScalar method of a Command object to return a single value from a database
query.
Using commands to modify data
Describes how to use the Microsoft SqlClient data provider for SQL Server to execute stored procedures or data
definition language (DDL) statements.
See also
DataAdapters and DataReaders
Connecting to a data source
Microsoft ADO.NET for SQL Server
Executing a command
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
The Microsoft SqlClient Data Provider for SQL Server has SqlCommand object that inherits from DbCommand.
This object exposes methods for executing commands based on the type of command and desired return value,
as described in the following table.
Each strongly typed command object also supports a CommandType enumeration that specifies how a
command string is interpreted, as described in the following table.
C O M M A N DT Y P E DESC RIP T IO N
StoredProcedure The name of the stored procedure. You can use the
Parameters property of a command to access input and
output parameters and return values, regardless of which
Execute method is called.
IMPORTANT
When using ExecuteReader , return values and output parameters will not be accessible until the DataReader is closed.
Example
The following code example demonstrates how to create a SqlCommand object to execute a stored procedure
by setting its properties. A SqlParameter object is used to specify the input parameter to the stored procedure.
The command is executed using the ExecuteReader method, and the output from the SqlDataReader is displayed
in the console window.
static void GetSalesByCategory(string connectionString,
string categoryName)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
// Create the command and set its properties.
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = "SalesByCategory";
command.CommandType = CommandType.StoredProcedure;
Troubleshooting commands
The Microsoft SqlClient Data Provider for SQL Server adds diagnostic counters to enable you to detect
intermittent problems related to failed command executions. For more information, see Diagnostic counters in
SqlClient.
See also
Commands and parameters
DataAdapters and DataReaders
Microsoft ADO.NET for SQL Server
Configuring parameters
4/27/2022 • 6 minutes to read • Edit Online
Download ADO.NET
Command objects use parameters to pass values to SQL statements or stored procedures, providing type
checking and validation. Unlike command text, parameter input is treated as a literal value, not as executable
code. This behavior helps guard against "SQL injection" attacks, in which an attacker inserts a command that
compromises security on the server into an SQL statement.
Parameterized commands can also improve query execution performance, because they help the database
server accurately match the incoming command with a proper cached query plan. For more information, see
Execution Plan Caching and Reuse and Parameters and Execution Plan Reuse. In addition to the security and
performance benefits, parameterized commands provide a convenient method for organizing values passed to a
data source.
A DbParameter object can be created by using its constructor, or by adding it to the DbParameterCollection by
calling the Add method of the DbParameterCollection collection. The Add method will take as input either
constructor arguments or an existing parameter object, depending on the data provider.
M EM B ER N A M E DESC RIP T IO N
. N ET T Y P E DBT Y P E SQ L DBT Y P E
AnsiString VarChar
AnsiStringFixedLength Char
Currency Money
StringFixedLength NChar
user-defined type (an object with SqlClient always returns an Object SqlDbType.Udt if
SqlUserDefinedAggregateAttribute SqlUserDefinedTypeAttribute is
present, otherwise Variant
NOTE
Conversions from decimal to other types are narrowing conversions that round the decimal value to the nearest integer
value toward zero. If the result of the conversion isn't representable in the destination type, an OverflowException is
thrown.
NOTE
When you send a null parameter value to the server, you must specify DBNull, not null ( Nothing in Visual Basic). The
null value in the system is an empty object that has no value. DBNull is used to represent null values.
NOTE
Deriving parameter information incurs a performance penalty because it requires an additional round trip to the data
source to retrieve the information. If parameter information is known at design time, you can improve the performance of
your application by setting the parameters explicitly.
NOTE
Parameterized statements are executed on the server by using sp_executesql, which allows for query plan reuse. Local
cursors or variables in the sp_executesql batch are not visible to the batch that calls sp_executesql . Changes in
database context last only to the end of the sp_executesql statement. For more information, see sp_executesql
(Transact-SQL).
When using parameters with a SqlCommand to execute a SQL Server stored procedure, the names of the
parameters added to the Parameters collection must match the names of the parameter markers in the stored
procedure. The Microsoft SqlClient Data Provider for SQL Server doesn't support the question mark (?)
placeholder for passing parameters to an SQL statement or a stored procedure. It treats parameters in the
stored procedure as named parameters and searches for matching parameter markers. For example, the
CustOrderHist stored procedure is defined by using a parameter named @CustomerID . When your code
executes the stored procedure, it must also use a parameter named @CustomerID .
Example
This example demonstrates how to call a SQL Server stored procedure in the Northwind sample database. The
name of the stored procedure is dbo.SalesByCategory and it has an input parameter named @CategoryName with
a data type of nvarchar(15) . The code creates a new SqlConnection inside a using block so that the connection
is disposed when the procedure ends. The SqlCommand and SqlParameter objects are created, and their
properties set. A SqlDataReader executes the SqlCommand and returns the result set from the stored procedure,
displaying the output in the console window.
NOTE
Instead of creating SqlCommand and SqlParameter objects and then setting properties in separate statements, you can
instead elect to use one of the overloaded constructors to set multiple properties in a single statement.
See also
Commands and parameters
DataAdapters and DataReaders
Data type mappings in ADO.NET
Microsoft ADO.NET for SQL Server
Generating commands with CommandBuilders
4/27/2022 • 6 minutes to read • Edit Online
Download ADO.NET
When the SelectCommand property of the DbDataAdapter object is dynamically specified at run time, such as
through a query tool that takes a textual command from the user, you may not be able to specify the
appropriate InsertCommand , UpdateCommand , or DeleteCommand at design time. If your DataTable maps to or is
generated from a single database table, you can take advantage of the DbCommandBuilder object to
automatically generate the DeleteCommand , InsertCommand , and UpdateCommand of the DbDataAdapter.
NOTE
In Microsoft SqlClient Data Provider for SQL Server, the SqlDataAdapter class is derived from the DbDataAdapter class,
and the SqlCommandBuilder class is derived from the DbCommandBuilder class.
As a minimum requirement, you must set the SelectCommand property in order for automatic command
generation to work. The table schema retrieved by the SelectCommand property determines the syntax of the
automatically generated INSERT, UPDATE, and DELETE statements.
The DbCommandBuilder must execute the SelectCommand in order to return the metadata necessary to
construct the INSERT, UPDATE, and DELETE SQL commands. As a result, an extra trip to the data source is
necessary, and this can hinder performance. To achieve optimal performance, specify your commands explicitly
rather than using the DbCommandBuilder.
NOTE
The SelectCommand must also return at least one primary key or unique column. If none is present, an
InvalidOperation exception is generated, and the commands are not generated.
When associated with a DataAdapter , the DbCommandBuilder automatically generates the InsertCommand ,
UpdateCommand , and DeleteCommand properties of the DataAdapter if they are null references. If a Command
already exists for a property, the existing Command is used.
Database views that are created by joining two or more tables together are not considered a single database
table. In this instance, you cannot use the DbCommandBuilder to automatically generate commands; you must
specify your commands explicitly. For information about explicitly setting commands to resolve updates to a
DataSet back to the data source, see Update data sources with DataAdapters.
You might want to map output parameters back to the updated row of a DataSet . One common task would be
retrieving the value of an automatically generated identity field or time stamp from the data source. The
DbCommandBuilder will not map output parameters to columns in an updated row by default. In this instance,
you must specify your command explicitly.
For an example of mapping an automatically generated identity field back to a column of an inserted row, see Re
trieve identity or autonumber values.
C OMMAND RUL E
InsertCommand Inserts a row at the data source for all rows in the table with
a RowState of Added. Inserts values for all columns that are
updateable (but not columns such as identities, expressions,
or timestamps).
UpdateCommand Updates rows at the data source for all rows in the table
with a RowState of Modified. Updates the values of all
columns except for columns that are not updateable, such as
identities or expressions. Updates all rows where the column
values at the data source match the primary key column
values of the row, and where the remaining columns at the
data source match the original values of the row. For more
information, see "Optimistic Concurrency Model for Updates
and Deletes," later in this topic.
DeleteCommand Deletes rows at the data source for all rows in the table with
a RowState of Deleted. Deletes all rows where the column
values match the primary key column values of the row, and
where the remaining columns at the data source match the
original values of the row. For more information, see
Optimistic Concurrency Model for Updates and Deletes, later
in this topic.
NOTE
Where an automatically generated update attempts to update a row that has been deleted or that does not contain the
original values found in the DataSet, the command does not affect any records, and a DBConcurrencyException is thrown.
If you want the UPDATE or DELETE to complete regardless of original values, you must explicitly set the
UpdateCommand for the DataAdapter and not rely on automatic command generation.
The following example recreates the table in the dataset. The RefreshSchema method is called to refresh the
automatically generated commands with this new column information.
dataSet.Tables.Remove(dataSet.Tables[tableName]);
adapter.Fill(dataSet, tableName);
See also
Commands and parameters
Executing a command
Microsoft ADO.NET for SQL Server
Obtaining a single value from a database
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
You may need to return database information that is simply a single value rather than in the form of a table or
data stream. For example, you may want to return the result of an aggregate function such as COUNT(*),
SUM(Price), or AVG(Quantity). The Command object provides the capability to return single values using the
ExecuteScalar method. The ExecuteScalar method returns, as a scalar value, the value of the first column of
the first row of the result set.
Example
The following code example inserts a new value in the database using a SqlCommand. The ExecuteScalar
method is used to return the identity column value for the inserted record.
See also
Commands and parameters
Executing a command
Microsoft ADO.NET for SQL Server
Using commands to modify data
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Using the Microsoft SqlClient Data Provider for SQL Server, you can execute stored procedures or data
definition language statements (for example, CREATE TABLE and ALTER COLUMN) to perform schema
manipulation on a database or catalog. These commands do not return rows as a query would, so the
SqlCommand object provides an ExecuteNonQuery to process them.
In addition to using ExecuteNonQuer y to modify schema, you can also use this method to process SQL
statements that modify data but that do not return rows, such as INSERT, UPDATE, and DELETE.
Although rows are not returned by the ExecuteNonQuer y method, input and output parameters and return
values can be passed and returned via the Parameters collection of the Command object.
In this section
Updating data in a data source
Describes how to execute commands or stored procedures that modify data in a database.
Performing catalog operations
Describes how to execute commands that modify database schema.
See also
Retrieving and modifying data in ADO.NET
Commands and parameters
Microsoft ADO.NET for SQL Server
Updating data in a data source
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
SQL statements that modify data (such as INSERT, UPDATE, or DELETE) do not return rows. Similarly, many
stored procedures perform an action but do not return rows. To execute commands that do not return rows,
create a Command object with the appropriate SQL command and a Connection , including any required
Parameters . Execute the command with the ExecuteNonQuery method of the SqlCommand object.
NOTE
The ExecuteNonQuer y method returns an integer that represents the number of rows affected by the statement or
stored procedure that was executed. If multiple statements are executed, the value returned is the sum of the records
affected by all of the statements executed.
Example
The following code example executes an INSERT statement to insert a record into a database using
ExecuteNonQuer y .
The following code example executes the stored procedure created by the sample code in Performing Catalog
Operations. No rows are returned by the stored procedure, so the ExecuteNonQuer y method is used, but the
stored procedure does receive an input parameter and returns an output parameter and a return value.
Download ADO.NET
To execute a command to modify a database or catalog, such as the CREATE TABLE or CREATE PROCEDURE
statement, create a Command object using the appropriate SQL statements and a Connection object. Execute
the command with the ExecuteNonQuery method of the SqlCommand object.
Example
The following code example creates a stored procedure in a Microsoft SQL Server database.
See also
Using commands to modify data
Commands and parameters
Microsoft ADO.NET for SQL Server
DataAdapters and DataReaders
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
You can use the Microsoft SqlClient Data Provider for SQL Server DataReader to retrieve a read-only, forward-
only stream of data from a database. Results are returned as the query executes, and are stored in the network
buffer on the client until you request them using the Read method of the DataReader . Using the DataReader
can increase application performance both by retrieving data as soon as it is available, and (by default) storing
only one row at a time in memory, reducing system overhead.
A DataAdapter is used to retrieve data from a data source and populate tables within a DataSet. The
DataAdapter also resolves changes made to the DataSet back to the data source. The DataAdapter uses the
Connection object of the Microsoft SqlClient Data Provider for SQL Server to connect to a data source, and it
uses Command objects to retrieve data from and resolve changes to the data source.
.NET has a DbDataReader and a DbDataAdapter object: the Microsoft SqlClient Data Provider for SQL Server
includes a SqlDataReader and a SqlDataAdapter object.
In this section
Retrieve data by a DataReader
Describes the ADO.NET DataReader object and how to use it to return a stream of results from a data source.
Populate a DataSet from a DataAdapter
Describes how to fill a DataSet with tables, columns, and rows by using a DataAdapter .
DataAdapter parameters
Describes how to use parameters with the command properties of a DataAdapter including how to map the
contents of a column in a DataSet to a command parameter.
Add existing constraints to a DataSet
Describes how to add existing constraints to a DataSet .
DataAdapter, DataTable, and DataColumn mappings
Describes how to set up DataTableMappings and ColumnMappings for a DataAdapter .
Paging through a query result
Provides an example of viewing the results of a query as pages of data.
Update data sources with DataAdapters
Describes how to use a DataAdapter to resolve changes in a DataSet back to the database.
Handle DataAdapter events
Describes DataAdapter events and how to use them.
Batch operations using DataAdapters
Describes enhancing application performance by reducing the number of round trips to SQL Server when
applying updates from the DataSet .
See also
Connecting to a data source
Commands and parameters
Transactions and concurrency
Microsoft ADO.NET for SQL Server
Retrieve data by a DataReader
4/27/2022 • 3 minutes to read • Edit Online
Download ADO.NET
To retrieve data using a DataReader , create an instance of the Command object, and then create a
DataReader by calling Command.ExecuteReader to retrieve rows from a data source. The DataReader
provides an unbuffered stream of data that allows procedural logic to efficiently process results from a data
source sequentially.
NOTE
The DataReader is a good choice when you're retrieving large amounts of data because the data is not cached in
memory.
The following example illustrates using a DataReader , where reader represents a valid DataReader and
command represents a valid Command object.
reader = command.ExecuteReader();
Use the DataReader.Read method to obtain a row from the query results. You can access each column of the
returned row by passing the name or ordinal number of the column to the DataReader . However, for best
performance, the DataReader provides a series of methods that allow you to access column values in their
native data types (GetDateTime , GetDouble , GetGuid , GetInt32 , and so on). For a list of typed accessor
methods for data provider-specific DataReaders , see SqlDataReader. Using the typed accessor methods when
you know the underlying data type reduces the amount of type conversion required when retrieving the column
value.
The following example iterates through a DataReader object and returns two columns from each row.
static void HasRows(SqlConnection connection)
{
using (connection)
{
SqlCommand command = new SqlCommand(
"SELECT CategoryID, CategoryName FROM Categories;",
connection);
connection.Open();
NOTE
If your Command contains output parameters or return values, those values are not available until the DataReader is
closed.
IMPORTANT
While a DataReader is open, the Connection is in use exclusively by that DataReader . You cannot execute any
commands for the Connection , including creating another DataReader , until the original DataReader is closed.
NOTE
Do not call Close or Dispose on a Connection , a DataReader , or any other managed object in the Finalize method of
your class. In a finalizer, only release unmanaged resources that your class owns directly. If your class does not own any
unmanaged resources, do not include a Finalize method in your class definition. For more information, see Garbage
Collection.
// Always call the Close method when you have finished using the DataReader object.
reader.Close();
}
}
See also
DataAdapters and DataReaders
Commands and parameters
Retrieving database schema information
Microsoft ADO.NET for SQL Server
Populate a DataSet from a DataAdapter
4/27/2022 • 6 minutes to read • Edit Online
Download ADO.NET
The ADO.NET DataSet is a memory-resident representation of data that provides a consistent relational
programming model independent of the data source. The DataSet represents a complete set of data that
includes tables, constraints, and relationships among the tables. Because the DataSet is independent of the data
source, a DataSet can include data local to the application, and data from multiple data sources. Interaction with
existing data sources is controlled through the DataAdapter .
The SelectCommand property of the DataAdapter is a Command object that retrieves data from the data source.
The InsertCommand , UpdateCommand , and DeleteCommand properties of the DataAdapter are Command objects that
manage updates to the data in the data source according to modifications made to the data in the DataSet .
These properties are covered in more detail in Update Data Sources with DataAdapters.
The Fill method of the DataAdapter is used to populate a DataSet with the results of the SelectCommand of
the DataAdapter . Fill takes as its arguments a DataSet to be populated, and a DataTable object, or the name
of the DataTable to be filled with the rows returned from the SelectCommand .
NOTE
Using the DataAdapter to retrieve all of a table takes time, especially if there are many rows in the table. This is because
accessing the database, locating and processing the data, and then transferring the data to the client is time-consuming.
Pulling all of the table to the client also locks all of the rows on the server. To improve performance, you can use the
WHERE clause to greatly reduce the number of rows returned to the client. You can also reduce the amount of data
returned to the client by only explicitly listing required columns in the SELECT statement. Another good workaround is
to retrieve the rows in batches (such as several hundred rows at a time) and only retrieve the next batch when the client is
finished with the current batch.
The Fill method uses the DataReader object implicitly to return the column names and types that are used to
create the tables in the DataSet , and the data to populate the rows of the tables in the DataSet . Tables and
columns are only created if they do not already exist; otherwise Fill uses the existing DataSet schema.
Column types are created as .NET Framework types according to the tables in Data Type Mappings in ADO.NET.
Primary keys are not created unless they exist in the data source and DataAdapter . MissingSchemaAction is set to
MissingSchemaAction . AddWithKey . If Fill finds that a primary key exists for a table, it will overwrite data in the
DataSet with data from the data source for rows where the primary key column values match those of the row
returned from the data source. If no primary key is found, the data is appended to the tables in the DataSet .
Fill uses any mappings that may exist when you populate the DataSet (see DataAdapter, DataTable, and
DataColumn Mappings).
NOTE
If the SelectCommand returns the results of an OUTER JOIN, the DataAdapter does not set a PrimaryKey value for
the resulting DataTable . You must define the PrimaryKey yourself to make sure that duplicate rows are resolved
correctly.
The following code example creates an instance of a SqlDataAdapter that uses a SqlConnection to the Microsoft
SQL Server Northwind database and populates a DataTable in a DataSet with the list of customers. The SQL
statement and SqlConnection arguments passed to the SqlDataAdapter constructor are used to create the
SelectCommand property of the SqlDataAdapter.
Example
// Assumes that connection is a valid SqlConnection object.
string queryString =
"SELECT CustomerID, CompanyName FROM dbo.Customers";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);
NOTE
The code shown in this example does not explicitly open and close the Connection . The Fill method implicitly opens
the Connection that the DataAdapter is using if it finds that the connection is not already open. If Fill opened the
connection, it also closes the connection when Fill is finished. This can simplify your code when you deal with a single
operation such as a Fill or an Update . However, if you are performing multiple operations that require an open
connection, you can improve the performance of your application by explicitly calling the Open method of the
Connection , performing the operations against the data source, and then calling the Close method of the
Connection . You should try to keep connections to the data source open as briefly as possible to free resources for use
by other client applications.
custAdapter.Fill(customerOrders, "Customers");
ordAdapter.Fill(customerOrders, "Orders");
See also
DataAdapters and DataReaders
Data type mappings in ADO.NET
Multiple Active Result Sets (MARS)
Microsoft ADO.NET for SQL Server
DataAdapter parameters
4/27/2022 • 4 minutes to read • Edit Online
Download ADO.NET
The DbDataAdapter has four properties that are used to retrieve data from and update data to the data source:
the SelectCommand property returns data from the data source; and the InsertCommand , UpdateCommand,
and DeleteCommand properties are used to manage changes at the data source.
NOTE
The SelectCommand property must be set before you call the Fill method of the DataAdapter . The InsertCommand
, UpdateCommand , or DeleteCommand properties must be set before the Update method of the DataAdapter is called,
depending on what changes were made to the data in the DataTable. For example, if rows have been added, the
InsertCommand must be set before you call Update . When Update is processing an inserted, updated, or deleted row,
the DataAdapter uses the respective Command property to process the action. Current information about the modified
row is passed to the Command object through the Parameters collection.
When you update a row at the data source, you call the UPDATE statement, which uses a unique identifier to
identify the row in the table to be updated. The unique identifier is typically the value of a primary key field. The
UPDATE statement uses parameters that contain both the unique identifier and the columns and values to be
updated, as shown in the following Transact-SQL statement.
NOTE
The syntax for parameter placeholders depends on the data source. This example shows placeholders for a SQL Server
data source.
In this example, the CompanyName field is updated with the value of the @CompanyName parameter for the row
where CustomerID equals the value of the @CustomerID parameter. The parameters retrieve information from
the modified row using the SourceColumn property of the SqlParameter object. The following are the
parameters for the previous sample UPDATE statement. The code assumes that the variable adapter represents
a valid SqlDataAdapter object.
The Add method of the Parameters collection takes the name of the parameter, the data type, the size (if
applicable to the type), and the name of the SourceColumn from the DataTable . Notice that the SourceVersion
of the @CustomerID parameter is set to Original . This guarantees that the existing row in the data source is
updated if the value of the identifying column or columns has been changed in the modified DataRow. In that
case, the Original row value would match the current value at the data source, and the Current row value
would contain the updated value. The SourceVersion for the @CompanyName parameter is not set and uses the
default, Current row value.
NOTE
For both the Fill operations of the DataAdapter and the Get methods of the DataReader , the .NET type is
inferred from the type returned from the Microsoft SqlClient Data Provider for SQL Server. The inferred .NET types and
accessor methods for Microsoft SQL Server data types are described in Data Type Mappings in ADO.NET.
Parameter.SourceColumn, Parameter.SourceVersion
The SourceColumn and SourceVersion may be passed as arguments to the Parameter constructor, or set as
properties of an existing Parameter . The SourceColumn is the name of the DataColumn from the DataRow where
the value of the Parameter will be retrieved. The SourceVersion specifies the DataRow version that the
DataAdapter uses to retrieve the value.
The following table shows the DataRowVersion enumeration values available for use with SourceVersion .
Current The parameter uses the current value of the column. This is
the default.
The SqlClient code example in the next section defines a parameter for an UpdateCommand in which the
CustomerID column is used as a SourceColumn for two parameters: @CustomerID ( SET CustomerID = @CustomerID
), and @OldCustomerID ( WHERE CustomerID = @OldCustomerID ). The @CustomerID parameter is used to update the
CustomerID column to the current value in the DataRow . As a result, the CustomerID SourceColumn with a
SourceVersion of Current is used. The @OldCustomerID parameter is used to identify the current row in the data
source. Because the matching column value is found in the Original version of the row, the same SourceColumn
( CustomerID ) with a SourceVersion of Original is used.
adapter.UpdateCommand.Parameters.Add("@CustomerID",
SqlDbType.Char, 5, "CustomerID");
adapter.UpdateCommand.Parameters.Add("@CompanyName",
SqlDbType.VarChar, 40, "CompanyName");
adapter.UpdateCommand.Parameters.Add("@oldCustomerID",
SqlDbType.Char, 5, "CustomerID").SourceVersion =
DataRowVersion.Original;
adapter.DeleteCommand.Parameters.Add("@CustomerID",
SqlDbType.Char, 5, "CustomerID").SourceVersion =
DataRowVersion.Original;
return adapter;
}
See also
DataAdapters and DataReaders
Commands and parameters
Update data sources with DataAdapters
Modify data with stored procedures
Data type mappings in ADO.NET
Microsoft ADO.NET for SQL Server
Add existing constraints to a DataSet
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
The Fill method of the SqlDataAdapter fills a DataSet only with table columns and rows from a data source;
though constraints are commonly set by the data source, the Fill method does not add this schema information
to the DataSet by default.
To populate a DataSet with existing primary key constraint information from a data source, you can either call
the FillSchema method of the DataAdapter , or set the MissingSchemaAction property of the DataAdapter to
AddWithKey before calling Fill . This will ensure that primary key constraints in the DataSet reflect those at the
data source.
NOTE
Foreign key constraint information is not included and must be created explicitly.
Adding schema information to a DataSet before filling it with data ensures that primary key constraints are
included with the DataTable objects in the DataSet . As a result, when additional calls to fill the DataSet are
made, the primary key column information is used to match new rows from the data source with current rows
in each DataTable , and current data in the tables is overwritten with data from the data source. Without the
schema information, the new rows from the data source are appended to the DataSet , resulting in duplicate
rows.
NOTE
If a column in a data source is identified as auto-incrementing, the FillSchema method, or the Fill method with a
MissingSchemaAction of AddWithKey , creates a DataColumn with an AutoIncrement property set to true .
However, you will need to set the AutoIncrementStep and AutoIncrementSeed values yourself.
NOTE
Using FillSchema or setting the MissingSchemaAction to AddWithKey requires extra processing at the data source
to determine primary key column information. This additional processing can hinder performance. If you know the
primary key information at design time, we recommend that you explicitly specify the primary key column or columns in
order to achieve optimal performance.
The following code example shows how to add schema information to a DataSet using FillSchema:
custAdapter.Fill(customerOrders, "Customers");
ordAdapter.Fill(customerOrders, "Orders");
See also
DataAdapters and DataReaders
Retrieving and modifying data in ADO.NET
Microsoft ADO.NET for SQL Server
DataAdapter, DataTable, and DataColumn
mappings
4/27/2022 • 3 minutes to read • Edit Online
Download ADO.NET
A SqlDataAdapter contains a collection of zero or more DataTableMapping objects in its TableMappings
property. A DataTableMapping provides a main mapping between the data returned from a query against a
data source, and a DataTable. The DataTableMapping name can be passed in place of the DataTable name to
the Fill method of the DataAdapter . The following example creates a DataTableMapping named
AuthorsMapping for the Authors table.
workAdapter.TableMappings.Add("AuthorsMapping", "Authors");
A DataTableMapping enables you to use column names in a DataTable that are different from those in the
database. The DataAdapter uses the mapping to match the columns when the table is updated.
NOTE
If you do not specify a TableName or a DataTableMapping name when calling the Fill or Update method of the
DataAdapter , the DataAdapter looks for a DataTableMapping named "Table". The TableName of the DataTable is
"Table" if that DataTableMapping does not exist. You can specify a default DataTableMapping by creating a
DataTableMapping with the name of "Table".
The following code example creates a DataTableMapping (from the System.Data.Common namespace) and
makes it the default mapping for the specified DataAdapter by naming it "Table". The example then maps the
columns from the first table in the query result (the Customers table of the Nor thwind database) to a set of
more user-friendly names in the Nor thwind Customers table in the DataSet. For columns that are not
mapped, the name of the column from the data source is used.
DataTableMapping mapping =
custAdapter.TableMappings.Add("Table", "NorthwindCustomers");
mapping.ColumnMappings.Add("CompanyName", "Company");
mapping.ColumnMappings.Add("ContactName", "Contact");
mapping.ColumnMappings.Add("PostalCode", "ZIPCode");
custAdapter.Fill(custDataSet);
In more advanced situations, you may decide that you want the same DataAdapter to support loading different
tables with different mappings. To do this, add additional DataTableMapping objects.
When the Fill method is passed an instance of a DataSet and a DataTableMapping name, if a mapping with
that name exists it is used; otherwise, a DataTable with that name is used.
The following examples create a DataTableMapping with a name of Customers and a DataTable name of
BizTalkSchema . The example then maps the rows returned by the SELECT statement to the BizTalkSchema
DataTable .
custAdapter.Fill(custDataSet);
NOTE
If a source column name is not supplied for a column mapping, default names will be automatically generated. The
column mapping is given an incremental default name of SourceColumn N, starting with SourceColumn1 if no source
column is supplied for a column mapping.
NOTE
If a source table name is not supplied for a table mapping, default names will be automatically generated. The table
mapping is given an incremental default name of SourceTable N, starting with SourceTable1 if no source table name is
supplied for a table mapping.
NOTE
We recommend that you avoid the naming convention of SourceColumn N for a column mapping, or SourceTable N
for a table mapping, because the name you supply may conflict with an existing default column mapping name in the
ColumnMappingCollection or table mapping name in the DataTableMappingCollection . If the supplied name
already exists, an exception will be thrown.
adapter.Fill(customersDataSet, "Customers");
Two tables are created in the DataSet : Customers and Customers1 . You can use table mappings to ensure
that the second table is named Orders instead of Customers1 . To do this, map the source table of
Customers1 to the DataSet table Orders , as shown in the following example.
// Assumes that connection is a valid SqlConnection object.
string queryString =
"SELECT * FROM dbo.Customers; SELECT * FROM dbo.Orders;";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);
adapter.TableMappings.Add("Customers1", "Orders");
adapter.Fill(customersDataSet, "Customers");
See also
DataAdapters and DataReaders
Retrieving and modifying data in ADO.NET
Microsoft ADO.NET for SQL Server
Paging through a query result
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Paging through a query result is the process of returning the results of a query in smaller subsets of data, or
pages. This is a common practice for displaying results to a user in small, easy-to-manage chunks.
The SqlDataAdapter provides a facility for returning only a page of data, through overloads of the Fill method.
However, this might not be the best choice for paging through large query results because, although the
DataAdapter fills the target DataTable or DataSet with only the requested records, the resources to return the
entire query are still used.
To return a page of data from a data source without using the resources to return the entire query, specify
additional criteria for your query that reduce the rows returned to only those required.
To use the Fill method to return a page of data, specify a star tRecord parameter, for the first record in the page
of data, and a maxRecords parameter, for the number of records in the page of data.
Example
The following code example shows how to use the Fill method to return the first page of a query result where
the page size is five records.
int currentIndex = 0;
int pageSize = 5;
In the previous example, the DataSet is only filled with five records, but the entire Orders table is returned. To
fill the DataSet with those same five records, but only return five records, use the TOP and WHERE clauses in
your SQL statement, as in the following code example.
int pageSize = 5;
string lastRecord =
dataSet.Tables["Orders"].Rows[pageSize - 1]["OrderID"].ToString();
To return the next page of records using the overload of the Fill method that takes the star tRecord and
maxRecords parameters, increment the current record index by the page size and fill the table.
NOTE
Remember that the database server returns the entire query results even though only one page of records is added to
the DataSet .
In the following code example, the table rows are cleared before they are filled with the next page of data. You
might want to preserve a certain number of returned rows in a local cache to reduce trips to the database
server.
currentIndex += pageSize;
To return the next page of records without having the database server return the entire query, specify restrictive
criteria to the SELECT statement. Because the preceding example preserved the last record returned, you can use
it in the WHERE clause to specify a starting point for the query, as shown in the following code example.
dataSet.Tables["Orders"].Rows.Clear();
adapter.Fill(dataSet, "Orders");
See also
DataAdapters and DataReaders
Microsoft ADO.NET for SQL Server
Update data sources with DataAdapters
4/27/2022 • 13 minutes to read • Edit Online
Download ADO.NET
The Update method of the DataAdapter is called to resolve changes from a DataSet back to the data source. The
Update method, like the Fill method, takes as arguments an instance of a DataSet , and an optional DataTable
object or DataTable name. The DataSet instance is the DataSet that contains the changes that have been
made, and the DataTable identifies the table from which to retrieve the changes. If no DataTable is specified,
the first DataTable in the DataSet is used.
When you call the Update method, the DataAdapter analyzes the changes that have been made and executes
the appropriate command (INSERT, UPDATE, or DELETE). When the DataAdapter encounters a change to a
DataRow, it uses the InsertCommand, UpdateCommand, or DeleteCommand to process the change.
These properties allow you to maximize the performance of your ADO.NET application by specifying command
syntax at design time and, where possible, through the use of stored procedures. You must explicitly set the
commands before calling Update . If Update is called and the appropriate command does not exist for a
particular update (for example, no DeleteCommand for deleted rows), an exception is thrown.
IMPORTANT
If you are using SQL Server stored procedures to edit or delete data using a DataAdapter , make sure that you do not
use SET NOCOUNT ON in the stored procedure definition. This causes the rows affected count returned to be zero, which
the DataAdapter interprets as a concurrency conflict. In this event, a DBConcurrencyException will be thrown.
Command parameters can be used to specify input and output values for an SQL statement or stored procedure
for each modified row in a DataSet . For more information, see DataAdapter parameters.
NOTE
It is important to understand the difference between deleting a row in a DataTable and removing the row. When you call
the Remove or RemoveAt method, the row is removed immediately. Any corresponding rows in the back end data
source will not be affected if you then pass the DataTable or DataSet to a DataAdapter and call Update . When
you use the Delete method, the row remains in the DataTable and is marked for deletion. If you then pass the
DataTable or DataSet to a DataAdapter and call Update , the corresponding row in the back end data source is
deleted .
If your DataTable maps to or is generated from a single database table, you can take advantage of the
DbCommandBuilder object to automatically generate the DeleteCommand , InsertCommand , and UpdateCommand
objects for the DataAdapter . For more information, see Generating commands with CommandBuilders.
Both Both the output parameters and the first row of a returned
result set may be mapped to the changed row in the
DataSet .
FirstReturnedRecord Only the data in the first row of a returned result set may be
mapped to the changed row in the DataSet .
The Update method resolves your changes back to the data source; however other clients may have modified
data at the data source since the last time you filled the DataSet . To refresh your DataSet with current data, use
the DataAdapter and Fill method. New rows will be added to the table, and updated information will be
incorporated into existing rows.
The Fill method determines whether a new row will be added or an existing row will be updated by
examining the primary key values of the rows in the DataSet and the rows returned by the SelectCommand . If
the Fill method encounters a primary key value for a row in the DataSet that matches a primary key value
from a row in the results returned by the SelectCommand , it updates the existing row with the information from
the row returned by the SelectCommand and sets the RowState of the existing row to Unchanged . If a row
returned by the SelectCommand has a primary key value that does not match any of the primary key values of
the rows in the DataSet , the Fill method adds a new row with a RowState of Unchanged .
NOTE
If the SelectCommand returns the results of an OUTER JOIN, the DataAdapter will not set a PrimaryKey value for
the resulting DataTable . You must define the PrimaryKey yourself to ensure that duplicate rows are resolved correctly.
To handle exceptions that may occur when calling the Update method, you can use the RowUpdated event to
respond to row update errors as they occur (see Handle DataAdapter events), or you can set
ContinueUpdateOnError to true before calling Update , and respond to the error information stored in the
RowError property of a particular row when the update is complete.
NOTE
Calling AcceptChanges on the DataSet , DataTable , or DataRow will cause all Original values for a DataRow to
be overwritten with the Current values for the DataRow . If the field values that identify the row as unique have been
modified, after calling AcceptChanges the Original values will no longer match the values in the data source.
AcceptChanges is called automatically for each row during a call to the Update method of a DataAdapter . You can
preserve the original values during a call to the Update method by first setting the AcceptChangesDuringUpdate
property of the DataAdapter to false, or by creating an event handler for the RowUpdated event and setting the Status
to SkipCurrentRow. For more information, see Handle DataAdapter Events.
The following examples demonstrate how to perform updates to modified rows by explicitly setting the
UpdateCommand of a DataAdapter and calling its Update method.
NOTE
The parameter specified in the WHERE clause of the UPDATE statement is set to use the Original value of the
SourceColumn . This is important, because the Current value may have been modified and may not match the value in
the data source. The Original value is the value that was used to populate the DataTable from the data source.
dataAdpater.UpdateCommand.Parameters.Add(
"@CategoryName", SqlDbType.NVarChar, 15, "CategoryName");
dataAdpater.Update(categoryTable);
Example
For example, the following code ensures that the deleted rows of the table are processed first, then the updated
rows, and then the inserted rows.
GO
USE [MySchool]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Course]([CourseID] [nvarchar](10) NOT NULL,
[Year] [smallint] NOT NULL,
[Title] [nvarchar](100) NOT NULL,
[Credits] [int] NOT NULL,
[DepartmentID] [int] NOT NULL,
CONSTRAINT [PK_Course] PRIMARY KEY CLUSTERED
(
[CourseID] ASC,
[Year] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Department]([DepartmentID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[Budget] [money] NOT NULL,
[StartDate] [datetime] NOT NULL,
[Administrator] [int] NULL,
CONSTRAINT [PK_Department] PRIMARY KEY CLUSTERED
(
[DepartmentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C1045', 2012,
N'Calculus', 4, 7)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C1061', 2012,
N'Physics', 4, 1)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C2021', 2012,
N'Composition', 3, 2)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C2042', 2012,
N'Literature', 4, 2)
ALTER TABLE [dbo].[Course] WITH CHECK ADD CONSTRAINT [FK_Course_Department] FOREIGN KEY([DepartmentID])
REFERENCES [dbo].[Department] ([DepartmentID])
REFERENCES [dbo].[Department] ([DepartmentID])
GO
ALTER TABLE [dbo].[Course] CHECK CONSTRAINT [FK_Course_Department]
GO
using System;
using System.Data;
using System.Data.Common;
using Microsoft.Data.SqlClient;
using System.Linq;
using CSDataAdapterOperations.Properties;
class Program
{
static void Main(string[] args)
{
Settings settings = new Settings();
// Copy the data from the database. Get the table Department and Course from the database.
String selectString = @"SELECT [DepartmentID],[Name],[Budget],[StartDate],[Administrator]
FROM [MySchool].[dbo].[Department];
// Use DataTableMapping to map the source tables and the destination tables.
DataTableMapping[] tableMappings = { new DataTableMapping("Table", "Department"), new
DataTableMapping("Table1", "Course") };
CopyData(mySchool, settings.MySchoolConnectionString, selectCommand, tableMappings);
department.RejectChanges();
Console.WriteLine("After use the RejectChanges method in Department table to roll back the
changes:");
ShowDataTable(department);
connection.Open();
adapter.Fill(dataSet);
}
}
}
// Roll back only one column or several columns data of the Course table by call ResetDataTable method.
private static void ResetCourse(DataTable table, String connectionString,
DataColumn[] primaryColumns, DataColumn[] resetColumns)
{
table.PrimaryKey = primaryColumns;
// RejectChanges will roll back all changes made to the table since it was loaded, or the last time
AcceptChanges
// was called. When you copy from the database, you can lose all the data after calling RejectChanges
// The ResetDataTable method rolls back one or more columns of data.
private static void ResetDataTable(DataTable table, String connectionString,
SqlCommand selectCommand)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
selectCommand.Connection = connection;
connection.Open();
connection.Open();
adapter.Fill(table);
}
}
}
connection.Open();
adapter.Update(table);
namespace CSDataAdapterOperations.Properties
{
internal sealed partial class Settings : System.Configuration.ApplicationSettingsBase
{
private static readonly Settings defaultInstance =
((Settings)(System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
((Settings)(System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
[System.Configuration.ApplicationScopedSetting()]
[System.Configuration.DefaultSettingValue("Data Source=(local);Initial Catalog=MySchool;Integrated
Security=True")]
public string MySchoolConnectionString => ((string)(this["MySchoolConnectionString"]));
}
}
See also
DataAdapters and DataReaders
Retrieve identity or autonumber values
Microsoft ADO.NET for SQL Server
Handle DataAdapter events
4/27/2022 • 5 minutes to read • Edit Online
Download ADO.NET
The Microsoft SqlClient data provider for SQL Server SqlDataAdapter exposes three events that you can use to
respond to changes made to data at the data source. The following table shows the DataAdapter events.
You can use the Status property to determine if an error has occurred during the operation and, if desired, to
control the actions against the current and resulting rows. When the event occurs, the Status property equals
either Continue or ErrorsOccurred . The following table shows the values to which you can set the Status
property in order to control later actions during the update.
SkipCurrentRow Ignore the current row and continue the update operation.
STAT US DESC RIP T IO N
Setting the Status property to ErrorsOccurred causes an exception to be thrown. You can control which
exception is thrown by setting the Errors property to the desired exception. Using one of the other values for
Status prevents an exception from being thrown.
You can also use the ContinueUpdateOnError property to handle errors for updated rows. If
DataAdapter.ContinueUpdateOnError is true , when an update to a row results in an exception being thrown, the
text of the exception is placed into the RowError information of the particular row, and processing continues
without throwing an exception. This enables you to respond to errors when the Update is complete, in contrast
to the RowUpdated event, which enables you to respond to errors when the error is encountered.
The following code sample shows how to both add and remove event handlers. The RowUpdating event handler
writes a log of all deleted records with a time stamp. The RowUpdated event handler adds error information to
the RowError property of the row in the DataSet , suppresses the exception, and continues processing
(mirroring the behavior of ContinueUpdateOnError = true ).
static DataSet DataAdapterEventsDemo(SqlConnection connection, DataSet custDS)
{
// Assumes that connection is a valid SqlConnection object
// and custDS includes the Customers table.
SqlDataAdapter custAdapter = new SqlDataAdapter(
"SELECT CustomerID, CompanyName FROM Customers", connection);
// Add handlers.
custAdapter.RowUpdating += new SqlRowUpdatingEventHandler(OnRowUpdating);
custAdapter.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated);
// Remove handlers.
custAdapter.RowUpdating -= new SqlRowUpdatingEventHandler(OnRowUpdating);
custAdapter.RowUpdated -= new SqlRowUpdatedEventHandler(OnRowUpdated);
return custDS;
}
FillError event
The DataAdapter issues the FillError event when an error occurs during a Fill operation. This type of error
commonly occurs when the data in the row being added could not be converted to a .NET type without some
loss of precision.
If an error occurs during a Fill operation, the current row is not added to the DataTable . The FillError event
enables you to resolve the error and add the row, or to ignore the excluded row and continue the Fill
operation.
The FillErrorEventArgs passed to the FillError event can contain several properties that enable you to respond
to and resolve errors. The following table shows the properties of the FillErrorEventArgs object.
DataTable The DataTable object being filled when the error occurred.
Values An array of objects that contains the values of the row being
added when the error occurred. The ordinal references of the
Values array correspond to the ordinal references of the
columns of the row being added. For example, Values[0]
is the value that was being added as the first column of the
row.
The following code example adds an event handler for the FillError event of the DataAdapter . In the
FillError event code, the example determines if there is the potential for precision loss, providing the
opportunity to respond to the exception.
See also
DataAdapters and DataReaders
Events
Microsoft ADO.NET for SQL Server
Batch operations using DataAdapters
4/27/2022 • 4 minutes to read • Edit Online
Download ADO.NET
Batch support in ADO.NET allows a DataAdapter to group INSERT, UPDATE, and DELETE operations from a
DataSet or DataTable to the server, instead of sending one operation at a time. The reduction in the number of
round trips to the server typically results in significant performance gains. Batch update is supported for the
Microsoft SqlClient data provider for SQL Server (Microsoft.Data.SqlClient).
When updating a database with changes from a DataSet in previous versions of ADO.NET, the Update method
of a DataAdapter performed updates to the database one row at a time. As it iterated through the rows in the
specified DataTable, it examined each DataRow to see if it had been modified. If the row had been modified, it
called the appropriate UpdateCommand , InsertCommand , or DeleteCommand , depending on the value of the
RowState property for that row. Every row update involved a network round-trip to the database.
At the Microsoft SqlClient Data Provider for SQL Server, the SqlDataAdapter exposes an UpdateBatchSize
property. Setting the UpdateBatchSize to a positive integer value causes updates to the database to be sent as
batches of the specified size. For example, setting the UpdateBatchSize to 10 will group 10 separate statements
and submit them as single batch. Setting the UpdateBatchSize to 0 will cause the SqlDataAdapter to use the
largest batch size that the server can handle. Setting it to 1 disables batch updates, as rows are sent one at a
time.
NOTE
Executing an extremely large batch could decrease performance. Therefore, you should test for the optimum batch size
setting before implementing your application.
NOTE
The Microsoft SqlClient Data Provider for SQL Server and the back-end database server determine which SQL constructs
are supported for batch execution. An exception may be thrown if a non-supported statement is submitted for execution.
See also
DataAdapters and DataReaders
Update data sources with DataAdapters
Handle DataAdapter events
Microsoft ADO.NET for SQL Server
Transactions and concurrency
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
A transaction consists of a single command or a group of commands that execute as a package. Transactions
allow you to combine multiple operations into a single unit of work. If a failure occurs at one point in the
transaction, all of the updates can be rolled back to their pre-transaction state.
A transaction must conform to the ACID properties—atomicity, consistency, isolation, and durability—in order to
guarantee data consistency. Most relational database systems, such as Microsoft SQL Server, support
transactions by providing locking, logging, and transaction management facilities whenever a client application
performs an update, insert, or delete operation.
NOTE
Transactions that involve multiple resources can lower concurrency if locks are held too long. Therefore, keep transactions
as short as possible.
If a transaction involves multiple tables in the same database or server, then explicit transactions in stored
procedures often perform better. You can create transactions in SQL Server stored procedures by using the
Transact-SQL BEGIN TRANSACTION , COMMIT TRANSACTION , and ROLLBACK TRANSACTION statements. For more
information, see SQL Server Books Online.
Transactions involving different resource managers, such as a transaction between SQL Server and Oracle,
require a distributed transaction.
In this section
Local transactions
Demonstrates how to perform transactions against a database.
Distributed transactions
Describes how to perform distributed transactions in ADO.NET.
System.Transactions integration with SQL Server
Describes System.Transactions integration with SQL Server for working with distributed transactions.
Optimistic concurrency Describes optimistic and pessimistic concurrency, and how you can test for concurrency
violations.
See also
Transaction fundamentals
Connecting to data source
Commands and parameters
DataAdapters and DataReaders
DbProviderFactories
Microsoft ADO.NET for SQL Server
Local transactions
4/27/2022 • 3 minutes to read • Edit Online
Download ADO.NET
Transactions in ADO.NET are used when you want to bind multiple tasks together so that they execute as a single
unit of work. For example, imagine that an application performs two tasks. First, it updates a table with order
information. Second, it updates a table that contains inventory information, debiting the items ordered. If either
task fails, then both updates are rolled back.
NOTE
Transactions are most efficient when they are performed on the server. If you are working with a SQL Server database that
makes extensive use of explicit transactions, consider writing them as stored procedures using the Transact-SQL BEGIN
TRANSACTION statement.
NOTE
The EnlistDistributedTransaction method should not be used for a local transaction.
The scope of the transaction is limited to the connection. The following example performs an explicit transaction
that consists of two separate commands in the try block. The commands execute INSERT statements against
the Production.ScrapReason table in the AdventureWorks SQL Server sample database, which are committed if
no exceptions are thrown. The code in the catch block rolls back the transaction if an exception is thrown. If the
transaction is aborted or the connection is closed before the transaction has completed, it is automatically rolled
back.
Example
Follow these steps to perform a transaction.
1. Call the BeginTransaction method of the SqlConnection object to mark the start of the transaction. The
BeginTransaction method returns a reference to the transaction. This reference is assigned to the
SqlCommand objects that are enlisted in the transaction.
2. Assign the Transaction object to the Transaction property of the SqlCommand to be executed. If a
command is executed on a connection with an active transaction, and the Transaction object has not
been assigned to the Transaction property of the Command object, an exception is thrown.
3. Execute the required commands.
4. Call the Commit method of the SqlTransaction object to complete the transaction, or call the Rollback
method to end the transaction. If the connection is closed or disposed before either the Commit or
Rollback methods have been executed, the transaction is rolled back.
The following code example demonstrates transactional logic using the Microsoft SqlClient Data Provider for
SQL Server.
using System;
using Microsoft.Data.SqlClient;
class Program
{
static void Main(string[] args)
{
string connectionString = "Data Source = localhost; Integrated Security = true; Initial Catalog =
AdventureWorks";
try
{
// Execute two separate commands.
command.CommandText =
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')";
command.ExecuteNonQuery();
command.CommandText =
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')";
command.ExecuteNonQuery();
try
{
// Attempt to roll back the transaction.
sqlTran.Rollback();
}
catch (Exception exRollback)
{
// Throws an InvalidOperationException if the connection
// is closed or the transaction has already been rolled
// back on the server.
Console.WriteLine(exRollback.Message);
}
}
}
}
}
See also
Transactions and concurrency
Distributed transactions
System.Transactions integration with SQL Server
Microsoft ADO.NET for SQL Server
Distributed transactions
4/27/2022 • 4 minutes to read • Edit Online
Download ADO.NET
A transaction is a set of related tasks that either succeeds (commit) or fails (abort) as a unit, among other things.
A distributed transaction is a transaction that affects several resources. For a distributed transaction to commit,
all participants must guarantee that any change to data will be permanent. Changes must persist despite system
crashes or other unforeseen events. If even a single participant fails to make this guarantee, the entire
transaction fails, and any changes to data within the scope of the transaction are rolled back.
NOTE
An exception will be thrown if you attempt to commit or roll back a transaction if a DataReader is started while the
transaction is active.
NOTE
Once a connection is explicitly enlisted on a transaction, it cannot be un-enlisted or enlisted in another transaction until
the first transaction finishes.
Cau t i on
EnlistTransaction throws an exception if the connection has already begun a transaction using the connection's
BeginTransaction method. However, if the transaction is a local transaction started at the data source (for
example, executing the BEGIN TRANSACTION statement explicitly using a SqlCommand), EnlistTransaction will
roll back the local transaction and enlist in the existing distributed transaction as requested. You will not receive
notice that the local transaction was rolled back, and must manage any local transactions not started using
BeginTransaction. If you are using the Microsoft SqlClient Data Provider for SQL Server with SQL Server, an
attempt to enlist will throw an exception. All other cases will go undetected.
See also
Transactions and concurrency
System.Transactions integration with SQL Server
Microsoft ADO.NET for SQL Server
System.Transactions integration with SQL Server
4/27/2022 • 6 minutes to read • Edit Online
Download ADO.NET
.NET includes a transaction framework that can be accessed through the System.Transactions namespace. This
framework exposes transactions in a way that is fully integrated in .NET, including ADO.NET.
In addition to the programmability enhancements, System.Transactions and ADO.NET can work together to
coordinate optimizations when you work with transactions. A promotable transaction is a lightweight (local)
transaction that can be automatically promoted to a fully distributed transaction on an as-needed basis.
The Microsoft SqlClient Data Provider for SQL Server supports promotable transactions when you work with
SQL Server. A promotable transaction does not invoke the added overhead of a distributed transaction unless
the added overhead is required. Promotable transactions are automatic and require no intervention from the
developer.
NOTE
In a partially trusted scenario, the DistributedTransactionPermission is required when a transaction is promoted to a
distributed transaction.
K EY W O RD DESC RIP T IO N
Implicit Unbind The default. The connection detaches from the transaction
when it ends, switching back to autocommit mode.
Explicit Unbind The connection remains attached to the transaction until the
transaction is closed. The connection will fail if the associated
transaction is not active or does not match Current.
Using TransactionScope
The TransactionScope class makes a code block transactional by implicitly enlisting connections in a distributed
transaction. You must call the Complete method at the end of the TransactionScope block before leaving it.
Leaving the block invokes the Dispose method. If an exception has been thrown that causes the code to leave
scope, the transaction is considered aborted.
We recommend that you use a using block to make sure that Dispose is called on the TransactionScope object
when the using block is exited. Failure to commit or roll back pending transactions can significantly damage
performance because the default time-out for the TransactionScope is one minute. If you do not use a using
statement, you must perform all work in a Try block and explicitly call the Dispose method in the Finally
block.
If an exception occurs in the TransactionScope, the transaction is marked as inconsistent and is abandoned. It will
be rolled back when the TransactionScope is disposed. If no exception occurs, participating transactions commit.
NOTE
The TransactionScope class creates a transaction with a IsolationLevel of Serializable by default. Depending on
your application, you might want to consider lowering the isolation level to avoid high contention in your application.
NOTE
We recommend that you perform only updates, inserts, and deletes within distributed transactions because they
consume significant database resources. Select statements may lock database resources unnecessarily, and in some
scenarios, you may have to use transactions for selects. Any non-database work should be done outside the scope of the
transaction, unless it involves other transacted resource managers. Although an exception in the scope of the transaction
prevents the transaction from committing, the TransactionScope class has no provision for rolling back any changes your
code has made outside the scope of the transaction itself. If you have to take some action when the transaction is rolled
back, you must write your own implementation of the IEnlistmentNotification interface and explicitly enlist in the
transaction.
Example
Working with System.Transactions requires that you have a reference to System.Transactions.dll.
The following function demonstrates how to create a promotable transaction against two different SQL Server
instances, represented by two different SqlConnection objects, which are wrapped in a TransactionScope block.
The code below creates the TransactionScope block with a using statement and opens the first connection,
which automatically enlists it in the TransactionScope.
The transaction is initially enlisted as a lightweight transaction, not a full distributed transaction. The second
connection is enlisted in the TransactionScope only if the command in the first connection does not throw an
exception. When the second connection is opened, the transaction is automatically promoted to a full distributed
transaction.
Later, the Complete method is invoked, which commits the transaction only if no exceptions have been thrown. If
an exception has been thrown at any point in the TransactionScope block, Complete will not be called, and the
distributed transaction will roll back when the TransactionScope is disposed at the end of its using block.
using System;
using System.Transactions;
using Microsoft.Data.SqlClient;
class Program
{
static void Main(string[] args)
{
string connectionString = "Data Source = localhost; Integrated Security = true; Initial Catalog =
AdventureWorks";
// Display messages.
Console.WriteLine(writer.ToString());
return returnValue;
}
}
See also
Transactions and concurrency
Microsoft ADO.NET for SQL Server
Optimistic concurrency
4/27/2022 • 8 minutes to read • Edit Online
Download ADO.NET
In a multiuser environment, there are two models for updating data in a database: optimistic concurrency and
pessimistic concurrency. The DataSet object is designed to encourage the use of optimistic concurrency for long-
running activities, such as remoting data and interacting with data.
Pessimistic concurrency involves locking rows at the data source to prevent other users from modifying data in
a way that affects the current user. In a pessimistic model, when a user performs an action that causes a lock to
be applied, other users cannot perform actions that would conflict with the lock until the lock owner releases it.
This model is primarily used in environments where there is heavy contention for data, so that the cost of
protecting data with locks is less than the cost of rolling back transactions if concurrency conflicts occur.
Therefore, in a pessimistic concurrency model, a user who updates a row establishes a lock. Until the user has
finished the update and released the lock, no one else can change that row. For this reason, pessimistic
concurrency is best implemented when lock times will be short, as in programmatic processing of records.
Pessimistic concurrency is not a scalable option when users are interacting with data and causing records to be
locked for relatively large periods of time.
NOTE
If you need to update multiple rows in the same operation, then creating a transaction is a more scalable option than
using pessimistic locking.
By contrast, users who use optimistic concurrency do not lock a row when reading it. When a user wants to
update a row, the application must determine whether another user has changed the row since it was read.
Optimistic concurrency is generally used in environments with a low contention for data. Optimistic concurrency
improves performance because no locking of records is required, and locking of records requires additional
server resources. Also, in order to maintain record locks, a persistent connection to the database server is
required. Because this is not the case in an optimistic concurrency model, connections to the server are free to
serve a larger number of clients in less time.
In an optimistic concurrency model, a violation is considered to have occurred if, after a user receives a value
from the database, another user modifies the value before the first user has attempted to modify it. How the
server resolves a concurrency violation is best shown by first describing the following example.
The following tables follow an example of optimistic concurrency.
At 1:00 p.m., User1 reads a row from the database with the following values:
CustID LastName FirstName
101 Smith Bob
The update succeeds because the values in the database at the time of update match the original values that
User2 has.
At 1:05 p.m., User1 changes "Bob"'s first name to "James" and tries to update the row.
At this point, User1 encounters an optimistic concurrency violation because the value in the database ("Robert")
no longer matches the original value that User1 was expecting ("Bob"). The concurrency violation simply lets
you know that the update failed. The decision now needs to be made whether to overwrite the changes supplied
by User2 with the changes supplied by User1, or to cancel the changes by User1.
To test for an optimistic concurrency violation when updating a row in Table1 , you would issue the following
UPDATE statement:
As long as the original values match the values in the database, the update is performed. If a value has been
modified, the update will not modify the row because the WHERE clause will not find a match.
Note that it is recommended to always return a unique primary key value in your query. Otherwise, the
preceding UPDATE statement may update more than one row, which might not be your intent.
If a column at your data source allows nulls, you may need to extend your WHERE clause to check for a
matching null reference in your local table and at the data source. For example, the following UPDATE statement
verifies that a null reference in the local row still matches a null reference at the data source, or that the value in
the local row still matches the value at the data source.
You may also choose to apply less restrictive criteria when using an optimistic concurrency model. For example,
using only the primary key columns in the WHERE clause causes the data to be overwritten regardless of
whether the other columns have been updated since the last query. You can also apply a WHERE clause only to
specific columns, resulting in data being overwritten unless particular fields have been updated since they were
last queried.
The DataAdapter.RowUpdated event
The RowUpdated event of the DataAdapter object can be used in conjunction with the techniques described
earlier, to provide notification to your application of optimistic concurrency violations. RowUpdated occurs
after each attempt to update a Modified row from a DataSet . This enables you to add special handling code,
including processing when an exception occurs, adding custom error information, adding retry logic, and so on.
The RowUpdatedEventArgs object returns a RecordsAffected property containing the number of rows affected
by a particular update command for a modified row in a table. By setting the update command to test for
optimistic concurrency, the RecordsAffected property will, as a result, return a value of 0 when an optimistic
concurrency violation has occurred, because no records were updated. If this is the case, an exception is thrown.
The RowUpdated event enables you to handle this occurrence and avoid the exception by setting an
appropriate RowUpdatedEventArgs.Status value, such as UpdateStatus.SkipCurrentRow . For more
information about the RowUpdated event, see Handling DataAdapter Events.
Optionally, you can set DataAdapter.ContinueUpdateOnError to true , before calling Update , and respond
to the error information stored in the RowError property of a particular row when the Update is completed.
For more information, see Row Error Information.
class Program
{
static void Main(string[] args)
{
string connectionString = "Data Source = localhost; Integrated Security = true; Initial Catalog =
Northwind";
See also
Retrieving and modifying data in ADO.NET
Updating Data Sources with DataAdapters
Transactions and concurrency
Microsoft ADO.NET for SQL Server
Retrieving database schema information
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Obtaining schema information from a database is accomplished with the process of schema discovery. Schema
discovery allows applications to request that managed providers find and return information about the
database schema, also known as metadata, of a given database. Different database schema elements such as
tables, columns, and stored-procedures are exposed through schema collections. Each schema collection
contains a variety of schema information specific to the provider being used.
The Microsoft SqlClient Data Provider for SQL Server implements the GetSchema method in the
SqlConnection class, and the schema information that is returned from the GetSchema method comes in the
form of a DataTable. The GetSchema method is an overloaded method that provides optional parameters for
specifying the schema collection to return, and restricting the amount of information returned. The SqlClient
data provider also provides a GetSchemaTable method that returns a DataTable describing the column
metadata of the SqlDataReader .
In this section
GetSchema and schema collections
Describes the GetSchema method and how it can be used to retrieve and restrict schema information from a
database.
Schema restrictions
Describes schema restrictions that can be used with GetSchema .
Common schema collections
Describes all of the common schema collections supported by all of the .NET managed providers.
SQL Server schema collections
Describes the additional schema collections supported by the Microsoft SqlClient Data Provider for SQL Server.
Reference
GetSchema
Describes the GetSchema method of the DbConnection class.
GetSchema
Describes the GetSchema method of the SqlConnection class.
GetSchemaTable
Describes the GetSchemaTable method of the DbDataReader class.
GetSchemaTable
Describes the GetSchemaTable method of the SqlDataReader class.
See also
Retrieving and modifying data in ADO.NET
Microsoft ADO.NET for SQL Server
Get schema and schema collections
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
The SqlConnection classes in the Microsoft SqlClient Data Provider for SQL Server implements a GetSchema
method which is used to retrieve schema information about the database that is currently connected, and the
schema information returned from the GetSchema method comes in the form of a DataTable. The GetSchema
method is an overloaded method that provides optional parameters for specifying the schema collection to
return, and restricting the amount of information returned.
class Program
{
static void Main(string[] args)
{
string connectionString = "Data Source = localhost; Integrated Security = true; Initial Catalog =
AdventureWorks";
See also
Retrieving database schema information
Microsoft ADO.NET for SQL Server
Schema restrictions
4/27/2022 • 4 minutes to read • Edit Online
Download ADO.NET
The second optional parameter of the GetSchema method is the restrictions that are used to limit the amount
of schema information returned, and it is passed to the GetSchema method as an array of strings. The position
in the array determines the values that you can pass, and this is equivalent to the restriction number.
For example, the following table describes the restrictions supported by the "Tables" schema collection using the
Microsoft SqlClient Data Provider for SQL Server. Additional restrictions for SQL Server schema collections are
listed at the end of this topic.
NOTE
The restrictions collections for SqlClient have an additional ParameterName column. The restriction default column
is still there for backwards compatibility, but is currently ignored. Parameterized queries rather than string replacement
should be used to minimize the risk of an SQL injection attack when specifying restriction values.
The number of elements in the array must be less than or equal to the number of restrictions supported for the
specified schema collection else an ArgumentException will be thrown. There can be fewer than the maximum number
of restrictions. The missing restrictions are assumed to be null (unrestricted).
You can query the Microsoft SqlClient Data Provider for SQL Server to determine the list of supported
restrictions by calling the GetSchema method with the name of the restrictions schema collection, which is
"Restrictions". This will return a DataTable with a list of the collection names, the restriction names, the default
restriction values, and the restriction numbers.
Example
The following examples demonstrate how to use the GetSchema method of the Microsoft SqlClient Data
Provider for SQL Server SqlConnection class to retrieve schema information about all of the tables contained in
the AdventureWorks sample database, and to restrict the information returned to only those tables in the
"Sales" schema:
using System;
using System.Data;
using Microsoft.Data.SqlClient;
class Program
{
static void Main(string[] args)
{
string connectionString = "Data Source = localhost; Integrated Security = true; Initial Catalog =
AdventureWorks";
Databases
REST RIC T IO N N A M E PA RA M ET ER N A M E REST RIC T IO N DEFA ULT REST RIC T IO N N UM B ER
Tables
REST RIC T IO N N A M E PA RA M ET ER N A M E REST RIC T IO N DEFA ULT REST RIC T IO N N UM B ER
Columns
REST RIC T IO N N A M E PA RA M ET ER N A M E REST RIC T IO N DEFA ULT REST RIC T IO N N UM B ER
StructuredTypeMembers
REST RIC T IO N N A M E PA RA M ET ER N A M E REST RIC T IO N DEFA ULT REST RIC T IO N N UM B ER
Views
REST RIC T IO N N A M E PA RA M ET ER N A M E REST RIC T IO N DEFA ULT REST RIC T IO N N UM B ER
ViewColumns
REST RIC T IO N N A M E PA RA M ET ER N A M E REST RIC T IO N DEFA ULT REST RIC T IO N N UM B ER
ProcedureParameters
REST RIC T IO N N A M E PA RA M ET ER N A M E REST RIC T IO N DEFA ULT REST RIC T IO N N UM B ER
Procedures
REST RIC T IO N N A M E PA RA M ET ER N A M E REST RIC T IO N DEFA ULT REST RIC T IO N N UM B ER
IndexColumns
REST RIC T IO N N A M E PA RA M ET ER N A M E REST RIC T IO N DEFA ULT REST RIC T IO N N UM B ER
Indexes
REST RIC T IO N N A M E PA RA M ET ER N A M E REST RIC T IO N DEFA ULT REST RIC T IO N N UM B ER
UserDefinedTypes
REST RIC T IO N N A M E PA RA M ET ER N A M E REST RIC T IO N DEFA ULT REST RIC T IO N N UM B ER
ForeignKeys
REST RIC T IO N N A M E PA RA M ET ER N A M E REST RIC T IO N DEFA ULT REST RIC T IO N N UM B ER
See also
Microsoft ADO.NET for SQL Server
Common schema collections
4/27/2022 • 9 minutes to read • Edit Online
Download ADO.NET
The common schema collections are the schema collections that are implemented by each of the .NET managed
providers. You can query a .NET managed provider to determine the list of supported schema collections by
calling the GetSchema method with no arguments, or with the schema collection name "MetaDataCollections".
This method will return a DataTable with a list of the supported schema collections, the number of restrictions
that they each support, and the number of identifier parts that they use. These collections describe all of the
required columns. Providers are free to add more columns if they wish. For example, the Microsoft SqlClient
Data Provider for SQL Server adds ParameterName to the restrictions collection.
If a provider is unable to determine the value of a required column, it will return null.
For more information about using the GetSchema methods, see GetSchema and Schema Collections.
MetaDataCollections
This collection exposes information about all of the schema collections supported by the provider that is
currently used to connect to the database.
DataSourceInformation
This schema collection exposes information about data source that the Microsoft SqlClient Data Provider for
SQL Server is currently connected to.
In some cases,
DataSourceProductVersion and
DataSourceProductVersionNormalized
will be the same value.
In some cases,
DataSourceProductVersion and
DataSourceProductVersionNormalized
will be the same value.
DataTypes
This schema collection exposes information about the data types that are supported by the database that the
provider is currently connected to.
Restrictions
This schema collection exposed information about the restrictions that are supported by the provider that is
currently used to connect to the database.
ReservedWords
This schema collection exposes information about the words that are reserved by the database that the provider
that is currently connected to.
See also
Retrieving database schema information
GetSchema and schema collections
Microsoft ADO.NET for SQL Server
SQL Server schema collections
4/27/2022 • 10 minutes to read • Edit Online
Download ADO.NET
The Microsoft SqlClient Data Provider for SQL Server supports additional schema collections in addition to the
common schema collections. The schema collections vary slightly by the version of SQL Server you are using. To
determine the list of supported schema collections, call the GetSchema method with no arguments, or with the
schema collection name "MetaDataCollections". This will return a DataTable with a list of the supported schema
collections, the number of restrictions that they each support, and the number of identifier parts that they use.
Databases
C O L UM N N A M E DATAT Y P E DESC RIP T IO N
Foreign Keys
C O L UM N N A M E DATAT Y P E DESC RIP T IO N
Indexes
C O L UM N N A M E DATAT Y P E DESC RIP T IO N
- HEAP
- CLUSTERED
- NONCLUSTERED
- XML
- SPATIAL
IndexColumns
C O L UM N N A M E DATAT Y P E DESC RIP T IO N
Procedure Parameters
C O L UM N N A M E DATAT Y P E DESC RIP T IO N
Tables
C O L UM N N A M E DATAT Y P E DESC RIP T IO N
Columns
C O L UM N N A M E DATAT Y P E DESC RIP T IO N
CHARACTER_OCTET_LENGTH Int32 – SQL8, Int16 – Sql7 Maximum length, in bytes, for binary
data, character data, or text and image
data. Otherwise, NULL is returned.
C O L UM N N A M E DATAT Y P E DESC RIP T IO N
AllColumns
The AllColumns schema collection is used to support sparse columns. AllColumns has the same restrictions and
resulting DataTable schema as the Columns schema collection. The only difference is that AllColumns includes
column set columns that are not included in the Columns schema collection. The following table describes these
columns.
ColumnSetColumns
The ColumnSetColumns schema collection is used to support sparse columns. The ColumnSetColumns schema
collection returns the schema for all of the columns in a column set. The following table describes these
columns.
Users
C O L UM N N A M E DATAT Y P E DESC RIP T IO N
Views
C O L UM N N A M E DATAT Y P E DESC RIP T IO N
ViewColumns
C O L UM N N A M E DATAT Y P E DESC RIP T IO N
UserDefinedTypes
C O L UM N N A M E DATAT Y P E DESC RIP T IO N
See also
Retrieving database schema information
Microsoft ADO.NET for SQL Server
Configurable retry logic in SqlClient
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
An application that communicates with elements running in the cloud has to be sensitive to the transient faults
that can occur in this environment. These faults are typically self-correcting. If the action that triggered a fault is
repeated after a suitable delay, it's likely to be successful.
NOTE
This feature is available starting with Microsoft.Data.SqlClient version 3.0.0 preview 1.
Retry pattern
Attempting to complete an operation despite transient errors, instead of throwing an exception and letting a
user decide the next action, is an intelligent decision called a retry pattern. For more information, see Retry
pattern.
Transient faults
You can have a robust infrastructure and use well-known applications implemented with the latest technologies
to reduce service downtime. However, it's impossible to reduce failures to zero. Transient errors are those faults
that sometimes happen for known reasons and will disappear after a short time. For example, when a load-
balancing change is in progress on the server-side, it may briefly cause requested services to fail or time out. For
more information, see Transient faults.
Do and don't
Even though using a retry pattern greatly improves an application's resiliency, it could negatively impact an
application if used in the wrong circumstances. Before adding an exception to the list of transient faults, pause
for a moment and ask yourself, "Will it resolve itself soon?". Don't rush. Study the reasons if you don't have a
good answer for the question. For more information, see Troubleshooting connectivity issues and other errors
with Azure SQL Database and Azure SQL Managed Instance.
In this section
Configurable retry logic in SqlClient introduction
Introduces different section of configurable retry logic.
Internal retry logic providers in SqlClient
Demonstrates how to use pre-defined retry providers to apply the retry logic against database.
Configurable retry logic core APIs in SqlClient
Demonstrates how to use core APIs to implement custom retry logic.
Configurable retry logic configuration file with SqlClient
Demonstrates how to specify default retry logic providers through a configuration file.
See also
Retry Pattern
Transient faults
Troubleshooting connectivity issues and other errors with Azure SQL Database and Azure SQL Managed
Instance
Microsoft ADO.NET for SQL Server
Configurable retry logic in SqlClient introduction
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Configurable retry logic lets developers and administrators manage application behavior when transient faults
happen. The feature adds controls during connection or execution of a command. The controls can be defined
through code or an application configuration file. Transient error numbers and retry properties can be defined
to control retry behavior. Also, regular expressions can be used to filter specific SQL statements.
Feature components
This feature consists of three main components:
1. Core APIs : Developers can use these interfaces to implement their own retry logic on SqlConnection and
SqlCommand objects. For more information, see Configurable retry logic core APIs in SqlClient.
2. Pre-defined configurable retr y logic : Built-in retry logic methods using the core APIs are accessible from
the SqlConfigurableRetryFactory class. For more information, see Internal retry logic providers in SqlClient.
3. Configuration file schema : To specify the default retry logic for SqlConnection and SqlCommand in an
application. For more information, see Configurable retry logic configuration file with SqlClient.
Quick start
To use this feature, follow these four steps:
1. Enable the safety switch in the preview version. For information on how to enable the AppContext safety
switch, see Enable configurable retry logic.
2. Define the retry logic options using SqlRetryLogicOption.
In this sample, some of the retry parameters are set and the rest of them will use the default values.
NOTE
These steps are the same for a command execution, except you would instead assign the retry provider to the
SqlCommand.RetryLogicProvider property before executing the command.
See also
Configurable retry logic core APIs in SqlClient
Internal retry logic providers in SqlClient
Configurable retry logic configuration file with SqlClient
Enable configurable retry logic
Configurable retry logic in SqlClient
Microsoft ADO.NET for SQL Server
Internal retry logic providers in SqlClient
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Built-in, internal retry providers have been implemented for the most common retry patterns. You can use the
retry providers by using the following Microsoft.Data.SqlClient.SqlConfigurableRetryFactory static methods:
SqlConfigurableRetryFactory.CreateFixedRetryProvider
SqlConfigurableRetryFactory.CreateIncrementalRetryProvider
SqlConfigurableRetryFactory.CreateExponentialRetryProvider
SqlConfigurableRetryFactory.CreateNoneRetryProvider
NOTE
All of the internal retry providers slightly randomize interval gap times before each retry. This randomization avoids
hitting the database at the same time when multiple clients are trying to connect or execute a command with the same
configuration.
WARNING
Internal retry providers don't support retrying on a command that executes in an open transaction. That operation will
execute without retry logic. You can override this behavior by using custom retry logic. For more information, see
Configurable retry logic core APIs in SqlClient.
Example
You can find samples for connection and command retry logic at the following links:
SqlConnection.RetryLogicProvider
SqlCommand.RetryLogicProvider
See also
Configurable retry logic core APIs in SqlClient
Configurable retry logic in SqlClient
Microsoft ADO.NET for SQL Server
Configurable retry logic core APIs in SqlClient
4/27/2022 • 5 minutes to read • Edit Online
Download ADO.NET
If the built-in retry logic providers don't cover your needs, you can create your own custom providers. You can
then assign those providers to a SqlConnection or SqlCommand object to apply your custom logic.
The built-in providers are designed around three interfaces that can be used to implement custom providers.
Custom retry providers can then be used in the same way as internal retry providers on a SqlConnection or
SqlCommand:
1. SqlRetryIntervalBaseEnumerator: Generates a sequence of time intervals.
2. SqlRetryLogicBase: Retrieves the next time interval for a given enumerator, if the number of retries has not
been exceeded and a transient condition is met.
3. SqlRetryLogicBaseProvider: Applies retry logic to connection and command operations.
Cau t i on
By implementing a custom retry logic provider, you're in charge of all aspects, including concurrency,
performance, and exception management.
Example
The implementation in this sample is as simple as possible to demonstrate step-by-step customization. It doesn't
include advanced practices like thread safety, async, and concurrency. For a deep-dive into a real
implementation, you can study the pre-defined retry logic in the Microsoft.Data.SqlClient GitHub repository.
1. Define custom configurable retry logic classes:
Enumerator : Define a fixed sequence of time intervals and extend the acceptable range of times from
two minutes to four minutes.
public class CustomEnumerator : SqlRetryIntervalBaseEnumerator
{
// Set the maximum acceptable time to 4 minutes
private readonly TimeSpan _maxValue = TimeSpan.FromMinutes(4);
// Override the validate method with the new time range validation
protected override void Validate(TimeSpan timeInterval, TimeSpan maxTimeInterval, TimeSpan
minTimeInterval)
{
if (minTimeInterval < TimeSpan.Zero || minTimeInterval > _maxValue)
{
throw new ArgumentOutOfRangeException(nameof(minTimeInterval));
}
Retr y logic : Implement retry logic on any command that isn't part of an active transaction. Lower the
number of retries from 60 to 20.
public class CustomRetryLogic : SqlRetryLogicBase
{
// Maximum number of attempts
private const int maxAttempts = 20;
if (result)
{
// Increase the number of attempts
Current++;
// It's okay if the RetryIntervalEnumerator gets to the last value before we've reached
our maximum number of attempts.
// MoveNext() will simply leave the enumerator on the final interval value and we will
repeat that for the final attempts.
RetryIntervalEnumerator.MoveNext();
// Receive the current time from enumerator
intervalTime = RetryIntervalEnumerator.Current;
}
return result;
}
}
Provider : Implements a retry provider that retries on synchronous operations without a Retrying
event. Adds TimeoutException to the existing SqlException transient exception error numbers.
public class CustomProvider : SqlRetryLogicBaseProvider
{
// Preserve the given retryLogic on creation
public CustomProvider(SqlRetryLogicBase retryLogic)
{
RetryLogic = retryLogic;
}
The following function will evaluate an exception by using the given list of retryable exceptions and
the special TimeoutException exception to determine if it's retryable:
NOTE
Don't forget to enable the configurable retry logic switch before using it. For more information, see Enable configurable
retry logic.
See also
Microsoft.Data.SqlClient GitHub repository
Configurable retry logic in SqlClient
Microsoft ADO.NET for SQL Server
Configurable retry logic configuration file with
SqlClient
4/27/2022 • 4 minutes to read • Edit Online
Download ADO.NET
The default retry method when the safety switch is enabled is the
SqlConfigurableRetryFactory.CreateNoneRetryProvider for both SqlConnection and SqlCommand. You can
specify a different retry method by using a configuration file.
Configuration sections
Default retry logic options for an application can be changed by adding the following sections inside the
configSections section of the configuration file:
<section name="SqlConfigurableRetryLogicConnection"
type="Microsoft.Data.SqlClient.SqlConfigurableRetryConnectionSection, Microsoft.Data.SqlClient"/>
<section name="SqlConfigurableRetryLogicCommand"
type="Microsoft.Data.SqlClient.SqlConfigurableRetryCommandSection, Microsoft.Data.SqlClient"/>
<section name="AppContextSwitchOverrides"
type="Microsoft.Data.SqlClient.AppContextSwitchOverridesSection, Microsoft.Data.SqlClient"/>
NOTE
The following configurations should be specified inside the configuration section. Declare these new sections to
configure the default retry logic through an application configuration file.
NOTE
Starting from Microsoft.Data.SqlClient v4.0, the App Context switch "Switch.Microsoft.Data.SqlClient.EnableRetryLogic" will
no longer be required to use the configurable retry logic feature. The feature is now supported in production. The default
behavior of the feature will continue to be a non-retry policy, which will need to be overridden by client applications to
enable retries.
You can enable the safety switch through a configuration file. To learn how to enable it through application code,
see Enable configurable retry logic.
.NET Framework : For more information, see AppContextSwitchOverrides element.
<runtime>
<AppContextSwitchOverrides value="Switch.Microsoft.Data.SqlClient.EnableRetryLogic=true"/>
</runtime>
.NET Core : supports multiple, semi-colon (;) delimited switches like .NET Framework.
<AppContextSwitchOverrides value="Switch.Microsoft.Data.SqlClient.EnableRetryLogic=true"/>
Connection section
The following attributes can be used to specify the default retry logic for all SqlConnection instances in an
application:
numberOfTries : sets the number of times to try.
deltaTime : sets the gap time interval as a TimeSpan object.
minTime : sets the allowed minimum gap time interval as a TimeSpan object.
maxTime : sets the allowed maximum gap time interval as a TimeSpan object.
transientErrors : sets the list of transient error numbers on which to retry.
retr yMethod : specifies a retry method creator that receives the retry configuration via a
SqlRetryLogicOption parameter and returns a SqlRetryLogicBaseProvider object.
retr yLogicType : sets a custom retry logic provider, which contains the retry method creators that
provide the retryMethod . These methods should meet the criteria for retryMethod . The fully qualified
type name of the provider should be used. For more information, see Specifying fully qualified type
names.
NOTE
It's not required to specify the retryLogicType if you use the built-in retry providers. To find the built-in retry providers,
see Internal retry logic providers in SqlClient.
Command section
The following attribute can also be set for all SqlCommand instances in an application:
authorizedSqlCondition : Sets a pre-retry regular expression for SqlCommand.CommandText to filter
specific SQL statements.
NOTE
The regular expression is case sensitive.
Examples
Attempts to establish a connection up to three times with an approximate 1-second delay between tries
by using the SqlConfigurableRetryFactory.CreateFixedRetryProvider method and the default transient
error list:
<SqlConfigurableRetryLogicConnection retryMethod ="CreateFixedRetryProvider"
numberOfTries ="3" deltaTime ="00:00:01"/>
Attempts to establish a connection up to five times with up to a 45-second delay between tries by using
the SqlConfigurableRetryFactory.CreateExponentialRetryProvider method and the default transient error
list:
Attempts to execute a command up to four times with a delay between 2 and 30 seconds by using the
SqlConfigurableRetryFactory.CreateIncrementalRetryProvider method and the default transient error list:
Attempts to execute a command up to eight times with a delay from one second to one minute. It's
limited to commands with CommandText containing the word SELECT and exception numbers 102 or 997.
It uses the built-in SqlConfigurableRetryFactory.CreateIncrementalRetryProvider method:
NOTE
In the next two samples, you can find the custom retry logic source code from Configurable retry logic core APIs in
SqlClient. It's assumed the CreateCustomProvider method is defined in the CustomCRL_Doc.CustomRetry class in the
CustomCRL_Doc.dll assembly that is in the application's executing directory.
Attempts to establish a connection up to five times, with a delay between 3 and 45 seconds, error
numbers 4060, 997, and 233 in the list, and using the specified custom retry provider:
NOTE
Any errors when reading an application configuration file for retry logic settings won't cause errors in the application. The
default SqlConfigurableRetryFactory.CreateNoneRetryProvider will be used instead.
You can use event source tracing to verify or troubleshoot issues with configuring retry logic. For more information, see
Enable event tracing in SqlClient.
See also
Enable configurable retry logic
Internal retry logic providers in SqlClient
Enable event tracing in SqlClient
Specifying fully qualified type names
Configurable retry logic in SqlClient
Microsoft ADO.NET for SQL Server
DbProviderFactories
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
The System.Data.Common namespace provides classes for creating DbProviderFactory instances to work with
specific data sources. When you create a DbProviderFactory instance and pass it information about the data
provider, the DbProviderFactory can determine the correct, strongly typed connection object to return based on
the information it has been provided.
The data provider Microsoft.Data.SqlClient is no longer listed in machine.config file, but custom providers will
continue to be listed there.
In this section
Obtain a SqlClientFactory
Demonstrates how to obtain a SqlClientFactory from the DbProviderFactories class to work with specific data
sources in .NET.
See also
Retrieving and modifying data in ADO.NET
Microsoft ADO.NET for SQL Server
Obtain a SqlClientFactory
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
The process of obtaining a DbProviderFactory involves passing information about a data provider to the
DbProviderFactories class. Based on this information, the GetFactory method creates a strongly typed provider
factory. For example, to create a SqlClientFactory, you can pass GetFactory a string with the provider name
specified as "Microsoft.Data.SqlClient ".
The other overload of GetFactory takes a DataRow. Once you create the provider factory, you can then use its
methods to create additional objects. Some of the methods of a SqlClientFactory include CreateConnection,
CreateCommand, and CreateDataAdapter.
Register SqlClientFactory
To retrieve the SqlClientFactory object by the DbProviderFactories class in .NET Framework, it's necessary to
register it in a App.config or web.config file. The following configuration file fragment shows the syntax and
format for Microsoft.Data.SqlClient.
<system.data>
<DbProviderFactories>
<add name="Microsoft SqlClient Data Provider"
invariant="Microsoft.Data.SqlClient"
description="Microsoft SqlClient Data Provider for SQL Server"
type="Microsoft.Data.SqlClient.SqlClientFactory, Microsoft.Data.SqlClient, Version=2.0.20168.4,
Culture=neutral, PublicKeyToken=23ec7fc2d6eaa4a5"/>
</DbProviderFactories>
</system.data>
The invariant attribute identifies the underlying data provider. This three-part naming syntax is also used when
creating a new factory and for identifying the provider in an application configuration file so that the provider
name, along with its associated connection string, can be retrieved at run time.
NOTE
In .NET core, since there is no GAC or global configuration support, the SqlClientFactory object should be registered by
calling RegisterFactory method in the project.
The following sample shows how to use the SqlClientFactory in a .NET core application.
return DbProviderFactories.GetFactory("Microsoft.Data.SqlClient");
}
See also
DbProviderFactories
Connection strings
Using the configuration classes
Microsoft ADO.NET for SQL Server
Diagnostic counters in SqlClient
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
You can use Microsoft.Data.SqlClient diagnostic counters in multiple target frameworks to monitor the status of
your application and the connection resources that it uses. Use performance counters in .NET Framework, and
event counters in .NET Core and .NET Standard.
NOTE
When using Windows Authentication (integrated security), you must monitor either the pair
number-of-active-connection-pool-groups and number-of-active-connection-pools event counters or the
NumberOfActiveConnectionPoolGroups and NumberOfActiveConnectionPools performance counters. The reason is
that connection pool groups map to unique connection strings. When integrated security is used, connection pools map
to connection strings and additionally create separate pools for individual Windows identities. For example, if Fred and
Julie, each within the same AppDomain, both use the connection string
"Data Source=MySqlServer;Integrated Security=true" , a connection pool group is created for the connection string,
and two additional pools are created, one for Fred and one for Julie. If John and Martha use a connection string with an
identical SQL Server login, "Data Source=MySqlServer;User Id=<myUserID>;Password=<myPassword>" , then only a
single pool is created for the <myUserID> identity.
In this section
Performance counters in SqlClient
Use Microsoft SqlClient Data Provider for SQL Server performance counters to monitor your application status
and its connection resources by using Windows Performance Monitor or programmatically in .NET Framework .
Event counters in SqlClient
Use Microsoft SqlClient Data Provider for SQL Server event counters to monitor your application status and its
connection resources in .NET Core and .NET Standard .
See also
Retrieving and modifying data in ADO.NET
Microsoft ADO.NET for SQL Server
Event counters in SqlClient
4/27/2022 • 5 minutes to read • Edit Online
Download ADO.NET
IMPORTANT
Event counters are available when targeting .NET Core 3.1 and higher or .NET Standard 2.1 and higher. This feature is
available starting with Microsoft.Data.SqlClient version 3.0.0 .
You can use Microsoft.Data.SqlClient event counters to monitor the status of your application and the
connection resources that it uses. Event counters can be monitored by .NET CLI global tools and perfView or
can be accessed programmatically using the EventListener class in the System.Diagnostics.Tracing namespace.
active-hard-connections Actual active connections currently The number of connections that are
made to servers currently open to database servers.
hard-connects Actual connection rate to servers The number of connections per second
that are being opened to database
servers.
hard-disconnects Actual disconnection rate from servers The number of disconnects per second
that are being made to database
servers.
soft-connects Rate of connections retrieved from the The number of connections per second
connection pool that are being consumed from the
connection pool.
soft-disconnects Rate of connections returned to the The number of connections per second
connection pool that are being returned to the
connection pool.
number-of-non-pooled- Number of connections not using The number of active connections that
connections connection pooling aren't pooled.
NAME DISP L AY N A M E DESC RIP T IO N
number-of-active-connection- Number of active unique connection The number of unique connection pool
pool-groups strings groups that are active. This counter is
controlled by the number of unique
connection strings that are found in
the AppDomain.
number-of-inactive-connection- Number of unique connection strings The number of unique connection pool
pool-groups waiting for pruning groups that are marked for pruning.
This counter is controlled by the
number of unique connection strings
that are found in the AppDomain.
number-of-active-connection- Number of active connection pools The total number of connection pools.
pools
number-of-reclaimed-connections Number of reclaimed connections from The number of connections that have
GC been reclaimed through garbage
collection where Close or Dispose
wasn't called by the application. Note
Not explicitly closing or disposing
connections hurts performance.
The following command collects SqlClient event counters values once every second.
The following command monitors SqlClient event counters values once every three seconds.
The following command monitors selected SqlClient event counters values once every second.
Consume in-proc
You can consume the counter values via the EventListener API. An EventListener is an in-proc way of
consuming any event written by instances of an EventSource in your application. For more information, see
EventListener.
In-proc example
The following sample code captures Microsoft.Data.SqlClient.EventSource events using
EventCounterIntervalSec=1 . It writes the counter name and its Mean value on each event counter update.
NOTE
It's required to specify the EventCounterIntervalSec property value when enabling this event.
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Linq;
// This listener class will listen for events from the SqlClientEventSource class.
// SqlClientEventSource is an implementation of the EventSource class which gives
// it the ability to create events.
public class EventCounterListener : EventListener
{
protected override void OnEventSourceCreated(EventSource eventSource)
{
// Only enable events from SqlClientEventSource.
if (eventSource.Name.Equals("Microsoft.Data.SqlClient.EventSource"))
{
var options = new Dictionary<string, string>();
// define time interval 1 second
// without defining this parameter event counters will not enabled
options.Add("EventCounterIntervalSec", "1");
// enable for the None keyword
EnableEvents(eventSource, EventLevel.Informational, EventKeywords.None, options);
}
}
class Program
{
static void Main(string[] args)
{
// Create a new event listener
using (var listener = new EventCounterListener())
{
string connectionString = "Data Source=localhost; Integrated Security=true";
See also
Performance counters in SqlClient
dotnet-counters
dotnet-trace
Enable event tracing in SqlClient
Microsoft ADO.NET for SQL Server
Performance counters in SqlClient
4/27/2022 • 5 minutes to read • Edit Online
Download ADO.NET
You can use Microsoft.Data.SqlClient performance counters to monitor the status of your application and the
connection resources that it uses. Performance counters can be monitored by using Windows Performance
Monitor or can be accessed programmatically using the PerformanceCounter class in the System.Diagnostics
namespace.
HardConnectsPerSecond The number of connections per second that are being made
to a database server.
HardDisconnectsPerSecond The number of disconnects per second that are being made
to a database server.
NumberOfInactiveConnectionPools The number of inactive connection pools that have not had
any recent activity and are waiting to be disposed.
<system.diagnostics>
<switches>
<add name="ConnectionPoolPerformanceCounterDetail" value="4"/>
<!-- A value of 4 corresponds to System.Diagnostics.TraceLevel.Verbose -->
</switches>
</system.diagnostics>
NOTE
This example uses the sample AdventureWorks database. The connection strings provided in the sample code assume
that the database is installed and available on the local computer, and that you have created logins that match those
supplied in the connection strings. You may need to enable SQL Server logins if your server is configured using the
default security settings which allow only Windows Authentication. Modify the connection strings as necessary to suit
your environment.
Example
using System;
using Microsoft.Data.SqlClient;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace PerformanceCounterTest
{
class Program
{
PerformanceCounter[] PerfCounters = new PerformanceCounter[10];
SqlConnection connection = new SqlConnection();
connection1.Close();
Console.WriteLine("Closed the 1st Connection:");
WritePerformanceCounters();
connection2.Close();
Console.WriteLine("Closed the 2nd Connection:");
WritePerformanceCounters();
connection3.Close();
Console.WriteLine("Closed the 3rd Connection:");
WritePerformanceCounters();
connection4.Close();
Console.WriteLine("Closed the 4th Connection:");
WritePerformanceCounters();
}
See also
Event counters in SqlClient
Connecting to a data source
Runtime profiling
Introduction to monitoring performance thresholds
Microsoft ADO.NET for SQL Server
Retrieve identity or autonumber values
4/27/2022 • 15 minutes to read • Edit Online
Download ADO.NET
A primary key in a relational database is a column or combination of columns that always contain unique
values. Knowing the primary key value allows you to locate the row that contains it. Relational database engines,
such as SQL Server, Oracle, and Microsoft Access/Jet support the creation of automatically incrementing
columns that can be designated as primary keys. These values are generated by the server as rows are added to
a table. In SQL Server, you set the identity property of a column, in Oracle you create a Sequence, and in
Microsoft Access you create an AutoNumber column.
A DataColumn can also be used to generate automatically incrementing values by setting the AutoIncrement
property to true. However, you might end up with duplicate values in separate instances of a DataTable, if
multiple client applications are independently generating automatically incrementing values. Having the server
generate automatically incrementing values eliminates potential conflicts by allowing each user to retrieve the
generated value for each inserted row.
During a call to the Update method of a DataAdapter , the database can send data back to your ADO.NET
application as output parameters or as the first returned record of the result set of a SELECT statement executed
in the same batch as the INSERT statement. The Microsoft SqlClient Data Provider for SQL Server can retrieve
these values and update the corresponding columns in the DataRow being updated.
NOTE
An alternative to using an auto incrementing value is to use the NewGuid method of a Guid object to generate a GUID, or
globally unique identifier, on the client computer that can be copied to the server as each new row is inserted. The
NewGuid method generates a 16-byte binary value that is created using an algorithm that provides a high probability
that no value will be duplicated. In a SQL Server database, a GUID is stored in a uniqueidentifier column which SQL
Server can automatically generate using the Transact-SQL NEWID() function. Using a GUID as a primary key can
adversely affect performance. SQL Server provides support for the NEWSEQUENTIALID() function, which generates a
sequential GUID that is not guaranteed to be globally unique but that can be indexed more efficiently.
F UN C T IO N DESC RIP T IO N
SCOPE_IDENTITY Returns the last identity value within the current execution
scope. SCOPE_IDENTITY is recommended for most scenarios.
@@IDENTITY Contains the last identity value generated in any table in the
current session. @@IDENTITY can be affected by triggers
and may not return the identity value that you expect.
F UN C T IO N DESC RIP T IO N
IDENT_CURRENT Returns the last identity value generated for a specific table
in any session and any scope.
The following stored procedure demonstrates how to insert a row into the Categories table and use an output
parameter to return the new identity value generated by the Transact-SQL SCOPE_IDENTITY() function.
The stored procedure can then be specified as the source of the InsertCommand of a SqlDataAdapter object. The
CommandType property of the InsertCommand must be set to StoredProcedure. The identity output is retrieved
by creating a SqlParameter that has a ParameterDirection of Output. When the InsertCommand is processed, the
auto-incremented identity value is returned and placed in the Categor yID column of the current row if you set
the UpdatedRowSource property of the insert command to UpdateRowSource.OutputParameters or to
UpdateRowSource.Both .
If your insert command executes a batch that includes both an INSERT statement and a SELECT statement that
returns the new identity value, then you can retrieve the new value by setting the UpdatedRowSource property of
the insert command to UpdateRowSource.FirstReturnedRecord .
private static void RetrieveIdentity(string connectionString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
// Create a SqlDataAdapter based on a SELECT query.
SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT CategoryID, CategoryName FROM dbo.Categories",
connection);
adapter.Update(categories);
When either of these methods is used to preserve original values in a DataRow during a DataAdapter update,
the Microsoft SqlClient Data Adapter for SQL Server performs a series of actions to set the current values of the
DataRow to new values returned by output parameters or by the first returned row of a result set, while still
preserving the original value in each DataColumn . First, the AcceptChanges method of the DataRow is called to
preserve the current values as original values, and then the new values are assigned. Following these actions,
DataRows that had their RowState property set to Added will have their RowState property set to Modified,
which may be unexpected.
How the command results are applied to each DataRow being updated is determined by the UpdatedRowSource
property of each DbCommand. This property is set to a value from the UpdateRowSource enumeration.
The following table describes how the UpdateRowSource enumeration values affect the RowState property of
updated rows.
M EM B ER N A M E DESC RIP T IO N
Example
This example demonstrates extracting changed rows from a DataTable and using a SqlDataAdapter to update
the data source and retrieve a new identity column value. The InsertCommand executes two Transact-SQL
statements; the first one is the INSERT statement, and the second one is a SELECT statement that uses the
SCOPE_IDENTITY function to retrieve the identity value.
INSERT INTO dbo.Shippers (CompanyName)
VALUES (@CompanyName);
SELECT ShipperID, CompanyName FROM dbo.Shippers
WHERE ShipperID = SCOPE_IDENTITY();
The UpdatedRowSource property of the insert command is set to UpdateRowSource.FirstReturnedRow and the
MissingSchemaAction property of the DataAdapter is set to MissingSchemaAction.AddWithKey . The DataTable is
filled and the code adds a new row to the DataTable . The changed rows are then extracted into a new
DataTable , which is passed to the DataAdapter , which then updates the server.
private static void MergeIdentityColumns(string connectionString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
// Create the DataAdapter
SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT ShipperID, CompanyName FROM dbo.Shippers",
connection);
adapter.Update(dataChanges);
connection.Close();
The OnRowUpdated event handler checks the StatementType of the SqlRowUpdatedEventArgs to determine if the
row is an insert. If it is, then the Status property is set to SkipCurrentRow. The row is updated, but the original
values in the row are preserved. In the main body of the procedure, the Merge method is called to merge the
new identity value into the original DataTable , and finally AcceptChanges is called.
USE [master]
GO
USE [MySchool]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE procedure [dbo].[CourseExtInfo] @CourseId int
as
select c.CourseID,c.Title,c.Credits,d.Name as DepartmentName
from Course as c left outer join Department as d on c.DepartmentID=d.DepartmentID
where c.CourseID=@CourseId
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create procedure [dbo].[DepartmentInfo] @DepartmentId int,@CourseCount int output
as
select @CourseCount=Count(c.CourseID)
from course as c
where c.DepartmentID=@DepartmentId
select d.DepartmentID,d.Name,d.Budget,d.StartDate,d.Administrator
from Department as d
where d.DepartmentID=@DepartmentId
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
GO
Create PROCEDURE [dbo].[GetDepartmentsOfSpecifiedYear]
@Year int,@BudgetSum money output
AS
BEGIN
SELECT @BudgetSum=SUM([Budget])
FROM [MySchool].[dbo].[Department]
Where YEAR([StartDate])=@Year
SELECT [DepartmentID]
,[Name]
,[Budget]
,[StartDate]
,[Administrator]
FROM [MySchool].[dbo].[Department]
Where YEAR([StartDate])=@Year
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[GradeOfStudent]
-- Add the parameters for the stored procedure here
@CourseTitle nvarchar(100),@FirstName nvarchar(50),
@LastName nvarchar(50),@Grade decimal(3,2) output
AS
BEGIN
select @Grade=Max(Grade)
from [dbo].[StudentGrade] as s join [dbo].[Course] as c on
s.CourseID=c.CourseID join [dbo].[Person] as p on s.StudentID=p.PersonID
where c.Title=@CourseTitle and p.FirstName=@FirstName
and p.LastName= @LastName
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[InsertPerson]
-- Add the parameters for the stored procedure here
@FirstName nvarchar(50),@LastName nvarchar(50),
@PersonID int output
AS
BEGIN
insert [dbo].[Person](LastName,FirstName) Values(@LastName,@FirstName)
set @PersonID=SCOPE_IDENTITY()
END
Go
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Course]([CourseID] [nvarchar](10) NOT NULL,
[Year] [smallint] NOT NULL,
[Title] [nvarchar](100) NOT NULL,
[Credits] [int] NOT NULL,
[DepartmentID] [int] NOT NULL,
CONSTRAINT [PK_Course] PRIMARY KEY CLUSTERED
(
[CourseID] ASC,
[Year] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Department]([DepartmentID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[Budget] [money] NOT NULL,
[StartDate] [datetime] NOT NULL,
[Administrator] [int] NULL,
CONSTRAINT [PK_Department] PRIMARY KEY CLUSTERED
(
[DepartmentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Person]([PersonID] [int] IDENTITY(1,1) NOT NULL,
[LastName] [nvarchar](50) NOT NULL,
[FirstName] [nvarchar](50) NOT NULL,
[HireDate] [datetime] NULL,
[EnrollmentDate] [datetime] NULL,
[Picture] [varbinary](max) NULL,
CONSTRAINT [PK_School.Student] PRIMARY KEY CLUSTERED
(
[PersonID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[StudentGrade]([EnrollmentID] [int] IDENTITY(1,1) NOT NULL,
[CourseID] [nvarchar](10) NOT NULL,
[StudentID] [int] NOT NULL,
[Grade] [decimal](3, 2) NOT NULL,
CONSTRAINT [PK_StudentGrade] PRIMARY KEY CLUSTERED
(
[EnrollmentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create view [dbo].[EnglishCourse]
as
select c.CourseID,c.Title,c.Credits,c.DepartmentID
from Course as c join Department as d on c.DepartmentID=d.DepartmentID
where d.Name=N'English'
GO
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C1045', 2012,
N'Calculus', 4, 7)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C1061', 2012,
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C1061', 2012,
N'Physics', 4, 1)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C2021', 2012,
N'Composition', 3, 2)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C2042', 2012,
N'Literature', 4, 2)
SET IDENTITY_INSERT [dbo].[Department] ON
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (1, N'Hu',
N'Nan', NULL, CAST(0x0000A0BF00000000 AS DateTime))
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (2,
N'Norman', N'Laura', NULL, CAST(0x0000A0BF00000000 AS DateTime))
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (3,
N'Olivotto', N'Nino', NULL, CAST(0x0000A0BF00000000 AS DateTime))
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (4,
N'Anand', N'Arturo', NULL, CAST(0x0000A0BF00000000 AS DateTime))
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (5, N'Jai',
N'Damien', NULL, CAST(0x0000A0BF00000000 AS DateTime))
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (6,
N'Holt', N'Roger', CAST(0x000097F100000000 AS DateTime), NULL)
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (7,
N'Martin', N'Randall', CAST(0x00008B1A00000000 AS DateTime), NULL)
SET IDENTITY_INSERT [dbo].[Person] OFF
SET IDENTITY_INSERT [dbo].[StudentGrade] ON
// Using stored procedure to insert a new row and retrieve the identity value
static void InsertPersonInCommand(String connectionString, String firstName, String lastName)
{
String commandText = "dbo.InsertPerson";
conn.Open();
cmd.ExecuteNonQuery();
// Using stored procedure in adapter to insert new rows and update the identity value.
static void InsertPersonInAdapter(String connectionString, String firstName, String lastName)
{
String commandText = "dbo.InsertPerson";
using (SqlConnection conn = new SqlConnection(connectionString))
{
SqlDataAdapter mySchool = new SqlDataAdapter("Select PersonID,FirstName,LastName from [dbo].
[Person]", conn);
mySchool.InsertCommand.Parameters.Add(
mySchool.InsertCommand.Parameters.Add(
new SqlParameter("@FirstName", SqlDbType.NVarChar, 50, "FirstName"));
mySchool.InsertCommand.Parameters.Add(
new SqlParameter("@LastName", SqlDbType.NVarChar, 50, "LastName"));
mySchool.Update(persons);
Console.WriteLine("Show all persons:");
ShowDataTable(persons, 14);
}
}
Console.WriteLine();
}
}
See also
Retrieving and modifying data in ADO.NET
DataAdapters and DataReaders
Update data sources with DataAdapters
Microsoft ADO.NET for SQL Server
Retrieve binary data
4/27/2022 • 3 minutes to read • Edit Online
Download ADO.NET
By default, the DataReader loads incoming data as a row as soon as an entire row of data is available. Binary
large objects (BLOBs) need different treatment, however, because they can contain gigabytes of data that cannot
be contained in a single row. The Command.ExecuteReader method has an overload that will take a
CommandBehavior argument to modify the default behavior of the DataReader . You can pass
SequentialAccess to the ExecuteReader method to modify the default behavior of the DataReader so that
instead of loading rows of data, it will load data sequentially as it is received. This is ideal for loading BLOBs or
other large data structures.
NOTE
When setting the DataReader to use SequentialAccess , it is important to note the sequence in which you access the
fields returned. The default behavior of the DataReader , which loads an entire row as soon as it is available, allows you to
access the fields returned in any order until the next row is read. When using SequentialAccess however, you must
access the fields returned by the DataReader in order. For example, if your query returns three columns, the third of
which is a BLOB, you must return the values of the first and second fields before accessing the BLOB data in the third field.
If you access the third field before the first or second fields, the first and second field values are no longer available. This is
because SequentialAccess has modified the DataReader to return data in sequence and the data is not available after
the DataReader has read past it.
When accessing the data in the BLOB field, use the GetBytes or GetChars typed accessors of the DataReader ,
which fill an array with data. You can also use GetString for character data; however, to conserve system
resources you might not want to load an entire BLOB value into a single string variable. You can instead specify a
specific buffer size of data to be returned, and a starting location for the first byte or character to be read from
the returned data. GetBytes and GetChars will return a long value, which represents the number of bytes or
characters returned. If you pass a null array to GetBytes or GetChars , the long value returned will be the total
number of bytes or characters in the BLOB. You can optionally specify an index in the array as a starting position
for the data being read.
Example
The following example returns the publisher ID and logo from the pubs sample database. The publisher ID (
pub_id ) is a character field, and the logo is an image, which is a BLOB. Because the logo field is a bitmap, the
example returns binary data using GetBytes . Notice that the publisher ID is accessed for the current row of data
before the logo, because the fields must be accessed sequentially.
// Assumes that connection is a valid SqlConnection object.
SqlCommand command = new SqlCommand(
"SELECT pub_id, logo FROM pub_info", connection);
while (reader.Read())
{
// Get the publisher id, which must occur before getting the logo.
pubID = reader.GetString(0);
// Read bytes into outByte[] and retain the number of bytes returned.
retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize);
// Continue while there are bytes beyond the size of the buffer.
while (retval == bufferSize)
{
writer.Write(outByte);
writer.Flush();
Download ADO.NET
Stored procedures can accept data as input parameters and can return data as output parameters, result sets, or
return values. The sample below illustrates how Microsoft SqlClient Data Provider for SQL Server sends and
receives input parameters, output parameters, and return values. The example inserts a new record into a table
where the primary key column is an identity column.
NOTE
If you are using stored procedures to edit or delete data using a SqlDataAdapter, make sure that you do not use SET
NOCOUNT ON in the stored procedure definition. This causes the rows affected count returned to be zero, which the
DataAdapter interprets as a concurrency conflict. In this event, a DBConcurrencyException will be thrown.
Example
The sample uses the following stored procedure to insert a new category into the Nor thwind Categories
table. The stored procedure takes the value in the Categor yName column as an input parameter and uses the
SCOPE_IDENTITY() function to retrieve the new value of the identity field, Categor yID , and return it in an
output parameter. The RETURN statement uses the @@ROWCOUNT function to return the number of rows
inserted.
The following code example uses the InsertCategory stored procedure shown above as the source for the
InsertCommand of the SqlDataAdapter. The @Identity output parameter will be reflected in the DataSet after
the record has been inserted into the database when the Update method of the SqlDataAdapter is called. The
code also retrieves the return value.
using System;
using System.Data;
using Microsoft.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString = GetConnectionString();
ReturnIdentity(connectionString);
// Console.ReadLine();
}
See also
Retrieving and modifying data in ADO.NET
DataAdapters and DataReaders
Executing a command
Microsoft ADO.NET for SQL Server
Data tracing in SqlClient
4/27/2022 • 3 minutes to read • Edit Online
Download ADO.NET
.NET features built-in data tracing functionality that is supported by the Microsoft SqlClient Data Provider for
SQL Server and SQL Server network protocols.
Tracing data access API calls can help diagnose the following problems:
Schema mismatch between client program and the database.
Database unavailability or network library problems.
Incorrect SQL whether hard coded or generated by an application.
Incorrect programming logic.
Issues resulting from the interaction between Microsoft SqlClient Data Provider for SQL Server and your
own components.
To support different trace technologies, tracing is extensible, so a developer can trace a problem at any level of
the application stack. The Microsoft SqlClient Data Provider for SQL Server takes advantage of generalized
tracing and instrumentation APIs.
For more information about setting and configuring managed tracing in .NET, see Tracing Data Access.
NOTE
The Microsoft SqlClient Data Provider for SQL Server supports the server process ID since version 2.1.0. You can get it
programmatically by using the SqlConnection.ServerProcessId property.
The ClientConnectionID and ServerProcessId are available for a SqlConnection object that successfully
establishes a connection. If a connection attempt fails, ClientConnectionID may be available via
SqlException.ToString .
The Microsoft SqlClient Data Provider for SQL Server also sends a thread-specific activity ID. The activity ID is
captured in the extended events sessions if the sessions are started with the TRACK_CAUSALITY option enabled.
For performance issues with an active connection, you can get the activity ID from the client's data access trace (
ActivityID field) and then locate the activity ID in the extended events output. The activity ID in extended events
is a 16-byte GUID (not the same as the GUID for the client connection ID) appended with a 4-bytes sequence
number. The sequence number represents the order of a request within a thread and indicates the relative
ordering of batch and RPC statements for the thread. The ActivityID is currently optionally sent for SQL batch
statements and RPC requests when data access tracing is enabled on and the 18th bit in the data access tracing
configuration word is turned ON.
The following SQL statement is a sample that uses Transact-SQL to start an extended events session that will be
stored in a ring buffer and will record the activity ID sent from a client on RPC and batch operations.
See also
Microsoft ADO.NET for SQL Server
Asynchronous programming
4/27/2022 • 15 minutes to read • Edit Online
Download ADO.NET
This article discusses support for asynchronous programming in the Microsoft SqlClient Data Provider for SQL
Server (SqlClient).
TIP
In the Microsoft SqlClient Data Provider for SQL Server, these legacy methods no longer require
Asynchronous Processing=true in the connection string.
Calling an async method doesn't create extra threads. It may use the existing I/O completion thread briefly at
the end.
The following methods in the Microsoft SqlClient Data Provider for SQL Server support asynchronous
programming:
DbConnection.OpenAsync
DbCommand.ExecuteDbDataReaderAsync
DbCommand.ExecuteNonQueryAsync
DbCommand.ExecuteReaderAsync
DbCommand.ExecuteScalarAsync
GetFieldValueAsync
IsDBNullAsync
DbDataReader.NextResultAsync
DbDataReader.ReadAsync
SqlConnection.OpenAsync
SqlCommand.ExecuteNonQueryAsync
SqlCommand.ExecuteReaderAsync
SqlCommand.ExecuteScalarAsync
SqlCommand.ExecuteXmlReaderAsync
SqlDataReader.NextResultAsync
SqlDataReader.ReadAsync
SqlBulkCopy.WriteToServerAsync
Other asynchronous members support SqlClient streaming support.
TIP
The asynchronous methods don't require Asynchronous Processing=true in the connection string. And this property is
obsolete in the Microsoft SqlClient Data Provider for SQL Server.
namespace SqlCommandCS
{
class Program
{
static void Main()
{
string str = "Data Source=(local);Initial Catalog=Northwind;"
+ "Integrated Security=SSPI";
string qs = "SELECT OrderID, CustomerID FROM dbo.Orders;";
CreateCommand(qs, str);
}
private static void CreateCommand(string queryString,
string connectionString)
{
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
}
}
}
When converted to use the asynchronous functionality, the program would look like:
using Microsoft.Data.SqlClient;
using System.Threading.Tasks;
class A {
public static void Main()
{
using (SqlConnection conn = new SqlConnection("Data Source=(local); Initial Catalog=NorthWind;
Integrated Security=SSPI"))
{
SqlCommand command = new SqlCommand("SELECT TOP 2 * FROM dbo.Orders", conn);
Add the asynchronous feature in an existing application (mixing old and new patterns)
It's also possible to add asynchronous capability (SqlConnection::OpenAsync) without changing the existing
asynchronous logic. For example, if an application currently uses:
AsyncCallback productList = new AsyncCallback(ProductList);
SqlConnection conn = new SqlConnection("Data Source=(local); Initial Catalog=NorthWind; Integrated
Security=SSPI");
conn.Open();
SqlCommand cmd = new SqlCommand("select top 2 * from orders", conn);
IAsyncResult ia = cmd.BeginExecuteReader(productList, cmd);
You can begin to use the asynchronous pattern without substantially changing the existing algorithm.
using Microsoft.Data.SqlClient;
using System.Threading.Tasks;
class A
{
static void ProductList(IAsyncResult result) { }
class program
{
static async Task PerformDBOperationsUsingProviderModel(string connectionString)
{
using (DbConnection connection = SqlClientFactory.Instance.CreateConnection())
{
connection.ConnectionString = connectionString;
await connection.OpenAsync();
using Microsoft.Data.SqlClient;
using System.Threading.Tasks;
class Program
{
static void Main()
{
string connectionString =
"Persist Security Info=False;Integrated Security=SSPI;database=Northwind;server=(local)";
Task task = ExecuteSqlTransaction(connectionString);
task.Wait();
}
try {
command.CommandText =
"Insert into Region (RegionID, RegionDescription) VALUES (555, 'Description')";
await command.ExecuteNonQueryAsync();
command.CommandText =
"Insert into Region (RegionID, RegionDescription) VALUES (556, 'Description')";
await command.ExecuteNonQueryAsync();
using Microsoft.Data.SqlClient;
using System.Threading.Tasks;
using System.Transactions;
class Program
{
public static void Main()
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
// replace these with your own values
// create two tables RegionTable1 and RegionTable2
// and add a constraint in one of these tables
// to avoid duplicate RegionID
builder.DataSource = "localhost";
builder.InitialCatalog = "Northwind";
builder.IntegratedSecurity = true;
await connection2.OpenAsync();
connection2.EnlistTransaction(transaction);
try
{
SqlCommand command1 = connection1.CreateCommand();
command1.CommandText = "Insert into RegionTable1 (RegionID, RegionDescription) VALUES
(100, 'Description')";
await command1.ExecuteNonQueryAsync();
transaction.Commit();
}
catch (Exception ex)
{
Console.WriteLine("Exception Type: {0}", ex.GetType());
Console.WriteLine(" Message: {0}", ex.Message);
try
{
transaction.Rollback();
}
catch (Exception ex2)
{
Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
Console.WriteLine(" Message: {0}", ex2.Message);
}
}
}
}
}
}
namespace Samples
{
class CancellationSample
{
public static void Main(string[] args)
{
CancellationTokenSource source = new CancellationTokenSource();
source.CancelAfter(2000); // give up after 2 seconds
try
{
Task result = CancellingAsynchronousOperations(source.Token);
result.Wait();
}
catch (AggregateException exception)
{
if (exception.InnerException is SqlException)
{
Console.WriteLine("Operation canceled");
}
else
{
throw;
}
}
}
using System.Data;
using Microsoft.Data.SqlClient;
using System.Threading;
using System.Threading.Tasks;
namespace SqlBulkCopyAsyncCodeSample
{
class Program
{
static string selectStatement = "SELECT * FROM [pubs].[dbo].[titles]";
static string createDestTableStatement =
@"CREATE TABLE {0} (
[title_id] [varchar](6) NOT NULL,
[title] [varchar](80) NOT NULL,
[type] [char](12) NOT NULL,
[pub_id] [char](4) NULL,
[price] [money] NULL,
[advance] [money] NULL,
[royalty] [int] NULL,
[ytd_sales] [int] NULL,
[notes] [varchar](200) NULL,
[pubdate] [datetime] NOT NULL)";
// Replace the connection string if needed, for instance to connect to SQL Express: @"Server=
(local)\SQLEXPRESS;Database=Demo;Integrated Security=true"
// static string connectionString = @"Server=(localdb)\V11.0;Database=Demo";
static string connectionString = @"Server=(local);Database=Demo;Integrated Security=true";
// Replace the Server name with your actual sql azure server name and User ID/Password
static string azureConnectionString = @"Server=SqlAzure;User ID=<myUserID>;Password=
<myPassword>;Database=Demo";
// 3.2 Add new Async.NET capabilities in an existing application (Mixing synchronous and
asynchronous calls)
private static async Task MixSyncAsyncSqlBulkCopy()
{
using (SqlConnection conn1 = new SqlConnection(connectionString))
{
conn1.Open();
using (SqlCommand cmd = new SqlCommand(selectStatement, conn1))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
using (SqlConnection conn2 = new SqlConnection(connectionString))
{
await conn2.OpenAsync();
string temptable = "[#" + Guid.NewGuid().ToString("N") + "]";
SqlCommand createCmd = new SqlCommand(string.Format(createDestTableStatement,
temptable), conn2);
await createCmd.ExecuteNonQueryAsync();
using (SqlBulkCopy bcp = new SqlBulkCopy(conn2))
{
bcp.DestinationTableName = temptable;
await bcp.WriteToServerAsync(reader);
}
}
}
}
}
}
// 3.5 Copying data from SQL Server to SQL Azure in .NET 4.5
private static async Task AsyncSqlBulkCopySqlServerToSqlAzure()
{
using (SqlConnection srcConn = new SqlConnection(connectionString))
using (SqlConnection destConn = new SqlConnection(azureConnectionString))
{
await srcConn.OpenAsync();
await destConn.OpenAsync();
using (SqlCommand srcCmd = new SqlCommand(selectStatement, srcConn))
{
using (SqlDataReader reader = await srcCmd.ExecuteReaderAsync())
{
string temptable = "[#" + Guid.NewGuid().ToString("N") + "]";
using (SqlCommand destCmd = new SqlCommand(string.Format(createDestTableStatement,
temptable), destConn))
{
await destCmd.ExecuteNonQueryAsync();
using (SqlBulkCopy bcp = new SqlBulkCopy(destConn))
{
bcp.DestinationTableName = temptable;
await bcp.WriteToServerAsync(reader);
}
}
}
}
}
}
using System.Data.Common;
using Microsoft.Data.SqlClient;
using System.Threading.Tasks;
class Class1
{
static void Main()
{
Task task = MultipleCommands();
task.Wait();
}
int vendorID;
SqlDataReader productReader = null;
string vendorSQL =
"SELECT BusinessEntityID, Name FROM Purchasing.Vendor";
string productSQL =
"SELECT Production.Product.Name FROM Production.Product " +
"INNER JOIN Purchasing.ProductVendor " +
"ON Production.Product.ProductID = " +
"Purchasing.ProductVendor.ProductID " +
"WHERE Purchasing.ProductVendor.BusinessEntityID = @VendorId";
productCmd.Parameters.Add("@VendorId", SqlDbType.Int);
await awConnection.OpenAsync();
using (SqlDataReader vendorReader = await vendorCmd.ExecuteReaderAsync())
{
while (await vendorReader.ReadAsync())
{
Console.WriteLine(vendorReader["Name"]);
vendorID = (int)vendorReader["BusinessEntityID"];
productCmd.Parameters["@VendorId"].Value = vendorID;
// The following line of code requires a MARS-enabled connection.
productReader = await productCmd.ExecuteReaderAsync();
using (productReader)
{
while (await productReader.ReadAsync())
{
Console.WriteLine(" " +
productReader["Name"].ToString());
}
}
}
}
}
}
}
NOTE
The following example uses the sample AdventureWorks database. The connection string provided in the sample code
assumes that the database is installed and available on the local computer. Modify the connection string as necessary for
your environment.
using System.Data.Common;
using Microsoft.Data.SqlClient;
using System.Threading.Tasks;
class Program
{
static void Main()
{
Task task = ReadingAndUpdatingData();
task.Wait();
}
string vendorSQL =
"SELECT BusinessEntityID, Name FROM Purchasing.Vendor " +
"WHERE CreditRating = 5";
string prodVendSQL =
"SELECT ProductID, MaxOrderQty, MinOrderQty, OnOrderQty " +
"FROM Purchasing.ProductVendor " +
"WHERE BusinessEntityID = @VendorID";
string updateSQL =
"UPDATE Purchasing.ProductVendor " +
"SET OnOrderQty = @OrderQty " +
"WHERE ProductID = @ProductID AND BusinessEntityID = @VendorID";
vendorID = (int)vendorReader["BusinessEntityID"];
prodVendCmd.Parameters["@VendorID"].Value = vendorID;
prodVendReader = await prodVendCmd.ExecuteReaderAsync();
using (prodVendReader)
{
while (await prodVendReader.ReadAsync())
{
productID = (int)prodVendReader["ProductID"];
if (prodVendReader["OnOrderQty"] == DBNull.Value)
{
minOrderQty = (int)prodVendReader["MinOrderQty"];
onOrderQty = minOrderQty;
}
else
{
maxOrderQty = (int)prodVendReader["MaxOrderQty"];
onOrderQty = (int)(maxOrderQty / 2);
}
updateCmd.Parameters["@OrderQty"].Value = onOrderQty;
updateCmd.Parameters["@ProductID"].Value = productID;
updateCmd.Parameters["@VendorID"].Value = vendorID;
updateCmd.Parameters["@VendorID"].Value = vendorID;
See also
Retrieving and modifying data in ADO.NET
Microsoft ADO.NET for SQL Server
SqlClient streaming support
4/27/2022 • 11 minutes to read • Edit Online
Download ADO.NET
Streaming support between SQL Server and an application supports unstructured data on the server
(documents, images, and media files). A SQL Server database can store binary large objects (BLOBs), but
retrieving BLOBS can use a lot of memory.
Streaming support to and from SQL Server simplifies writing applications that stream data, without having to
fully load the data into memory, resulting in fewer memory overflow exceptions.
Streaming support will also enable middle-tier applications to scale better, especially in scenarios where
business objects connect to Azure SQL in order to send, retrieve, and manipulate large BLOBs.
WARNING
The members that support streaming are used to retrieve data from queries and to pass parameters to queries and
stored procedures. The streaming feature addresses basic OLTP and data migration scenarios and is applicable to on-
premises and off-premises data migrations environments.
NOTE
Disposing a SqlCommand object or calling Cancel must cancel any streaming operation. If an application sends
CancellationToken, cancellation is not guaranteed.
namespace StreamingFromServer
{
class Program
{
private const string connectionString = @"Server=localhost;Database=Demo;Integrated Security=true";
Console.WriteLine("Done");
}
// Application retrieving a large BLOB from SQL Server in .NET 4.5 using the new asynchronous
capability
private static async Task CopyBinaryValueToFile()
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
await connection.OpenAsync();
using (SqlCommand command = new SqlCommand("SELECT [bindata] FROM [Streams] WHERE [id]=@id",
connection))
{
command.Parameters.AddWithValue("id", 1);
// The reader needs to be executed with the SequentialAccess behavior to enable network
streaming
// Otherwise ReadAsync will buffer the entire BLOB into memory which can cause
scalability issues or even OutOfMemoryExceptions
using (SqlDataReader reader = await
command.ExecuteReaderAsync(CommandBehavior.SequentialAccess))
{
if (await reader.ReadAsync())
{
if (!(await reader.IsDBNullAsync(0)))
{
using (FileStream file = new FileStream("binarydata.bin", FileMode.Create,
FileAccess.Write))
{
using (Stream data = reader.GetStream(0))
{
// The reader needs to be executed with the SequentialAccess behavior to enable network
streaming
// Otherwise ReadAsync will buffer the entire text document into memory which can cause
scalability issues or even OutOfMemoryExceptions
using (SqlDataReader reader = await
command.ExecuteReaderAsync(CommandBehavior.SequentialAccess))
{
while (await reader.ReadAsync())
{
Console.Write("{0}: ", reader.GetInt32(0));
if (await reader.IsDBNullAsync(1))
{
Console.Write("(NULL)");
}
else
{
char[] buffer = new char[4096];
int charsRead = 0;
using (TextReader data = reader.GetTextReader(1))
{
do
{
// Grab each chunk of text and write it to the console
// If you are writing to a TextWriter you should use WriteAsync or
WriteLineAsync
charsRead = await data.ReadAsync(buffer, 0, buffer.Length);
Console.Write(buffer, 0, charsRead);
} while (charsRead > 0);
}
}
Console.WriteLine();
}
}
}
}
}
// The reader needs to be executed with the SequentialAccess behavior to enable network
streaming
// Otherwise ReadAsync will buffer the entire Xml Document into memory which can cause
scalability issues or even OutOfMemoryExceptions
using (SqlDataReader reader = await
command.ExecuteReaderAsync(CommandBehavior.SequentialAccess))
{
while (await reader.ReadAsync())
{
Console.WriteLine("{0}: ", reader.GetInt32(0));
if (await reader.IsDBNullAsync(1))
{
Console.WriteLine("\t(NULL)");
Console.WriteLine("\t(NULL)");
}
else
{
using (XmlReader xmlReader = reader.GetXmlReader(1))
{
int depth = 1;
// NOTE: The XmlReader returned by GetXmlReader does NOT support async
operations
// See the example below (PrintXmlValuesViaNVarChar) for how to get an
XmlReader with asynchronous capabilities
while (xmlReader.Read())
{
switch (xmlReader.NodeType)
{
case XmlNodeType.Element:
Console.WriteLine("{0}<{1}>", new string('\t', depth),
xmlReader.Name);
depth++;
break;
case XmlNodeType.Text:
Console.WriteLine("{0}{1}", new string('\t', depth),
xmlReader.Value);
break;
case XmlNodeType.EndElement:
depth--;
Console.WriteLine("{0}</{1}>", new string('\t', depth),
xmlReader.Name);
break;
}
}
}
}
}
}
}
}
}
// Cast the XML into NVarChar to enable GetTextReader - trying to use GetTextReader on an
XML type will throw an exception
using (SqlCommand command = new SqlCommand("SELECT [id], CAST([xmldata] AS NVARCHAR(MAX))
FROM [Streams]", connection))
{
// The reader needs to be executed with the SequentialAccess behavior to enable network
streaming
// Otherwise ReadAsync will buffer the entire Xml Document into memory which can cause
// Otherwise ReadAsync will buffer the entire Xml Document into memory which can cause
scalability issues or even OutOfMemoryExceptions
using (SqlDataReader reader = await
command.ExecuteReaderAsync(CommandBehavior.SequentialAccess))
{
while (await reader.ReadAsync())
{
Console.WriteLine("{0}:", reader.GetInt32(0));
if (await reader.IsDBNullAsync(1))
{
Console.WriteLine("\t(NULL)");
}
else
{
// Grab the row as a TextReader, then create an XmlReader on top of it
// We are not keeping a reference to the TextReader since the XmlReader is
created with the "CloseInput" setting (so it will close the TextReader when needed)
using (XmlReader xmlReader = XmlReader.Create(reader.GetTextReader(1),
xmlSettings))
{
int depth = 1;
// The XmlReader above now supports asynchronous operations, so we can
use ReadAsync here
while (await xmlReader.ReadAsync())
{
switch (xmlReader.NodeType)
{
case XmlNodeType.Element:
Console.WriteLine("{0}<{1}>", new string('\t', depth),
xmlReader.Name);
depth++;
break;
case XmlNodeType.Text:
// Depending on what your data looks like, you should either
use Value or GetValueAsync
// Value has less overhead (since it doesn't create a Task),
but it may also block if additional data is required
Console.WriteLine("{0}{1}", new string('\t', depth), await
xmlReader.GetValueAsync());
break;
case XmlNodeType.EndElement:
depth--;
Console.WriteLine("{0}</{1}>", new string('\t', depth),
xmlReader.Name);
break;
}
}
}
}
}
}
}
}
}
}
}
using System;
using System.Data;
using Microsoft.Data.SqlClient;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace StreamingToServer
{
class Program
{
private const string connectionString = @"Server=localhost;Database=Demo2;Integrated Security=true";
StreamBLOBToServer().Wait();
StreamTextToServer().Wait();
Console.WriteLine("Done");
}
// This is used to generate the files which are used by the other sample methods
private static void CreateDemoFiles()
{
Random rand = new Random();
byte[] data = new byte[1024];
rand.NextBytes(data);
NOTE
Before running the following sample, be sure the Demo and Demo2 databases are created.
using System;
using System.Data;
using Microsoft.Data.SqlClient;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace StreamingFromServerToAnother
{
class Program
{
private const string connectionString = @"Server=localhost;Database=Demo2;Integrated Security=true";
static void Main(string[] args)
{
// For this example, we don't want to cancel
// So we can pass in a "blank" cancellation token
E2EStream(CancellationToken.None).Wait();
Console.WriteLine("Done");
}
// Note that we are using the same cancellation token for calls to both
connections\commands
// Also we can start both the connection opening asynchronously, and then wait for both
to complete
Task openReadConn = readConn.OpenAsync(cancellationToken);
Task openWriteConn = writeConn.OpenAsync(cancellationToken);
await Task.WhenAll(openReadConn, openWriteConn);
// Add an empty parameter to the write command which will be used for the
streams we are copying
// Size is set to -1 to indicate "MAX"
SqlParameter streamParameter = writeCmd.Parameters.Add("@bindata",
SqlDbType.Binary, -1);
// Set the parameter value to the stream source that was opened
streamParameter.Value = dataStream;
Download ADO.NET
Microsoft.Data.SqlClient
Microsoft.Data.SqlClient provides access to versions of SQL Server, which encapsulates database-specific
protocols. Microsoft.Data.SqlClient includes a tabular data stream (TDS) parser to communicate directly with
SQL Server.
NOTE
To use the Microsoft SqlClient Data Provider for SQL Server, an application must reference the Microsoft.Data.SqlClient
namespace.
In this section
SQL Server security
Provides an overview of SQL Server security features, and application scenarios for creating secure ADO.NET
applications that target SQL Server.
SQL Server data types and ADO.NET
Describes how to work with SQL Server data types and how they interact with .NET data types.
SQL Server binary and large-value data
Describes how to work with large value data in SQL Server.
SQL Server data operations in ADO.NET
Describes how to work with data in SQL Server. Contains sections about bulk copy operations, MARS,
asynchronous operations, and table-valued parameters.
SQL Server features and ADO.NET
Describes SQL Server features that are useful for ADO.NET application developers.
For complete documentation of the SQL Server Database Engine, see SQL Server Books Online for the version
of SQL Server you are using.
SQL Server Books Online
SQL Server security
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
SQL Server has many features that support creating secure database applications.
Common security considerations, such as data theft or vandalism, apply regardless of the version of SQL Server
you are using. Data integrity should also be considered as a security issue. If data is not protected, it is possible
that it could become worthless if ad hoc data manipulation is permitted and the data is inadvertently or
maliciously modified with incorrect values or deleted entirely. In addition, there are often legal requirements that
must be adhered to, such as the correct storage of confidential information. Storing some kinds of personal data
is proscribed entirely, depending on the laws that apply in a particular jurisdiction.
Each version of SQL Server has different security features, as does each version of Windows, with later versions
having enhanced functionality over earlier ones. It is important to understand that security features alone
cannot guarantee a secure database application. Each database application is unique in its requirements,
execution environment, deployment model, physical location, and user population. Some applications that are
local in scope may need only minimal security whereas other local applications or applications deployed over
the Internet may require stringent security measures and ongoing monitoring and evaluation.
The security requirements of a SQL Server database application should be considered at design time, not as an
afterthought. Evaluating threats early in the development cycle gives you the opportunity to mitigate potential
damage wherever a vulnerability is detected.
Even if the initial design of an application is sound, new threats may emerge as the system evolves. By creating
multiple lines of defense around your database, you can minimize the damage inflicted by a security breach.
Your first line of defense is to reduce the attack surface area by never to granting more permissions than are
absolutely necessary.
The topics in this section briefly describe the security features in SQL Server that are relevant for developers,
with links to relevant topics in SQL Server Books Online and other resources that provide more detailed
coverage.
In this section
Authentication in SQL Server
Describes logins and authentication in SQL Server and provides links to additional resources.
Azure Active Directory authentication
Describes how to use supported Azure Active Directory authentication modes to connect to Azure SQL data
sources with SqlClient.
Application security scenarios in SQL Server
Contains topics discussing various application security scenarios for ADO.NET and SQL Server applications.
SQL Server Express security
Describes security considerations for SQL Server Express.
Related sections
Security Center for SQL Server Database Engine and Azure SQL Database
Describes security considerations for SQL Server and Azure SQL Database.
Security Considerations for a SQL Server Installation
Describes security concerns to consider before installing SQL Server.
Next steps
SQL Server and ADO.NET
Authentication in SQL Server
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
SQL Server supports two authentication modes, Windows authentication mode and mixed mode.
Windows authentication is the default, and is often referred to as integrated security because this SQL
Server security model is tightly integrated with Windows. Specific Windows user and group accounts are
trusted to log in to SQL Server. Windows users who have already been authenticated do not have to
present additional credentials.
Mixed mode supports authentication both by Windows and by SQL Server. User name and password
pairs are maintained within SQL Server.
IMPORTANT
We recommend using Windows authentication wherever possible. Windows authentication uses a series of encrypted
messages to authenticate users in SQL Server. When SQL Server logins are used, SQL Server login names and encrypted
passwords are passed across the network, which makes them less secure.
With Windows authentication, users are already logged onto Windows and do not have to log on separately to
SQL Server. The following SqlConnection.ConnectionString specifies Windows authentication without requiring
users to provide a user name or password.
"Server=MSSQL1;Database=AdventureWorks;Integrated Security=true;"
NOTE
Logins are distinct from database users. You must map logins or Windows groups to database users or roles in a separate
operation. You then grant permissions to users or roles to access database objects.
Authentication scenarios
Windows authentication is usually the best choice in the following situations:
There is a domain controller.
The application and the database are on the same computer.
You are using an instance of SQL Server Express or LocalDB.
SQL Server logins are often used in the following situations:
If you have a workgroup.
Users connect from different, non-trusted domains.
Internet applications, such as ASP.NET.
NOTE
Specifying Windows authentication does not disable SQL Server logins. Use the ALTER LOGIN DISABLE Transact-SQL
statement to disable highly-privileged SQL Server logins.
Login types
SQL Server supports three types of logins:
A local Windows user account or trusted domain account. SQL Server relies on Windows to authenticate
the Windows user accounts.
Windows group. Granting access to a Windows group grants access to all Windows user logins that are
members of the group.
SQL Server login. SQL Server stores both the username and a hash of the password in the master
database, by using internal authentication methods to verify login attempts.
NOTE
SQL Server provides logins created from certificates or asymmetric keys that are used only for code signing. They cannot
be used to connect to SQL Server.
IMPORTANT
SQL Server installs with a SQL Server login named sa (an abbreviation of "system administrator"). Assign a strong
password to the sa login and do not use the sa login in your application. The sa login maps to the sysadmin fixed
server role, which has irrevocable administrative credentials on the whole server. There are no limits to the potential
damage if an attacker gains access as a system administrator. All members of the Windows BUILTIN\Administrators
group (the local administrator's group) are members of the sysadmin role by default, but can be removed from that role.
IMPORTANT
Concatenating connection strings from user input can leave you vulnerable to a connection string injection attack. Use
the SqlConnectionStringBuilder to create syntactically valid connection strings at run time.
External resources
For more information, see the following resources.
Next steps
Application security scenarios in SQL Server
Using Azure Active Directory authentication with
SqlClient
4/27/2022 • 13 minutes to read • Edit Online
Download ADO.NET
This article describes how to connect to Azure SQL data sources by using Azure Active Directory (Azure AD)
authentication from a .NET application with SqlClient.
Azure AD authentication uses identities in Azure AD to access Azure SQL data sources such as Azure SQL
Database, Azure SQL Managed Instance, and Azure Synapse Analytics. The Microsoft.Data.SqlClient
namespace allows client applications to specify Azure AD credentials in different authentication modes when
they're connecting to Azure SQL Database. To use Azure AD authentication, you must configure your Azure SQL
data source. For more information, see Configure and manage Azure AD authentication with Azure SQL.
When you set the Authentication connection property in the connection string, the client can choose a
preferred Azure AD authentication mode according to the value provided:
The earliest Microsoft.Data.SqlClient version supports Active Directory Password for .NET
Framework, .NET Core, and .NET Standard. It also supports Active Directory Integrated authentication
and Active Directory Interactive authentication for .NET Framework.
Starting with Microsoft.Data.SqlClient 2.0.0, support for Active Directory Integrated authentication
and Active Directory Interactive authentication has been extended across .NET Framework, .NET Core,
and .NET Standard.
A new Active Directory Service Principal authentication mode is also added in SqlClient 2.0.0. It makes
use of the client ID and secret of a service principal identity to accomplish authentication.
More authentication modes are added in Microsoft.Data.SqlClient 2.1.0, including
Active Directory Device Code Flow and Active Directory Managed Identity (also known as
Active Directory MSI ). These new modes enable the application to acquire an access token to connect to
the server.
For information about Azure AD authentication beyond what the following sections describe, see Connecting to
SQL Database by using Azure Active Directory authentication.
M IC RO SO F T. DATA . SQ L C L IEN T
VA L UE DESC RIP T IO N VERSIO N
Active Directory Device Code Flow Authenticate with an Azure AD identity 2.1.0+
by using Device Code Flow mode
1 Before Microsoft.Data.SqlClient 2.0.0, Active Directory Integrated , and Active Directory Interactive
authentication modes are supported only on .NET Framework.
The following example demonstrates Active Directory Managed Identity authentication with a user-assigned
managed identity with Microsoft.Data.SqlClient v3.0 onwards .
The following example demonstrates Active Directory Managed Identity authentication with a user-assigned
managed identity with Microsoft.Data.SqlClient v2.1 .
NOTE
InteractiveBrowserCredential is disabled in the driver implementation of "Active Directory Default", and "Active Directory
Interactive" is the only option available to acquire a token using MFA/Interactive authentication.
Further customization options are not available at the moment.
The following example shows how to use Active Director y Default authentication.
using System;
using System.Threading.Tasks;
using Microsoft.Identity.Client;
using Microsoft.Data.SqlClient;
namespace CustomAuthenticationProviderExamples
{
public class Program
{
public static void Main()
{
SqlAuthenticationProvider authProvider = new
ActiveDirectoryAuthenticationProvider(CustomDeviceFlowCallback);
SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow,
authProvider);
using (SqlConnection sqlConnection = new SqlConnection("Server=
<myserver>.database.windows.net;Authentication=Active Directory Device Code Flow;Database=<db>;"))
{
sqlConnection.Open();
Console.WriteLine("Connected successfully!");
}
}
namespace CustomAuthenticationProviderExamples
{
public class Program
{
public static void Main()
{
// Supported for all authentication modes supported by ActiveDirectoryAuthenticationProvider
ActiveDirectoryAuthenticationProvider provider = new ActiveDirectoryAuthenticationProvider("
<application_client_id>");
if (provider.IsSupported(SqlAuthenticationMethod.ActiveDirectoryInteractive))
{
SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryInteractive,
provider);
}
The following example shows how to set an application client ID through a configuration section.
<configuration>
<configSections>
<section name="SqlClientAuthenticationProviders"
type="Microsoft.Data.SqlClient.SqlClientAuthenticationProviderConfigurationSection,
Microsoft.Data.SqlClient" />
</configSections>
<SqlClientAuthenticationProviders applicationClientId ="<GUID>" />
</configuration>
<!--or-->
<configuration>
<configSections>
<section name="SqlAuthenticationProviders"
type="Microsoft.Data.SqlClient.SqlAuthenticationProviderConfigurationSection,
Microsoft.Data.SqlClient" />
</configSections>
<SqlAuthenticationProviders applicationClientId ="<GUID>" />
</configuration>
namespace CustomAuthenticationProviderExamples
{
/// <summary>
/// Example demonstrating creating a custom device code flow authentication provider and attaching it to
the driver.
/// This is helpful for applications that wish to override the Callback for the Device Code Result
implemented by the SqlClient driver.
/// </summary>
public class CustomDeviceCodeFlowAzureAuthenticationProvider : SqlAuthenticationProvider
{
public override async Task<SqlAuthenticationToken> AcquireTokenAsync(SqlAuthenticationParameters
parameters)
{
string clientId = "my-client-id";
string clientName = "My Application Name";
string s_defaultScopeSuffix = "/.default";
// For .NET Framework, .NET Core, and .NET Standard targeted applications
// Sets a callback method that's invoked with a custom web UI instance that will let the user sign in
with Azure AD, present consent if needed, and get back the authorization code.
// Applicable when working with Active Directory Interactive authentication.
public void SetAcquireAuthorizationCodeAsyncCallback(Func<Uri, Uri, CancellationToken, Task<Uri>>
acquireAuthorizationCodeAsyncCallback);
// For .NET Framework, .NET Core, and .NET Standard targeted applications
// Clears cached user tokens from the token provider.
public static void ClearUserTokenCache();
}
See also
Application and service principal objects in Azure Active Directory
Authentication flows
Application security scenarios in SQL Server
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
There is no single correct way to create a secure SQL Server client application. Every application is unique in its
requirements, deployment environment, and user population. An application that is reasonably secure when it is
initially deployed can become less secure over time. It is impossible to predict with any accuracy what threats
may emerge in the future.
SQL Server, as a product, has evolved over many versions to incorporate the latest security features that enable
developers to create secure database applications. However, security doesn't come in the box; it requires
continual monitoring and updating.
Common threats
Developers need to understand security threats, the tools provided to counter them, and how to avoid self-
inflicted security holes. Security can best be thought of as a chain, where a break in any one link compromises
the strength of the whole. The following list includes some common security threats that are discussed in more
detail in the topics in this section.
SQL injection
SQL Injection is the process by which a malicious user enters Transact-SQL statements instead of valid input. If
the input is passed directly to the server without being validated and if the application inadvertently executes
the injected code, then the attack has the potential to damage or destroy data. You can thwart SQL Server
injection attacks by using stored procedures and parameterized commands, avoiding dynamic SQL, and
restricting permissions on all users.
Elevation of privilege
Elevation of privilege attacks occur when a user is able to assume the privileges of a trusted account, such as an
owner or administrator. Always run under least-privileged user accounts and assign only needed permissions.
Avoid using administrative or owner accounts for executing code. This limits the amount of damage that can
occur if an attack succeeds. When performing tasks that require additional permissions, use procedure signing
or impersonation only for the duration of the task. You can sign stored procedures with certificates or use
impersonation to temporarily assign permissions.
Probing and intelligent observation
A probing attack can use error messages generated by an application to search for security vulnerabilities.
Implement error handling in all procedural code to prevent SQL Server error information from being returned
to the end user.
Authentication
A connection string injection attack can occur when using SQL Server logins if a connection string based on user
input is constructed at run time. If the connection string is not checked for valid keyword pairs, an attacker can
insert extra characters, potentially accessing sensitive data or other resources on the server. Use Windows
authentication wherever possible. If you must use SQL Server logins, use the SqlConnectionStringBuilder to
create and validate connection strings at run time.
Passwords
Many attacks succeed because an intruder was able to obtain or guess a password for a privileged user.
Passwords are your first line of defense against intruders, so setting strong passwords is essential to the security
of your system. Create and enforce password policies for mixed mode authentication.
Always assign a strong password to the sa account, even when using Windows Authentication.
In this section
Writing secure dynamic SQL in SQL Server
Describes techniques for writing secure dynamic SQL using stored procedures.
Next steps
SQL Server security
Writing secure dynamic SQL in SQL Server
4/27/2022 • 3 minutes to read • Edit Online
Download ADO.NET
SQL Injection is the process by which a malicious user enters Transact-SQL statements instead of valid input. If
the input is passed directly to the server without being validated and if the application inadvertently executes
the injected code, the attack has the potential to damage or destroy data.
Any procedure that constructs SQL statements should be reviewed for injection vulnerabilities because SQL
Server will execute all syntactically valid queries that it receives. Even parameterized data can be manipulated by
a skilled and determined attacker. If you use dynamic SQL, be sure to parameterize your commands, and never
include parameter values directly into the query string.
External resources
For more information, see the following resources.
Stored Procedures and SQL Injection in SQL Server Books Topics describe how to create stored procedures and how
Online SQL Injection works.
Next steps
Application security scenarios in SQL Server
SQL Server Express security
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Microsoft SQL Server Express Edition (SQL Server Express) is based on Microsoft SQL Server, and supports
most of the features of the database engine. It is designed so that nonessential features and network
connectivity are off by default. This reduces the surface area available for attack by a malicious user.
SQL Server Express is usually installed as a named instance. The default name of the instance is SQLExpress . A
named instance is identified by the network name of the computer plus the instance name that you specify
during installation.
Network access
For security reasons, networking protocols are disabled by default in SQL Server Express. This prevents attacks
from outside users that might compromise the computer that hosts the instance of SQL Server Express. You
must explicitly enable network connectivity and start the SQL Server Browser service to connect to a SQL Server
Express instance from another computer.
Once network connectivity is enabled, a SQL Server Express instance has the same security requirements as the
other editions of SQL Server.
User instances
A user instance is a separate instance of the SQL Server Express database engine that is generated by a parent
instance of SQL Server Express. The primary goal of a user instance is to allow users who are running Windows
under a least-privilege user account to have system administrator ( sysadmin ) privileges on the SQL Server
Express instance on their local computer. User instances are not intended for users who are system
administrators on their own computers.
A user instance is generated from a primary instance of SQL Server or SQL Server Express on behalf of a user. It
runs as a user process under the Windows security context of the user, not as a service. SQL Server logins are
disallowed; only Windows logins are supported. This prevents software executing on a user instance from
making system-wide changes that the user would not have permissions to make. A user instance is also known
as a child or client instance, and is sometimes referred to by using the RANU acronym ("run as normal user").
Each user instance is isolated from its parent instance and from other user instances running on the same
computer. Databases installed on user instances are opened in single-user mode only; multiple users cannot
connect to them. Replication, distributed queries and remote connections are disabled for user instances. When
connected to a user instance, users do not have any special privileges on the parent SQL Server Express
instance.
External resources
For more information about SQL Server Express, see the following resources.
Microsoft SQL Server 2005 Express Edition Books Online Complete documentation for SQL Server 2005 Express
Edition.
RESO URC E DESC RIP T IO N
User Instances for Non-Administrators in SQL Server Books Describes how to create and deploy user instances.
Online
SQL Server Express user instances Describes user instance capabilities in an ADO.NET
application. Provides information about how to enable a user
instance, connect to a user instance using a SqlConnection,
user instance lifetime, and user instance scenarios.
Next steps
SQL Server security
SQL Server Express user instances
SQL Server data types and ADO.NET
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
SQL Server and the .NET are based on different type systems, which can result in potential data loss. To preserve
data integrity, the Microsoft SqlClient Data Provider for SQL Server (Microsoft.Data.SqlClient) provides typed
accessor methods for working with SQL Server data. You can use the enumerations in the SqlDbType classes to
specify SqlParameter data types.
SQL Server 2008 introduces new data types that are designed to meet business needs to work with date and
time, structured, semi-structured, and unstructured data. These are documented in SQL Server 2008 Books
Online.
The SQL Server data types that are available for use in your application depends on the version of SQL Server
that you are using. For more information, see Data Types (Database Engine) from SQL Server Books Online.
In this section
SqlTypes and the DataSet
Describes type support for SqlTypes in the DataSet .
Handling null values
Demonstrates how to work with null values and three-valued logic.
Comparing GUID and uniqueidentifier values
Demonstrates how to work with GUID and uniqueidentifier values in SQL Server and .NET.
Date and time data
Describes how to use the new date and time data types introduced in SQL Server 2008.
Large UDTs
Demonstrates how to retrieve data from large value UDTs introduced in SQL Server 2008.
XML data in SQL Server
Describes how to work with XML data retrieved from SQL Server.
Reference
DataSet
Describes the DataSet class and all of its members.
System.Data.SqlTypes
Describes the SqlTypes namespace and all of its members.
SqlDbType
Describes the SqlDbType enumeration and all of its members.
DbType
Describes the DbType enumeration and all of its members.
Next steps
Table-valued parameters
SQL Server binary and large-value data
SqlTypes and the DataSet
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
ADO.NET 2.0 introduced enhanced type support for the DataSet through the System.Data.SqlTypes namespace.
The types in System.Data.SqlTypes are designed to provide data types with the same semantics and precision as
the data types in a SQL Server database. Each data type in System.Data.SqlTypes has an equivalent data type in
SQL Server, with the same underlying data representation.
Using System.Data.SqlTypes directly in a DataSet confers several benefits when working with SQL Server data
types. System.Data.SqlTypes supports the same semantics as SQL Server native data types. Specifying one of
the System.Data.SqlTypes in the definition of a DataColumn eliminates the loss of precision that can occur when
converting decimal or numeric data types to one of the common language runtime (CLR) data types.
The following example creates a DataTable object, explicitly defining the DataColumn data types by using
System.Data.SqlTypes instead of CLR types. The code fills the DataTable with data from the
Sales.SalesOrderDetail table in the AdventureWorks database in SQL Server. The output displayed in the console
window shows the data type of each column, and the values retrieved from SQL Server.
using Microsoft.Data.SqlClient;
using System.Data.SqlTypes;
class Program
{
static void Main()
{
string connectionString = GetConnectionString();
GetSqlTypesAW(connectionString);
Console.ReadLine();
}
static private void GetSqlTypesAW(string connectionString)
{
// Create a DataTable and specify a SqlType
// for each column.
DataTable table = new DataTable();
DataColumn icolumnolumn =
table.Columns.Add("SalesOrderID", typeof(SqlInt32));
DataColumn priceColumn =
table.Columns.Add("UnitPrice", typeof(SqlMoney));
DataColumn totalColumn =
table.Columns.Add("LineTotal", typeof(SqlDecimal));
DataColumn columnModifiedDate =
table.Columns.Add("ModifiedDate", typeof(SqlDateTime));
Download ADO.NET
A null value in a relational database is used when the value in a column is unknown or missing. A null is neither
an empty string (for character or datetime data types) nor a zero value (for numeric data types). The ANSI SQL-
92 specification states that a null must be the same for all data types, so that all nulls are handled consistently.
The System.Data.SqlTypes namespace provides null semantics by implementing the INullable interface. Each of
the data types in System.Data.SqlTypes has its own IsNull property and a Null value that can be assigned to
an instance of that data type.
NOTE
The .NET Framework version 2.0 and .NET Core version 1.0 introduced support for nullable types, which allow
programmers to extend a value type to represent all values of the underlying type. These CLR nullable types represent an
instance of the Nullable structure. This capability is especially useful when value types are boxed and unboxed, providing
enhanced compatibility with object types. CLR nullable types are not intended for storage of database nulls because an
ANSI SQL null does not behave the same way as a null reference (or Nothing in Visual Basic). For working with
database ANSI SQL null values, use System.Data.SqlTypes nulls rather than Nullable. For more information on working
with CLR nullable types in C# see Nullable Types, and for C# see Using Nullable Types.
Use the IS NULL or IS NOT NULL predicate to test for a null value. This can add complexity to the WHERE clause.
For example, the TerritoryID column in the AdventureWorks Customer table allows null values. If a SELECT
statement is to test for null values in addition to others, it must include an IS NULL predicate:
If you set ANSI_NULLS off in SQL Server, you can create expressions that use the equality operator to compare
to null. However, you can't prevent different connections from setting null options for that connection. Using IS
NULL to test for null values always works, regardless of the ANSI_NULLS settings for a connection.
Setting ANSI_NULLS off is not supported in a DataSet , which always follows the ANSI SQL-92 standard for
handling null values in System.Data.SqlTypes.
derivedUdt.Null
For UDT columns, nulls are always stored based on the type associated with the DataColumn . Consider the case
of a UDT associated with a DataColumn that does not implement INullable while its sub-class does. In this case,
if a strongly typed null value associated with the derived class is assigned, it is stored as an untyped
DbNull.Value , because null storage is always consistent with the DataColumn's data type.
NOTE
The Nullable<T> or Nullable structure is not currently supported in the DataSet .
using Microsoft.Data.SqlClient;
using System.Data.SqlTypes;
class Program
{
static void Main()
{
WorkWithSqlNulls();
Console.ReadLine();
}
static private void WorkWithSqlNulls()
{
DataTable table = new DataTable();
namespace SqlNullsCS
{
class Program
{
static void Main()
{
CompareNulls();
Console.ReadLine();
}
private static void CompareNulls()
{
// Create two new null strings.
SqlString a = new SqlString();
SqlString b = new SqlString();
// When comparing two empty strings (""), both the shared/static and
// the instance Equals methods evaluate to true.
Console.WriteLine();
Console.WriteLine("SqlString.Equals shared/static method:");
Console.WriteLine(" Two empty strings={0}", SqlStringEquals(a, b));
Console.WriteLine();
Console.WriteLine("String.Equals instance method:");
Console.WriteLine(" Two empty strings={0}", StringEquals(a, b));
}
Next steps
SQL Server data types and ADO.NET
Comparing GUID and uniqueidentifier values
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
The globally unique identifier (GUID) data type in SQL Server is represented by the uniqueidentifier data type,
which stores a 16-byte binary value. A GUID is a binary number, and its main use is as an identifier that must be
unique in a network that has many computers at many sites. GUIDs can be generated by calling the Transact-
SQL NEWID function, and is guaranteed to be unique throughout the world. For more information, see
uniqueidentifier (Transact-SQL).
class Program
{
static void Main()
{
WorkWithGuids();
Console.ReadLine();
}
private static void WorkWithGuids()
{
// Create an ArrayList and fill it with Guid values.
ArrayList guidList = new ArrayList();
guidList.Add(new Guid("3AAAAAAA-BBBB-CCCC-DDDD-2EEEEEEEEEEE"));
guidList.Add(new Guid("2AAAAAAA-BBBB-CCCC-DDDD-1EEEEEEEEEEE"));
guidList.Add(new Guid("1AAAAAAA-BBBB-CCCC-DDDD-3EEEEEEEEEEE"));
// Sort the SqlGuids. The unsorted SqlGuids are in the same order
// as the unsorted Guid values.
sqlGuidList.Sort();
// Display the sorted SqlGuids. The sorted SqlGuid values are ordered
// differently than the Guid values.
Console.WriteLine("Sorted SqlGuids:");
foreach (SqlGuid sqlGuidValue in sqlGuidList)
{
Console.WriteLine(" {0}", sqlGuidValue);
}
}
}
Sorted Guids:
1aaaaaaa-bbbb-cccc-dddd-3eeeeeeeeeee
2aaaaaaa-bbbb-cccc-dddd-1eeeeeeeeeee
3aaaaaaa-bbbb-cccc-dddd-2eeeeeeeeeee
Sorted SqlGuids:
2aaaaaaa-bbbb-cccc-dddd-1eeeeeeeeeee
3aaaaaaa-bbbb-cccc-dddd-2eeeeeeeeeee
1aaaaaaa-bbbb-cccc-dddd-3eeeeeeeeeee
Next steps
SQL Server data types and ADO.NET
Date and time data
4/27/2022 • 9 minutes to read • Edit Online
Download ADO.NET
SQL Server 2008 introduces new data types for handling date and time information. The new data types include
separate types for date and time, and expanded data types with greater range, precision, and time-zone
awareness. The Microsoft SqlClient Data Provider for SQL Server (Microsoft.Data.SqlClient) provides full
support for all the new features of the SQL Server 2008 Database Engine. You must install the .NET Framework
3.5 SP1 (or later) or .NET Core 1.0 (or later) to use these new features with SqlClient.
Versions of SQL Server earlier than SQL Server 2008 only had two data types for working with date and time
values: datetime and smalldatetime . Both of these data types contain both the date value and a time value,
which makes it difficult to work with only date or only time values. Also, these data types only support dates that
occur after the introduction of the Gregorian calendar in England in 1753. Another limitation is that these older
data types are not time-zone aware, which makes it difficult to work with data that originates from multiple time
zones.
Complete documentation for SQL Server data types is available in SQL Server Books Online. See Using Date
and Time Data for entry-level topics on date and time data.
time The time data type stores time values only, based on a 24-
hour clock. The time data type has a range of
00:00:00.0000000 through 23:59:59.9999999 with an
accuracy of 100 nanoseconds. The default value is
00:00:00.0000000 (midnight). The time data type
supports user-defined fractional second precision, and the
storage size varies from 3 to 6 bytes, based on the precision
specified.
The default values and string literal formats are the same as
those defined in the date and time data types.
SQ L SERVER DATA T Y P E DESC RIP T IO N
NOTE
For more information about using the Type System Version keyword, see ConnectionString.
NOTE
The YDM date format is not supported when converting from a string format to date , time , datetime2 , or
datetimeoffset .
For more information about how SQL Server interprets date and time data, see Using Date and Time Data in
SQL Server 2008 Books Online.
SqlDbType.Time
SqlDbType.DateTime2
SqlDbType.DateTimeOffSet
You can specify the data type of a SqlParameter by using one of the preceding SqlDbType enumerations.
NOTE
You cannot set the DbType property of a SqlParameter to SqlDbType.Date .
You can also specify the type of a SqlParameter generically by setting the DbType property of a SqlParameter
object to a particular DbType enumeration value. The following enumeration values have been added to DbType
to support the datetime2 and datetimeoffset data types:
DbType.DateTime2
DbType.DateTimeOffset
These new enumerations supplement the Date , Time , and DateTime enumerations.
The Microsoft SqlClient Data Provider type of a parameter object is inferred from the .NET type of the value of
the parameter object, or from the DbType of the parameter object. No new System.Data.SqlTypes data types
have been introduced to support the new date and time data types. The following table describes the mappings
between the SQL Server 2008 date and time data types and the CLR data types.
SqlParameter properties
The following table describes SqlParameter properties that are relevant to date and time data types.
Scale Gets or sets the number of decimal places to which the time
portion of the value is resolved for Time , DateTime2 ,and
DateTimeOffset . The default value is 0, which means that
the actual scale is inferred from the value and sent to the
server.
P RO P ERT Y DESC RIP T IO N
NOTE
Time values that are less than zero or greater than or equal to 24 hours will throw an ArgumentException.
Creating parameters
You can create a SqlParameter object by using its constructor, or by adding it to a SqlCommand.Parameters
collection by calling the Add method of the SqlParameterCollection. The Add method will take as input either
constructor arguments or an existing parameter object.
The next sections in this topic provide examples of how to specify date and time parameters.
Date example
The following code fragment demonstrates how to specify a date parameter.
Time example
The following code fragment demonstrates how to specify a time parameter.
Datetime2 example
The following code fragment demonstrates how to specify a datetime2 parameter with both the date and time
parts.
DateTimeOffSet example
The following code fragment demonstrates how to specify a DateTimeOffSet parameter with a date, a time, and
a time zone offset of 0.
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "@DateTimeOffSet";
parameter.SqlDbType = SqlDbType.DateTimeOffSet;
parameter.Value = DateTimeOffset.Parse("1666-09-02 1:00:00+0");
AddWithValue
You can also supply parameters by using the AddWithValue method of a SqlCommand, as shown in the
following code fragment. However, the AddWithValue method does not allow you to specify the DbType or
SqlDbType for the parameter.
command.Parameters.AddWithValue(
"@date", DateTimeOffset.Parse("16660902"));
The @date parameter could map to a date , datetime , or datetime2 data type on the server. When working
with the new datetime data types, you must explicitly set the parameter's SqlDbType property to the data type
of the instance. Using Variant or implicitly supplying parameter values can cause problems with backward
compatibility with the datetime and smalldatetime data types.
The following table shows which SqlDbTypes are inferred from which CLR types:
DateTime SqlDbType.DateTime
TimeSpan SqlDbType.Time
DateTimeOffset SqlDbType.DateTimeOffset
GetProviderSpecificValue Retrieves the value of the specified column. Returns the same
types as GetValue for the new date and time types.
NOTE
The new date and time SqlDbTypes are not supported for code that is executing in-process in SQL Server. An exception
will be raised if one of these types is passed to the server.
NOTE
You can find complete documentation for all of the literal string formats and other features of the date and time data
types in SQL Server Books Online.
Time values that are less than zero or greater than or equal to 24 hours will throw an ArgumentException.
Date and Time Data Types and Functions (Transact-SQL) Provides an overview of all Transact-SQL date and time data
types and functions.
Using Date and Time Data Provides information about the date and time data types
and functions, and examples of using them.
Data Types (Transact-SQL) Describes system data types in SQL Server 2008.
Next steps
SQL Server data types and ADO.NET
Large UDTs
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
User-defined types (UDTs) allow a developer to extend the server's scalar type system by storing common
language runtime (CLR) objects in a SQL Server database. UDTs can contain multiple elements and can have
behaviors, unlike the traditional alias data types, which consist of a single SQL Server system data type.
Previously, UDTs were restricted to a maximum size of 8 kilobytes. In SQL Server 2008, this restriction has been
removed for UDTs that have a format of UserDefined.
For the complete documentation for user-defined types, see CLR User-Defined Types from SQL Server Books
Online.
SqlDataReader considerations
The SqlDataReader has been extended beginning in SQL Server 2008 to support retrieving large UDT values.
How large UDT values are processed by a SqlDataReader depends on the version of SQL Server you are using,
as well as on the Type System Version specified in the connection string. For more information, see
ConnectionString.
The following methods of SqlDataReader will return a SqlBinary instead of a UDT when the Type System Version
is set to SQL Server 2005:
GetProviderSpecificFieldType
GetProviderSpecificValue
GetProviderSpecificValues
GetSqlValue
GetSqlValues
The following methods will return an array of Byte[] instead of a UDT when the Type System Version is set to
SQL Server 2005:
GetValue
GetValues
Note that no conversions are made for the current version of ADO.NET.
Specifying SqlParameters
The following SqlParameter properties have been extended to work with large UDTs.
Size Gets or sets the size of the parameter value to resolve. The
default value is 0. The property can be an integer that
represents the size of the parameter value. For large UDTs, it
can be the actual size of the UDT, or -1 for unknown.
Console.WriteLine(
"ID={0} LargeUDT={1}", id, udt);
}
reader.close
}
Next steps
SQL Server binary and large-value data
XML data in SQL Server
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
SQL Server exposes the functionality of SQLXML inside the .NET. Developers can write applications that access
XML data from an instance of SQL Server, bring the data into the .NET environment, process the data, and send
the updates back to SQL Server. XML data can be used in several ways in SQL Server, including data storage, and
as parameter values for retrieving data. The SqlXml class in the .NET provides the client-side support for
working with data stored in an XML column within SQL Server. For more information, see "SQLXML Managed
Classes" in SQL Server Books Online.
In this section
SQL XML column values
Demonstrates how to retrieve and work with XML data retrieved from SQL Server.
Specifying XML values as parameters
Demonstrates how to pass XML data as a parameter to a command.
Next steps
SQL Server and ADO.NET
SQL XML column values
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
SQL Server supports the xml data type, and developers can retrieve result sets including this type using
standard behavior of the SqlCommand class. An xml column can be retrieved just as any column is retrieved
(into a SqlDataReader, for example) but if you want to work with the content of the column as XML, you must
use an XmlReader.
Example
The following console application selects two rows, each containing an xml column, from the Sales.Store table
in the AdventureWorks database to a SqlDataReader instance. For each row, the value of the xml column is
read using the GetSqlXml method of SqlDataReader. The value is stored in an XmlReader. Note that you must
use GetSqlXml rather than the GetValue method if you want to set the contents to a SqlXml variable; GetValue
returns the value of the xml column as a string.
NOTE
The AdventureWorks sample database is not installed by default when you install SQL Server. You can install it by
running SQL Server Setup.
using Microsoft.Data.SqlClient;
using System.Xml;
using System.Data.SqlTypes;
class Class1
{
static void Main()
{
string c = "Data Source=(local);Integrated Security=true;" +
"Initial Catalog=AdventureWorks; ";
GetXmlData(c);
Console.ReadLine();
}
Next steps
SqlXml
XML data in SQL Server
Specifying XML values as parameters
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
If a query requires a parameter whose value is an XML string, developers can supply that value using an
instance of the SqlXml data type. There really are no tricks; XML columns in SQL Server accept parameter
values in exactly the same way as other data types.
Example
The following console application creates a new table in the AdventureWorks database. The new table includes
a column named SalesID and an XML column named SalesInfo .
NOTE
The AdventureWorks sample database is not installed by default when you install SQL Server. You can install it by
running SQL Server Setup.
The example prepares a SqlCommand object to insert a row in the new table. A saved file provides the XML data
needed for the SalesInfo column.
To create the file needed for the example to run, create a new text file in the same folder as your project. Name
the file MyTestStoreData.xml. Open the file in Notepad and copy and paste the following text:
<StoreSurvey xmlns="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/StoreSurvey">
<AnnualSales>300000</AnnualSales>
<AnnualRevenue>30000</AnnualRevenue>
<BankName>International Bank</BankName>
<BusinessType>BM</BusinessType>
<YearOpened>1970</YearOpened>
<Specialty>Road</Specialty>
<SquareFeet>7000</SquareFeet>
<Brands>3</Brands>
<Internet>T1</Internet>
<NumberEmployees>2</NumberEmployees>
</StoreSurvey>
using System;
using System.Data;
using Microsoft.Data.SqlClient;
using System.Xml;
using System.Data.SqlTypes;
class Class1
{
static void Main()
{
using (SqlConnection connection = new SqlConnection(GetConnectionString()))
{
connection.Open();
// Create a sample table (dropping first if it already
// exists.)
string commandNewTable =
"IF EXISTS (SELECT * FROM dbo.sysobjects " +
"WHERE id = " +
"object_id(N'[dbo].[XmlDataTypeSample]') " +
"AND OBJECTPROPERTY(id, N'IsUserTable') = 1) " +
"DROP TABLE [dbo].[XmlDataTypeSample];" +
"CREATE TABLE [dbo].[XmlDataTypeSample](" +
"[SalesID] [int] IDENTITY(1,1) NOT NULL, " +
"[SalesInfo] [xml])";
SqlCommand commandAdd =
new SqlCommand(commandNewTable, connection);
commandAdd.ExecuteNonQuery();
string commandText =
"INSERT INTO [dbo].[XmlDataTypeSample] " +
"([SalesInfo] ) " +
"VALUES(@xmlParameter )";
SqlCommand command =
new SqlCommand(commandText, connection);
Next steps
SqlXml
XML data in SQL Server
SQL Server binary and large-value data
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
SQL Server provides the max specifier, which expands the storage capacity of the varchar , nvarchar , and
varbinary data types. varchar(max) , nvarchar(max) , and varbinary(max) are collectively called large-value
data types. You can use the large-value data types to store up to 2^31-1 bytes of data.
SQL Server 2008 introduces the FILESTREAM attribute, which is not a data type, but rather an attribute that can
be defined on a column, allowing large-value data to be stored on the file system instead of in the database.
In this section
Modifying large-value (max) data in ADO.NET
Describes how to work with the large-value data types.
FILESTREAM data
Describes how to work with large-value data stored in SQL Server 2008 with the FILESTREAM attribute.
Next steps
SQL Server data types and ADO.NET
SQL Server data operations in ADO.NET
Modifying large-value (max) data in ADO.NET
4/27/2022 • 9 minutes to read • Edit Online
Download ADO.NET
Large object (LOB) data types are those that exceed the maximum row size of 8 kilobytes (KB). SQL Server
provides a max specifier for varchar , nvarchar , and varbinary data types to allow storage of values as large
as 2^32 bytes. Table columns and Transact-SQL variables may specify varchar(max) , nvarchar(max) , or
varbinary(max) data types. In .NET, the max data types can be fetched by a DataReader , and can also be
specified as both input and output parameter values without any special handling. For large varchar data types,
data can be retrieved and updated incrementally.
The max data types can be used for comparisons, as Transact-SQL variables, and for concatenation. They can
also be used in the DISTINCT, ORDER BY, GROUP BY clauses of a SELECT statement as well as in aggregates,
joins, and subqueries.
See Using Large-Value Data Types from SQL Server Books Online more details on large-value data types.
IF T H EN
The expression is set to NULL @Length is ignored and the value in column_name is
truncated at the specified @Offset .
@Offset is NULL The update operation appends the expression at the end of
the existing column_name value and @Length is ignored.
@Offset is greater than the length of the column_name SQL Server returns an error.
value
@Length is NULL The update operation removes all data from @Offset to
the end of the column_name value.
NOTE
Neither @Offset nor @Length can be a negative number.
Example
This Transact-SQL example updates a partial value in DocumentSummary, an nvarchar(max) column in the
Document table in the AdventureWorks database. The word 'components' is replaced by the word 'features' by
specifying the replacement word, the beginning location (offset) of the word to be replaced in the existing data,
and the number of characters to be replaced (length). The example includes SELECT statements before and after
the UPDATE statement to compare results.
USE AdventureWorks;
GO
--View the existing value.
SELECT DocumentSummary
FROM Production.Document
WHERE DocumentID = 3;
GO
-- The first sentence of the results will be:
-- Reflectors are vital safety components of your bicycle.
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (reader.Read())
{
SqlBytes bytes = reader.GetSqlBytes(0);
}
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (reader.Read())
{
SqlChars buffer = reader.GetSqlChars(0);
}
while (reader.Read())
{
byte[] buffer = new byte[4000];
long byteCount = reader.GetBytes(1, 0, buffer, 0, 4000);
}
while (reader.Read())
{
// Read the data from varbinary(max) column
byte[] binaryData = (byte[])reader.GetValue(0);
while (reader.Read())
{
string str = reader[0].ToString();
Console.WriteLine(str);
}
Example
The following code retrieves the name and the LargePhoto object from the ProductPhoto table in the
AdventureWorks database and saves it to a file. The assembly needs to be compiled with a reference to the
System.Drawing namespace. The GetSqlBytes method of the SqlDataReader returns a SqlBytes object that
exposes a Stream property. The code uses this to create a new Bitmap object, and then saves it in the Gif
ImageFormat .
using Microsoft.Data.SqlClient;
using System.Data.SqlTypes;
using System.Drawing;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
class Program
{
static void Main()
{
// Supply any valid DocumentID value and file path.
// The value 3 is supplied for DocumentID, and a literal
// string for the file path where the image will be saved. 1, 60
TestGetSqlBytes(7, @"c:\temp\");
Console.ReadLine();
}
static private void TestGetSqlBytes(int documentID, string filePath)
{
// Assumes GetConnectionString returns a valid connection string.
using (SqlConnection connection =
new SqlConnection(GetConnectionString()))
{
SqlCommand command = connection.CreateCommand();
SqlDataReader reader = null;
try
{
// Setup the command
command.CommandText =
"SELECT LargePhotoFileName, LargePhoto "
+ "FROM Production.ProductPhoto "
+ "WHERE ProductPhotoID=@ProductPhotoID";
command.CommandType = CommandType.Text;
reader = command.ExecuteReader(CommandBehavior.CloseConnection);
if (reader.HasRows)
{
while (reader.Read())
{
// Get the name of the file.
photoName = reader.GetString(0);
Example
The ADO.NET code creates SqlConnection and SqlCommand objects to execute the GetDocumentSummary
stored procedure and retrieve the document summary, which is stored as a large value type. The code passes a
value for the @DocumentID input parameter, and displays the results passed back in the @DocumentSummary
output parameter in the Console window.
using Microsoft.Data.SqlClient;
class Program
{
static void Main()
{
// Supply any valid Document ID value.
// The value 7 is supplied for demonstration purposes.
string summaryString = GetDocumentSummary(7);
Console.ReadLine();
}
static private string GetDocumentSummary(int documentID)
{
//Assumes GetConnectionString returns a valid connection string.
using (SqlConnection connection =
new SqlConnection(GetConnectionString()))
{
connection.Open();
SqlCommand command = connection.CreateCommand();
try
{
// Setup the command to execute the stored procedure.
command.CommandText = "GetDocumentSummary";
command.CommandType = CommandType.StoredProcedure;
Next steps
SQL Server binary and large-value data
SQL Server data operations in ADO.NET
FILESTREAM data
4/27/2022 • 4 minutes to read • Edit Online
Download ADO.NET
The FILESTREAM storage attribute is for binary (BLOB) data stored in a varbinary(max) column. Before
FILESTREAM, storing binary data required special handling. Unstructured data, such as text documents, images
and video, is often stored outside of the database, making it difficult to manage.
NOTE
You must install the .NET Framework 3.5 SP1 (or later) or .NET Core to work with FILESTREAM data using SqlClient.
Specifying the FILESTREAM attribute on a varbinary(max) column causes SQL Server to store the data on the
local NTFS file system instead of in the database file. Although it's stored separately, you can use the same
Transact-SQL statements that are supported for working with varbinary(max) data that is stored in the database.
using System;
using Microsoft.Data.SqlClient;
using System.Data.SqlTypes;
using System.Data;
using System.IO;
namespace FileStreamTest
{
class Program
{
static void Main(string[] args)
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder("server=(local);integrated
security=true;database=myDB");
ReadFileStream(builder);
OverwriteFileStream(builder);
InsertFileStream(builder);
Console.WriteLine("Done");
}
}
}
}
For another sample, see How to store and fetch binary data into a file stream column.
Resources in SQL Server Books Online
The complete documentation for FILESTREAM is located in the following sections in SQL Server Books Online.
A RT IC L E DESC RIP T IO N
FILESTREAM (SQL Server) Describes when to use FILESTREAM storage and how it
integrates the SQL Server Database Engine with an NTFS file
system.
Create Client Applications for FILESTREAM Data Describes the Windows API functions for working with
FILESTREAM data.
FILESTREAM and Other SQL Server Features Provides considerations, guidelines, and limitations for using
FILESTREAM data with other features of SQL Server.
Next steps
SQL Server data types and ADO.NET
SQL Server binary and large-value data
Inserting an image from a file
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
You can write a binary large object (BLOB) to a database as either binary or character data, depending on the
type of field at your data source. BLOB is a generic term that refers to the text , ntext , and image data types,
which typically contain documents and pictures.
To write a BLOB value to your database, issue the appropriate INSERT or UPDATE statement and pass the BLOB
value as an input parameter. If your BLOB is stored as text, such as a SQL Server text field, you can pass the
BLOB as a string parameter. If the BLOB is stored in binary format, such as a SQL Server image field, you can
pass an array of type byte as a binary parameter.
Example
The following code example adds employee information to the Employees table in the Northwind database. A
photo of the employee is read from a file and added to the Photo field in the table, which is an image field.
public static void AddEmployee(
string lastName,
string firstName,
string title,
DateTime hireDate,
int reportsTo,
string photoFilePath,
string connectionString)
{
byte[] photo = GetPhoto(photoFilePath);
command.Parameters.Add("@LastName",
SqlDbType.NVarChar, 20).Value = lastName;
command.Parameters.Add("@FirstName",
SqlDbType.NVarChar, 10).Value = firstName;
command.Parameters.Add("@Title",
SqlDbType.NVarChar, 30).Value = title;
command.Parameters.Add("@HireDate",
SqlDbType.DateTime).Value = hireDate;
command.Parameters.Add("@ReportsTo",
SqlDbType.Int).Value = reportsTo;
command.Parameters.Add("@Photo",
SqlDbType.Image, photo.Length).Value = photo;
connection.Open();
command.ExecuteNonQuery();
}
}
reader.Close();
stream.Close();
return photo;
}
Next steps
SQL Server binary and large-value data
SQL Server data operations in ADO.NET
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
This section describes SQL Server features and functionality that are specific to the Microsoft SqlClient Data
Provider for SQL Server (Microsoft.Data.SqlClient).
In this section
Bulk copy operations in SQL Server
Describes the bulk copy functionality for the .NET Data Provider for SQL Server.
Multiple Active Result Sets (MARS)
Describes how to have more than one SqlDataReader open on a connection when each instance of
SqlDataReader is started from a separate command.
Asynchronous operations
Describes how to perform asynchronous database operations by using an API that is modeled after the
asynchronous model used by the .NET Framework.
Table-valued parameters
Describes how to work with table-valued parameters, which were introduced in SQL Server 2008.
Next steps
SQL Server and ADO.NET
Bulk copy operations in SQL Server
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Microsoft SQL Server includes a popular command-line utility named bcp . Bcp is used to quickly bulk copy
large files into tables or views in SQL Server databases. The SqlBulkCopy class allows you to write managed
code solutions that provide similar functionality. There are other ways to load data into a table (INSERT
statements, for example) but SqlBulkCopy offers a significant performance advantage over them.
Using the SqlBulkCopy class, you can perform:
A single bulk copy operation
Multiple bulk copy operations
A bulk copy operation within a transaction
NOTE
When using .NET Framework version 1.1 or earlier (which does not support the SqlBulkCopy class), you can execute the
SQL Server Transact-SQL BULK INSERT statement using the SqlCommand object.
In this section
Bulk copy example setup:
Describes the tables used in the bulk copy examples and provides SQL scripts for creating the tables in the
AdventureWorks database.
Single bulk copy operations:
Describes how to do a single bulk copy of data into a database instance using the SqlBulkCopy class. It includes
how to do the bulk copy operation using Transact-SQL statements and the SqlCommand class.
Multiple bulk copy operations:
Describes how to do multiple bulk copy operations of data into a database instance using the SqlBulkCopy class.
Transaction and bulk copy operations:
Describes how to do a bulk copy operation within a transaction, including how to commit or roll back the
transaction.
Order hints for bulk copy operations:
Describes how to use order hints to improve bulk copy performance.
Next steps
SQL Server and ADO.NET
Bulk copy example setup
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
The SqlBulkCopy class can be used to write data only to SQL Server tables. The code samples shown in this topic
use the SQL Server sample database, AdventureWorks . To avoid altering the existing tables code samples
write data to tables that you must create first.
The BulkCopyDemoMatchingColumns and BulkCopyDemoDifferentColumns tables are both based on
the AdventureWorks Production.Products table. In code samples that use these tables, data is added from
the Production.Products table to one of these sample tables. The BulkCopyDemoDifferentColumns table
is used when the sample illustrates how to map columns from the source data to the destination table;
BulkCopyDemoMatchingColumns is used for most other samples.
A few of the code samples demonstrate how to use one SqlBulkCopy class to write to multiple tables. For these
samples, the BulkCopyDemoOrderHeader and BulkCopyDemoOrderDetail tables are used as the
destination tables. These tables are based on the Sales.SalesOrderHeader and Sales.SalesOrderDetail
tables in AdventureWorks .
NOTE
The SqlBulkCopy code samples are provided to demonstrate the syntax for using SqlBulkCopy only. If the source and
destination tables are located in the same SQL Server instance, it is easier and faster to use a Transact-SQL
INSERT … SELECT statement to copy the data.
Table setup
To create the tables necessary for the code samples to run correctly, you must run the following Transact-SQL
statements in a SQL Server database.
USE AdventureWorks
Next steps
Bulk copy operations in SQL Server
Single bulk copy operations
4/27/2022 • 4 minutes to read • Edit Online
Download ADO.NET
The simplest approach to performing a SQL Server bulk copy operation is to perform a single operation against
a database. By default, a bulk copy operation is performed as an isolated operation: the copy operation occurs in
a non-transacted way, with no opportunity for rolling it back.
NOTE
If you need to roll back all or part of the bulk copy when an error occurs, you can either use a SqlBulkCopy-managed
transaction, or perform the bulk copy operation within an existing transaction. SqlBulkCopy will also work with
System.Transactions if the connection is enlisted (implicitly or explicitly) into a System.Transactions transaction.
For more information, see Transaction and bulk copy operations.
The general steps for performing a bulk copy operation are as follows:
1. Connect to the source server and obtain the data to be copied. Data can also come from other sources, if
it can be retrieved from an IDataReader or DataTable object.
2. Connect to the destination server (unless you want SqlBulkCopy to establish a connection for you).
3. Create a SqlBulkCopy object, setting any necessary properties.
4. Set the DestinationTableName property to indicate the target table for the bulk insert operation.
5. Call one of the WriteToSer ver methods.
6. Optionally, update properties and call WriteToSer ver again as necessary.
7. Call Close, or wrap the bulk copy operations within a Using statement.
Cau t i on
We recommend that the source and target column data types match. If the data types do not match,
SqlBulkCopy attempts to convert each source value to the target data type, using the rules employed by Value.
Conversions can affect performance, and also can result in unexpected errors. For example, a Double data type
can be converted to a Decimal data type most of the time, but not always.
Example
The following console application demonstrates how to load data using the SqlBulkCopy class. In this example, a
SqlDataReader is used to copy data from the Production.Product table in the SQL Server AdventureWorks
database to a similar table in the same database.
IMPORTANT
This sample will not run unless you have created the work tables as described in Bulk copy example setup. This code is
provided to demonstrate the syntax for using SqlBulkCopy only. If the source and destination tables are located in the
same SQL Server instance, it is easier and faster to use a Transact-SQL INSERT … SELECT statement to copy the data.
using Microsoft.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString = GetConnectionString();
// Open a sourceConnection to the AdventureWorks database.
using (SqlConnection sourceConnection =
new SqlConnection(connectionString))
{
sourceConnection.Open();
try
{
// Write from the source to the destination.
bulkCopy.WriteToServer(reader);
// Print the number of rows processed using the
// RowsCopied property.
Console.WriteLine("{0} rows were processed.",
bulkCopy.RowsCopied);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
// Close the SqlDataReader. The SqlBulkCopy
// object is automatically closed at the end
// of the using block.
reader.Close();
}
}
}
NOTE
The file path for the data source is relative to the server. The server process must have access to that path in order for the
bulk copy operation to succeed.
command.ExecuteNonQuery();
}
Next steps
Bulk copy operations in SQL Server
Multiple bulk copy operations
4/27/2022 • 3 minutes to read • Edit Online
Download ADO.NET
You can perform multiple bulk copy operations using a single instance of a SqlBulkCopy class. If the operation
parameters change between copies (for example, the name of the destination table), you must update them
prior to any subsequent calls to any of the WriteToSer ver methods, as demonstrated in the following example.
Unless explicitly changed, all property values remain the same as they were on the previous bulk copy operation
for a given instance.
NOTE
Performing multiple bulk copy operations using the same instance of SqlBulkCopy is usually more efficient than using a
separate instance for each operation.
If you perform several bulk copy operations using the same SqlBulkCopy object, there are no restrictions on
whether source or target information is equal or different in each operation. However, you must ensure that
column association information is properly set each time you write to the server.
Example
IMPORTANT
This sample will not run unless you have created the work tables as described in Bulk copy example setup. This code is
provided to demonstrate the syntax for using SqlBulkCopy only. If the source and destination tables are located in the
same SQL Server instance, it is easier and faster to use a Transact-SQL INSERT … SELECT statement to copy the data.
using Microsoft.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString = GetConnectionString();
// Open a connection to the AdventureWorks database.
using (SqlConnection connection =
new SqlConnection(connectionString))
{
connection.Open();
Next steps
Bulk copy operations in SQL Server
Transaction and bulk copy operations
4/27/2022 • 11 minutes to read • Edit Online
Download ADO.NET
Bulk copy operations can be performed as isolated operations or as part of a multiple step transaction. This
latter option enables you to perform more than one bulk copy operation within the same transaction, as well as
perform other database operations such as inserts, updates, and deletes, while still being able to commit or roll
back the entire transaction.
By default, a bulk copy operation is done as an isolated operation. The bulk copy operation occurs in a non-
transacted way, with no opportunity for rolling it back. If you need to roll back all or part of the bulk copy when
an error occurs, you can:
Use a SqlBulkCopy-managed transaction
Do the bulk copy operation within an existing transaction
Enlist in a System.Transactions Transaction.
NOTE
This sample will not run unless you have created the work tables as described in Bulk copy example setup. This code is
provided to demonstrate the syntax for using SqlBulkCopy only. If the source and destination tables are located in the
same SQL Server instance, it is easier and faster to use a Transact-SQL INSERT … SELECT statement to copy the data.
using Microsoft.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString = GetConnectionString();
// Open a sourceConnection to the AdventureWorks database.
using (SqlConnection sourceConnection =
new SqlConnection(connectionString))
{
sourceConnection.Open();
sourceConnection.Open();
NOTE
Since different batches are executed in different transactions, if an error occurs during the bulk copy operation, all the
rows in the current batch will be rolled back, but rows from previous batches will remain in the database.
The following console application is similar to the previous example, with one exception: In this example, the
bulk copy operation manages its own transactions. All batches that are copied up to the point of the error are
committed. The batch containing the duplicate key is rolled back, and the bulk copy operation is halted before it
processes any remaining batches.
IMPORTANT
This sample will not run unless you have created the work tables as described in Bulk copy example setup. This code is
provided to demonstrate the syntax for using SqlBulkCopy only. If the source and destination tables are located in the
same SQL Server instance, it is easier and faster to use a Transact-SQL INSERT … SELECT statement to copy the data.
using Microsoft.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString = GetConnectionString();
string connectionString = GetConnectionString();
// Open a sourceConnection to the AdventureWorks database.
using (SqlConnection sourceConnection =
new SqlConnection(connectionString))
{
sourceConnection.Open();
IMPORTANT
This sample will not run unless you have created the work tables as described in Bulk copy example setup. This code is
provided to demonstrate the syntax for using SqlBulkCopy only. If the source and destination tables are located in the
same SQL Server instance, it is easier and faster to use a Transact-SQL INSERT … SELECT statement to copy the data.
using Microsoft.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString = GetConnectionString();
// Open a sourceConnection to the AdventureWorks database.
using (SqlConnection sourceConnection =
new SqlConnection(connectionString))
{
sourceConnection.Open();
Next steps
Bulk copy operations in SQL Server
Order hints for bulk copy operations
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Bulk copy operations offer significant performance advantages over other methods for loading data into a SQL
Server table. Performance can be further enhanced by using order hints. Specifying order hints for your bulk
copy operations can lower the insertion time of sorted data into tables with clustered indexes.
By default, the bulk insert operation assumes the incoming data is unordered. SQL Server forces an
intermediate sort of this data before bulk loading it. If you know your incoming data is already sorted, you can
use order hints to tell the bulk copy operation about the sort order of any destination columns that are part of a
clustered index.
using System;
using System.Data;
using Microsoft.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString = GetConnectionString();
// Open a sourceConnection to the AdventureWorks database.
using (SqlConnection sourceConnection =
new SqlConnection(connectionString))
{
sourceConnection.Open();
Next steps
Bulk copy operations in SQL Server
Multiple Active Result Sets (MARS)
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Multiple Active Result Sets (MARS) is a feature that allows the execution of multiple batches on a single
connection. In previous versions, only one batch could be executed at a time against a single connection.
Executing multiple batches with MARS does not imply simultaneous execution of operations.
In this section
Enabling Multiple Active Result Sets
Discusses how to use MARS with SQL Server.
Manipulating data
Provides examples of coding MARS applications.
Related sections
Asynchronous operations
Provides details on using the new asynchronous features in .NET.
Next steps
SQL Server and ADO.NET
Enabling Multiple Active Result Sets
4/27/2022 • 4 minutes to read • Edit Online
Download ADO.NET
Multiple Active Result Sets (MARS) is a feature that works with SQL Server to allow the execution of multiple
batches on a single connection. When MARS is enabled for use with SQL Server, each command object used
adds a session to the connection.
NOTE
A single MARS session opens one logical connection for MARS to use and then one logical connection for each active
command.
The MARS feature is disabled by default. It can be enabled by adding the "MultipleActiveResultSets=True"
keyword pair to your connection string. "True" is the only valid value for enabling MARS. The following example
demonstrates how to connect to an instance of SQL Server and how to specify that MARS should be enabled.
You can disable MARS by adding the "MultipleActiveResultSets=False" keyword pair to your connection string.
"False" is the only valid value for disabling MARS. The following connection string demonstrates how to disable
MARS.
Next steps
Multiple Active Result Sets (MARS)
Manipulating data
4/27/2022 • 4 minutes to read • Edit Online
Download ADO.NET
Before the introduction of Multiple Active Result Sets (MARS), developers had to use either multiple connections
or server-side cursors to solve certain scenarios. In addition, when multiple connections were used in a
transactional situation, bound connections (with sp_getbindtoken and sp_bindsession ) were required. The
following scenarios show how to use a MARS-enabled connection instead of multiple connections.
NOTE
The following example uses the sample AdventureWorks database included with SQL Server. The connection string
provided in the sample code assumes that the database is installed and available on the local computer. Modify the
connection string as necessary for your environment.
using System;
using System.Data;
using Microsoft.Data.SqlClient;
class Class1
{
static void Main()
{
// By default, MARS is disabled when connecting
// to a MARS-enabled host.
// It must be enabled in the connection string.
string connectionString = GetConnectionString();
int vendorID;
SqlDataReader productReader = null;
string vendorSQL =
"SELECT VendorId, Name FROM Purchasing.Vendor";
string productSQL =
"SELECT Production.Product.Name FROM Production.Product " +
"INNER JOIN Purchasing.ProductVendor " +
"ON Production.Product.ProductID = " +
"Purchasing.ProductVendor.ProductID " +
"WHERE Purchasing.ProductVendor.VendorID = @VendorId";
productCmd.Parameters.Add("@VendorId", SqlDbType.Int);
awConnection.Open();
using (SqlDataReader vendorReader = vendorCmd.ExecuteReader())
{
while (vendorReader.Read())
{
Console.WriteLine(vendorReader["Name"]);
vendorID = (int)vendorReader["VendorId"];
productCmd.Parameters["@VendorId"].Value = vendorID;
// The following line of code requires
// a MARS-enabled connection.
productReader = productCmd.ExecuteReader();
using (productReader)
{
while (productReader.Read())
{
Console.WriteLine(" " +
productReader["Name"].ToString());
}
}
}
}
Console.WriteLine("Press any key to continue");
Console.ReadLine();
}
}
private static string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
return "Data Source=(local);Integrated Security=SSPI;" +
"Initial Catalog=AdventureWorks;MultipleActiveResultSets=True";
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Microsoft.Data.SqlClient;
class Program
{
static void Main()
{
// By default, MARS is disabled when connecting
// to a MARS-enabled host.
// It must be enabled in the connection string.
string connectionString = GetConnectionString();
int vendorID = 0;
int productID = 0;
int minOrderQty = 0;
int maxOrderQty = 0;
int onOrderQty = 0;
int recordsUpdated = 0;
int totalRecordsUpdated = 0;
string vendorSQL =
"SELECT VendorID, Name FROM Purchasing.Vendor " +
"WHERE CreditRating = 5";
string prodVendSQL =
"SELECT ProductID, MaxOrderQty, MinOrderQty, OnOrderQty " +
"FROM Purchasing.ProductVendor " +
"WHERE VendorID = @VendorID";
string updateSQL =
"UPDATE Purchasing.ProductVendor " +
"SET OnOrderQty = @OrderQty " +
"WHERE ProductID = @ProductID AND VendorID = @VendorID";
using (prodVendReader)
{
while (prodVendReader.Read())
{
productID = (int) prodVendReader["ProductID"];
if (prodVendReader["OnOrderQty"] == DBNull.Value)
{
minOrderQty = (int) prodVendReader["MinOrderQty"];
onOrderQty = minOrderQty;
}
else
{
maxOrderQty = (int) prodVendReader["MaxOrderQty"];
onOrderQty = (int)(maxOrderQty / 2);
}
updateCmd.Parameters["@OrderQty"].Value = onOrderQty;
updateCmd.Parameters["@ProductID"].Value = productID;
updateCmd.Parameters["@VendorID"].Value = vendorID;
recordsUpdated = updateCmd.ExecuteNonQuery();
totalRecordsUpdated += recordsUpdated;
}
}
}
}
Console.WriteLine("Total Records Updated: " +
totalRecordsUpdated.ToString());
updateTx.Rollback();
Console.WriteLine("Transaction Rolled Back");
}
Next steps
Multiple Active Result Sets (MARS)
Asynchronous operations
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Some database operations, such as command executions, can take significant time to complete. In such a case,
single-threaded applications must block other operations and wait for the command to finish before they can
continue their own operations. In contrast, being able to assign the long-running operation to a background
thread allows the foreground thread to remain active throughout the operation. In a Windows application, for
example, delegating the long-running operation to a background thread allows the user interface thread to
remain responsive while the operation is executing.
The .NET provides several standard asynchronous design patterns that developers can use to take advantage of
background threads and free the user interface or high-priority threads to complete other operations in its
SqlCommand class. Specifically, the BeginExecuteNonQuery, BeginExecuteReader, and BeginExecuteXmlReader
methods, paired with the EndExecuteNonQuery, EndExecuteReader, and EndExecuteXmlReader methods,
provide the asynchronous support.
NOTE
Asynchronous programming is a core feature of the .NET. For more information about the different asynchronous
techniques available to developers, see Calling Synchronous Methods Asynchronously.
Although using asynchronous techniques with ADO.NET features does not add any special considerations, it is
important to be aware of the benefits and pitfalls of creating multithreaded applications. The examples that
follow in this section point out several important issues that developers will need to take into account when
building applications that incorporate multithreaded functionality.
In this section
Windows applications using callbacks
Provides an example demonstrating how to execute an asynchronous command safely, correctly handling
interaction with a form and its contents from a separate thread.
ASP.NET applications using wait handles
Provides an example demonstrating how to execute multiple concurrent commands from an ASP.NET page,
using Wait handles to manage the operation at completion of all the commands.
Polling in console applications
Provides an example demonstrating the use of polling to wait for the completion of an asynchronous command
execution from a console application. This technique is also valid in a class library or other application without a
user interface.
Next steps
SQL Server and ADO.NET
Calling Synchronous Methods Asynchronously
Windows applications using callbacks
4/27/2022 • 5 minutes to read • Edit Online
Download ADO.NET
In most asynchronous processing scenarios, you want to start a database operation and continue running other
processes without waiting for the database operation to complete. However, many scenarios require doing
something once the database operation has ended. In a Windows application, for example, you may want to
delegate the long-running operation to a background thread while allowing the user interface thread to remain
responsive. However, when the database operation is complete, you want to use the results to populate the
form. This type of scenario is best implemented with a callback.
You define a callback by specifying an AsyncCallback delegate in the BeginExecuteNonQuery,
BeginExecuteReader, or BeginExecuteXmlReader method. The delegate is called when the operation is complete.
You can pass the delegate a reference to the SqlCommand itself, making it easy to access the SqlCommand
object and call the appropriate End method without having to use a global variable.
Example
The following Windows application demonstrates the use of the BeginExecuteNonQuery method, executing a
Transact-SQL statement that includes a delay of a few seconds (emulating a long-running command).
This example demonstrates a number of important techniques, including calling a method that interacts with the
form from a separate thread. In addition, this example demonstrates how you must block users from
concurrently executing a command multiple times, and how you must ensure that the form does not close
before the callback procedure is called.
To set up this example, create a new Windows application. Place a Button control and two Label controls on the
form (accepting the default name for each control). Add the following code to the form's class, modifying the
connection string as necessary for your environment.
// Add these to the top of the class, if they're not already there:
using System;
using System.Data;
using Microsoft.Data.SqlClient;
DisplayStatus("Executing...");
isExecuting = true;
// Although it's not required that you pass the
// SqlCommand object as the second parameter in the
// BeginExecuteNonQuery call, doing so makes it easier
// to call EndExecuteNonQuery in the callback procedure.
AsyncCallback callback = new AsyncCallback(HandleCallback);
}
catch (Exception ex)
{
isExecuting = false;
DisplayStatus($"Ready (last error: {ex.Message})");
if (connection != null)
{
connection.Close();
}
}
}
}
// You may not interact with the form and its contents
// from a different thread, and this callback procedure
// is all but guaranteed to be running from a different thread
// than the form. Therefore you cannot simply call code that
// displays the results, like this:
// DisplayResults(rowText)
// Instead, you must call the procedure from the form's thread.
// One simple way to accomplish this is to call the Invoke
// method of the form, which calls the delegate you supply
// from the form's thread.
DisplayInfoDelegate del =
new DisplayInfoDelegate(DisplayResults);
this.Invoke(del, rowText);
}
catch (Exception ex)
{
// Because you're now running code in a separate thread,
// if you don't handle the exception here, none of your other
// code will catch the exception. Because none of your
// code is on the call stack in this thread, there's nothing
// higher up the stack to catch the exception if you don't
// handle it here. You can either log the exception or
// invoke a delegate (as in the non-error case in this
// example) to display the error on the form. In no case
// can you simply display the error without executing a
// delegate as in the try block here.
Next steps
Asynchronous operations
ASP.NET applications using wait handles
4/27/2022 • 7 minutes to read • Edit Online
Download ADO.NET
The callback and polling models for handling asynchronous operations are useful when your application is
processing only one asynchronous operation at a time. The Wait models provide a more flexible way of
processing multiple asynchronous operations. There are two Wait models, named for the WaitHandle methods
used to implement them: the Wait (Any) model and the Wait (All) model.
To use either Wait model, you need to use the AsyncWaitHandle property of the IAsyncResult object returned by
the BeginExecuteNonQuery, BeginExecuteReader, or BeginExecuteXmlReader methods. The WaitAny and WaitAll
methods both require you to send the WaitHandle objects as an argument, grouped together in an array.
Both Wait methods monitor the asynchronous operations, waiting for completion. The WaitAny method waits
for any of the operations to complete or time out. Once you know a particular operation is complete, you can
process its results and then continue waiting for the next operation to complete or time out. The WaitAll method
waits for all of the processes in the array of WaitHandle instances to complete or time out before continuing.
The Wait models' benefit is most striking when you need to run multiple operations of some length on different
servers, or when your server is powerful enough to process all the queries at the same time. In the examples
presented here, three queries emulate long processes by adding WAITFOR commands of varying lengths to
inconsequential SELECT queries.
// Add the following using statements, if they are not already there.
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Threading;
using Microsoft.Data.SqlClient;
SqlConnection connection1 =
new SqlConnection(GetConnectionString());
SqlConnection connection2 =
new SqlConnection(GetConnectionString());
SqlConnection connection3 =
new SqlConnection(GetConnectionString());
// To keep the example simple, all three asynchronous
// processes select a row from the same table. WAITFOR
// commands are used to emulate long-running processes
// that complete after different periods of time.
connection2.Open();
SqlCommand command2 =
new SqlCommand(commandText2, connection2);
IAsyncResult result2 = command2.BeginExecuteReader();
WaitHandle waitHandle2 = result2.AsyncWaitHandle;
connection3.Open();
SqlCommand command3 =
new SqlCommand(commandText3, connection3);
IAsyncResult result3 = command3.BeginExecuteReader();
WaitHandle waitHandle3 = result3.AsyncWaitHandle;
WaitHandle[] waitHandles = {
waitHandle1, waitHandle2, waitHandle3
};
int index;
for (int countWaits = 0; countWaits <= 2; countWaits++)
{
// WaitAny waits for any of the processes to
// complete. The return value is either the index
// of the array element whose process just
// completed, or the WaitTimeout value.
index = WaitHandle.WaitAny(waitHandles,
60000, false);
// This example doesn't actually do anything with
// the data returned by the processes, but the
// code opens readers for each just to demonstrate
// the concept.
// Instead of using the returned data to fill the
// controls on the page, the example adds the time
// the process was completed to the corresponding
// text box.
switch (index)
{
case 0:
SqlDataReader reader1;
reader1 =
command1.EndExecuteReader(result1);
if (reader1.Read())
{
TextBox1.Text =
"Completed " +
System.DateTime.Now.ToLongTimeString();
}
reader1.Close();
break;
case 1:
SqlDataReader reader2;
reader2 =
command2.EndExecuteReader(result2);
if (reader2.Read())
{
TextBox2.Text =
"Completed " +
System.DateTime.Now.ToLongTimeString();
}
reader2.Close();
break;
case 2:
SqlDataReader reader3;
reader3 =
command3.EndExecuteReader(result3);
if (reader3.Read())
{
TextBox3.Text =
"Completed " +
System.DateTime.Now.ToLongTimeString();
}
reader3.Close();
break;
case WaitHandle.WaitTimeout:
throw new Exception("Timeout");
break;
}
}
}
catch (Exception ex)
{
TextBox4.Text = ex.ToString();
}
connection1.Close();
connection2.Close();
connection3.Close();
}
// Add the following using statements, if they are not already there.
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Threading;
using Microsoft.Data.SqlClient;
SqlConnection connection1 =
new SqlConnection(GetConnectionString());
SqlConnection connection2 =
new SqlConnection(GetConnectionString());
SqlConnection connection3 =
new SqlConnection(GetConnectionString());
// To keep the example simple, all three asynchronous
// processes execute UPDATE queries that result in
// no change to the data. WAITFOR
// commands are used to emulate long-running processes
// that complete after different periods of time.
string commandText1 =
"UPDATE Production.Product " +
"SET ReorderPoint = ReorderPoint + 1 " +
"WHERE ReorderPoint Is Not Null;" +
"WAITFOR DELAY '0:0:01';" +
"UPDATE Production.Product " +
"SET ReorderPoint = ReorderPoint - 1 " +
"WHERE ReorderPoint Is Not Null";
string commandText2 =
"UPDATE Production.Product " +
"SET ReorderPoint = ReorderPoint + 1 " +
"SET ReorderPoint = ReorderPoint + 1 " +
"WHERE ReorderPoint Is Not Null;" +
"WAITFOR DELAY '0:0:05';" +
"UPDATE Production.Product " +
"SET ReorderPoint = ReorderPoint - 1 " +
"WHERE ReorderPoint Is Not Null";
string commandText3 =
"UPDATE Production.Product " +
"SET ReorderPoint = ReorderPoint + 1 " +
"WHERE ReorderPoint Is Not Null;" +
"WAITFOR DELAY '0:0:10';" +
"UPDATE Production.Product " +
"SET ReorderPoint = ReorderPoint - 1 " +
"WHERE ReorderPoint Is Not Null";
try
// For each process, open a connection and begin
// execution. Use the IAsyncResult object returned by
// BeginExecuteReader to add a WaitHandle for the
// process to the array.
{
connection1.Open();
SqlCommand command1 =
new SqlCommand(commandText1, connection1);
IAsyncResult result1 = command1.BeginExecuteNonQuery();
WaitHandle waitHandle1 = result1.AsyncWaitHandle;
connection2.Open();
SqlCommand command2 =
new SqlCommand(commandText2, connection2);
IAsyncResult result2 = command2.BeginExecuteNonQuery();
WaitHandle waitHandle2 = result2.AsyncWaitHandle;
connection3.Open();
SqlCommand command3 =
new SqlCommand(commandText3, connection3);
IAsyncResult result3 = command3.BeginExecuteNonQuery();
WaitHandle waitHandle3 = result3.AsyncWaitHandle;
WaitHandle[] waitHandles = {
waitHandle1, waitHandle2, waitHandle3
};
bool result;
// WaitAll waits for all of the processes to
// complete. The return value is True if the processes
// all completed successfully, False if any process
// timed out.
long rowCount3 =
command3.EndExecuteNonQuery(result3);
TextBox3.Text = "Completed " +
System.DateTime.Now.ToLongTimeString();
}
else
{
throw new Exception("Timeout");
}
}
}
Next steps
Asynchronous operations
Polling in console applications
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Asynchronous operations in ADO.NET allow you to initiate time-consuming database operations on one thread
while performing other tasks on another thread. In most scenarios, however, you will eventually reach a point
where your application should not continue until the database operation is complete. For such cases, it is useful
to poll the asynchronous operation to determine whether the operation has completed or not.
You can use the IsCompleted property to find out whether or not the operation has completed.
Example
The following console application updates data within the AdventureWorks sample database, doing its work
asynchronously. In order to emulate a long-running process, this example inserts a WAITFOR statement in the
command text. Normally, you would not try to make your commands run slower, but doing so in this case
makes it easier to demonstrate asynchronous behavior.
using System;
using System.Data;
using Microsoft.Data.SqlClient;
class Class1
{
[STAThread]
static void Main()
{
// The WAITFOR statement simply adds enough time to
// prove the asynchronous nature of the command.
string commandText =
"UPDATE Production.Product SET ReorderPoint = " +
"ReorderPoint + 1 " +
"WHERE ReorderPoint Is Not Null;" +
"WAITFOR DELAY '0:0:3';" +
"UPDATE Production.Product SET ReorderPoint = " +
"ReorderPoint - 1 " +
"WHERE ReorderPoint Is Not Null";
RunCommandAsynchronously(
commandText, GetConnectionString());
IAsyncResult result =
command.BeginExecuteNonQuery();
while (!result.IsCompleted)
{
Console.WriteLine(
"Waiting ({0})", count++);
// Wait for 1/10 second, so the counter
// doesn't consume all available
// resources on the main thread.
System.Threading.Thread.Sleep(100);
}
Console.WriteLine(
"Command complete. Affected {0} rows.",
command.EndExecuteNonQuery(result));
}
catch (SqlException ex)
{
Console.WriteLine("Error ({0}): {1}",
ex.Number, ex.Message);
}
catch (InvalidOperationException ex)
{
Console.WriteLine("Error: {0}", ex.Message);
}
catch (Exception ex)
{
// You might want to pass these errors
// back out to the caller.
Console.WriteLine("Error: {0}", ex.Message);
}
}
}
Next steps
Asynchronous operations
Table-valued parameters
4/27/2022 • 7 minutes to read • Edit Online
Download ADO.NET
Table-valued parameters provide an easy way to marshal multiple rows of data from a client application to SQL
Server. They don't require multiple round trips or special server-side logic for processing the data. You can use
table-valued parameters to encapsulate rows of data in a client application and send the data to the server in a
single parameterized command. The incoming data rows are stored in a table variable that can then be operated
on by using Transact-SQL.
Column values in table-valued parameters can be accessed using standard Transact-SQL SELECT statements.
Table-valued parameters are strongly typed and their structure is automatically validated. The size of table-
valued parameters is limited only by server memory.
NOTE
You cannot return data in a table-valued parameter. Table-valued parameters are input-only; the OUTPUT keyword is not
supported.
For more information about table-valued parameters, see the following resources.
Use Table-Valued Parameters (Database Engine) Describes how to create and use table-valued parameters.
Creating a user-defined table type Describes user-defined table types that are used to declare
table-valued parameters.
User-Defined Table Types Describes user-defined table types that are used to declare
table-valued parameters.
After you create a table type, you can declare table-valued parameters based on that type. The following
Transact-SQL fragment demonstrates how to declare a table-valued parameter in a stored procedure definition.
The READONLY keyword is required for declaring a table-valued parameter.
UPDATE dbo.Categories
SET Categories.CategoryName = ec.CategoryName
FROM dbo.Categories INNER JOIN @tvpEditedCategories AS ec
ON dbo.Categories.CategoryID = ec.CategoryID;
This Transact-SQL example demonstrates how to select rows from a table-valued parameter to perform an
INSERT in a single set-based operation.
You can also use any object derived from DbDataReader to stream rows of data to a table-valued parameter, as
shown in this fragment:
NOTE
If you supply a value for an identity column in a table-valued parameter, you must issue the SET IDENTITY_INSERT
statement for the session.
Next steps
SQL Server data operations in ADO.NET
SQL Server features and ADO.NET
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
The topics in this section discuss features in SQL Server that are targeted at developing database applications
using ADO.NET.
For more information, see Development (Database Engine) from SQL Server Books Online.
In this section
Enumerating instances of SQL Server (ADO.NET)
Describes how to enumerate active instances of SQL Server.
Provider statistics for SQL Server
Describes support for obtaining SQL Server run-time statistics.
SQL Server Express user instances
Describes support for SQL Server Express user instances.
Database mirroring in SQL Server
Describes database mirroring functionality.
The context connection
Describes the context connection.
Query notifications in SQL Server
Describes how .NET applications can request notification from SQL Server when data has changed.
Snapshot isolation in SQL Server
Describes support for snapshot isolation, a row versioning mechanism designed to reduce blocking in
transactional applications.
SqlClient support for high availability, disaster recovery
Describes SqlClient support for high-availability, disaster recovery (AlwaysOn) availability groups.
SqlClient support for LocalDB
Describes SqlClient support for LocalDB databases.
SqlClient support for Always Encrypted
Describes SqlClient support for the Always Encrypted feature.
SqlClient support for Data Discovery and Classification
Describes how to access Data Discovery and Classification information through SqlClient.
Next steps
SQL Server data operations in ADO.NET
SQL Server and ADO.NET
Enumerating instances of SQL Server (ADO.NET)
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
SQL Server permits applications to find SQL Server instances within the current network. The
SqlDataSourceEnumerator class exposes this information to the application developer, providing a DataTable
containing information about all the visible servers. This returned table contains a list of server instances
available on the network that matches the list provided when a user attempts to create a new connection, and
expands the drop-down list containing all the available servers on the Connection Proper ties dialog box. The
results displayed are not always complete.
NOTE
As with most Windows services, it is best to run the SQL Browser service with the least possible privileges. See SQL Server
Books Online for more information on the SQL Browser service, and how to manage its behavior.
System.Data.Sql.SqlDataSourceEnumerator instance =
System.Data.Sql.SqlDataSourceEnumerator.Instance
Once you have retrieved the static instance, you can call the GetDataSources method, which returns a DataTable
containing information about the available servers:
The table returned from the method call contains the following columns, all of which contain string values:
C O L UM N DESC RIP T IO N
NOTE
Server enumeration is only available when running in full-trust. Assemblies running in a partially-trusted environment will
not be able to use it, even if they have the SqlClientPermission Code Access Security (CAS) permission.
SQL Server provides information for the SqlDataSourceEnumerator through the use of an external Windows
service named SQL Browser. This service is enabled by default, but administrators may turn it off or disable it,
making the server instance invisible to this class.
Example
The following console application retrieves information about all of the visible SQL Server instances and
displays the information in the console window.
using System.Data.Sql;
class Program
{
static void Main()
{
// Retrieve the enumerator instance and then the data.
SqlDataSourceEnumerator instance =
SqlDataSourceEnumerator.Instance;
System.Data.DataTable table = instance.GetDataSources();
Next steps
SQL Server and ADO.NET
Provider statistics for SQL Server
4/27/2022 • 8 minutes to read • Edit Online
Download ADO.NET
Starting with the .NET Framework version 2.0 and .NET Core version 1.0, the Microsoft SqlClient Data Provider
for SQL Server supports run-time statistics. You must enable statistics by setting the StatisticsEnabled property
of the SqlConnection object to True after you have a valid connection object created. After statistics are
enabled, you can review them as a "snapshot in time" by retrieving an IDictionary reference via the
RetrieveStatistics method of the SqlConnection object. You enumerate through the list as a set of name/value
pair dictionary entries. These name/value pairs are unordered. At any time, you can call the ResetStatistics
method of the SqlConnection object to reset the counters. If statistic gathering has not been enabled, an
exception is not generated. In addition, if RetrieveStatistics is called without StatisticsEnabled having been called
first, the values retrieved are the initial values for each entry. If you enable statistics, run your application for a
while, and then disable statistics, the values retrieved will reflect the values collected up to the point where
statistics were disabled. All statistical values gathered are on a per-connection basis.
NOTE
A dictionary is used for returning provider statistics because the number, names and order of the returned statistics may
change in the future. Applications should not rely on a specific value being found in the dictionary, but should instead
check whether the value is there and branch accordingly.
The following table describes the current statistical values available. Note that the key names for the individual
values are not localized across regional versions of the Microsoft .NET Framework and .NET Core.
K EY N A M E DESC RIP T IO N
ConnectionTime The amount of time (in milliseconds) that the connection has
been opened after statistics have been enabled (total
connection time if statistics were enabled before opening the
connection).
CursorOpens Returns the number of times a cursor was open through the
connection once the application has started using the
provider and has enabled statistics.
SqlConnection
SqlCommand
SqlDataReader
SqlDataAdapter
SqlTransaction
SqlCommandBuilder
SqlDataReader
GetBoolean
GetChar
GetDateTime
GetDecimal
GetDouble
GetFloat
K EY N A M E DESC RIP T IO N
GetGuid
GetInt16
GetInt32
GetInt64
GetName
GetOrdinal
GetSqlBinary
GetSqlBoolean
GetSqlByte
GetSqlDateTime
GetSqlDecimal
GetSqlDouble
GetSqlGuid
GetSqlInt16
GetSqlInt32
GetSqlInt64
GetSqlMoney
GetSqlSingle
GetSqlString
GetString
IsDBNull
IduCount Returns the total number of INSERT, DELETE, and UPDATE
statements executed through the connection once the
application has started using the provider and has enabled
statistics.
SumResultSets Returns the number of result sets that have been used once
the application has started using the provider and has
enabled statistics. For example this would include any result
set returned to the client. For cursors, each fetch or block-
fetch operation is considered an independent result set.
Retrieving a value
The following console application shows how to enable statistics on a connection, retrieve four individual
statistic values, and write them out to the console window.
NOTE
The following example uses the sample AdventureWorks database included with SQL Server. The connection string
provided in the sample code assumes the database is installed and available on the local computer. Modify the connection
string as necessary for your environment.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data;
using Microsoft.Data.SqlClient;
namespace CS_Stats_Console_GetValue
{
class Program
{
static void Main(string[] args)
{
string connectionString = GetConnectionString();
awConnection.Open();
productAdapter.Fill(awDataSet, "ProductTable");
// Retrieve the current statistics as
// a collection of values at this point
// and time.
IDictionary currentStatistics =
awConnection.RetrieveStatistics();
Console.WriteLine("BytesReceived: " +
bytesReceived.ToString());
Console.WriteLine("BytesSent: " +
bytesSent.ToString());
Console.WriteLine("SelectCount: " +
selectCount.ToString());
Console.WriteLine("SelectRows: " +
selectRows.ToString());
Console.WriteLine();
Console.WriteLine("Press any key to continue");
Console.ReadLine();
}
}
private static string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
return "Data Source=localhost;Integrated Security=SSPI;" +
"Initial Catalog=AdventureWorks";
"Initial Catalog=AdventureWorks";
}
}
}
NOTE
The following example uses the sample AdventureWorks database included with SQL Server. The connection string
provided in the sample code assumes the database is installed and available on the local computer. Modify the connection
string as necessary for your environment.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Microsoft.Data.SqlClient;
namespace CS_Stats_Console_GetAll
{
class Program
{
static void Main(string[] args)
{
string connectionString = GetConnectionString();
awConnection.Open();
productAdapter.Fill(awDataSet, "ProductTable");
Console.WriteLine();
Console.WriteLine("Press any key to continue");
Console.ReadLine();
}
}
private static string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
return "Data Source=localhost;Integrated Security=SSPI;" +
"Initial Catalog=AdventureWorks";
}
}
}
Next steps
SQL Server and ADO.NET
SQL Server Express user instances
4/27/2022 • 8 minutes to read • Edit Online
Download ADO.NET
Microsoft SQL Server Express Edition (SQL Server Express) supports the user instance feature, which is only
available when using the Microsoft SqlClient Data Provider for SQL Server. A user instance is a separate instance
of the SQL Server Express Database Engine that is generated by a parent instance. User instances allow users
who are not administrators on their local computers to attach and connect to SQL Server Express databases.
Each instance runs under the security context of the individual user, on a one-instance-per-user basis.
NOTE
User instances are not needed for users who are already administrators on their own computers, or for scenarios
involving multiple database users.
The network protocol for user instances must be local Named Pipes. A user instance cannot be started on a
remote instance of SQL Server, and SQL Server logins are not allowed.
NOTE
You can also use the SqlConnectionStringBuilderUserInstance and AttachDBFilename properties to build a connection
string at run time.
When DataDirectory is used, the resulting file path cannot be higher in the directory structure than the
directory pointed to by the substitution string. For example, if the fully expanded DataDirectory is
C:\AppDirectory\app_data, then the sample connection string shown above works because it is below
c:\AppDirectory. However, attempting to specify DataDirectory as |DataDirectory|\..\data will result in an
error because \data is not a subdirectory of \AppDirectory.
If the connection string has an improperly formatted substitution string, an ArgumentException will be thrown.
NOTE
Microsoft.Data.SqlClient resolves the substitution strings into full paths against the local computer file system. Therefore,
remote server, HTTP, and UNC path names are not supported. An exception is thrown when the connection is opened if
the server is not located on the local computer.
When the SqlConnection is opened, it is redirected from the default SQL Server Express instance to a run-time
initiated instance running under the caller's account.
NOTE
It may be necessary to increase the ConnectionTimeout value since user instances may take longer to load than regular
instances.
The following code fragment opens a new SqlConnection , displays the connection string in the console window,
and then closes the connection when exiting the using code block.
NOTE
User instances are not supported in common language runtime (CLR) code that is running inside of SQL Server. An
InvalidOperationException is thrown if Open is called on a SqlConnection that has User Instance=true in the
connection string.
NOTE
If Min Pool Size is used in the connection string with a value greater than zero, the connection pooler will always
maintain a few opened connections, and the user instance will not automatically shut down.
NOTE
The .mdf and .ldf files represent the database and log files, respectively. These two files are a matched set, so care must be
taken during backup and restore operations. The database file contains information about the exact version of the log file,
and the database will not open if it is coupled with the wrong log file.
To avoid data corruption, a database in the user instance is opened with exclusive access. If two different user
instances share the same database on the same computer, the user on the first instance must close the database
before it can be opened in a second instance.
IMPORTANT
User instances should only be used in scenarios where all the applications using it are fully trusted.
Next steps
SQL Server and ADO.NET
Database mirroring in SQL Server
4/27/2022 • 3 minutes to read • Edit Online
Download ADO.NET
Database mirroring in SQL Server allows you to keep a copy, or mirror, of a SQL Server database on a standby
server. Mirroring ensures two separate copies of the data always exist, providing high availability and complete
data redundancy. The Microsoft SqlClient Provider for SQL Server provides implicit support for database
mirroring. The developer doesn't need to do anything once the client has been configured for a SQL Server
database. Also, the SqlConnection object supports an explicit connection mode that allows supplying the name
of a failover partner server in the ConnectionString.
The following simplified sequence of events occurs for a SqlConnection object that targets a database
configured for mirroring:
1. The client application successfully connects to the principal database, and the server sends back the name of
the partner server, which the client caches.
2. If the server containing the principal database fails or connectivity is interrupted, connection and transaction
state is lost. The client application attempts to re-establish a connection to the principal database and fails.
3. The client application then transparently attempts to establish a connection to the mirror database on the
partner server. If it succeeds, the connection is redirected to the mirror database, which then becomes the
new principal database.
";Failover Partner=PartnerServerName"
If you omit the name of the failover partner server and the principal database is unavailable when the client
application first connects, then a SqlException occurs.
When a SqlConnection is successfully opened, the server returns the failover partner name, which supersedes
any values that are supplied in the connection string.
NOTE
You must explicitly specify the initial catalog or database name in the connection string for database mirroring scenarios. If
the client receives failover information on a connection that doesn't have an explicitly specified initial catalog or database,
the failover information is not cached and the application does not attempt to fail over if the principal server fails. If a
connection string has a value for the failover partner, but no value for the initial catalog or database, an
InvalidArgumentException is raised.
NOTE
Mirroring support on the server is configured on a per-database basis. If data manipulation operations are executed
against other databases not included in the principal/mirror set, either by using multipart names or by changing the
current database, the changes to these other databases do not propagate in the event of failure. No error is generated
when data is modified in a database that is not mirrored. The developer must evaluate the possible impact of such
operations.
Next steps
Database mirroring resources
For conceptual documentation and information on configuring, deploying, and administering mirroring, see the
following resources in SQL Server documentation.
Download ADO.NET
The problem of internal data access is a fairly common scenario. That is, you wish to access the same server on
which your common language runtime (CLR) stored procedure or function is executing. One option is to create
a connection using SqlConnection, specify a connection string that points to the local server, and open the
connection. This requires specifying credentials for logging in. The connection is in a different database session
than the stored procedure or function, it may have different SET options, it is in a separate transaction, it does
not see your temporary tables, and so on. If your managed stored procedure or function code is executing in the
SQL Server process, it is because someone connected to that server and executed a SQL statement to invoke it.
You probably want the stored procedure or function to execute in the context of that connection, along with its
transaction, SET options, and so on. This is called the context connection.
The context connection lets you execute Transact-SQL statements in the same context that your code was
invoked in the first place. For more detailed information, see The context connection from SQL Server Books
Online.
Query notifications in SQL Server
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Built upon the Service Broker infrastructure, query notifications allow applications to be notified when data has
changed. This feature is particularly useful for applications that provide a cache of information from a database,
such as a Web application, and need to be notified when the source data is changed.
There are three ways you can implement query notifications using ADO.NET:
The low-level implementation is provided by the SqlNotificationRequest class that exposes server-side
functionality, enabling you to execute a command with a notification request.
The high-level implementation is provided by the SqlDependency class, which is a class that provides a
high-level abstraction of notification functionality between the source application and SQL Server,
enabling you to use a dependency to detect changes in the server. In most cases, this is the simplest and
most effective way to leverage SQL Server notifications capability by managed client applications using
the Microsoft SqlClient Data Provider for SQL Server.
In addition, Web applications built using ASP.NET 2.0 or later can use the SqlCacheDependency helper
classes.
Query notifications are used for applications that need to refresh displays or caches in response to changes in
underlying data. Microsoft SQL Server allows .NET applications to send a command to SQL Server and request
notification if executing the same command would produce result sets different from those initially retrieved.
Notifications generated at the server are sent through queues to be processed later.
You can set up notifications for SELECT and EXECUTE statements. When using an EXECUTE statement, SQL
Server registers a notification for the command executed rather than the EXECUTE statement itself. The
command must meet the requirements and limitations for a SELECT statement. When a command that registers
a notification contains more than one statement, the Database Engine creates a notification for each statement
in the batch.
If you are developing an application where you need reliable sub-second notifications when data changes,
review the sections Planning an Efficient Quer y Notifications Strategy and Alternatives to Quer y
Notifications in the Planning for Notifications topic in SQL Server Books Online. For more information about
Query Notifications and SQL Server Service Broker, see the following links to topics in SQL Server Books Online.
SQL Ser ver documentation
Using Query Notifications
Creating a Query for Notification
Development (Service Broker)
Service Broker Developer InfoCenter
Developer's Guide (Service Broker)
In this section
Enabling query notifications
Discusses how to use query notifications, including the requirements for enabling and using them.
SqlDependency in an ASP.NET application
Demonstrates how to use query notifications from an ASP.NET application.
Detecting changes with SqlDependency
Demonstrates how to detect when query results will be different from those originally received.
SqlCommand execution with a SqlNotificationRequest
Demonstrates configuring a SqlCommand object to work with a query notification.
Reference
SqlNotificationRequest
Describes the SqlNotificationRequest class and all of its members.
SqlDependency
Describes the SqlDependency class and all of its members.
SqlCacheDependency
Describes the SqlCacheDependency class and all of its members.
Next steps
SQL Server and ADO.NET
Enabling query notifications
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Applications that consume query notifications have a common set of requirements. Your data source must be
correctly configured to support SQL query notifications and the user must have the correct client-side and
server-side permissions.
To use query notifications, you must:
Enable query notifications for your database.
Ensure that the user ID used to connect to the database has the necessary permissions.
Use a SqlCommand object to execute a valid SELECT statement with an associated notification object—either
SqlDependency or SqlNotificationRequest.
Provide code to process the notification if the data being monitored changes.
For the query notification samples to run correctly, the following Transact-SQL statements must be executed on
the database server.
using Microsoft.Data.SqlClient;
using System.Security.Permissions;
class Program
{
static void Main()
{
}
Next steps
Query notifications in SQL Server
SqlDependency in an ASP.NET application
4/27/2022 • 3 minutes to read • Edit Online
Download ADO.NET
The example in this section shows how to use SqlDependency indirectly by using the ASP.NET
SqlCacheDependency object. The SqlCacheDependency object uses a SqlDependency to listen for notifications
and correctly update the cache.
NOTE
The sample code assumes that you have enabled query notifications by executing the scripts in Enabling query
notifications.
using Microsoft.Data.SqlClient;
using System.Web.Caching;
Response.Cache.SetExpires(expires);
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(true);
Response.AddCacheDependency(dependency);
connection.Open();
GridView1.DataSource = command.ExecuteReader();
GridView1.DataBind();
}
}
}
5. Add two helper methods, GetConnectionString and GetSQL . The connection string defined uses
integrated security. Verify that the account you're using has the necessary database permissions and that
the sample database, AdventureWorks , has notifications enabled.
// using Microsoft.Data.SqlClient;
private string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
return "Data Source=(local);Integrated Security=true;" +
"Initial Catalog=AdventureWorks;";
}
private string GetSQL()
{
return "SELECT Production.Product.ProductID, " +
"Production.Product.Name, " +
"Production.Location.Name AS Location, " +
"Production.ProductInventory.Quantity " +
"FROM Production.Product INNER JOIN " +
"Production.ProductInventory " +
"ON Production.Product.ProductID = " +
"Production.ProductInventory.ProductID " +
"INNER JOIN Production.Location " +
"ON Production.ProductInventory.LocationID = " +
"Production.Location.LocationID " +
"WHERE ( Production.ProductInventory.Quantity <= 100 ) " +
"ORDER BY Production.ProductInventory.Quantity, " +
"Production.Product.Name;";
}
Next steps
Query notifications in SQL Server
Detecting changes with SqlDependency
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
A SqlDependency object can be associated with a SqlCommand to detect when query results differ from the
results originally retrieved. You can also assign a delegate to the OnChange event, which will fire when the results
change for an associated command. Associate the SqlDependency with the command before you execute the
command. The HasChanges property of the SqlDependency can also be used to determine if the query results
have changed since the data was first retrieved.
Security considerations
The dependency infrastructure relies on a SqlConnection that is opened when Start is called to receive
notifications that the underlying data has changed for a given command. The ability for a client to begin the call
to SqlDependency.Start is controlled by using SqlClientPermission and code access security attributes. For more
information, see Enabling query notifications.
Example
The following steps illustrate how to declare a dependency, execute a command, and receive a notification when
the result set changes:
1. Initiate a SqlDependency connection to the server.
2. Create SqlConnection and SqlCommand objects to connect to the server and define a Transact-SQL
statement.
3. Create a new SqlDependency object, or use an existing one, and bind it to the SqlCommand object.
Internally, this association creates a SqlNotificationRequest object and binds it to the command object as
needed. This notification request contains an internal identifier that uniquely identifies this SqlDependency
object. It also starts the client listener if it isn't already active.
4. Subscribe an event handler to the OnChange event of the SqlDependency object.
5. Execute the command using any of the Execute methods of the SqlCommand object. Because the
command is bound to the notification object, the server recognizes that it must generate a notification,
and the queue information will point to the dependencies queue.
6. Stop the SqlDependency connection to the server.
If any user then changes the underlying data, Microsoft SQL Server detects that there's a notification pending for
such a change, and posts a notification that is processed and forwarded to the client through the underlying
SqlConnection that was created by calling SqlDependency.Start . The client listener receives the invalidation
message. The client listener then locates the associated SqlDependency object and fires the OnChange event.
The following code fragment shows the design pattern you would use to create a sample application.
void Initialization()
{
// Create a dependency connection.
SqlDependency.Start(connectionString, queueName);
}
void SomeMethod()
{
// Assume connection is an open SqlConnection.
// Handler method
void OnDependencyChange(object sender,
SqlNotificationEventArgs e )
{
// Handle the event (for example, invalidate this cache entry).
}
void Termination()
{
// Release the dependency.
SqlDependency.Stop(connectionString, queueName);
}
Next steps
Query notifications in SQL Server
SqlCommand execution with a
SqlNotificationRequest
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
A SqlCommand can be configured to generate a notification when data changes after it has been fetched from
the server and the result set would be different if the query were executed again. This is useful for scenarios
where you want to use custom notification queues on the server or when you do not want to maintain live
objects.
NOTE
When using SQL Server notification requests with SqlDependency, create your own queue name instead of using the
default service name.
There are no new client-side security elements for SqlNotificationRequest. This is primarily a server feature, and
the server has created special privileges that users must have to request a notification.
Example
The following code fragment demonstrates how to create a SqlNotificationRequest and associate it with a
SqlCommand.
// Assume connection is an open SqlConnection.
// Create a new SqlCommand object.
SqlCommand command=new SqlCommand(
"SELECT ShipperID, CompanyName, Phone FROM dbo.Shippers", connection);
Next steps
Query notifications in SQL Server
Snapshot isolation in SQL Server
4/27/2022 • 15 minutes to read • Edit Online
Download ADO.NET
Snapshot isolation enhances concurrency for OLTP applications.
Setting the READ_COMMITTED_SNAPSHOT ON option allows access to versioned rows under the default READ
COMMITTED isolation level. If the READ_COMMITTED_SNAPSHOT option is set to OFF, you must explicitly set
the Snapshot isolation level for each session in order to access versioned rows.
SqlTransaction sqlTran =
connection.BeginTransaction(IsolationLevel.Snapshot);
Example
The following example demonstrates how the different isolation levels behave by attempting to access locked
data, and it is not intended to be used in production code.
The code connects to the AdventureWorks sample database in SQL Server and creates a table named
TestSnapshot and inserts one row of data. The code uses the ALTER DATABASE Transact-SQL statement to turn
on snapshot isolation for the database, but it does not set the READ_COMMITTED_SNAPSHOT option, leaving
the default READ COMMITTED isolation-level behavior in effect. The code then performs the following actions:
1. It begins, but does not complete, sqlTransaction1, which uses the SERIALIZABLE isolation level to start an
update transaction. This has the effect of locking the table.
2. It opens a second connection and initiates a second transaction using the SNAPSHOT isolation level to
read the data in the TestSnapshot table. Because snapshot isolation is enabled, this transaction can read
the data that existed before sqlTransaction1 started.
3. It opens a third connection and initiates a transaction using the READ COMMITTED isolation level to
attempt to read the data in the table. In this case, the code cannot read the data because it cannot read
past the locks placed on the table in the first transaction and times out. The same result would occur if the
REPEATABLE READ and SERIALIZABLE isolation levels were used because these isolation levels also
cannot read past the locks placed in the first transaction.
4. It opens a fourth connection and initiates a transaction using the READ UNCOMMITTED isolation level,
which performs a dirty read of the uncommitted value in sqlTransaction1. This value may never actually
exist in the database if the first transaction is not committed.
5. It rolls back the first transaction and cleans up by deleting the TestSnapshot table and turning off
snapshot isolation for the AdventureWorks database.
NOTE
The following examples use the same connection string with connection pooling turned off. If a connection is pooled,
resetting its isolation level does not reset the isolation level at the server. As a result, subsequent connections that use the
same pooled inner connection start with their isolation levels set to that of the pooled connection. An alternative to
turning off connection pooling is to set the isolation level explicitly for each connection.
using Microsoft.Data.SqlClient;
class Program
{
static void Main()
{
// Assumes GetConnectionString returns a valid connection string
// where pooling is turned off by setting Pooling=False;.
string connectionString = GetConnectionString();
using (SqlConnection connection1 = new SqlConnection(connectionString))
{
// Drop the TestSnapshot table if it exists
connection1.Open();
SqlCommand command1 = connection1.CreateCommand();
command1.CommandText = "IF EXISTS "
+ "(SELECT * FROM sys.tables WHERE name=N'TestSnapshot') "
+ "DROP TABLE TestSnapshot";
try
{
command1.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
// Enable Snapshot isolation
command1.CommandText =
"ALTER DATABASE AdventureWorks SET ALLOW_SNAPSHOT_ISOLATION ON";
command1.ExecuteNonQuery();
transaction4.Commit();
}
// CLEANUP
// Delete the TestSnapshot table and set
// ALLOW_SNAPSHOT_ISOLATION OFF
using (SqlConnection connection5 = new SqlConnection(connectionString))
{
connection5.Open();
SqlCommand command5 = connection5.CreateCommand();
command5.CommandText = "DROP TABLE TestSnapshot";
SqlCommand command6 = connection5.CreateCommand();
command6.CommandText =
"ALTER DATABASE AdventureWorks SET ALLOW_SNAPSHOT_ISOLATION OFF";
try
{
command5.ExecuteNonQuery();
command6.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Console.WriteLine("Done!");
}
Example
The following example demonstrates the behavior of snapshot isolation when data is being modified. The code
performs the following actions:
1. Connects to the AdventureWorks sample database and enables SNAPSHOT isolation.
2. Creates a table named TestSnapshotUpdate and inserts three rows of sample data.
3. Begins, but does not complete, sqlTransaction1 using SNAPSHOT isolation. Three rows of data are
selected in the transaction.
4. Creates a second SqlConnection to AdventureWorks and creates a second transaction using the READ
COMMITTED isolation level that updates a value in one of the rows selected in sqlTransaction1.
5. Commits sqlTransaction2.
6. Returns to sqlTransaction1 and attempts to update the same row that sqlTransaction1 already committed.
Error 3960 is raised, and sqlTransaction1 is rolled back automatically. The SqlException.Number and
SqlException.Message are displayed in the Console window.
7. Executes clean-up code to turn off snapshot isolation in AdventureWorks and delete the
TestSnapshotUpdate table.
using Microsoft.Data.SqlClient;
using System.Data.Common;
class Program
{
static void Main()
{
// Assumes GetConnectionString returns a valid connection string
// where pooling is turned off by setting Pooling=False;.
string connectionString = GetConnectionString();
using (SqlConnection connection1 = new SqlConnection(connectionString))
{
connection1.Open();
SqlCommand command1 = connection1.CreateCommand();
// CLEANUP:
// Turn off Snapshot isolation and delete the table
using (SqlConnection connection3 = new SqlConnection(connectionString))
{
connection3.Open();
SqlCommand command3 = connection3.CreateCommand();
command3.CommandText =
"ALTER DATABASE AdventureWorks SET ALLOW_SNAPSHOT_ISOLATION OFF";
try
{
command3.ExecuteNonQuery();
Console.WriteLine(
"CLEANUP: Snapshot isolation turned off in AdventureWorks.");
}
catch (Exception ex)
{
Console.WriteLine("CLEANUP FAILED: {0}", ex.Message);
}
command3.CommandText = "DROP TABLE TestSnapshotUpdate";
try
{
command3.ExecuteNonQuery();
Console.WriteLine("CLEANUP: TestSnapshotUpdate table deleted.");
}
catch (Exception ex)
{
Console.WriteLine("CLEANUP FAILED: {0}", ex.Message);
}
}
Console.WriteLine("Done");
Console.ReadLine();
}
Using the UPDLOCK lock hint blocks any rows attempting to update the rows before the first transaction
completes. This guarantees that the selected rows have no conflicts when they are updated later in the
transaction. See "Locking Hints" in SQL Server Books Online.
If your application has many conflicts, snapshot isolation may not be the best choice. Hints should only be used
when really needed. Your application should not be designed so that it constantly relies on lock hints for its
operation.
Next steps
SQL Server and ADO.NET
Transaction Locking and Row Versioning Guide
SqlClient support for high availability, disaster
recovery
4/27/2022 • 5 minutes to read • Edit Online
Download ADO.NET
This topic discusses Microsoft SqlClient Data Provider for SQL Server support for high-availability, disaster
recovery -- AlwaysOn Availability Groups. AlwaysOn Availability Groups feature was added to SQL Server 2012.
For more information about AlwaysOn Availability Groups, see SQL Server Books Online.
You can now specify the availability group listener of a (high-availability, disaster-recovery) availability group
(AG) or SQL Server 2012 Failover Cluster Instance in the connection property. If a SqlClient application is
connected to an AlwaysOn database that fails over, the original connection is broken and the application must
open a new connection to continue work after the failover.
If you are not connecting to an availability group listener or SQL Server 2012 Failover Cluster Instance, and if
multiple IP addresses are associated with a hostname, SqlClient will iterate sequentially through all IP addresses
associated with DNS entry. This can be time consuming if the first IP address returned by DNS server is not
bound to any network interface card (NIC). When connecting to an availability group listener or SQL Server
2012 Failover Cluster Instance, SqlClient attempts to establish connections to all IP addresses in parallel and if a
connection attempt succeeds, the driver will discard any pending connection attempts.
NOTE
Increasing connection timeout and implementing connection retry logic will increase the probability that an application
will connect to an availability group. Also, because a connection can fail because of a failover, you should implement
connection retry logic, retrying a failed connection until it reconnects.
The following connection properties are supported in the Microsoft SqlClient Data Provider for SQL Server:
ApplicationIntent
MultiSubnetFailover
Read-only routing
Read-only routing is a feature that can ensure the availability of a read only replica of a database. To enable
read-only routing:
You must connect to an Always On Availability Group availability group listener.
The ApplicationIntent connection string keyword must be set to ReadOnly .
The Availability Group must be configured by the database administrator to enable read-only routing.
It is possible that multiple connections using read-only routing will not all connect to the same read-only replica.
Changes in database synchronization or changes in the server's routing configuration can result in client
connections to different read-only replicas. To ensure that all read-only requests connect to the same read-only
replica, do not pass an availability group listener to the Data Source connection string keyword. Instead, specify
the name of the read-only instance.
Read-only routing may take longer than connecting to the primary because read only routing first connects to
the primary and then looks for the best available readable secondary. Because of this, you should increase your
login timeout.
Next steps
SQL Server features and ADO.NET
SqlClient support for LocalDB
4/27/2022 • 2 minutes to read • Edit Online
Download ADO.NET
Beginning in SQL Server code name Denali, a lightweight version of SQL Server, called LocalDB, will be
available. This topic discusses how to connect to a LocalDB database.
Remarks
For more information about LocalDB, including how to install LocalDB and configure your LocalDB instance, see
SQL Server Books Online.
To summarize what you can do with LocalDB:
Create and start LocalDB instances with sqllocaldb.exe or your app.config file.
Use sqlcmd.exe to add and modify databases in a LocalDB instance. For example,
sqlcmd -S (localdb)\myinst .
Use the AttachDBFilename connection string keyword to add a database to your LocalDB instance. When
using AttachDBFilename , if you do not specify the name of the database with the Database connection
string keyword, the database will be removed from the LocalDB instance when the application closes.
Specify a LocalDB instance in your connection string. For example, your instance name is myInstance , the
connection string would include:
server=(localdb)\\myInstance
type="System.Data.LocalDBConfigurationSection,System.Data,Version=4.0.0.0,Culture=neutral,PublicKeyTo
ken=b77a5c561934e089"/>
</configSections>
<system.data.localdb>
<localdbinstances>
<add name="myInstance" version="11.0" />
</localdbinstances>
</system.data.localdb>
</configuration>
Specify the name of the instance using the server connection string keyword. The instance name
specified in the server connection string keyword must match the name specified in the app.config file.
Use the AttachDBFilename connection string keyword to specify the .MDF file.
Next steps
SQL Server features and ADO.NET
Using Always Encrypted with the Microsoft .NET
Data Provider for SQL Server
4/27/2022 • 37 minutes to read • Edit Online
Prerequisites
Configure Always Encrypted in your database. This process involves provisioning Always Encrypted keys and
setting up encryption for selected database columns. If you don't already have a database with Always
Encrypted configured, follow the directions in Getting Started with Always Encrypted.
If you're using Always Encrypted with secure enclaves, see Develop applications using Always Encrypted with
secure enclaves for more prerequisites.
Ensure the required .NET platform is installed on your development machine. With Microsoft.Data.SqlClient,
the Always Encrypted feature is supported for both .NET Framework and .NET Core. Make sure .NET
Framework 4.6 or higher, or .NET Core 2.1 or higher is configured as the target .NET platform version in your
development environment. With Microsoft.Data.SqlClient version 2.1.0 and higher, the Always Encrypted
feature is also supported for .NET Standard 2.0. To use Always Encrypted with secure enclaves, .NET Standard
2.1 is required. If you're using Visual Studio, refer to Framework targeting overview.
The following table summarizes the required .NET platforms to use Always Encrypted with
Microsoft.Data.SqlClient .
SUP P O RT A L WAY S
SUP P O RT A L WAY S EN C RY P T ED W IT H TA RGET M IC RO SO F T. DATA . SQ
EN C RY P T ED SEC URE EN C L AVE F RA M EW O RK L C L IEN T VERSIO N O P ERAT IN G SY ST EM
Always Encrypted can also be enabled for individual queries. See the Controlling the performance impact
of Always Encr ypted section below. Enabling Always Encrypted isn't sufficient for encryption or decryption to
succeed. You also need to make sure:
The application has the VIEW ANY COLUMN MASTER KEY DEFINITION and VIEW ANY COLUMN
ENCRYPTION KEY DEFINITION database permissions, required to access the metadata about Always
Encrypted keys in the database. For details, see the Database Permissions section in Always Encrypted
(Database Engine).
The application can access the column master key that protects the column encryption keys, which encrypt
the queried database columns.
A L WAY S EN C RY P T ED IS A L WAY S EN C RY P T ED IS
EN A B L ED A N D T H E EN A B L ED A N D T H E
A P P L IC AT IO N C A N A C C ESS A P P L IC AT IO N C A N 'T
T H E K EY S A N D K EY A C C ESS T H E K EY S O R K EY A L WAY S EN C RY P T ED IS
Q UERY C H A RA C T ERIST IC M ETA DATA M ETA DATA DISA B L ED
Queries retrieving data Results from encrypted Error Results from encrypted
from encrypted columns columns are transparently columns aren't decrypted.
without parameters decrypted. The application The application receives
targeting encrypted receives plaintext values of encrypted values as byte
columns. the .NET data types arrays (byte[]).
corresponding to the SQL
Server types configured for
the encrypted columns.
The following examples illustrate retrieving and modifying data in encrypted columns. The examples assume the
target table with the below schema. The SSN and BirthDate columns are encrypted.
CREATE TABLE [dbo].[Patients]([PatientId] [int] IDENTITY(1,1),
[SSN] [char](11) COLLATE Latin1_General_BIN2
ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC,
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256',
COLUMN_ENCRYPTION_KEY = CEK1) NOT NULL,
[FirstName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL,
[BirthDate] [date]
ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED,
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256',
COLUMN_ENCRYPTION_KEY = CEK1) NOT NULL
PRIMARY KEY CLUSTERED ([PatientId] ASC) ON [PRIMARY])
GO
cmd.ExecuteNonQuery();
}
NOTE
The value used in the WHERE clause to filter on the SSN column needs to be passed using SqlParameter, so that
the Microsoft .NET Data Provider for SQL Ser ver can transparently encrypt it before sending it to the
database.
All values printed by the program will be in plaintext, as the Microsoft .NET Data Provider for SQL Ser ver
will transparently decrypt the data retrieved from the SSN and BirthDate columns.
Queries can perform equality comparisons on columns if they are encrypted using deterministic encryption. For
more information, see Selecting Deterministic or Randomized Encryption.
NOTE
As Always Encrypted is not enabled in the connection string, the query will return encrypted values of SSN and
BirthDate as byte arrays (the program converts the values to strings).
A query retrieving data from encrypted columns with Always Encrypted disabled can have parameters, as long as
none of the parameters target an encrypted column. The above query filters by LastName, which isn't encrypted
in the database. If the query filtered by SSN or BirthDate , the query would fail.
You don't need to make any application code changes to use these providers, but note the following details:
You (or your DBA) need to make sure the provider name, configured in the column master key metadata, is
correct and the column master key path complies with the key path format that is valid for a given provider.
It's recommended that you configure the keys using tools such as SQL Server Management Studio, which
automatically generates the valid provider names and key paths when issuing the CREATE COLUMN MASTER
KEY (Transact-SQL) statement. For more information, see Configuring Always Encrypted using SQL Server
Management Studio and Configure Always Encrypted using PowerShell.
Ensure your application can access the key in the key store. This process may involve granting your
application access to the key and/or the key store, depending on the key store, or performing other key
store-specific configuration steps. For example, to access a key store implementing CNG or CAPI (like a
hardware security module), you need to make sure a library implementing CNG or CAPI for your store is
installed on your application machine. For details, see Create and store column master keys for Always
Encrypted.
Using the Azure Key Vault provider
Azure Key Vault is a convenient option to store and manage column master keys for Always Encrypted
(especially if your applications are hosted in Azure). The Microsoft .NET Data Provider for SQL Ser ver
doesn't include a built-in column master key store provider for Azure Key Vault, but it's available as a NuGet
package (Microsoft.Data.SqLClient.AlwaysEncrypted.AzureKeyVaultProvider) that you can easily integrate with
your application. For details, see Always Encrypted - Protect sensitive data in SQL Database with data encryption
and store your encryption keys in the Azure Key Vault.
.NET Supportability
M IC RO SO F T. DATA . SQ L C L IEN T
VERSIO N VERSIO N . N ET P L AT F O RM S
NOTE
The Microsoft.Data.SqLClient.AlwaysEncrypted.AzureKeyVaultProvider supports both Vaults and Managed HSMs
in Azure Key Vault.
For examples that demonstrate encryption/decryption with Azure Key Vault, see Azure Key Vault working with
Always Encrypted and Azure Key Vault working with Always Encrypted with secure enclaves.
Implementing a custom column master key store provider
If you want to store column master keys in a key store that isn't supported by an existing provider, you can
implement a custom provider by extending the SqlColumnEncryptionKeyStoreProvider class and registering the
provider using one of the following methods:
SqlConnection.RegisterColumnEncryptionKeyStoreProviders
SqlConnection.RegisterColumnEncryptionKeyStoreProvidersOnConnection (Added in version 3.0.0)
SqlCommand.RegisterColumnEncryptionKeyStoreProvidersOnCommand (Added in version 3.0.0)
public class MyCustomKeyStoreProvider : SqlColumnEncryptionKeyStoreProvider
{
public const string ProviderName = "MY_CUSTOM_STORE";
class Program
{
static void Main()
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand command = connection.CreateCommand())
{
Dictionary<string, SqlColumnEncryptionKeyStoreProvider> customKeyStoreProviders = new
Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();
SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider = new
SqlColumnEncryptionAzureKeyVaultProvider();
customKeyStoreProviders.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName,
azureKeyVaultProvider);
command.RegisterColumnEncryptionKeyStoreProvidersOnCommand(customKeyStoreProviders);
// Perform database operation using Azure Key Vault Provider
// Any decrypted column encryption keys will be cached
} // Column encryption key cache of "azureKeyVaultProvider" is cleared when
"azureKeyVaultProvider" goes out of scope
}
}
}
NOTE
CEK caching implemented by custom key store providers will be disabled by the driver if the key store provider instance is
registered in the driver globally using the SqlConnection.RegisterColumnEncryptionKeyStoreProviders method. Any CEK
caching implementation should reference the value of
SqlColumnEncryptionKeyStoreProvider.ColumnEncryptionKeyCacheTtl before caching a CEK and not cache it if the value is
zero. This will avoid duplicate caching and possible user confusion when they are trying to configure key caching.
The following example shows the precedence of custom column master key store providers registered on a
command instance:
class Program
{
static void Main()
{
Dictionary<string, SqlColumnEncryptionKeyStoreProvider> customKeyStoreProviders = new
Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();
MyCustomKeyStoreProvider firstProvider = new MyCustomKeyStoreProvider();
customKeyStoreProviders.Add("FIRST_CUSTOM_STORE", firstProvider);
// Registers the provider globally
SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customKeyStoreProviders);
Using column master key store providers for programmatic key provisioning
When the Microsoft .NET Data Provider for SQL Ser ver accesses encrypted columns, it transparently finds
and calls the right column master key store provider to decrypt column encryption keys. Typically, your normal
application code doesn't directly call column master key store providers. You may, however, instantiate and call a
provider explicitly to programmatically create and manage Always Encrypted keys: to generate an encrypted
column encryption key and decrypt a column encryption key (for example, as part column master key rotation).
For more information, see Overview of key management for Always Encrypted. Implementing your own key
management tools may be required only if you use a custom key store provider. When using keys stored in keys
stores, for which built-in providers exist, and or in Azure Key Vault, you can use existing tools, such as SQL
Server Management Studio or PowerShell, to manage and provision keys. The below example, illustrates
generating a column encryption key and using the SqlColumnEncryptionCertificateStoreProvider class to
encrypt the key with a certificate.
using System.Security.Cryptography;
static void Main(string[] args)
{
byte[] EncryptedColumnEncryptionKey = GetEncryptedColumnEncryptonKey();
Console.WriteLine("0x" + BitConverter.ToString(EncryptedColumnEncryptionKey).Replace("-", ""));
Console.ReadKey();
}
NOTE
Setting Always Encrypted at the query level limits the performance benefit of parameter encryption metadata caching.
To control the Always Encrypted behavior of individual queries, you need to use this constructor of
SqlCommand and SqlCommandColumnEncryptionSetting. Here are some useful guidelines:
If most queries a client application executes access encrypted columns:
Set the Column Encr yption Setting connection string keyword to Enabled .
Set SqlCommandColumnEncr yptionSetting to Disabled for individual queries that don't access
any encrypted columns. This setting will disable both calling
sys.sp_describe_parameter_encr yption and an attempt to decrypt any values in the result set.
Set SqlCommandColumnEncr yptionSetting to ResultSetOnly for individual queries that don't
have any parameters requiring encryption, but retrieve data from encrypted columns. This setting will
disable calling sys.sp_describe_parameter_encr yption and parameter encryption. The query will
be able to decrypt the results from encryption columns.
If most queries a client application executes don't access encrypted columns:
Set the Column Encr yption Setting connection string keyword to Disabled .
Set SqlCommandColumnEncr yptionSetting to Enabled for individual queries that have any
parameters that need to be encrypted. This setting will enable both calling
sys.sp_describe_parameter_encr yption and the decryption of any query results retrieved from
encrypted columns.
Set SqlCommandColumnEncr yptionSetting to ResultSetOnly for queries that don't have any
parameters requiring encryption, but retrieve data from encrypted columns. This setting will disable
calling sys.sp_describe_parameter_encr yption and parameter encryption. The query will be able
to decrypt the results from encryption columns.
In the below example, Always Encrypted is disabled for the database connection. The query the application
issues has a parameter that targets the LastName column that isn't encrypted. The query retrieves data from the
SSN and BirthDate columns that are both encrypted. In such a case, calling
sys.sp_describe_parameter_encr yption to retrieve encryption metadata isn't required. However, the
decryption of the query results needs to be enabled, so that the application can receive plaintext values from the
two encrypted columns. The SqlCommandColumnEncr yptionSetting ResultSetOnly setting is used to
ensure that.
class Program
{
// Maps a SqlColumnEncryptionAzureKeyVaultProvider to some object that represents a user
static Dictionary<object, SqlColumnEncryptionAzureKeyVaultProvider> providerByUser = new();
using SqlCommand command = new("UPDATE Customers SET Name = 'NewName' WHERE CustomerId = 1",
connection);
command.RegisterColumnEncryptionKeyStoreProvidersOnCommand(customProviders);
// Perform database operations
// Any decrypted column encryption keys will be cached by azureKeyVaultProvider
}
}
cmd.CommandText = @"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE [SSN]
= @SSN;";
NOTE
Use caution when specifying AllowEncryptedValueModifications . This setting may lead to corrupting the database
because the Microsoft .NET Data Provider for SQL Ser ver does not check if the data is indeed encrypted, or if it is
correctly encrypted using the same encryption type, algorithm, and key as the target column.
Here's an example that copies data from one table to another. The SSN and BirthDate columns are assumed to
be encrypted.
SqlColumnEncryptionCertificateStoreProvider Class A key store provider for the Windows Certificate Store.
SqlColumnEncryptionCngProvider Class A key store provider for the Microsoft Cryptography API:
Next Generation (CNG).
SqlColumnEncryptionCspProvider Class A key store provider for the Microsoft CAPI based
Cryptographic Service Providers (CSP).
SqlConnectionAttestationProtocol Enumeration Specifies a value for Attestation Protocol when using Always
Encrypted with secure enclaves
SqlConnection.ColumnEncryptionKeyCacheTtl Property Gets and sets time-to-live for entries in the column
encryption key cache.
SqlConnection.ColumnEncryptionTrustedMasterKeyPaths Allows you to set a list of trusted key paths for a database
Property server. If while processing an application query the driver
receives a key path that isn't on the list, the query will fail.
This property provides extra protection against security
attacks that involve a compromised SQL Server providing
fake key paths, which may lead to leaking key store
credentials.
SqlCommand Constructor (String, SqlConnection, Enables you to control the behavior of Always Encrypted for
SqlTransaction, SqlCommandColumnEncryptionSetting) individual queries.
NAME DESC RIP T IO N
connection string keyword: Enables or disables Always Encrypted functionality for the
Column Encryption Setting=enabled connection.
See also
Always Encrypted
Always Encrypted with secure enclaves
SQL Database tutorial: Protect sensitive data with Always Encrypted
Tutorial: Develop a .NET application using Always Encrypted with secure enclaves
Example: Azure Key Vault working with Always Encrypted
Example: Azure Key Vault working with Always Encrypted with secure enclaves
Tutorial: Develop a .NET application using Always
Encrypted with secure enclaves
4/27/2022 • 3 minutes to read • Edit Online
Applies to: SQL Server 2019 (15.x) - Windows only Azure SQL Database
APPLIES TO: .NET Framework .NET Core .NET Standard
This tutorial teaches you how to develop an application that issues database queries that use a server-side
secure enclave for Always Encrypted with secure enclaves.
NOTE
Always Encrypted with secure enclaves is only supported on Windows.
Prerequisites
Make sure you've completed one of the below tutorials before following the below steps in this tutorial:
Tutorial: Getting started with Always Encrypted with secure enclaves in SQL Server
Tutorial: Getting started with Always Encrypted with secure enclaves in Azure SQL Database
In addition, you need Visual Studio (version 2019 is recommended) - you can download it from
https://visualstudio.microsoft.com/. Your application development environment must use .NET Framework 4.6
or later or .NET Core 2.1 or later.
5. If you use Azure Key Vault for storing your column master keys, install the following NuGet packages by
going to Tools (main menu) > NuGet Package Manager > Package Manager Console . Run the
following code in the Package Manager Console.
Install-Package Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider -Version 1.0.0
Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
paramSSNPattern.ParameterName = @"@SSNPattern";
paramSSNPattern.DbType = DbType.AnsiStringFixedLength;
paramSSNPattern.Direction = ParameterDirection.Input;
paramSSNPattern.Value = "%9838";
paramSSNPattern.Size = 11;
cmd.Parameters.Add(paramSSNPattern);
MinSalary.ParameterName = @"@MinSalary";
MinSalary.DbType = DbType.Currency;
MinSalary.Direction = ParameterDirection.Input;
MinSalary.Value = 20000;
cmd.Parameters.Add(MinSalary);
cmd.ExecuteNonQuery();
{
Console.WriteLine(reader[0] + ", " + reader[1] + ", " + reader[2] + ", " +
reader[3]);
}
Console.ReadKey();
}
}
}
}
See also
Using Always Encrypted with the Microsoft .NET Data Provider for SQL Server
Example demonstrating use of Azure Key Vault provider with Always Encrypted
Example demonstrating use of Azure Key Vault provider with Always Encrypted enabled with secure enclaves
Example demonstrating use of Azure Key Vault
provider with Always Encrypted
4/27/2022 • 14 minutes to read • Edit Online
AzureKeyVaultProvider v2.0+
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using Azure.Identity;
using Microsoft.Data.SqlClient;
using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider;
namespace Microsoft.Data.SqlClient.Samples
{
public class AzureKeyVaultProviderExample_2_0
{
static readonly string s_algorithm = "RSA_OAEP";
try
{
sqlConnection.Open();
string sql =
$@"CREATE COLUMN MASTER KEY [{cmkName}]
WITH (
KEY_STORE_PROVIDER_NAME = N'{KeyStoreProviderName}',
KEY_PATH = N'{s_akvUrl}'
);";
byte[] encryptedColumnEncryptionKey =
sqlColumnEncryptionAzureKeyVaultProvider.EncryptColumnEncryptionKey(s_akvUrl, s_algorithm,
plainTextColumnEncryptionKey);
string EncryptedValue = string.Concat("0x",
BitConverter.ToString(encryptedColumnEncryptionKey).Replace("-", string.Empty));
return EncryptedValue;
}
string sql =
$@"CREATE TABLE [dbo].[{tblName}]
(
[CustomerId] [int] ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE
= DETERMINISTIC, ALGORITHM = '{ColumnEncryptionAlgorithmName}'),
[FirstName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH
(COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM =
'{ColumnEncryptionAlgorithmName}'),
[LastName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH
(COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM =
'{ColumnEncryptionAlgorithmName}')
)";
sqlCommand.ExecuteNonQuery();
sqlTransaction.Commit();
}
}
while (sqlDataReader.Read())
{
if (sqlDataReader.GetInt32(0) == 1)
{
Console.WriteLine(" * Employee Id received as sent: " + sqlDataReader.GetInt32(0));
}
else
{
Console.WriteLine("Employee Id didn't match");
}
if (sqlDataReader.GetString(1) == @"Microsoft")
{
Console.WriteLine(" * Employee Firstname received as sent: " +
sqlDataReader.GetString(1));
}
else
{
Console.WriteLine("Employee FirstName didn't match.");
}
if (sqlDataReader.GetString(2) == @"Corporation")
{
Console.WriteLine(" * Employee LastName received as sent: " +
sqlDataReader.GetString(2));
}
else
{
Console.WriteLine("Employee LastName didn't match.");
}
}
}
private static void dropObjects(SqlConnection sqlConnection, string cmkName, string cekName, string
tblName)
{
using (SqlCommand cmd = sqlConnection.CreateCommand())
{
cmd.CommandText = $@"IF EXISTS (select * from sys.objects where name = '{tblName}') BEGIN
DROP TABLE [{tblName}] END";
cmd.ExecuteNonQuery();
cmd.CommandText = $@"IF EXISTS (select * from sys.column_encryption_keys where name =
'{cekName}') BEGIN DROP COLUMN ENCRYPTION KEY [{cekName}] END";
cmd.ExecuteNonQuery();
cmd.CommandText = $@"IF EXISTS (select * from sys.column_master_keys where name =
'{cmkName}') BEGIN DROP COLUMN MASTER KEY [{cmkName}] END";
cmd.ExecuteNonQuery();
}
}
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using Azure.Identity;
using Microsoft.Data.SqlClient;
using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider;
namespace Microsoft.Data.SqlClient.Samples
{
public class AzureKeyVaultProviderLegacyExample_2_0
{
const string s_algorithm = "RSA_OAEP";
try
{
sqlConnection.Open();
string sql =
$@"CREATE COLUMN MASTER KEY [{cmkName}]
WITH (
KEY_STORE_PROVIDER_NAME = N'{KeyStoreProviderName}',
KEY_PATH = N'{s_akvUrl}'
);";
byte[] encryptedColumnEncryptionKey =
sqlColumnEncryptionAzureKeyVaultProvider.EncryptColumnEncryptionKey(s_akvUrl, s_algorithm,
plainTextColumnEncryptionKey);
string EncryptedValue = string.Concat("0x",
BitConverter.ToString(encryptedColumnEncryptionKey).Replace("-", string.Empty));
return EncryptedValue;
}
string sql =
$@"CREATE TABLE [dbo].[{tblName}]
(
[CustomerId] [int] ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE
= DETERMINISTIC, ALGORITHM = '{ColumnEncryptionAlgorithmName}'),
[FirstName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH
(COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM =
'{ColumnEncryptionAlgorithmName}'),
[LastName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH
(COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM =
'{ColumnEncryptionAlgorithmName}')
)";
sqlCommand.ExecuteNonQuery();
sqlTransaction.Commit();
}
}
while (sqlDataReader.Read())
{
if (sqlDataReader.GetInt32(0) == 1)
{
Console.WriteLine(" * Employee Id received as sent: " + sqlDataReader.GetInt32(0));
}
else
{
Console.WriteLine("Employee Id didn't match");
}
if (sqlDataReader.GetString(1) == @"Microsoft")
{
Console.WriteLine(" * Employee Firstname received as sent: " +
sqlDataReader.GetString(1));
}
else
{
Console.WriteLine("Employee FirstName didn't match.");
}
if (sqlDataReader.GetString(2) == @"Corporation")
{
Console.WriteLine(" * Employee LastName received as sent: " +
sqlDataReader.GetString(2));
}
else
{
Console.WriteLine("Employee LastName didn't match.");
}
}
}
private static void dropObjects(SqlConnection sqlConnection, string cmkName, string cekName, string
tblName)
{
using (SqlCommand cmd = sqlConnection.CreateCommand())
{
cmd.CommandText = $@"IF EXISTS (select * from sys.objects where name = '{tblName}') BEGIN
DROP TABLE [{tblName}] END";
cmd.ExecuteNonQuery();
cmd.CommandText = $@"IF EXISTS (select * from sys.column_encryption_keys where name =
'{cekName}') BEGIN DROP COLUMN ENCRYPTION KEY [{cekName}] END";
cmd.ExecuteNonQuery();
cmd.CommandText = $@"IF EXISTS (select * from sys.column_master_keys where name =
'{cmkName}') BEGIN DROP COLUMN MASTER KEY [{cmkName}] END";
cmd.ExecuteNonQuery();
}
}
if (pair.Length == 2)
{
string key = pair[0]?.Trim().Trim(new char[] { '\"' });
string value = pair[1]?.Trim().Trim(new char[] { '\"' });
if (!string.IsNullOrEmpty(key))
{
if (key.Equals("authorization",
StringComparison.InvariantCultureIgnoreCase))
{
_authority = value;
}
else if (key.Equals("resource",
StringComparison.InvariantCultureIgnoreCase))
{
_resource = value;
}
}
}
}
}
}
_akvUrl = s_akvUrl;
}
if (!trimmedChallenge.StartsWith(Bearer))
throw new ArgumentException("Challenge is not Bearer", nameof(challenge));
return trimmedChallenge.Substring(Bearer.Length);
}
/// <summary>
/// Legacy implementation of Authentication Callback, used by Azure Key Vault provider 1.0.
/// This can be leveraged to support multi-user authentication support in the same Azure Key
Vault Provider.
/// </summary>
/// <param name="authority">Authorization URL</param>
/// <param name="resource">Resource</param>
/// <returns></returns>
public static async Task<string> AzureActiveDirectoryAuthenticationCallback(string authority,
string resource)
{
var authContext = new AuthenticationContext(authority);
ClientCredential clientCred = new ClientCredential(s_clientId, s_clientSecret);
AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred);
if (result == null)
{
throw new InvalidOperationException($"Failed to retrieve an access token for
{resource}");
{resource}");
}
return result.AccessToken;
}
}
}
}
AzureKeyVaultProvider v1.x
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Threading.Tasks;
using Microsoft.Data.SqlClient;
using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
namespace Microsoft.Data.SqlClient.Samples
{
public class AzureKeyVaultProviderExample
{
static readonly string s_algorithm = "RSA_OAEP";
try
{
sqlConnection.Open();
return result.AccessToken;
}
string sql =
$@"CREATE COLUMN MASTER KEY [{cmkName}]
WITH (
KEY_STORE_PROVIDER_NAME = N'{KeyStoreProviderName}',
KEY_PATH = N'{s_akvUrl}'
);";
byte[] encryptedColumnEncryptionKey =
sqlColumnEncryptionAzureKeyVaultProvider.EncryptColumnEncryptionKey(s_akvUrl, s_algorithm,
plainTextColumnEncryptionKey);
string EncryptedValue = string.Concat("0x",
BitConverter.ToString(encryptedColumnEncryptionKey).Replace("-", string.Empty));
return EncryptedValue;
}
string sql =
$@"CREATE TABLE [dbo].[{tblName}]
(
[CustomerId] [int] ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE
= DETERMINISTIC, ALGORITHM = '{ColumnEncryptionAlgorithmName}'),
[FirstName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH
(COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM =
'{ColumnEncryptionAlgorithmName}'),
[LastName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH
(COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM =
'{ColumnEncryptionAlgorithmName}')
)";
sqlCommand.ExecuteNonQuery();
sqlTransaction.Commit();
}
}
while (sqlDataReader.Read())
{
if (sqlDataReader.GetInt32(0) == 1)
{
Console.WriteLine(" * Employee Id received as sent: " + sqlDataReader.GetInt32(0));
}
else
{
Console.WriteLine("Employee Id didn't match");
}
if (sqlDataReader.GetString(1) == @"Microsoft")
{
Console.WriteLine(" * Employee Firstname received as sent: " +
sqlDataReader.GetString(1));
}
else
{
Console.WriteLine("Employee FirstName didn't match.");
}
if (sqlDataReader.GetString(2) == @"Corporation")
{
Console.WriteLine(" * Employee LastName received as sent: " +
sqlDataReader.GetString(2));
}
else
{
Console.WriteLine("Employee LastName didn't match.");
}
}
}
private static void dropObjects(SqlConnection sqlConnection, string cmkName, string cekName, string
tblName)
{
using (SqlCommand cmd = sqlConnection.CreateCommand())
{
cmd.CommandText = $@"IF EXISTS (select * from sys.objects where name = '{tblName}') BEGIN
DROP TABLE [{tblName}] END";
cmd.ExecuteNonQuery();
cmd.CommandText = $@"IF EXISTS (select * from sys.column_encryption_keys where name =
'{cekName}') BEGIN DROP COLUMN ENCRYPTION KEY [{cekName}] END";
cmd.ExecuteNonQuery();
cmd.CommandText = $@"IF EXISTS (select * from sys.column_master_keys where name =
'{cmkName}') BEGIN DROP COLUMN MASTER KEY [{cmkName}] END";
cmd.ExecuteNonQuery();
}
}
}
NOTE
To use Always Encrypted feature without secure enclaves for .NET Standard application,
Microsoft.Data.SqlClient version 2.1.0 or higher is required. The supported .NET Standard version is 2.0 or
higher.
To use Always Encrypted feature on Linux and macOS, Microsoft.Data.SqlClient version 2.1.0 or higher is
required.
See also
Example demonstrating use of Azure Key Vault provider with Always Encrypted enabled with secure enclaves
Tutorial: Develop a .NET application using Always Encrypted with secure enclaves
Using Always Encrypted with the Microsoft .NET Data Provider for SQL Server
Example demonstrating use of Azure Key Vault
provider with Always Encrypted enabled with secure
enclaves
4/27/2022 • 8 minutes to read • Edit Online
Applies to: SQL Server 2019 (15.x) - Windows only Azure SQL Database
APPLIES TO: .NET Framework .NET Core .NET Standard
AzureKeyVaultProvider v2.0+
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Threading.Tasks;
using Azure.Identity;
using Microsoft.Data.SqlClient;
using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider;
namespace AKVEnclaveExample
{
class Program
{
static readonly string s_algorithm = "RSA_OAEP";
try
{
sqlConnection.Open();
string sql =
$@"CREATE COLUMN MASTER KEY [{cmkName}]
WITH (
KEY_STORE_PROVIDER_NAME = N'{KeyStoreProviderName}',
KEY_PATH = N'{s_akvUrl}',
ENCLAVE_COMPUTATIONS (SIGNATURE = {cmkSignStr})
);";
byte[] encryptedColumnEncryptionKey =
sqlColumnEncryptionAzureKeyVaultProvider.EncryptColumnEncryptionKey(s_akvUrl, s_algorithm,
plainTextColumnEncryptionKey);
string EncryptedValue = string.Concat("0x",
BitConverter.ToString(encryptedColumnEncryptionKey).Replace("-", string.Empty));
return EncryptedValue;
}
string sql =
$@"CREATE TABLE [dbo].[{tblName}]
(
[CustomerId] [int] ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE
= RANDOMIZED, ALGORITHM = '{ColumnEncryptionAlgorithmName}'),
[FirstName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH
(COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM =
'{ColumnEncryptionAlgorithmName}'),
[LastName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH
(COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM =
'{ColumnEncryptionAlgorithmName}')
)";
sqlCommand.ExecuteNonQuery();
sqlTransaction.Commit();
}
}
while (sqlDataReader.Read())
{
if (sqlDataReader.GetInt32(0) == 1)
{
Console.WriteLine(" * Employee Id received as sent: " + sqlDataReader.GetInt32(0));
}
else
{
Console.WriteLine("Employee Id didn't match");
}
if (sqlDataReader.GetString(1) == @"Microsoft")
{
Console.WriteLine(" * Employee Firstname received as sent: " +
sqlDataReader.GetString(1));
}
else
{
Console.WriteLine("Employee FirstName didn't match.");
}
if (sqlDataReader.GetString(2) == @"Corporation")
{
Console.WriteLine(" * Employee LastName received as sent: " +
sqlDataReader.GetString(2));
}
else
{
Console.WriteLine("Employee LastName didn't match.");
}
}
}
private static void dropObjects(SqlConnection sqlConnection, string cmkName, string cekName, string
tblName)
{
using (SqlCommand cmd = sqlConnection.CreateCommand())
{
cmd.CommandText = $@"IF EXISTS (select * from sys.objects where name = '{tblName}') BEGIN
DROP TABLE [{tblName}] END";
cmd.ExecuteNonQuery();
cmd.CommandText = $@"IF EXISTS (select * from sys.column_encryption_keys where name =
'{cekName}') BEGIN DROP COLUMN ENCRYPTION KEY [{cekName}] END";
cmd.ExecuteNonQuery();
cmd.CommandText = $@"IF EXISTS (select * from sys.column_master_keys where name =
'{cmkName}') BEGIN DROP COLUMN MASTER KEY [{cmkName}] END";
cmd.ExecuteNonQuery();
}
}
AzureKeyVaultProvider v1.x
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Threading.Tasks;
using Microsoft.Data.SqlClient;
using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
namespace AKVEnclaveExample
{
class Program
{
static readonly string s_algorithm = "RSA_OAEP";
try
{
sqlConnection.Open();
Console.ReadKey();
}
}
return result.AccessToken;
}
string sql =
$@"CREATE COLUMN MASTER KEY [{cmkName}]
WITH (
KEY_STORE_PROVIDER_NAME = N'{KeyStoreProviderName}',
KEY_PATH = N'{s_akvUrl}',
ENCLAVE_COMPUTATIONS (SIGNATURE = {cmkSignStr})
);";
byte[] encryptedColumnEncryptionKey =
sqlColumnEncryptionAzureKeyVaultProvider.EncryptColumnEncryptionKey(s_akvUrl, s_algorithm,
plainTextColumnEncryptionKey);
string EncryptedValue = string.Concat("0x",
BitConverter.ToString(encryptedColumnEncryptionKey).Replace("-", string.Empty));
return EncryptedValue;
}
string sql =
$@"CREATE TABLE [dbo].[{tblName}]
(
[CustomerId] [int] ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE
= RANDOMIZED, ALGORITHM = '{ColumnEncryptionAlgorithmName}'),
[FirstName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH
(COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM =
'{ColumnEncryptionAlgorithmName}'),
[LastName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH
(COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM =
'{ColumnEncryptionAlgorithmName}')
)";
sqlCommand.ExecuteNonQuery();
sqlTransaction.Commit();
}
}
while (sqlDataReader.Read())
{
if (sqlDataReader.GetInt32(0) == 1)
{
Console.WriteLine(" * Employee Id received as sent: " + sqlDataReader.GetInt32(0));
}
else
{
Console.WriteLine("Employee Id didn't match");
}
if (sqlDataReader.GetString(1) == @"Microsoft")
{
Console.WriteLine(" * Employee Firstname received as sent: " +
sqlDataReader.GetString(1));
}
else
{
Console.WriteLine("Employee FirstName didn't match.");
}
if (sqlDataReader.GetString(2) == @"Corporation")
{
{
Console.WriteLine(" * Employee LastName received as sent: " +
sqlDataReader.GetString(2));
}
else
{
Console.WriteLine("Employee LastName didn't match.");
}
}
}
private static void dropObjects(SqlConnection sqlConnection, string cmkName, string cekName, string
tblName)
{
using (SqlCommand cmd = sqlConnection.CreateCommand())
{
cmd.CommandText = $@"IF EXISTS (select * from sys.objects where name = '{tblName}') BEGIN
DROP TABLE [{tblName}] END";
cmd.ExecuteNonQuery();
cmd.CommandText = $@"IF EXISTS (select * from sys.column_encryption_keys where name =
'{cekName}') BEGIN DROP COLUMN ENCRYPTION KEY [{cekName}] END";
cmd.ExecuteNonQuery();
cmd.CommandText = $@"IF EXISTS (select * from sys.column_master_keys where name =
'{cmkName}') BEGIN DROP COLUMN MASTER KEY [{cmkName}] END";
cmd.ExecuteNonQuery();
}
}
NOTE
To use Always Encrypted with secure enclaves for .NET Standard application, Microsoft.Data.SqlClient version
2.1.0 or higher is required. The supported .NET Standard version is 2.1 or higher.
To use Always Encrypted with secure enclaves on Linux and macOS, Microsoft.Data.SqlClient version 2.1.0 or
higher is required.
See also
Example demonstrating use of Azure Key Vault provider with Always Encrypted
Tutorial: Develop a .NET application using Always Encrypted with secure enclaves
Using Always Encrypted with the Microsoft .NET Data Provider for SQL Server
Data discovery and classification in SqlClient
4/27/2022 • 5 minutes to read • Edit Online
Download ADO.NET
Data Discovery & Classification is a set of advanced services for discovering, classifying, labeling & reporting
the sensitive data in your databases. SqlClient provides an API exposing read-only Data Discovery and
Classification information when the underlying source supports the feature. This information is accessed
through SqlDataReader.
Microsoft.Data.SqlClient v2.1.0 introduces support for Data Classification's Sensitivity Rank information.
Sensitivity Rank is an identifier based on a predefined set of values, which define sensitivity rank. It can be
used by other services like Advanced Threat Protection to detect anomalies based on their rank. The following
Data Classification APIs are now available in Microsoft.Data.SqlClient.DataClassification namespace:
// New in Microsoft.Data.SqlClient v2.1.0
public enum SensitivityRank
{
NOT_DEFINED = -1,
NONE = 0,
LOW = 10,
MEDIUM = 20,
HIGH = 30,
CRITICAL = 40
}
This sample application demonstrates how to access the Data Classification properties of SqlDataReader.
using System;
using Microsoft.Data.SqlClient;
using Microsoft.Data.SqlClient.DataClassification;
class Program
{
// Name of the temporary table created for this sample program.
static string tableName = "SQLCLIENT_DATA_DISCOVERY_CLASSIFICATION";
try
{
// Check if the target SQL Server supports Data Discovery and Classification.
if (DataClassificationSupported(connection))
{
// Create the temporary table and retrieve its Data Discovery and Classification
information.
// Set rankEnabled to be true if testing with rank information.
CreateTable(connection, rankEnabled : true);
RunTests(connection, rankEnabled : true);
}
}
finally
{
// Drop the temporary table.
DropTable(connection);
}
}
}
/// <summary>
/// Verifies if SQL Data Discovery and Classification feature is available on the target server.
/// </summary>
/// <param name="connection">The SqlConnection to work with.</param>
/// <returns>True if the target SQL Server supports the feature and false otherwise.</returns>
public static bool DataClassificationSupported(SqlConnection connection)
{
try
{
SqlCommand command = new SqlCommand(null, connection);
command.CommandText = "SELECT * FROM SYS.SENSITIVITY_CLASSIFICATIONS";
command.ExecuteNonQuery();
}
catch (SqlException e)
{
// Error 208: Object Not Found
if (e.Errors != null && e.Errors[0].Number == 208)
{
{
Console.WriteLine("This feature is not supported on the target SQL Server.");
return false;
}
}
return true;
}
/// <summary>
/// Creates a temporary table for this sample program and sets tags for Sensitivity Classification.
/// </summary>
/// <param name="connection">The SqlConnection to work with.</param>
/// <param name="rankEnabled">True if rank information is enabled and false otherwise</param>
private static void CreateTable(SqlConnection connection, bool rankEnabled = false)
{
SqlCommand command = new SqlCommand(null, connection);
if (rankEnabled)
{
// Set Sensitivity Classification tags for table columns with rank information
command.CommandText = $"ADD SENSITIVITY CLASSIFICATION TO {tableName}"
+ ".CompanyName WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Company Name',
INFORMATION_TYPE_ID='COMPANY', RANK=LOW)";
command.ExecuteNonQuery();
/// <summary>
/// Run query to fetch result set from target table.
/// </summary>
/// <param name="connection">The SqlConnection to work with.</param>
/// <param name="rankEnabled">True if rank information is enabled and false otherwise</param>
private static void RunTests(SqlConnection connection, bool rankEnabled = false)
{
SqlCommand command = new SqlCommand(null, connection);
command.CommandText = $"SELECT * FROM {tableName}";
using (SqlDataReader reader = command.ExecuteReader())
{
PrintSensitivityClassification(reader, rankEnabled);
}
}
/// <summary>
/// Prints Sensitivity Classification data as received in the result set.
/// </summary>
/// <param name="reader">The SqlDataReader to work with.</param>
/// <param name="rankEnabled">True if rank information is enabled and false otherwise</param>
private static void PrintSensitivityClassification(SqlDataReader reader, bool rankEnabled = false)
{
if (reader.SensitivityClassification != null)
{
for (int columnPos = 0; columnPos < reader.SensitivityClassification.ColumnSensitivities.Count;
columnPos++)
{
foreach (SensitivityProperty sp in
reader.SensitivityClassification.ColumnSensitivities[columnPos].SensitivityProperties)
{
if (sp.Label != null)
{
Console.WriteLine($"Labels received for Column : {columnPos}");
Console.WriteLine($"Label ID: {sp.Label.Id}");
Console.WriteLine($"Label Name: {sp.Label.Name}");
Console.WriteLine();
}
if (sp.InformationType != null)
{
Console.WriteLine($"Information Types received for Column : {columnPos}");
Console.WriteLine($"Information Type ID: {sp.InformationType.Id}");
Console.WriteLine($"Information Type: {sp.InformationType.Name}");
Console.WriteLine();
}
/// <summary>
/// Deletes the table created for this sample program.
/// </summary>
/// <param name="connection">The SqlConnection to work with.</param>
private static void DropTable(SqlConnection connection)
{
SqlCommand command = new SqlCommand(null, connection);
command.CommandText = $"DROP TABLE {tableName}";
command.ExecuteNonQuery();
}
}
See also
SQL Server features and ADO.NET
sys.sensitivity_classifications (Transact-SQL)
ADD SENSITIVITY CLASSIFICATION
Microsoft JDBC Driver for SQL Server
4/27/2022 • 2 minutes to read • Edit Online
Getting started
Step 1: Configure development environment for Java development
Step 2: Create a SQL database for Java development
Step 3: Proof of concept connecting to SQL using Java
Documentation
Getting Started
Overview
Programming Guide
Security
Performance and Reliability
Troubleshooting
Code Samples
Compliance and Legal
Community
Feedback and finding additional JDBC driver information
Download
Download Microsoft JDBC Driver for SQL Server - has additional information about Maven projects, and more.
Samples
Sample JDBC driver applications
Getting started with Java on Windows
Getting started with Java on macOS
Getting started with Java on Ubuntu
Getting started with Java on Red Hat Enterprise Linux (RHEL)
Getting started with Java on SUSE Linux Enterprise Server (SLES)
Getting started with the JDBC driver
4/27/2022 • 2 minutes to read • Edit Online
Getting started
Step 1: Configure development environment for Java development
Step 2: Create a SQL database for Java development
Step 3: Proof of concept connecting to SQL using Java
Step 1: Configure development environment for
Java development
4/27/2022 • 2 minutes to read • Edit Online
Windows
Identify which version of the JDBC driver you'll use, based on your environment, as noted here: System
Requirements for the JDBC Driver
Download and install applicable JDBC Driver here: Download Microsoft JDBC Driver for SQL Server
Set class path based on the driver version, as noted here: Using the JDBC Driver
Step 2: Create a SQL database for Java
development
4/27/2022 • 2 minutes to read • Edit Online
The samples in this section only work with the AdventureWorks schema, on either Microsoft SQL Server or
Azure SQL Database.
This example should be considered a proof of concept only. The sample code is simplified for clarity, and doesn't
necessarily represent best practices recommended by Microsoft.
Step 1: Connect
Use the connection class to connect to SQL Database.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
prepsInsertProduct.execute();
// Retrieve the generated key from the insert.
resultSet = prepsInsertProduct.getGeneratedKeys();
Additional samples
Sample JDBC driver applications
Overview of the JDBC driver
4/27/2022 • 2 minutes to read • Edit Online
Redistribution
The JDBC Driver versions 6.0 and up are redistributable. Review the Distributable Code clause in the license
agreements.
The JDBC Driver versions 4.x are obsolete. Support for 4.x expired before 2018.
In this section
The articles in this section provide a general overview of the JDBC driver, including the system requirements
needed to use it, how it can be used, and where you can go for more information.
A RT IC L E DESC RIP T IO N
Download Microsoft JDBC Driver for SQL Server Download links for Microsoft JDBC driver for SQL Server
Release notes for the JDBC driver Describes the features that have been added to the current
release of the Microsoft JDBC driver.
System requirements for the JDBC driver Describes the system requirements needed to use the
Microsoft JDBC driver.
Using the JDBC driver Describes how to configure your environment to use the
Microsoft JDBC driver and how to make a simple connection
to a SQL Server database.
Understanding Java EE support Describes how to use the Microsoft JDBC driver within a
Java Platform, Enterprise Edition (Java EE) environment.
Deploying the JDBC driver Describes how to redistribute and deploy the Microsoft
JDBC driver on Windows and Unix operating systems.
Finding additional JDBC driver information Describes where to find additional resources about the
Microsoft JDBC driver, including links to external resources.
Microsoft JDBC Driver for SQL Server support matrix Support matrix and support lifecycle policy for the Microsoft
JDBC driver for SQL Server.
Frequently asked questions (FAQ) for JDBC driver Frequently asked questions about the Microsoft JDBC driver.
Feature dependencies of Microsoft JDBC Driver for SQL Feature dependencies of Microsoft JDBC Driver for SQL
Server Server.
A RT IC L E DESC RIP T IO N
See also
JDBC driver GitHub repository
JDBC driver API reference
Download Microsoft JDBC Driver for SQL Server
4/27/2022 • 2 minutes to read • Edit Online
The Microsoft JDBC Driver for SQL Server is a Type 4 JDBC driver that provides database connectivity through
the standard JDBC application program interfaces (APIs) available on the Java platform. The driver downloads
are available to all users at no extra charge. They provide access to SQL Server from any Java application,
application server, or Java-enabled applet.
Download
Version 10.2 is the latest general availability (GA) version. It supports Java 8, 11, and 17. If you need to use an
older Java runtime, see the Java and JDBC specification support matrix to see if there's a supported driver
version you can use. We're continually improving Java connectivity support. As such we highly recommend that
you work with the latest version of Microsoft JDBC driver.
Download Microsoft JDBC Driver 10.2 for SQL Ser ver (zip)
Download Microsoft JDBC Driver 10.2 for SQL Ser ver (tar.gz)
Version information
Release number: 10.2.0
Released: January 31, 2022
When you download the driver, there are multiple JAR files. The name of the JAR file indicates the version of
Java that it supports.
NOTE
If you are accessing this page from a non-English language version, and want to see the most up-to-date content, please
select Read in English at the top of this page. You can download different languages from the US-English version site by
selecting available languages.
Available languages
This release of Microsoft JDBC Driver for SQL Server is available in the following languages:
Microsoft JDBC Driver 10.2.0 for SQL Server (zip): Chinese (Simplified) | Chinese (Traditional) | English (United
States) | French | German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Microsoft JDBC Driver 10.2.0 for SQL Server (tar.gz): Chinese (Simplified) | Chinese (Traditional) | English (United
States) | French | German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Release notes
For details about this release, see the release notes and system requirements.
Previous releases
To download previous releases, see previous Microsoft JDBC Driver for SQL Server releases.
Unsupported drivers
Unsupported driver versions aren't available for download here. We're continually improving the Java
connectivity support. As such we highly recommend that you work with the latest version of Microsoft JDBC
driver.
Next steps
For more information about the Microsoft JDBC Driver for SQL Server, see Overview of the JDBC driver and the
JDBC driver GitHub repository.
Release notes for the Microsoft JDBC Driver for
SQL Server
4/27/2022 • 32 minutes to read • Edit Online
This article lists the releases of the Microsoft JDBC Driver for SQL Server. For each release version, the changes
are named and described.
10.2
Download Microsoft JDBC Driver 10.2.0 for SQL Ser ver (zip)
Download Microsoft JDBC Driver 10.2.0 for SQL Ser ver (tar.gz)
Release number: 10.2.0
Released: January 31, 2022
If you need to download the driver in a language other than the one detected for you, you can use these direct
links.
For the driver in a zip file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German |
Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the driver in a tar.gz file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French |
German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
10.2 Compliance
C O M P L IA N C E C H A N GE DETA IL S
Download the latest updates for JDBC Driver 10.2. • GitHub, 10.2.0
• Maven Central
Fully compliant with JDBC API Specification 4.2. The jars in the 10.2 package are named according to Java
version compatibility.
Compatible with Java Development Kit (JDK) version 17.0, Microsoft JDBC Driver 10.2 for SQL Server is now
11.0, and 1.8. compatible with Java Development Kit (JDK) version 17.0 in
addition to JDK 11.0 and 1.8.
Java 17 support The driver is now compatible with Java Development Kit
(JDK) version 17.0 in addition to JDK 11.0 and 1.8.
Idle Connection Resiliency support Idle Connection Resiliency is now supported. See Idle
Connection Resiliency.
F EAT URE DETA IL S
Multi-user Key Store Providers The driver now supports Key Store providers at the
connection and statement level to support multi-user
scenarios. See Using Always Encrypted with the JDBC driver.
Changes in 10.2
C H A N GE DETA IL S
Certificate validation when encrypt = false BREAKING CHANGE When encrypt = false but the server
requires encryption, the certificate will be validated based on
the trustServerCertificate connection setting.
CNAME resolution for realm Added CNAME resolution when realm is specified.
Fixes in 10.2
F IX DETA IL S
Previous releases
9.4
Download Microsoft JDBC Driver 9.4.1 for SQL Ser ver (zip)
Download Microsoft JDBC Driver 9.4.1 for SQL Ser ver (tar.gz)
Release number: 9.4.1
Released: December 7, 2021
If you need to download the driver in a language other than the one detected for you, you can use these direct
links.
For the driver in a zip file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German |
Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the driver in a tar.gz file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French |
German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
9.4 Compliance
C O M P L IA N C E C H A N GE DETA IL S
Download the latest updates for JDBC Driver 9.4. • GitHub, 9.4.0
• Maven Central
Fully compliant with JDBC API Specification 4.2. The jars in the 9.4 package are named according to Java
version compatibility.
Compatible with Java Development Kit (JDK) version 16.0, Microsoft JDBC Driver 9.4 for SQL Server is now compatible
11.0, and 1.8. with Java Development Kit (JDK) version 16.0 in addition to
JDK 11.0 and 1.8.
9.4 Releases
Version number: 9.4.1
Released: December 07, 2021
Fixed issues in 9.4.1:
Fixed potential hang when the driver encounters unsupported TDS_COLMETADATA
Fixed conversion of LocalDateTime and LocalTime to String in Bulk Copy
Version number: 9.4.0
Released: July 30, 2021
Download Microsoft JDBC Driver 9.4.0 for SQL Ser ver (zip)
Download Microsoft JDBC Driver 9.4.0 for SQL Ser ver (tar.gz)
If you need to download the driver in a language other than the one detected for you, you can use these direct
links.
For the driver in a zip file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German |
Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the driver in a tar.gz file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French |
German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
New features in 9.4
F EAT URE DETA IL S
Java 16 support The driver is now compatible with Java Development Kit
(JDK) version 16.0 in addition to JDK 11.0 and 1.8.
F EAT URE DETA IL S
Replication connection support Replication connections are now supported. See Setting the
connection properties.
Custom Kerberos authentication realm The driver now supports specifying a custom authentication
realm when using Kerberos authentication. See Setting the
connection properties.
Changes in 9.4
C H A N GE DETA IL S
Azure Key Vault Provider Multiple, successive connections can be opened that specify
different Azure Key Vault provider information.
Updated error messages Error messages related to Enclave exceptions now include a
link to a troubleshooting guide.
Error messages related to Active Directory authentication
failures now include the error string from the underlying
library.
Driver version sent to server The driver version is now correctly sent to the database
during PRELOGIN .
Client process ID The client process ID is now sent to the server when running
on Java 9+. Java 8 keeps the previous functionality of
sending 0 for the client process ID.
Removed unnecessary references Removed unused Java 9-specific class references from the
Java 8 jar
Fixes in 9.4
F IX DETA IL S
GitHub Issue #1499 Fixed: Batch fails when always encrypted is enabled in the
connection string and clearParameters is called.
GitHub Issue #1565 Fixed an issue where trustStorePassword is null when using
applicationIntent=ReadOnly
F IX DETA IL S
GitHub Issue #1568 Fixed an issue where redirected token contains named
instance in servername
9.2
Download Microsoft JDBC Driver 9.2.1 for SQL Ser ver (zip)
Download Microsoft JDBC Driver 9.2.1 for SQL Ser ver (tar.gz)
Version number: 9.2.1
Released: March 02, 2021
If you need to download the driver in a language other than the one detected for you, you can use these direct
links.
For the driver in a zip file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German |
Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the driver in a tar.gz file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French |
German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
9.2 Compliance
C O M P L IA N C E C H A N GE DETA IL S
Download the latest updates for JDBC Driver 9.2. • GitHub, 9.2.1
• Maven Central
Fully compliant with JDBC API Specification 4.2. The jars in the 9.2 package are named according to Java
version compatibility.
Compatible with Java Development Kit (JDK) version 15.0, Microsoft JDBC Driver 9.2 for SQL Server is now compatible
11.0, and 1.8. with Java Development Kit (JDK) version 15.0 in addition to
JDK 11.0 and 1.8.
9.2 Releases
Version number: 9.2.1
Released: March 02, 2021
Fixed issues in 9.2.1:
Fixed an issue with client secret being empty during ActiveDirectoryServicePrincipal authentication in Azure
environment.
Version number: 9.2.0
Released: January 29, 2021
Download Microsoft JDBC Driver 9.2.0 for SQL Ser ver (zip)
Download Microsoft JDBC Driver 9.2.0 for SQL Ser ver (tar.gz)
If you need to download the driver in a language other than the one detected for you, you can use these direct
links.
For the driver in a zip file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German |
Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the driver in a tar.gz file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French |
German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Support for JDK 15
Microsoft JDBC Driver 9.2 for SQL Server is now compatible with Java Development Kit (JDK) version 15.0 in
addition to JDK 11.0 and 1.8.
Added support for Azure Active Directory Interactive Authentication
A UT H EN T IC AT IO N T Y P E A DDIT IO N DETA IL S
Microsoft JDBC Driver 9.2 for SQL Server now supports See Connecting using Azure Active Directory authentication.
authentication to Azure Key Vault via interactive
authentication.
Microsoft JDBC Driver 9.2 for SQL Server now supports See Connecting using Azure Active Directory authentication.
authentication to Azure Key Vault using the client ID and
secret of a service principal identity.
Updated Azure Key Vault library to use modern Azure Key Vault library
L IB RA RY C H A N GES F O R A Z URE K EY VA ULT DETA IL S
Microsoft JDBC Driver 9.2 migrated from the previous- DEPENDENCY CHANGE Make sure you update your
generation Azure Key Vault library and ADAL libraries to the application dependencies if you take advantage of Azure
more modern Azure Key Vault and Azure Identity Active Directory authentication or Azure Key Vault. See the
equivalents. dependency requirements when work with the Azure Key
Vault provider or Azure Active Directory authentication
Microsoft JDBC Driver 9.2 now allows bulk copy API for See Using bulk copy API for batch insert operation.
batch insert operation against non-Azure Synapse Analytics
servers.
8.4
Download Microsoft JDBC Driver 8.4 for SQL Ser ver (zip)
Download Microsoft JDBC Driver 8.4 for SQL Ser ver (tar.gz)
Version number: 8.4.1
Released: August 27, 2020
If you need to download the driver in a language other than the one detected for you, you can use these direct
links.
For the driver in a zip file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German |
Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the driver in a tar.gz file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French |
German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
8.4 Compliance
C O M P L IA N C E C H A N GE DETA IL S
Download the latest updates for JDBC Driver 8.4. • GitHub, 8.4.1
• Maven Central
Fully compliant with JDBC API Specification 4.2. The jars in the 8.4 package are named according to Java
version compatibility.
Compatible with Java Development Kit (JDK) version 14.0, Microsoft JDBC Driver 8.4 for SQL Server is now compatible
11.0, and 1.8. with Java Development Kit (JDK) version 14.0 in addition to
JDK 11.0 and 1.8.
8.4 Releases
Version number: 8.4.1
Released: August 27, 2020
Fixed issues:
Fixed an issue with SQLServerConnectionPoolProxy not being compatible with delayLoadingLobs
Fixed a potential NullPointerException issue with delayLoadingLobs
Fixed an issue with decrypting column encryption keys when using the Windows Certificate Store
Version number: 8.4.0
Released: July 31, 2020
Support for JDK 14
Microsoft JDBC Driver 8.4 for SQL Server is now compatible with Java Development Kit (JDK) version 14.0 in
addition to JDK 11.0 and 1.8.
Added support for authentication to Azure Key Vault using Managed Identity
A UT H EN T IC AT IO N T Y P E A DDIT IO N DETA IL S
Microsoft JDBC Driver 8.4 for SQL Server now supports See Using Always Encrypted with the JDBC driver.
authentication to Azure Key Vault using Managed Identity.
A UT H EN T IC AT IO N T Y P E A DDIT IO N DETA IL S
Microsoft JDBC Driver 8.4 adds a new connection property, See Using bulk copy with the JDBC driver.
sendTemporalDataTypesAsStringForBulkCopy . This
boolean property is TRUE by default.
Microsoft JDBC Driver 8.4 for SQL Server now supports DNS
caching against Azure SQL Servers.
Microsoft JDBC Driver 8.4 for SQL Server added a new Setting delayLoadingLobs to FALSE will cause all LOB
connection property delayLoadingLobs . objects retrieved from the ResultSet to not be streamed. This
means that the driver will load the entire LOB object into
memory at once, similar to how the driver was functioning
before version 6.4 release.
Microsoft JDBC Driver 8.4 for SQL Server added a new See Client Certificate Authentication for Loopback Scenarios.
authentication method called client certificate authentication
for loopback scenarios.
8.2
Download Microsoft JDBC Driver 8.2 for SQL Ser ver (zip)
Download Microsoft JDBC Driver 8.2 for SQL Ser ver (tar.gz)
Version number: 8.2.2 Released: March 24, 2020
If you need to download the driver in a language other than the one detected for you, you can use these direct
links.
For the driver in a zip file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German |
Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the driver in a tar.gz file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French |
German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
8.2 Compliance
C O M P L IA N C E C H A N GE DETA IL S
Download the latest updates for JDBC Driver 8.2. • GitHub, 8.2.2
• Maven Central
Fully compliant with JDBC API Specification 4.2. The jars in the 8.2 package are named according to Java
version compatibility.
Compatible with Java Development Kit (JDK) version 13.0, Microsoft JDBC Driver 8.2 for SQL Server is now compatible
11.0, and 1.8. with Java Development Kit (JDK) version 13.0 in addition to
JDK 11.0 and 1.8.
8.2 Releases
Version number: 8.2.2
Released: March 24, 2020
Fixed issues:
Added an option to configure the list of trusted Azure Key Vault endpoints
Version number: 8.2.1
Released: February 26, 2020
Fixed issues:
Fixed a potential NullPointerException issue when retrieving data as java.time.LocalTime or
java.time.LocalDate type with SQLServerResultSet.getObject()
More details and sample code. See Always Encrypted with secure enclaves.
Microsoft JDBC Driver 8.2 for SQL Server has improved This change eliminates unnecessary temporal datatype
performance when retrieving temporal datatypes from SQL conversions by eliminating the use of java.util.Calendar
Server. wherever possible.
The following is a list of the temporal datatypes that have date (java.sql.Date), datetime (java.sql.Timestamp),
been affected by this performance improvement; in format datetime2 (java.sql.Timestamp), smalldatetime
SQL Server datatype followed by the respective Java (java.sql.Timestamp), and time (java.sql.Time).
mapping.
1 Due to the differences in howtime zones are handled between java.util.Calendar and java.time.LocalDateTime
API, temporal datatypes with a user provided java.util.Calendar object associated with it or
microsoft.sql.DateTimeOffset datatypes do not benefit from this improvement.
Deployment of mssql-jdbc_auth-<version>-<arch>.dll (previously sqljdbc_auth.dll) to Maven Repository
SQ L JDB C _A UT H . DL L C H A N GE DETA IL S
Starting from Microsoft JDBC Driver 8.2 for SQL Server, the
driver relies on mssql-jdbc_auth-<version>-<arch>.dll
instead of sqljdbc_auth.dll to use Azure Active Directory
Authentication feature.
The DLL has also been uploaded to Maven repository for See this page.
easier access.
When using Always Encrypted with secure enclaves with Users must include BouncyCastle Provider as a dependency
Java 8. OR map/load a security provider which supports the
RSASSA-PSS signature algorithm.
7.4.1
Download Microsoft JDBC Driver 7.4.1 for SQL Ser ver (self-extracting exe)
Download Microsoft JDBC Driver 7.4.1 for SQL Ser ver (tar.gz)
Version number: 7.4.1
Released: August 2, 2019
If you need to download the driver in a language other than the one detected for you, you can use these direct
links.
For the driver in a self-extracting exe file: Chinese (Simplified) | Chinese (Traditional) | English (United States) |
French | German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the driver in a tar.gz file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French |
German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
7.4 Compliance
C O M P L IA N C E C H A N GE DETA IL S
Download the latest updates for JDBC Driver 7.4. • GitHub, 7.4.1
• Maven Central
Fully compliant with JDBC API Specification 4.2. The jars in the 7.4 package are named according to Java
version compatibility.
Compatible with Java Development Kit (JDK) version 12.0, Microsoft JDBC Driver 7.4 for SQL Server is now compatible
11.0, and 1.8. with Java Development Kit (JDK) version 12.0 in addition to
JDK 11.0 and 1.8.
7.4 Releases
Version number: 7.4.1
Released: August 2, 2019
Fixed issues:
Reverted new hashCode() and equals() API implementations from SQLServerDataTable and
SQLServerDataColumn as the API change broke backwards compatibility
Supports NTLM authentication mode. This mode of authentication allows both Windows and non-
Windows clients to authenticate themselves against SQL
Server using Windows domain users.
More details and a sample application to use this See Connecting using NTLM Authentication.
authentication mode.
useFmtOnly connection property added. This feature allows users to optionally query
ParameterMetaData via the SET FMTONLY ON legacy API.
This is useful for scenarios where
sp_describe_undeclared_parameters doesn't perform as
expected.
USEF M TO N LY C H A N GE DETA IL S
Updated Microsoft Azure Key Vault SDK for Java, version 1.2.1
K EY VA ULT SDK C H A N GE DETA IL S
Additional details. See Feature dependencies of the Microsoft JDBC Driver for
SQL Server.
When using NTLM Authentication. Enabling Extended Protection and encrypted connections at
the same time is currently not supported.
When using useFmtOnly. There are some issues with the feature, which are caused by
deficiencies in SQL parsing logic. See Using useFmtOnly for
more details and workaround suggestions.
7.2.2
Download Microsoft JDBC Driver 7.2.2 for SQL Ser ver (self-extracting exe)
Download Microsoft JDBC Driver 7.2.2 for SQL Ser ver (tar.gz)
Version number: 7.2.2
Released: April 16, 2019
If you need to download the driver in a language other than the one detected for you, you can use these direct
links.
For the driver in a self-extracting exe file: Chinese (Simplified) | Chinese (Traditional) | English (United States) |
French | German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the driver in a tar.gz file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French |
German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
7.2 Compliance
C O M P L IA N C E C H A N GE DETA IL S
Download the latest updates for JDBC Driver 7.2. • GitHub, 7.2.2
• Maven Central
C O M P L IA N C E C H A N GE DETA IL S
Fully compliant with JDBC API Specification 4.2. The jars in the 7.2 package are named according to Java
version compatibility.
Compatible with Java Development Kit (JDK) version 11.0 in Microsoft JDBC Driver 7.2 for SQL Server is now compatible
addition to JDK 1.8. with Java Development Kit (JDK) version 11.0 in addition to
JDK 1.8.
7.2 Releases
Version number: 7.2.2
Released: April 16, 2019
Fixed issues:
Fixed issues with ActivityIDs not getting cleaned up properly
Version number: 7.2.1
Released: February 11, 2019
Fixed issues:
Fixed parsing issues with certain parameterized queries
Version number: 7.2.0
Released: January 31, 2019
Active Directory Managed Identity (MSI ) authentication
M SI C H A N GE DETA IL S
Supports Active Directory Managed Identity (MSI) This mode of authentication is applicable on Azure Resources
authentication mode. with support for the "Identity" feature enabled.
More details and a sample application to use this See Connecting using Azure Active Directory Authentication.
authentication mode.
SQLServerError API introduced. Getter APIs to retrieve additional details about the error
generated from the server.
• SQLServerException.getSQLServerError()
• SQLServerError
Updated Microsoft Azure Active Directory Authentication Library (ADAL4J ) for Java, version 1.6.3
A DA L 4J C H A N GE DETA IL S
Additional details. See Feature dependencies of the Microsoft JDBC Driver for
SQL Server.
Updated Microsoft Azure Key Vault SDK for Java, version 1.2.0
K EY VA ULT SDK C H A N GE DETA IL S
Additional details. See Feature dependencies of the Microsoft JDBC Driver for
SQL Server.
Parameterized queries, in certain cases. An update of the 7.2.0 version, v7.2.1, was released in
February 2019 to address this issue.
Cleaning up of ActivityIds. An update of the 7.2.1 version, v7.2.2, was released in April
2019 to address this issue.
7.0
Download Microsoft JDBC Driver 7.0 for SQL Ser ver (self-extracting exe)
Download Microsoft JDBC Driver 7.0 for SQL Ser ver (tar.gz)
Version number: 7.0.0
Released: July 31, 2018
If you need to download the driver in a language other than the one detected for you, you can use these direct
links.
For the driver in a self-extracting exe file: Chinese (Simplified) | Chinese (Traditional) | English (United States) |
French | German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the driver in a tar.gz file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French |
German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Microsoft JDBC Driver 7.0 for SQL Server is fully compliant with JDBC API Specification 4.2. The jars in the 7.0
package are named according to Java version compatibility. For example, the mssql-jdbc-7.0.0.jre10.jar file from
the 7.0 package should be used with Java 10.
Support for JDK 10
Microsoft JDBC Driver 7.0 for SQL Server is now compatible with Java Development Kit (JDK) version 10.0 in
addition to JDK 1.8. This update also exposes the driver's Automatic-Module-Name as
com.microsoft.sqlserver.jdbc through its MANIFEST file.
For more information about how to use this feature with the JDBC Driver, see the sample in SQL Data Discovery
and Classification.
Added connection property: useBulkCopyForBatchInsert
Microsoft JDBC Driver 7.0 for SQL Server introduces a new connection property, useBulkCopyForBatchInsert .
This property is supported only for Azure Synapse Analytics.
This property is disabled by default. You can enable it to increase performance of user applications when you're
pushing large amounts data to Azure Synapse Analytics. Enabling this property changes the behavior of batch
insert operations to switch to bulk copy operations with user-provided data. For more information about this
property and its limitations, see Using Bulk Copy API for batch insert operation.
Added connection property: cancelQueryTimeout
Microsoft JDBC Driver 7.0 for SQL Server introduces a new connection property, cancelQueryTimeout , to cancel
queryTimeout on java.sql.Connection and java.sql.Statement objects.
Updated "Microsoft Azure Active Directory Authentication Library (ADAL4J) for Java" version: 1.6.0
Microsoft JDBC Driver 7.0 for SQL Server has updated its Maven dependency on "Microsoft Azure Active
Directory Authentication Library (ADAL4J) for Java" to version 1.6.0. For more information about dependencies,
see Feature dependencies of the Microsoft JDBC Driver for SQL Server.
6.4
Download Microsoft JDBC Driver 6.4 for SQL Ser ver (self-extracting exe)
Download Microsoft JDBC Driver 6.4 for SQL Ser ver (tar.gz)
Version number: 6.4.0
Released: February 27, 2018
If you need to download the driver in a language other than the one detected for you, you can use these direct
links.
For the driver in a self-extracting exe file: Chinese (Simplified) | Chinese (Traditional) | English (United States) |
French | German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the driver in a tar.gz file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French |
German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Microsoft JDBC Driver 6.4 for SQL Server is fully compliant with JDBC specifications 4.1 and 4.2. The jars in the
6.4 package are named according to Java version compatibility. For example, the mssql-jdbc-6.4.0.jre8.jar file
from the 6.4 package must be used with Java 8.
Support for JDK 9
The driver supports JDK version 9.0 in addition to JDK 8.0 and 7.0.
JDBC 4.3 compliance
The driver supports the Java Database Connectivity API 4.3 specification, in addition to 4.1 and 4.2. The JDBC 4.3
API methods are added but not implemented yet. For details, see JDBC 4.3 compliance for the JDBC Driver.
Added connection property: sslProtocol
A new connection property lets users specify the TLS protocol keyword. Possible values are: "TLS", "TLSv1",
"TLSv1.1", and "TLSv1.2". For details, see SSLProtocol.
Deprecated connection property: fipsProvider
The connection property fipsProvider is removed from the list of accepted connection properties. For details,
see the related GitHub pull request.
Added connection properties for specifying a custom TrustManager
The driver now supports specifying a custom TrustManager with added trustManagerClass and
trustManagerConstructorArg connection properties. You can dynamically specify a set of certificates that are
trusted on a per-connection basis without modifying the global settings for the Java virtual machine (JVM)
environment.
Added support for datetime/smallDatetime in table -valued parameters
The driver now supports the datatypes datetime and smallDatetime when you're using table-valued
parameters (TVPs).
Added support for the sql_variant datatype
The JDBC Driver now supports sql_variant datatypes to be used with SQL Server. The sql_variant datatype is
also supported with features such as TVPs and bulk copy with the following limitations:
For date values :
When you're using a TVP to populate a table that contains datetime , smalldatetime , or date values
stored in a sql_variant column, calling the getDateTime() , getSmallDateTime() , or getDate() method
on the result set doesn't work and throws the following exception:
java java.lang.String cannot be cast to java.sql.Timestamp
6.2
Download Microsoft JDBC Driver 6.2 for SQL Ser ver (self-extracting exe)
Download Microsoft JDBC Driver 6.2 for SQL Ser ver (tar.gz)
Version number: 6.2.2
Released: September 29, 2017
If you need to download the driver in a language other than the one detected for you, you can use these direct
links.
For the driver in a self-extracting exe file: Chinese (Simplified) | Chinese (Traditional) | English (United States) |
French | German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the driver in a tar.gz file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French |
German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Microsoft JDBC Driver 6.2 for SQL Server is fully compliant with JDBC specifications 4.1 and 4.2. The jars in the
6.2 package are named according to Java version compatibility. For example, the mssql-jdbc-6.2.2.jre8.jar file
from the 6.2 package is recommended for use with Java 8.
6.2 Releases
Version number: 6.2.2
Released: October 3, 2017
Fixed issues:
Updated ADAL4J dependency to version 1.2.0 and Azure Key Vault dependency to version 1.0.0
Version number: 6.2.1
Released: July 14, 2017
Fixed issues:
Fixed an issue when running queries without parameters using preparedStatement
NOTE
An issue with the metadata caching improvement was found in the JDBC 6.2 RTW released on June 29, 2017. The
improvement was rolled back and new jars (version 6.2.1) were released on July 17, 2017.
Another improvement upgraded the Azure Key Vault dependent library version to 1.0.0, and new jars (version 6.2.2) were
released on October 19, 2017.
Download the latest updates for JDBC Driver 6.2 via the above links, GitHub, or Maven Central. Please update your
projects to use the 6.2.2 release jars. For more information, view release notes for 6.2.1 and 6.2.2.
6.1
Version number: 6.1.0
Released: November 17, 2016
Microsoft JDBC Driver 6.1 for SQL Server is fully compliant with JDBC specifications 4.1 and 4.2. This is the
initial open-source release of the JDBC Driver. The source code can be found at the GitHub v6.1.0 tag. It builds
the mssql-jdbc-6.1.0.jre8.jar and mssql-jdbc-6.1.0.jre7.jar files, which correspond to Java version compatibility.
6.0
Download Microsoft JDBC Driver 6.0 for SQL Ser ver (self-extracting exe)
Download Microsoft JDBC Driver 6.0 for SQL Ser ver (tar.gz)
Version number: 6.0.8112
Released: January 17, 2017
If you need to download the driver in a language other than the one detected for you, you can use these direct
links.
For the driver in a self-extracting exe file: Chinese (Simplified) | Chinese (Traditional) | English (United States) |
French | German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the driver in a tar.gz file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French |
German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Microsoft JDBC Driver 6.0 for SQL Server is fully compliant with JDBC specifications 4.1 and 4.2. The jars in the
6.0 package are named according to their compliance with the JDBC API version. For example, the sqljdbc42.jar
file from the 6.0 package is JDBC API 4.2 compliant. Similarly, the sqljdbc41.jar file is compliant with JDBC API
4.1.
To ensure that you have the right sqljdbc42.jar or sqljdbc41.jar file, run the following lines of code. If the output
is "Driver version: 6.0.7507.100", you have the JDBC Driver 6.0 package.
4.2
Download Microsoft JDBC Driver 4.2 for SQL Ser ver (self-extracting exe)
Download Microsoft JDBC Driver 4.2 for SQL Ser ver (tar.gz)
Version number: 4.2.8112
Released: August 24, 2015
If you need to download the driver in a language other than the one detected for you, you can use these direct
links.
For the driver in a self-extracting exe file: Chinese (Simplified) | Chinese (Traditional) | English (United States) |
French | German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the driver in a tar.gz file: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French |
German | Italian | Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Microsoft JDBC Driver 4.2 for SQL Server is fully compliant with JDBC specifications 4.1 and 4.2. The jars in the
4.2 package are named according to their compliance with the JDBC API version. For example, the sqljdbc42.jar
file from the 4.2 package is JDBC API 4.2 compliant. Similarly, the sqljdbc41.jar file is compliant with JDBC API
4.1.
To ensure you have the right sqljdbc42.jar or sqljdbc41.jar file, run the following lines of code. If the output is
"Driver version: 4.2.6420.100", you have the JDBC Driver 4.2 package.
4.1
Version number: 4.1.8112
Released: December 12, 2014
Support for JDK 7
The driver supports JDK version 7.0 in addition to JDK 6.0 and 5.0.
See also
Overview of the JDBC Driver
System requirements for the JDBC driver
4/27/2022 • 15 minutes to read • Edit Online
The JDBC Driver 10.2 is available on the Maven Central Repository, and can be added to a Maven project with
the following code in the POM.XML:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>10.2.0.jre11</version>
</dependency>
The JDBC Driver 9.4 is available on the Maven Central Repository and can be added to a Maven project with the
following code in the POM.XML:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>9.4.1.jre11</version>
</dependency>
The JDBC Driver 9.2 is available on the Maven Central Repository and can be added to a Maven project with the
following code in the POM.XML:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>9.2.1.jre11</version>
</dependency>
The JDBC Driver 8.4 is available on the Maven Central Repository and can be added to a Maven project with the
following code in the POM.XML:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>8.4.1.jre11</version>
</dependency>
The JDBC Driver 8.2 is available on the Maven Central Repository and can be added to a Maven project with the
following code in the POM.XML:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>8.2.2.jre11</version>
</dependency>
The JDBC Driver 7.4 is available on the Maven Central Repository and can be added to a Maven project with the
following code in the POM.XML:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>7.4.1.jre11</version>
</dependency>
Microsoft JDBC Driver 7.2 for SQL Ser ver :
The JDBC Driver 7.2 includes two JAR class libraries in each installation package: mssql-jdbc-7.2.2.jre8.jar ,
and mssql-jdbc-7.2.2.jre11.jar .
The JDBC Driver 7.2 is designed to work with, and supports all major Java virtual machines, but is tested only on
OpenJDK 8.0, OpenJDK 11.0, Azul Zulu JRE 8.0, and Azul Zulu JRE 11.0.
The following chart summarizes support provided by the two JAR files included with Microsoft JDBC Drivers 7.2
for SQL Server:
The JDBC Driver 7.2 is available on the Maven Central Repository and can be added to a Maven project with the
following code in the POM.XML:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>7.2.2.jre11</version>
</dependency>
The JDBC Driver 7.0 is available on the Maven Central Repository and can be added to a Maven project with the
following code in the POM.XML:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>7.0.0.jre10</version>
</dependency>
The JDBC Driver 6.4 is available on the Maven Central Repository and can be added to a Maven project with the
following code in the POM.XML
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>6.4.0.jre9</version>
</dependency>
The JDBC Driver 6.2 is available on the Maven Central Repository and can be added to a Maven project with the
following code in the POM.XML
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>6.2.2.jre8</version>
</dependency>
Microsoft JDBC Driver 6.0 and 4.2 for SQL Ser ver :
The JDBC Drivers 6.0 and 4.2 include two JAR class libraries in each installation package: sqljdbc41.jar , and
sqljdbc42.jar .
The JDBC Drivers 6.0 and 4.2 are designed to work with, and supports all major Java virtual machines, but is
tested only on Sun JRE 5.0, 6.0, 7.0, and 8.0.
The following chart summarizes support provided by the two JAR files included with Microsoft JDBC Drivers 6.0
and 4.2 for SQL Server:
JA R DESC RIP T IO N
The JDBC driver is designed to work with, and supports all major Java virtual machines, but is tested on Sun JRE
5.0, 6.0 and 7.0.
The following chart summarizes support provided by the JAR file included with Microsoft JDBC Driver 4.1 for
SQL Server.
sqljdbc41.jar 4 7 765
Supported languages
The JDBC driver supports all SQL Server column collations. For more information about the collations
supported by the JDBC driver, see International features of the JDBC driver.
For more information about collations, see "Working with Collations" in SQL Server Books Online.
See also
Overview of the JDBC driver
Microsoft JDBC Driver for SQL Server support
matrix
4/27/2022 • 5 minutes to read • Edit Online
EN D O F M A IN ST REA M
DRIVER N A M E DRIVER PA C K A GE VERSIO N A P P L IC A B L E JA R( S) SUP P O RT
Microsoft JDBC Driver 6.0 for SQL 6.0 July 14, 2021
Server
Microsoft JDBC Driver 4.2 for SQL 4.2 August 24, 2020
Server
Microsoft JDBC Driver 4.1 for SQL 4.1 December 12, 2019
Server
Microsoft SQL Server JDBC Driver 3.0 3.0 April 23, 2015
Microsoft SQL Server JDBC Driver 2.0 2.0 December 31, 2012
8.4 Yes Yes Yes Yes Yes Yes Yes Yes Yes
8.2 Yes Yes Yes Yes Yes Yes Yes Yes Yes
7.4 Yes Yes Yes Yes Yes Yes Yes Yes Yes
7.2 Yes Yes Yes Yes Yes Yes Yes Yes Yes
7.0 Yes Yes Yes Yes Yes Yes Yes Yes Yes
6.4 Yes Yes Yes Yes Yes Yes Yes Yes Yes
6.2 Yes Yes Yes Yes Yes Yes Yes Yes Yes
1.2 Yes3
1 Microsoft SQL Server JDBC Driver version 3.0 can connect to SQL Server 2012 as a down-level client.
2 Support forAzure SQL Database was introduced in the 3.0 driver as a hotfix. We recommend that Azure SQL
Database customers use the latest driver version available.
3 Microsoft SQL Server JDBC Driver version 2.0 and Microsoft SQL Server 2005 JDBC Driver version 1.2 can
connect to SQL Server 2008 as a down-level client. When down-level conversions are allowed, applications can
execute queries and perform updates on the new SQL Server 2008 data types, such as time, date, datetime2,
datetimeoffset, and FILESTREAM. For more information about how to use these new data types with the JDBC
driver, see Working with SQL Server 2008 Date/Time Data Types using JDBC Driver and Working with SQL
Server 2008 FileStream using JDBC Driver. For more information about the down-level compatibility of these
new data types, see Using Date and Time Dataand FILESTREAM Support topics in SQL Server Books Online.
4 Support for connections between the Microsoft JDBC Driver and Parallel Data Warehouse was first introduced
in the Microsoft JDBC Driver 4.0 for SQL Server and Microsoft SQL Server 2008 R2 Parallel Data Warehouse
Appliance Update 3.
5 Microsoft SQL Server JDBC Driver version 3.0 can connect to SQL Server 2014 as a down-level client.
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-10.2.0.jre8.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-10.2.0.jre11.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-10.2.0.jre17.jar
The following snippet is an example of the CLASSPATH statement that is used for a Windows application:
CLASSPATH =.;C:\Program Files\Microsoft JDBC Driver 10.2 for SQL Server\sqljdbc_10.2\enu\mssql-jdbc-
10.2.0.jre11.jar
The following snippet is an example of the CLASSPATH statement that is used for a Unix/Linux application:
CLASSPATH =.:/home/usr1/mssqlserverjdbc/Driver/sqljdbc_10.2/enu/mssql-jdbc-10.2.0.jre11.jar
Make sure that the CLASSPATH statement contains only one Microsoft JDBC Driver for SQL Server, such as
either mssql-jdbc-10.2.0.jre8.jar , mssql-jdbc-10.2.0.jre11.jar , or mssql-jdbc-10.2.0.jre17.jar .
For Microsoft JDBC Driver 9.4
The mssql-jdbc-9.4.1.jre8.jar , mssql-jdbc-9.4.1.jre11.jar , or mssql-jdbc-9.4.1.jre16.jar files are installed
in the following locations:
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-9.4.1.jre8.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-9.4.1.jre11.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-9.4.1.jre16.jar
The following snippet is an example of the CLASSPATH statement that is used for a Windows application:
CLASSPATH =.;C:\Program Files\Microsoft JDBC Driver 9.4 for SQL Server\sqljdbc_9.4\enu\mssql-jdbc-
9.4.1.jre11.jar
The following snippet is an example of the CLASSPATH statement that is used for a Unix/Linux application:
CLASSPATH =.:/home/usr1/mssqlserverjdbc/Driver/sqljdbc_9.4/enu/mssql-jdbc-9.4.1.jre11.jar
Make sure that the CLASSPATH statement contains only one Microsoft JDBC Driver for SQL Server, such as
either mssql-jdbc-9.4.1.jre8.jar , mssql-jdbc-9.4.1.jre11.jar , or mssql-jdbc-9.4.1.jre16.jar .
For Microsoft JDBC Driver 9.2
The mssql-jdbc-9.2.1.jre8.jar , mssql-jdbc-9.2.1.jre11.jar , or mssql-jdbc-9.2.1.jre15.jar files are installed
in the following locations:
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-9.2.1.jre8.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-9.2.1.jre11.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-9.2.1.jre15.jar
The following snippet is an example of the CLASSPATH statement that is used for a Windows application:
CLASSPATH =.;C:\Program Files\Microsoft JDBC Driver 9.2 for SQL Server\sqljdbc_9.2\enu\mssql-jdbc-
9.2.1.jre11.jar
The following snippet is an example of the CLASSPATH statement that is used for a Unix/Linux application:
CLASSPATH =.:/home/usr1/mssqlserverjdbc/Driver/sqljdbc_9.2/enu/mssql-jdbc-9.2.1.jre11.jar
Make sure that the CLASSPATH statement contains only one Microsoft JDBC Driver for SQL Server, such as
either mssql-jdbc-9.2.1.jre8.jar , mssql-jdbc-9.2.1.jre11.jar , or mssql-jdbc-9.2.1.jre15.jar .
For Microsoft JDBC Driver 8.4
The mssql-jdbc-8.4.1.jre8.jar , mssql-jdbc-8.4.1.jre11.jar , or mssql-jdbc-8.4.1.jre14.jar files are installed
in the following locations:
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-8.4.1.jre8.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-8.4.1.jre11.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-8.4.1.jre14.jar
The following snippet is an example of the CLASSPATH statement that is used for a Windows application:
CLASSPATH =.;C:\Program Files\Microsoft JDBC Driver 8.4 for SQL Server\sqljdbc_8.4\enu\mssql-jdbc-
8.4.1.jre11.jar
The following snippet is an example of the CLASSPATH statement that is used for a Unix/Linux application:
CLASSPATH =.:/home/usr1/mssqlserverjdbc/Driver/sqljdbc_8.4/enu/mssql-jdbc-8.4.1.jre11.jar
Make sure that the CLASSPATH statement contains only one Microsoft JDBC Driver for SQL Server, such as
either mssql-jdbc-8.4.1.jre8.jar , mssql-jdbc-8.4.1.jre11.jar , or mssql-jdbc-8.4.1.jre14.jar .
For Microsoft JDBC Driver 8.2
The mssql-jdbc-8.2.2.jre8.jar , mssql-jdbc-8.2.2.jre11.jar , or mssql-jdbc-8.2.2.jre13.jar files are installed
in the following locations:
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-8.2.2.jre8.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-8.2.2.jre11.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-8.2.2.jre13.jar
The following snippet is an example of the CLASSPATH statement that is used for a Windows application:
CLASSPATH =.;C:\Program Files\Microsoft JDBC Driver 8.2 for SQL Server\sqljdbc_8.2\enu\mssql-jdbc-
8.2.2.jre11.jar
The following snippet is an example of the CLASSPATH statement that is used for a Unix/Linux application:
CLASSPATH =.:/home/usr1/mssqlserverjdbc/Driver/sqljdbc_8.2/enu/mssql-jdbc-8.2.2.jre11.jar
Make sure that the CLASSPATH statement contains only one Microsoft JDBC Driver for SQL Server, such as
either mssql-jdbc-8.2.2.jre8.jar , mssql-jdbc-8.2.2.jre11.jar , or mssql-jdbc-8.2.2.jre13.jar .
For Microsoft JDBC Driver 7.4
The mssql-jdbc-7.4.1.jre8.jar , mssql-jdbc-7.4.1.jre11.jar , or mssql-jdbc-7.4.1.jre12.jar files are installed
in the following locations:
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-7.4.1.jre8.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-7.4.1.jre11.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-7.4.1.jre12.jar
The following snippet is an example of the CLASSPATH statement that is used for a Windows application:
CLASSPATH =.;C:\Program Files\Microsoft JDBC Driver 7.4 for SQL Server\sqljdbc_7.4\enu\mssql-jdbc-
7.4.1.jre11.jar
The following snippet is an example of the CLASSPATH statement that is used for a Unix/Linux application:
CLASSPATH =.:/home/usr1/mssqlserverjdbc/Driver/sqljdbc_7.4/enu/mssql-jdbc-7.4.1.jre11.jar
Make sure that the CLASSPATH statement contains only one Microsoft JDBC Driver for SQL Server, such as
either mssql-jdbc-7.4.1.jre8.jar , mssql-jdbc-7.4.1.jre11.jar , or mssql-jdbc-7.4.1.jre12.jar .
For Microsoft JDBC Driver 7.2
The mssql-jdbc-7.2.2.jre8.jar or mssql-jdbc-7.2.2.jre11.jar files are installed in the following locations:
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-7.2.2.jre8.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-7.2.2.jre11.jar
The following snippet is an example of the CLASSPATH statement that is used for a Windows application:
CLASSPATH =.;C:\Program Files\Microsoft JDBC Driver 7.2 for SQL Server\sqljdbc_7.2\enu\mssql-jdbc-
7.2.2.jre11.jar
The following snippet is an example of the CLASSPATH statement that is used for a Unix/Linux application:
CLASSPATH =.:/home/usr1/mssqlserverjdbc/Driver/sqljdbc_7.2/enu/mssql-jdbc-7.2.2.jre11.jar
Make sure that the CLASSPATH statement contains only one Microsoft JDBC Driver for SQL Server, such as
either mssql-jdbc-7.2.2.jre8.jar or mssql-jdbc-7.2.2.jre11.jar .
For Microsoft JDBC Driver 7.0
The mssql-jdbc-7.0.0.jre8.jar or mssql-jdbc-7.0.0.jre10.jar files are installed in the following locations:
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-7.0.0.jre8.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-7.0.0.jre10.jar
The following snippet is an example of the CLASSPATH statement that is used for a Windows application:
CLASSPATH =.;C:\Program Files\Microsoft JDBC Driver 7.0 for SQL Server\sqljdbc_7.0\enu\mssql-jdbc-
7.0.0.jre10.jar
The following snippet is an example of the CLASSPATH statement that is used for a Unix/Linux application:
CLASSPATH =.:/home/usr1/mssqlserverjdbc/Driver/sqljdbc_7.0/enu/mssql-jdbc-7.0.0.jre10.jar
Make sure that the CLASSPATH statement contains only one Microsoft JDBC Driver for SQL Server, such as
either mssql-jdbc-7.0.0.jre8.jar or mssql-jdbc-7.0.0.jre10.jar .
For Microsoft JDBC Driver 6.4
The mssql-jdbc-6.4.0.jre7.jar , **mssql-jdbc-6.4.0.jre8.jar, or mssql-jdbc-6.4.0.jre9.jar files are installed in
the following location:
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-6.4.0.jre7.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-6.4.0.jre8.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-6.4.0.jre9.jar
The following snippet is an example of the CLASSPATH statement that is used for a Windows application:
CLASSPATH =.;C:\Program Files\Microsoft JDBC Driver 6.4 for SQL Server\sqljdbc_6.4\enu\mssql-jdbc-
6.4.0.jre9.jar
The following snippet is an example of the CLASSPATH statement that is used for a Unix/Linux application:
CLASSPATH =.:/home/usr1/mssqlserverjdbc/Driver/sqljdbc_6.4/enu/mssql-jdbc-6.4.0.jre9.jar
Make sure that the CLASSPATH statement contains only one Microsoft JDBC Driver for SQL Server, such as
either mssql-jdbc-6.4.0.jre7.jar , **mssql-jdbc-6.4.0.jre8.jar, or mssql-jdbc-6.4.0.jre9.jar .
For Microsoft JDBC Driver 6.2
The mssql-jdbc-6.2.2.jre7.jar or mssql-jdbc-6.2.2.jre8.jar files are installed in the following locations:
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-6.2.2.jre7.jar
\<installation directory>\sqljdbc_<version>\<language>\mssql-jdbc-6.2.2.jre8.jar
The following snippet is an example of the CLASSPATH statement that is used for a Windows application:
CLASSPATH =.;C:\Program Files\Microsoft JDBC Driver 6.2 for SQL Server\sqljdbc_6.2\enu\mssql-jdbc-
6.2.2.jre8.jar
The following snippet is an example of the CLASSPATH statement that is used for a Unix/Linux application:
CLASSPATH =.:/home/usr1/mssqlserverjdbc/Driver/sqljdbc_6.2/enu/mssql-jdbc-6.2.2.jre8.jar
Make sure that the CLASSPATH statement contains only one Microsoft JDBC Driver for SQL Server, such as
either mssql-jdbc-6.2.2.jre7.jar or mssql-jdbc-6.2.2.jre8.jar.
For Microsoft JDBC Driver 4.1, 4.2, and 6.0
The sqljdbc.jar file, sqljdbc4.jar file, sqljdbc41.jar, or sqljdbc42.jar file are installed in the following location:
\<installation directory>\sqljdbc_<version>\<language>\sqljdbc.jar
\<installation directory>\sqljdbc_<version>\<language>\sqljdbc4.jar
\<installation directory>\sqljdbc_<version>\<language>\sqljdbc41.jar
\<installation directory>\sqljdbc_<version>\<language>\sqljdbc42.jar
The following snippet is an example of the CLASSPATH statement that is used for a Windows application:
CLASSPATH =.;C:\Program Files\Microsoft JDBC Driver 6.0 for SQL Server\sqljdbc_4.2\enu\sqljdbc42.jar
The following snippet is an example of the CLASSPATH statement that is used for a Unix/Linux application:
CLASSPATH =.:/home/usr1/mssqlserverjdbc/Driver/sqljdbc_4.2/enu/sqljdbc42.jar
Make sure that the CLASSPATH statement contains only one Microsoft JDBC Driver for SQL Server, such as
either sqljdbc.jar, sqljdbc4.jar, sqljdbc41.jar, or sqljdbc42.jar.
NOTE
On Windows systems, directory names longer than the 8.3 filename convention or folder names with spaces may cause
problems with classpaths. If you suspect these types of issues, you should temporarily move the sqljdbc.jar file,
sqljdbc4.jar file, or the sqljdbc41.jar file into a simple directory name such as C:\Temp , change the classpath, and
determine whether that addresses the problem.
When the driver is loaded, you can establish a connection with a connection URL and the getConnection method
of the DriverManager class:
String connectionUrl =
"jdbc:sqlserver://localhost:1433;databaseName=AdventureWorks;user=MyUserName;password=*****;";
Connection con = DriverManager.getConnection(connectionUrl);
Starting from JDBC API 4.0, the DriverManager.getConnection() method is enhanced to load JDBC drivers
automatically. Therefore, applications don't need to call the Class.forName method to register or load the driver
when using driver jar libraries.
When the getConnection method of the DriverManager class is called, an appropriate driver is located from the
set of registered JDBC drivers. sqljdbc4.jar, sqljdbc41.jar, or sqljdbc42.jar file includes "META-
INF/services/java.sql.Driver" file, which contains the com.microsoft.sqlser ver.jdbc.SQLSer verDriver as a
registered driver. The existing applications, which currently load the drivers by using the Class.forName method,
will continue to work without modification.
NOTE
sqljdbc4.jar, sqljdbc41.jar, or sqljdbc42.jar class library cannot be used with older versions of the Java Runtime
Environment (JRE). See System requirements for the JDBC driver for the list of JRE versions supported by the Microsoft
JDBC Driver for SQL Server.
For more information about how to connect with data sources and use a connection URL, see Building the
connection URL and Setting the connection properties.
See also
Overview of the JDBC driver
Parsing the results
4/27/2022 • 2 minutes to read • Edit Online
Exceptions
When you execute a statement that results in an error or an informational message, SQL Server can respond
differently. For example, if it can't generate an execution plan, the error message will be thrown immediately on
execute() . If an error is related to statement processing, the application needs to parse the result set to see the
exception.
When SQL Server is unable to generate an execution plan, the exception is thrown immediately.
When SQL Server returns an error message in a result set, the result set needs to be processed to retrieve the
exception.
String SQL = "SELECT 1/0;";
try (Statement statement = connection.createStatement();) {
boolean hasResult = statement.execute(SQL);
if (hasResult) {
try (ResultSet rs = statement.getResultSet()) {
// Exception is thrown on next().
while (rs.next()) {}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
If statement execution generates multiple result sets, each result set needs to be processed until the one with the
exception is reached.
For example, String SQL = "SELECT * FROM nonexistentTable; SELECT 1;"; , throws an exception immediately on
execute() and SELECT 1 isn't executed at all.
If the error from SQL Server has severity of 0 to 9 , it's considered as an informational message and returned
as SQLWarning .
See also
Overview of the JDBC driver
Retrieving ParameterMetaData via useFmtOnly
4/27/2022 • 3 minutes to read • Edit Online
The feature is also available on the Statement level. Users can turn the feature on/off through
PreparedStatement.setUseFmtOnly(boolean) .
NOTE
The driver will prioritize the Statement level property over the Connection level property.
NOTE
The feature only supports SELECT/INSERT/UPDATE/DELETE queries. Queries should start with one of the 4 supported key
words or a Common Table Expression followed by one of the supported queries. Parameters within Common Table
Expressions are not supported.
Known issues
There are currently some issues with the feature, which are caused by gaps in the SQL parsing logic. These
issues may be addressed in a future update to the feature, and are documented below along with workaround
suggestions.
A. Using a 'forward declared' alias
CREATE TABLE Foo(c1 int)
DELETE fooAlias FROM Foo fooAlias WHERE c1 > ?; --Invalid object name 'fooAlias'
SELECT c1,c2 FROM Foo WHERE c3 IN (SELECT c3 FROM Bar WHERE c1 > ? and c2 < ? and c3 = ?); --Ambiguous
Column Name
SELECT * FROM (SELECT * FROM Foo WHERE c1 = ?) WHERE c1 = ?; --Incorrect syntax near '?'
--Workaround: N/A
UPDATE Foo SET c1 = (SELECT c1 FROM Foo) WHERE c1 = ?; --Incorrect syntax near ')'
See also
Setting the connection properties
Understanding Java EE support
4/27/2022 • 2 minutes to read • Edit Online
Driver name
The driver class name is com.microsoft.sqlser ver.jdbc.SQLSer verDriver .
For JDBC Driver 10.2, the driver is contained in mssql-jdbc-10.2.0.jre8.jar , mssql-jdbc-10.2.0.jre11.jar , or
mssql-jdbc-10.2.0.jre17.jar .
For JDBC Driver 9.4, the driver is contained in mssql-jdbc-9.4.1.jre8.jar , mssql-jdbc-9.4.1.jre11.jar , or
mssql-jdbc-9.4.1.jre16.jar .
For JDBC Driver 9.2, the driver is contained in mssql-jdbc-9.2.1.jre8.jar , mssql-jdbc-9.2.1.jre11.jar , or
mssql-jdbc-9.2.1.jre15.jar .
For JDBC Driver 8.4, the driver is contained in mssql-jdbc-8.4.1.jre8.jar , mssql-jdbc-8.4.1.jre11.jar , or
mssql-jdbc-8.4.1.jre14.jar .
For JDBC Driver 8.2, the driver is contained in mssql-jdbc-8.2.2.jre8.jar , mssql-jdbc-8.2.2.jre11.jar , or
mssql-jdbc-8.2.2.jre13.jar .
For JDBC Driver 7.4, the driver is contained in mssql-jdbc-7.4.1.jre8.jar , mssql-jdbc-7.4.1.jre11.jar , or
mssql-jdbc-7.4.1.jre12.jar .
For JDBC Driver 7.2, the driver is contained in mssql-jdbc-7.2.2.jre8.jar , or mssql-jdbc-7.2.2.jre11.jar .
For JDBC Driver 7.0, the driver is contained in mssql-jdbc-7.0.0.jre8.jar , or mssql-jdbc-7.0.0.jre10.jar .
For JDBC Driver 6.4, the driver is contained in mssql-jdbc-6.4.0.jre7.jar , mssql-jdbc-6.4.0.jre8.jar , or
mssql-jdbc-6.4.0.jre9.jar .
For JDBC Driver 6.2, the driver is contained in mssql-jdbc-6.2.2.jre7.jar or mssql-jdbc-6.2.2.jre8.jar .
For JDBC Drivers 4.1, 4.2, and 6.0, the driver is contained in the sqljdbc.jar , sqljdbc4.jar , sqljdbc41.jar , or
sqljdbc42.jar files.
The class name is used whenever you load the driver with the JDBC DriverManager class, and whenever you
specify the class name of the driver in any driver configuration. For example, to configure a data source within a
Java EE application server might require you enter the driver class name.
Data sources
The JDBC driver provides support for Java EE / JDBC 3.0 data sources. The JDBC driver SQLServerXADataSource
class is implemented by com.microsoft.sqlserver.jdbc.SQLServerXADataSource .
Datasource names
You can make database connections by using data sources. The data sources available with JDBC driver are
described in the following table:
DataSource com.microsoft.sqlserver.jdbc.SQLServerDataSource
ConnectionPoolDataSource com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource
XADataSource com.microsoft.sqlserver.jdbc.SQLServerXADataSource
//initialize JNDI ..
Context ctx = new InitialContext(System.getProperties());
...
DataSource ds = (DataSource) ctx.lookup("MyDataSource");
Connection c = ds.getConnection("user", "pwd");
For more information about the data source properties, see Setting the data source properties.
See also
Overview of the JDBC driver
Deploying the JDBC driver
4/27/2022 • 2 minutes to read • Edit Online
NOTE
For information about deploying Java applications in general, see the Java website.
To unpack the tar file, move it to the directory where you want the driver installed and type the following
command:
tar -xf sqljdbc_<version>_<language>.tar
Remarks
RESO URC E DESC RIP T IO N
JDBC Driver for SQL Server GitHub Repository This repository contains the source code for the JDBC Driver
for SQL Server. Use this site to interact directly with
members of the JDBC driver team. Here you can file issues,
provide feedback, and contribute directly to the driver.
Data Access and Storage Developer Center This site provides documentation, technical articles, sample
code, and other resources for all data access technologies at
Microsoft.
SQL Server Data Access Forum This site serves as a community forum for data access to
SQL Server by using SQL Server Native Client, OLE DB,
ODBC, ADO, MDAC, JDBC, or SOAP/HTTP.
JDBC Blog This blog is used to provide information about the Microsoft
JDBC Driver for SQL Server.
See also
Overview of the JDBC driver
Feature dependencies of the Microsoft JDBC Driver
for SQL Server
4/27/2022 • 5 minutes to read • Edit Online
Compile time
com.azure:azure-security-keyvault-keys : Microsoft Azure Client Library For KeyVault Keys for JDBC driver
version 9.2 and above or com.microsoft.azure:azure-keyvault : Microsoft Azure SDK For Key Vault for JDBC
driver version 8.4 and below for Always Encrypted Azure Key Vault feature. (optional)
com.azure:azure-identity : Microsoft Azure Client Library For Identity for JDBC driver version 9.2 and above
or com.microsoft.azure:adal4j : Microsoft Azure Active Directory Authentication Library for JDBC driver
version 8.4 and below for Azure Active Directory Authentication features and Azure Key Vault feature.
(optional)
org.antlr:antlr4-runtime : ANTLR 4 Runtime for useFmtOnly feature. (optional)
org.osgi:org.osgi.core : OSGi Core library for OSGi Framework support.
org.osgi:org.osgi.compendium : OSGi Compendium library for OSGi Framework support.
com.google.code.gson : JSON parser for Always Encrypted with secure enclaves feature. (optional)
org.bouncycastle.bcprov-jdk15on : Bouncy Castle Provider for Always Encrypted with secure enclaves feature
for JAVA 8 only. (optional)
Run time
Projects that require any of the preceding features must explicitly declare the respective dependencies in their
POM file that match the dependencies of the version of the driver used.
For example: If you're using the Azure Active Directory Authentication feature with JDBC driver version 10.2
and above, you must declare the azure-identity dependency in your project POM file. See the following
snippet:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>10.2.0.jre11</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.4.3</version>
</dependency>
For example: If you're using the Azure Active Directory Authentication feature with JDBC driver version 8.4 and
below, you must declare the adal4j and client-runtimes dependencies in your project POM file. See the
following snippet:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>9.2.1.jre11</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>adal4j</artifactId>
<version>1.6.5</version>
</dependency>
<dependency>
<groupId>com.microsoft.rest</groupId>
<artifactId>client-runtime</artifactId>
<version>1.7.4</version>
</dependency>
For example: If you're using the Azure Key Vault feature with JDBC driver version 10.2 and above, you must
declare the azure-security-keyvault-keys and azure-identity dependencies in your project POM file. See the
following snippet:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>10.2.0.jre11</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.4.3</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-security-keyvault-keys</artifactId>
<version>4.3.6</version>
</dependency>
For example: If you're using the Azure Key Vault feature with JDBC driver version 8.4 and below, you must
declare the azure-keyvault , adal4j , and client-runtime dependencies in your project POM file. See the
following snippet:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>9.2.1.jre11</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>adal4j</artifactId>
<version>1.6.5</version>
</dependency>
<dependency>
<groupId>com.microsoft.rest</groupId>
<artifactId>client-runtime</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-keyvault</artifactId>
<version>1.2.4</version>
</dependency>
NOTE
Make sure to use the version of the POM file that's shipped with the version of the JDBC driver you're using. The
dependencies and versions may have changed.
If you're using Maven to build or test your project, Maven automatically downloads dependent libraries in the
POM file along with their transitive libraries. You can also use the Maven Dependency Plugin to download all
project dependencies to a desired location. If you're not using Maven, you have to download dependencies and
transitive dependencies manually to make sure you have all the correct versions of each library. Once you've
downloaded the required dependent libraries, add them to your project classpath to run your application.
NOTE
With 6.2.2 and 6.4.0 driver versions, the azure-keyvault-java dependency had been updated to version 1.0.0. However,
the new version was not compatible with the previous version (0.9.7) and breaks the existing implementation in the driver.
The new implementation in the driver required API changes, which in turn breaks client programs that use the Azure Key
Vault Provider.
This problem is resolved with latest driver version(s) (7.0.0 onwards). The removed constructor that used the
authentication callback mechanism is added back to the Azure Key Vault Provider for backward compatibility.
See also
JDBC Driver GitHub repository
JDBC Driver API reference
JDBC driver API reference
4/27/2022 • 3 minutes to read • Edit Online
Overview
The Microsoft JDBC Driver for SQL Server provides an API that can be used within Java programming code to
connect to and interact with a MicrosoftSQL Server database.
JavaDoc.io website is primary
The Microsoft JDBC API Reference documentation is hosted for your viewing on the JavaDoc.io website.
JavaDoc.io is now our primary website for JDBC reference documentation. Our JDBC reference documentation
on JavaDoc.io is available at the following direct link:
https://javadoc.io/doc/com.microsoft.sqlserver/mssql-jdbc/
JavaDoc.io has our JDBC reference documentation starting with version 6.0.
Only legacy JDBC documentation is here on docs
The JDBC API Reference documentation here on this website is no longer being updated. However, the articles
here do contain the reference for JDBC driver versions 4.1 and 4.2.
Documentation for JDBC driver version 6.0, and some later versions, is also here. For any version 6.0 or later, use
the JavaDoc.io website.
Important notes
NOTE
For conceptual information about using the JDBC driver, see Overview of the JDBC Driver.
IMPORTANT
For JDBC 4.1 and 4.2 compliance support, use Microsoft JDBC Driver 4.2 (or higher) for SQL Server. The previous
Microsoft JDBC Drivers 4.1 and 4.0 releases do not support new methods introduced with JDBC 4.1 or 4.2.
API details for JDBC 4.1 compliance are not in this section. See JDBC 4.1 Compliance for the JDBC Driver.
API details for JDBC 4.2 compliance are not found in this section. See JDBC 4.2 Compliance for the JDBC Driver.
API details for Bulk Copy, available starting with Microsoft JDBC Driver 4.2 for SQL Server, are not found in this section.
See Using Bulk Copy with the JDBC Driver.
API details for Always Encrypted, available starting with Microsoft JDBC Driver 6.0 for SQL Server, are not found in this
section. See Always Encrypted API Reference for the JDBC Driver
API details for Using Table-Valued Parameters, available starting with Microsoft JDBC Driver 6.0 for SQL Server, are not
found in this section. See Using Table-Valued Parameters
Microsoft JDBC Driver 6.4 supports compilation with JDK 7.0, 8.0, and 9.0.
Microsoft JDBC Driver 6.2 supports compilation with JDK 7.0, and 8.0.
Microsoft JDBC Drivers 6.0 and 4.2 support compilation with JDK 5.0, 6.0, 7.0, and 8.0.
Microsoft JDBC Driver 4.1 supports compilation with JDK 5.0, 6.0, and 7.0.
Interfaces
IN T ERFA C E N A M E DESC RIP T IO N
ISQLServerCallableStatement Interface Lets you specify the stored procedure name to call along
with input and output parameters.
Classes
C L A SS N A M E DESC RIP T IO N
SQLServerDriver Represents the JDBC driver. This class includes methods for
connecting to a SQL Server database, and for obtaining
information about the JDBC driver.
SQLServerNClob Class Represents a character large binary object using the National
Character Set.
See also
Overview of the JDBC driver
ISQLServerCallableStatement Interface
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public interface ISQLServerCallableStatement
Remarks
This interface is implemented by SQLServerCallableStatement Class.
This interface exposes the following Microsoft JDBC Driver for SQL Server-specific methods:
M ET H O D F O R M O RE IN F O RM AT IO N , SEE
See Also
JDBC Driver API Reference
ISQLServerConnection Interface
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public interface ISQLServerConnection
Remarks
This interface is implemented by SQLServerConnection Class.
This interface exposes the following Microsoft JDBC Driver for SQL Server-specific field:
F IEL D F O R M O RE IN F O RM AT IO N , SEE
See Also
JDBC Driver API Reference
ISQLServerDataSource Interface
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public interface ISQLServerDataSource
Remarks
This interface is implemented by SQLServerDataSource Class.
This interface exposes the following Microsoft JDBC Driver for SQL Server-specific methods:
M ET H O D F O R M O RE IN F O RM AT IO N , SEE
See Also
JDBC Driver API Reference
ISQLServerPreparedStatement Interface
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public interface ISQLServerPreparedStatement
Remarks
This interface is implemented by SQLServerPreparedStatement Class.
This interface exposes the following Microsoft JDBC Driver for SQL Server-specific methods:
M ET H O D F O R M O RE IN F O RM AT IO N , SEE
See Also
JDBC Driver API Reference
ISQLServerResultSet Interface
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public interface ISQLServerResultSet
Remarks
This interface is implemented by SQLServerResultSet Class.
This interface exposes the Microsoft JDBC Driver for SQL Server-specific methods:
M ET H O D F O R M O RE IN F O RM AT IO N , SEE
This interface exposes the following Microsoft JDBC Driver for SQL Server-specific fields:
F IEL D F O R M O RE IN F O RM AT IO N , SEE
See Also
JDBC Driver API Reference
ISQLServerStatement Interface
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public interface ISQLServerStatement
Remarks
This interface is implemented by SQLServerStatement Class.
This interface exposes the following Microsoft JDBC Driver for SQL Server-specific methods:
M ET H O D F O R M O RE IN F O RM AT IO N , SEE
See Also
JDBC Driver API Reference
DateTimeOffset Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final class DateTimeOffset
Remarks
For more information about data types, see Understanding the JDBC Driver Data Types.
See Also
JDBC Driver API Reference
DateTimeOffset Members
DateTimeOffset Members
4/27/2022 • 2 minutes to read • Edit Online
Constructors
None.
Fields
None.
Methods
NAME DESC RIP T IO N
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
DateTimeOffset Class
DateTimeOffset Methods
4/27/2022 • 2 minutes to read • Edit Online
See Also
DateTimeOffset Class
compareTo Method (DateTimeOffset)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int compareTo(DateTimeOffset other)
Parameters
A DateTimeOffset value that you want to compare to the current instance.
Return Value
The following table describes the return value of this method:
Remarks
When two DateTimeOffset objects have the same time at GMT, there is no additional ordering of the objects
based on the offset.
See Also
DateTimeOffset Class
DateTimeOffset Members
equals Method (DateTimeOffset)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean equals(Object o)
Parameters
o
The object you want compare to the current instance.
Return Value
Returns true if this DateTimeOffset object represents the same point in time at the same offset from GMT as
another DateTimeOffset .
See Also
DateTimeOffset Class
DateTimeOffset Members
getMinutesOffset Method (DateTimeOffset)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMinutesOffset()
Return Value
The offset in minutes.
Remarks
For a DateTimeOffset object representing 8 March 2010, 11:35:48 -0800, getMinutesOffset returns the value
480.
See Also
DateTimeOffset Class
DateTimeOffset Members
getTimestamp Method (DateTimeOffset)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Timestamp getTimestamp()
Return Value
A value of type java.sql.Timestamp.
See Also
DateTimeOffset Class
DateTimeOffset Members
hashCode Method (DateTimeOffset)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int hashCode()
Return Value
The hash code for the object.
See Also
DateTimeOffset Class
DateTimeOffset Members
toString Method (DateTimeOffset)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public String toString()
Return Value
A string representation of the DateTimeOffset object.
Remarks
The string has the format YYYY-MM-DD HH:mm:ss[.fffffff] [+|-]HH:mm .
The fractional seconds of the returned string are zero padded to the declared precision. For example, a
datetimeoffset(6) with a value of "2010-03-10 12:34:56.78 -08:00" will be formatted by
DateTimeOffset.toString as "2010-03-10 12:34:56.780000 -08:00".
See Also
DateTimeOffset Class
DateTimeOffset Members
valueOf Method (DateTimeOffset)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
DateTimeOffset Class
DateTimeOffset Members
valueOf Method ( java.sql.Timestamp, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public static DateTimeOffset valueOf(java.sql.Timestamp timestamp, int minutesOffset)
Parameters
timestamp
Ajava.sql.Timestamp value.
minutesOffset
The offset in minutes.
Return Value
Returns a DateTimeOffset object representing the point in time given by the java.sql.Timestamp object at the
given offset, in minutes, from GMT.
See Also
DateTimeOffset Class
DateTimeOffset Members
valueOf Method ( java.sql.Timestamp,
java.util.Calendar)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public static DateTimeOffset valueOf(java.sql.Timestamp timestamp, java.util.Calendar calendar)
Parameters
timestamp
Ajava.sql.Timestamp value.
calendar
The offset value. The date and time components of calendar will be set according to the timestamp value.
Return Value
Returns a DateTimeOffset object representing the point in time given by the java.sql.Timestamp object at the
given java.util.Calendar object's time zone.
Remarks
This method also sets the java.util.Calendar object to the point in time given by the java.sql.Timestamp object.
See Also
DateTimeOffset Class
DateTimeOffset Members
SQLServerBlob Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public class SQLServerBlob
Remarks
A BLOB is stored in SQL Server as an IMAGE data type.
See Also
SQLServerBlob Members
JDBC Driver API Reference
SQLServerBlob Members
4/27/2022 • 2 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
Fields
None.
Inherited Fields
None.
Methods
NAME DESC RIP T IO N
free This method frees the BLOB object and releases the
resources that it holds.
setBytes Writes the given array of bytes into the BLOB starting at the
given position, and then returns the number of bytes
written.
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerBlob Class
SQLServerBlob Constructors
4/27/2022 • 2 minutes to read • Edit Online
See Also
SQLServerBlob Class
SQLServerBlob Constructor (SQLServerConnection,
byte)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method has been deprecated in JDBC Driver version 2.0. Instead, use the createBlob method of the
SQLServerConnection class.
Syntax
public SQLServerBlob(SQLServerConnection connection,
byte[] data)
Parameters
connection
A SQLServerConnection object.
data
A byte array.
See Also
SQLServerBlob Constructors
SQLServerBlob Members
SQLServerBlob Class
SQLServerBlob Methods
4/27/2022 • 2 minutes to read • Edit Online
See Also
SQLServerBlob Class
free Method (SQLServerBlob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void free()
Exceptions
SQLServerException
Remarks
This free method is specified by the free method in the java.sql.Blob interface.
See Also
SQLServerBlob Methods
SQLServerBlob Members
SQLServerBlob Class
getBinaryStream Method (SQLServerBlob)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getBinaryStream Method () Returns an input stream to read data from the BLOB.
getBinaryStream Method (long, long) Returns an input stream object that contains a partial BLOB
value by using the specified starting position and the length.
See Also
SQLServerBlob Methods
SQLServerBlob Members
SQLServerBlob Class
getBinaryStream Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.InputStream getBinaryStream()
Return Value
An input stream that contains the BLOB data.
Exceptions
SQLServerException
Remarks
This getBinaryStream method is specified by the getBinaryStream method in the java.sql.Blob interface.
See Also
SQLServerBlob Methods
SQLServerBlob Members
SQLServerBlob Class
getBytes Method (SQLServerBlob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public byte[] getBytes(long pos,
int length)
Parameters
pos
The starting position, starting at 1 (not 0).
length
The length of the data to get.
Return Value
A byte array containing the requested data.
Exceptions
SQLServerException
Remarks
This getBytes method is specified by the getBytes method in the java.sql.Blob interface.
If you have a null or zero length BLOB, and try to get exactly zero bytes at position 1, an empty byte array is
returned (byte array of length 0).
If you have a null or zero length BLOB, and try to get any length of bytes at a position other than 1, a position
exception will be thrown.
See Also
SQLServerBlob Methods
SQLServerBlob Members
SQLServerBlob Class
length Method (SQLServerBlob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public long length()
Return Value
A long value that specifies the number of bytes.
Exceptions
SQLServerException
Remarks
This length method is specified by the length method in the java.sql.Blob interface.
See Also
SQLServerBlob Methods
SQLServerBlob Members
SQLServerBlob Class
position Method (SQLServerBlob)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
position (java.sql.Blob, long) Returns the position of a specified pattern in the BLOB based
on the given pattern and the starting index.
position (byte[], long) Returns the position of a specified pattern in the BLOB based
on the given byte array pattern and the starting index.
See Also
SQLServerBlob Methods
SQLServerBlob Members
SQLServerBlob Class
position Method ( java.sql.Blob, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public long position(java.sql.Blob pattern,
long start)
Parameters
pattern
The pattern to search for.
start
The start index to search at.
Return Value
A long value of the position where the pattern was found, or -1 if it was not found.
Exceptions
SQLServerException
Remarks
This position method is specified by the position method in the java.sql.Blob interface.
See Also
position Method (SQLServerBlob)
SQLServerBlob Methods
SQLServerBlob Members
SQLServerBlob Class
position Method (byte, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public long position(byte[] bPattern,
long start)
Parameters
bPattern
The pattern to search for.
start
The start index to search at.
Return Value
A long value of the position where the pattern was found, or -1 if it was not found.
Exceptions
SQLServerException
Remarks
This position method is specified by the position method in the java.sql.Blob interface.
See Also
position Method (SQLServerBlob)
SQLServerBlob Methods
SQLServerBlob Members
SQLServerBlob Class
setBinaryStream Method (SQLServerBlob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.OutputStream setBinaryStream(long pos)
Parameters
Pos
The position in the BLOB value at which to start writing)
Return Value
An output stream.
Exceptions
java.sql.SQLException
Remarks
This setBinaryStream method is specified by the setBinaryStream method in the java.sql.Blob interface.
Data in the BLOB is overwritten by the output stream starting at the specified position and can over-run the
initial length of the BLOB. Specifying a position+1 value will append bytes. Passing a position+2 or greater (or
zero or less) value will cause a position error to be thrown.
See Also
SQLServerBlob Methods
SQLServerBlob Members
SQLServerBlob Class
setBytes Method (SQLServerBlob)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setBytes (long, byte[]) Writes the given array of bytes into the BLOB starting at the
given position, and then returns the number of bytes
written.
setBytes (long, byte[], int, int) Writes all or part of the given array of bytes into the BLOB
starting at the given position, offset, and length, and then
returns the number of bytes written.
See Also
SQLServerBlob Methods
SQLServerBlob Members
SQLServerBlob Class
setBytes Method (long, byte)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int setBytes(long pos,
byte[] bytes)
Parameters
pos
The position (1-based) in the BLOB at which to start writing the data.
bytes
The array of bytes to be written into the BLOB.
Return Value
A long value that specifies the number of bytes written.
Exceptions
java.sql.SQLException
Remarks
This setBytes method is specified by the setBytes method in the java.sql.Blob interface.
Data is overwritten starting at the specified position and can overrun the initial length of the BLOB. Specifying a
position+1 values will append bytes. Passing a position+2 or greater (or zero or less) value will cause a position
error to be thrown. Passing a zero-length byte array will return zero because no bytes were written.
See Also
setBytes Method (SQLServerBlob)
SQLServerBlob Methods
SQLServerBlob Members
SQLServerBlob Class
setBytes Method (long, byte, int, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int setBytes(long pos,
byte[] bytes,
int offset,
int len)
Parameters
pos
The position (1 based) in the BLOB at which to start writing the data.
bytes
The array of bytes to be written into the BLOB.
offset
The offset in the bytes array where to start reading data from the byte array.
len
The number of bytes to attempt to read from the bytes array into the BLOB.
Return Value
An int containing the number of bytes written.
Exceptions
java.sql.SQLException
Remarks
This setBytes method is specified by the setBytes method in the java.sql.Blob interface.
Data is overwritten starting at the specified position and can over-run the initial length of the BLOB. Specifying a
position+1 values will append bytes. Passing a position+2 or greater (or zero or less) value will cause a position
error to be thrown. Passing a zero-length byte array will return zero because no bytes were written.
See Also
setBytes Method (SQLServerBlob)
SQLServerBlob Methods
SQLServerBlob Members
SQLServerBlob Class
truncate Method (SQLServerBlob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void truncate(long len)
Parameters
len
The new length for the BLOB.
Exceptions
java.sql.SQLException
Remarks
This truncate method is specified by the truncate method in the java.sql.Blob interface.
See Also
SQLServerBlob Methods
SQLServerBlob Members
SQLServerBlob Class
SQLServerCallableStatement Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final class SQLServerCallableStatement
Remarks
SQLServerCallableStatement lets you specify the stored procedure name to call along with input and output
parameters. SQLServerCallableStatement also provides the ability to retrieve the return status value with the
? = call( ?, ..) syntax.
See Also
SQLServerCallableStatement Members
JDBC Driver API Reference
SQLServerCallableStatement Members
4/27/2022 • 8 minutes to read • Edit Online
Constructors
None.
Fields
C L A SS IN H ERIT ED F RO M : M ET H O DS
Inherited Fields
None.
Methods
NAME DESC RIP T IO N
setNull Sets the designated parameter to a null value, given the type
of parameter to set.
setObject Sets the value of the designated parameter using the given
object.
wasNull Retrieves whether the last OUT parameter read had the
value of SQL NULL.
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerCallableStatement Class
SQLServerCallableStatement Methods
4/27/2022 • 2 minutes to read • Edit Online
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getArray Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getArray Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Array getArray(int i)
Parameters
i
An int that indicates the parameter index.
Return Value
An Array object.
Exceptions
SQLServerException
Remarks
This getArray method is specified by the getArray method in the java.sql.CallableStatement interface.
See Also
getArray Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getArray Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Array getArray(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
An Array object.
Exceptions
SQLServerException
Remarks
This getArray method is specified by the getArray method in the java.sql.CallableStatement interface.
See Also
getArray Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getAsciiStream Method
(SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getAsciiStream (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.io.InputStream getAsciiStream(int paramIndex)
Parameters
paramIndex
An int that indicates the parameter index.
Return Value
An InputStream object.
Exceptions
SQLServerException
See Also
getAsciiStream Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getAsciiStream ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.io.InputStream getAsciiStream(java.lang.String paramName)
Parameters
paramName
A String that indicates the parameter name.
Return Value
An InputStream object.
Exceptions
SQLServerException
See Also
getAsciiStream Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBigDecimal Method
(SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBigDecimal Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.math.BigDecimal getBigDecimal(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
A BigDecimal object.
Exceptions
SQLServerException
Remarks
This getBigDecimal method is specified by the getBigDecimal method in the java.sql.CallableStatement interface.
See Also
getBigDecimal Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBigDecimal Method (int, int)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method has been deprecated from the JDBC specification. Instead, you should use the getBigDecimal (int) method.
Syntax
public java.math.BigDecimal getBigDecimal(int index,
int scale)
Parameters
index
An int that indicates the parameter index.
scale
An int that indicates the number of digits to the right of the decimal point.
Return Value
A BigDecimal object.
Exceptions
SQLServerException
Remarks
This getBigDecimal method is specified by the getBigDecimal method in the java.sql.CallableStatement interface.
See Also
getBigDecimal Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBigDecimal Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.math.BigDecimal getBigDecimal(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
A BigDecimal object.
Exceptions
SQLServerException
Remarks
This getBigDecimal method is specified by the getBigDecimal method in the java.sql.CallableStatement interface.
See Also
getBigDecimal Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBigDecimal Method ( java.lang.String, int)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method has been deprecated from the JDBC specification. Instead, you should use the getBigDecimal
(java.lang.String) method.
Syntax
public java.math.BigDecimal getBigDecimal(java.lang.String sCol,
int scale)
Parameters
sCol
A String that contains the parameter name.
scale
An int that indicates the number of digits to the right of the decimal point.
Return Value
A BigDecimal object.
Exceptions
SQLServerException
Remarks
This getBigDecimal method is specified by the getBigDecimal method in the java.sql.CallableStatement interface.
See Also
getBigDecimal Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBinaryStream Method
(SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBinaryStream (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.io.InputStream getBinaryStream(int paramIndex)
Parameters
paramIndex
An int that indicates the parameter index.
Return Value
An InputStream object.
Exceptions
SQLServerException
See Also
getBinaryStream Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBinaryStream ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.io.InputStream getBinaryStream(java.lang.String paramName)
Parameters
paramName
A String that indicates the parameter name.
Return Value
An InputStream object.
Exceptions
SQLServerException
See Also
getBinaryStream Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBlob Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getBlob (int) Retrieves the value of the designated JDBC BLOB parameter
as a Blob object in the Java programming language given
the parameter index.
getBlob (java.lang.String) Retrieves the value of the designated JDBC BLOB parameter
as a Blob object in the Java programming language given
the parameter name.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBlob Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Blob getBlob(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
A Blob object.
Exceptions
SQLServerException
Remarks
This getBlob method is specified by the getBlob method in the java.sql.CallableStatement interface.
See Also
getBlob Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBlob Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Blob getBlob(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
A Blob object.
Exceptions
SQLServerException
Remarks
This getBlob method is specified by the getBlob method in the java.sql.CallableStatement interface.
See Also
getBlob Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBoolean Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBoolean Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getBoolean(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
A boolean value.
Exceptions
SQLServerException
Remarks
This getBoolean method is specified by the getBoolean method in the java.sql.CallableStatement interface.
See Also
getBoolean Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBoolean Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getBoolean(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
A boolean value.
Exceptions
SQLServerException
Remarks
This getBoolean method is specified by the getBoolean method in the java.sql.CallableStatement interface.
See Also
getBoolean Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getByte Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getByte Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public byte getByte(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
A byte value.
Exceptions
SQLServerException
Remarks
This getByte method is specified by the getByte method in the java.sql.CallableStatement interface.
See Also
getByte Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getByte Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public byte getByte(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
A byte value.
Exceptions
SQLServerException
Remarks
This getByte method is specified by the getByte method in the java.sql.CallableStatement interface.
See Also
getByte Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBytes Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
Remarks
In a previous version of the Microsoft JDBC Driver for SQL Server, you could use
SQLServerCallableStatement.getBytes to convert values between byte arrays and SQL Server data type date ,
time , datetime2 , or datetimeoffset . Now, using this method with those data types will cause an exception
indicating that the conversion is not supported.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getBytes Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public byte[] getBytes(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
An array of byte values.
Exceptions
SQLServerException
Remarks
In a previous version of Microsoft JDBC Driver for SQL Server, you could use
SQLServerCallableStatement.getBytes to convert values between byte arrays and SQL Server data type date ,
time , datetime2 , or datetimeoffset . Now, using this method with those data types will cause an exception
indicating that the conversion is not supported.
This getBytes method is specified by the getBytes method in the java.sql.CallableStatement interface.
See Also
getBytes Method (SQLServerCallableStatement)
SQLServerCallableStatement Class
getBytes Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public byte[] getBytes(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
An array of byte values.
Exceptions
SQLServerException
Remarks
In a previous version of Microsoft JDBC Driver for SQL Server, you could use
SQLServerCallableStatement.getBytes to convert values between byte arrays and SQL Server data type date ,
time , datetime2 , or datetimeoffset . Now, using this method with those data types will cause an exception
indicating that the conversion is not supported.
This getBytes method is specified by the getBytes method in the java.sql.CallableStatement interface.
See Also
getBytes Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getCharacterStream Method
(SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getCharacterStream (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.io.Reader getCharacterStream(int paramIndex)
Parameters
paramIndex
An int that indicates the parameter index.
Return Value
A Reader object.
Exceptions
SQLServerException
See Also
getCharacterStream Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getCharacterStream ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.io.Reader getCharacterStream(java.lang.String paramName)
Parameters
paramName
A String that indicates the parameter name.
Return Value
A Reader object.
Exceptions
SQLServerException
See Also
getCharacterStream Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getClob Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getClob (int) Retrieves the value of the designated JDBC BLOB parameter
as a Clob object in the Java programming language given
the parameter index.
getClob (java.lang.String) Retrieves the value of the designated JDBC BLOB parameter
as a Clob object in the Java programming language given
the parameter name.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getClob Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Clob getClob(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
A Clob object.
Exceptions
SQLServerException
Remarks
This getClob method is specified by the getClob method in the java.sql.CallableStatement interface.
See Also
getClob Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getClob Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Clob getClob(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
A Clob object.
Exceptions
SQLServerException
Remarks
This getClob method is specified by the getClob method in the java.sql.CallableStatement interface.
See Also
getClob Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getDate Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getDate Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Date getDate(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
A Date object.
Exceptions
SQLServerException
Remarks
This getDate method is specified by the getDate method in the java.sql.CallableStatement interface.
This method returns a valid date part of a SQL Server datetime or smalldatetime data type, with the time part
set to the Java time baseline of 00:00 (midnight).
See Also
getDate Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getDate Method (int, java.util.Calendar)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Date getDate(int index,
java.util.Calendar cal)
Parameters
index
An int that indicates the parameter index.
cal
A Calendar object.
Return Value
A Date object.
Exceptions
SQLServerException
Remarks
This getDate method is specified by the getDate method in the java.sql.CallableStatement interface.
This method returns a valid date part of a SQL Server datetime or smalldatetime data type, with the time part
set to the Java time baseline of 00:00 (midnight).
See Also
getDate Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getDate Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Date getDate(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
A Date object.
Exceptions
SQLServerException
Remarks
This getDate method is specified by the getDate method in the java.sql.CallableStatement interface.
This method returns a valid date part of a SQL Server datetime or smalldatetime data type, with the time part
set to the Java time baseline of 00:00 (midnight).
See Also
getDate Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getDate Method ( java.lang.String,
java.util.Calendar)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Date getDate(java.lang.String sCol,
java.util.Calendar cal)
Parameters
sCol
A String that contains the parameter name.
cal
A Calendar object.
Return Value
A Date object.
Exceptions
SQLServerException
Remarks
This getDate method is specified by the getDate method in the java.sql.CallableStatement interface.
This method returns a valid date part of a SQL Server datetime or smalldatetime data type, with the time part
set to the Java time baseline of 00:00 (midnight).
See Also
getDate Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getDateTimeOffset Method
(SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getDateTimeOffset Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public microsoft.sql.DateTimeOffset getDateTimeOffset(int index)
Parameters
index
The one-based parameter ordinal.
Return Value
A DateTimeOffset Class object.
Exceptions
SQLServerException
Remarks
You can set a DateTimeOffset Class parameter value with SQLServerCallableStatement.setDateTimeOffset.
See Also
getDateTimeOffset Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getDateTimeOffset Method (String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public microsoft.sql.DateTimeOffset getDateTimeOffset(String sCol)
Parameters
sCol
The name of a parameter.
Return Value
A DateTimeOffset Class object.
Exceptions
SQLServerException
Remarks
You can set a DateTimeOffset Class parameter value with SQLServerCallableStatement.setDateTimeOffset.
See Also
getDateTimeOffset Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getDouble Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getDouble Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public double getDouble(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
A double value.
Exceptions
SQLServerException
Remarks
This getDouble method is specified by the getDouble method in the java.sql.CallableStatement interface.
This method returns all number-based data types with Java double fidelity.
See Also
getDouble Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getDouble Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public double getDouble(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
A double value.
Exceptions
SQLServerException
Remarks
This getDouble method is specified by the getDouble method in the java.sql.CallableStatement interface.
This method returns all number-based data types with Java double fidelity.
See Also
getDouble Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getFloat Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getFloat Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public float getFloat(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
A float value.
Exceptions
SQLServerException
Remarks
This getFloat method is specified by the getFloat method in the java.sql.CallableStatement interface.
This method returns all number-based types with Java float fidelity.
See Also
getFloat Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getFloat Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public float getFloat(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
A float value.
Exceptions
SQLServerException
Remarks
This getFloat method is specified by the getFloat method in the java.sql.CallableStatement interface.
This method returns all number-based types with Java float fidelity.
See Also
getFloat Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getInt Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getInt Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getInt(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
An int value.
Exceptions
SQLServerException
Remarks
This getInt method is specified by the getInt method in the java.sql.CallableStatement interface.
This method is supported only on SQL Server data types that can safely return an integer value such as int,
smallint, tinyint, and bit. Using this method on any other data types will cause an exception to be thrown.
See Also
getInt Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getInt Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getInt(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
An int value.
Exceptions
SQLServerException
Remarks
This getInt method is specified by the getInt method in the java.sql.CallableStatement interface.
This method is supported only on SQL Server data types that can safely return an integer value such as int,
smallint, tinyint, and bit. Using this method on any other data types will cause an exception to be thrown.
See Also
getInt Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getLong Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getLong Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public long getLong(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
A long value.
Exceptions
SQLServerException
Remarks
This getLong method is specified by the getLong method in the java.sql.CallableStatement interface.
This method is supported only on SQL Server data types that can safely return an integer value such as bigint,
int, smallint, tinyint, and bit. Using this method on any other data types will cause an exception to be thrown.
See Also
getLong Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getLong Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public long getLong(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
A long value.
Exceptions
SQLServerException
Remarks
This getLong method is specified by the getLong method in the java.sql.CallableStatement interface.
This method is supported only on SQL Server data types that can safely return an integer value such as bigint ,
int , smallint , tinyint , and bit . Using this method on any other data types will cause an exception to be thrown.
See Also
getLong Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getNCharacterStream Method
(SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getNCharacterStream Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.io.Reader getNCharacterStream(int parameterIndex)
Parameters
parameterIndex
An int that indicates the parameter index.
Return Value
AReaderobject.
Exceptions
SQLServerException
Remarks
This method should be used when accessing NCHAR , NVARCHAR and LONGNVARCHAR parameters.
This getNCharacterStream method is specified by the getNCharacterStream method in the
java.sql.CallableStatement interface.
See Also
getNCharacterStream Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
getNCharacterStream Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.io.Reader getNCharacterStream(java.lang.String columnLabel)
Parameters
columnLabel
A String that contains the column label.
Return Value
AReaderobject.
Exceptions
SQLServerException
Remarks
This method should be used when accessing NCHAR , NVARCHAR and LONGNVARCHAR parameters.
This getNCharacterStream method is specified by the getNCharacterStream method in the
java.sql.CallableStatement interface.
See Also
getNCharacterStream Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
getNClob Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getNClob Method (int) Retrieves the value of the designated JDBC NCLOB
parameter as an NClob object in the Java programming
language.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getNClob Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.NClob getNClob(int parameterIndex)
Parameters
parameterIndex
An int that indicates the parameter index.
Return Value
ANClobobject.
Exceptions
SQLServerException
Remarks
This getNClob method is specified by the getNClob method in the java.sql.CallableStatement interface.
This method only supports retrieving NCHAR , NVARCHAR , NTEXT , and XML parameters. Calling these
methods on other data type parameters will cause an exception.
See Also
getNClob Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
getNClob Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.NClob getNClob(java.lang.String parameterName)
Parameters
parameterName
A String that contains the parameter name.
Return Value
ANClobobject.
Exceptions
SQLServerException
Remarks
This getNClob method is specified by the getNClob method in the java.sql.CallableStatement interface.
This method only supports retrieving NCHAR , NVARCHAR , NTEXT , and XML parameters. Calling these
methods on other data type parameters will cause an exception.
See Also
getNClob Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
getNString Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getNString Method (int) Retrieves the value of the designated NCHAR, NVARCHAR,
or LONGNVARCHAR parameter as a String in the Java
programming language.
getNString Method (java.lang.String) Retrieves the value of the designated NCHAR, NVARCHAR,
or LONGNVARCHAR parameter as a String in the Java
programming language.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getNString Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.lang.String getNString(int parameterIndex)
Parameters
parameterIndex
An int that indicates the parameter index.
Return Value
AStringobject.
Exceptions
SQLServerException
Remarks
This getNString method is specified by the getNString method in the java.sql.CallableStatement interface.
See Also
getNString Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
getNString Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.lang.String getNString(java.lang.String parameterName)
Parameters
parameterName
A String that contains the parameter name.
Return Value
AStringobject.
Exceptions
SQLServerException
Remarks
This getNString method is specified by the getNString method in the java.sql.CallableStatement interface.
See Also
getNString Method (SQLServerCallableStatement)
SQLServerCallableStatement Methods
getObject Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getObject (int, java.util.Map) Retrieves the value of the designated parameter as an object
in the Java programming language given the parameter
index, using the given Map object.
getObject (java.lang.String, java.util.Map) Retrieves the value of the designated parameter as an object
in the Java programming language given the parameter
name, using the given Map object.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getObject Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.Object getObject(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
An Object value.
Exceptions
SQLServerException
Remarks
This getObject method is specified by the getObject method in the java.sql.CallableStatement interface.
This method will return the value of the given column as a Java object. The type of the Java object will be the
default Java object type corresponding to the SQL type of the column, following the mapping for built-in types
that is specified in the JDBC specification. If the value is an SQL NULL, the driver returns a Java null.
This method can also be used to read database-specific abstract data types. In JDBC 2.0, the behavior of the
getObject method was extended to materialize data of SQL user-defined types. When a column contains a
structured or distinct value, the behavior of this method is as if it were a call to
getObject(columnIndex, this.getStatement().getConnection().getTypeMap()) .
See Also
getObject Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getObject Method (int, java.util.Map)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported by the Microsoft JDBC Driver for SQL Server. Using this method will always return
the default mapping.
Syntax
public java.lang.Object getObject(int index,
java.util.Map map)
Parameters
index
An int that indicates the parameter index.
map
A Map object.
Return Value
An Object value.
Exceptions
SQLServerException
Remarks
This getObject method is specified by the getObject method in the java.sql.CallableStatement interface.
This method will return the value of the given column as a Java object. The type of the Java object will be the
default Java object type corresponding to the SQL type of the column, following the mapping for built-in types
that is specified in the JDBC specification. If the value is an SQL NULL, the driver returns a Java null.
This method can also be used to read database-specific abstract data types. In the JDBC 2.0 API, the behavior of
the getObject method is extended to materialize data of SQL user-defined types. When a column contains a
structured or distinct value, the behavior of this method is as if it were a call to
getObject(columnIndex, this.getStatement().getConnection().getTypeMap()) .
See Also
getObject Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getObject Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.Object getObject(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
An Object value.
Exceptions
SQLServerException
Remarks
This getObject method is specified by the getObject method in the java.sql.CallableStatement interface.
This method will return the value of the given column as a Java object. The type of the Java object will be the
default Java object type corresponding to the SQL type of the column, following the mapping for built-in types
that is specified in the JDBC specification. If the value is an SQL NULL, the driver returns a Java null.
This method can also be used to read database-specific abstract data types. In the JDBC 2.0 API, the behavior of
the getObject method is extended to materialize data of SQL user-defined types. When a column contains a
structured or distinct value, the behavior of this method is as if it were a call to
getObject(columnIndex, this.getStatement().getConnection().getTypeMap()) .
See Also
getObject Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getObject Method ( java.lang.String, java.util.Map)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported by the Microsoft JDBC Driver for SQL Server. Using this method will always return
the default mapping.
Syntax
public java.lang.Object getObject(java.lang.String sCol,
java.util.Map m)
Parameters
sCol
A String that contains the parameter name.
m
A Map object.
Return Value
An Object value.
Exceptions
SQLServerException
Remarks
This getObject method is specified by the getObject method in the java.sql.CallableStatement interface.
This method will return the value of the given column as a Java object. The type of the Java object will be the
default Java object type corresponding to the SQL type of the column, following the mapping for built-in types
that is specified in the JDBC specification. If the value is an SQL NULL, the driver returns a Java null.
This method can also be used to read database-specific abstract data types. In the JDBC 2.0 API, the behavior of
the getObject method is extended to materialize data of SQL user-defined types. When a column contains a
structured or distinct value, the behavior of this method is as if it were a call to
getObject(columnIndex, this.getStatement().getConnection().getTypeMap()) .
See Also
getObject Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getRef Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getRef Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Ref getRef(int i)
Parameters
i
An int that indicates the parameter index.
Return Value
A Ref object.
Exceptions
SQLServerException
Remarks
This getRef method is specified by the getRef method in the java.sql.CallableStatement interface.
See Also
getRef Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getRef Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Ref getRef(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
A Ref object.
Exceptions
SQLServerException
Remarks
This getRef method is specified by the getRef method in the java.sql.CallableStatement interface.
See Also
getRef Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getShort Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getShort Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public short getShort(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
A shor t value.
Exceptions
SQLServerException
Remarks
This getShort method is specified by the getShort method in the java.sql.CallableStatement interface.
This method is supported only on SQL Server data types that can safely return an integer value such as
smallint , tinyint , and bit . Using this method on any other data types will cause an exception to be thrown.
See Also
getShort Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getShort Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public short getShort(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
A shor t value.
Exceptions
SQLServerException
Remarks
This getShort method is specified by the getShort method in the java.sql.CallableStatement interface.
This method is only supported on SQL Server data types that can safely return an integer value such as smallint,
tinyint, and bit. Using this method on any other data types will cause an exception to be thrown.
See Also
getShort Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getSQLXML Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getSQLXML Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.sql.SQLXML getSQLXML(int parameterIndex)
Parameters
parameterIndex
An int that indicates the parameter index.
Return Value
ASQLXMLobject.
Exceptions
SQLServerException
Remarks
This getSQLXML method is specified by the getSQLXML method in the java.sql.CallableStatement interface.
See Also
getSQLXML Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
getSQLXML Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.sql.SQLXML getSQLXML(java.lang.String parameterName)
Parameters
parameterName
A String that indicates the parameter name.
Return Value
ASQLXMLobject.
Exceptions
SQLServerException
Remarks
This getSQLXML method is specified by the getSQLXML method in the java.sql.CallableStatement interface.
See Also
getSQLXML Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
getString Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getString Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getString(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
A String value.
Exceptions
SQLServerException
Remarks
This getString method is specified by the getString method in the java.sql.CallableStatement interface.
All columns in SQL Server can be returned as a string. This means that a string representation of all number-
based and character-based types, and a hex-string representation of binary columns such as binary, varbinary,
varbinary(max), image, timestamp, and uniqueidentifier, can be returned.
Location-sensitive types such as money, smallmoney, datetime, smalldatetime, float, real, decimal, and numeric
will return the canonical toString() format for the underlying value of the type.
User-defined types are returned as hexadecimal string values.
See Also
getString Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getString Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getString(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
A String value.
Exceptions
SQLServerException
Remarks
This getString method is specified by the getString method in the java.sql.CallableStatement interface.
All columns in SQL Server can be returned as a string. This means that a string representation of all number-
based and character-based types, and a hex-string representation of binary columns such as binary, varbinary,
varbinary(max), image, timestamp, and uniqueidentifier, can be returned.
Location-sensitive types such as money, smallmoney, datetime, smalldatetime, float, real, decimal, and numeric
will return the canonical toString() format for the underlying value of the type.
User-defined types are returned as hexadecimal string values.
See Also
getString Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getTime Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getTime Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Time getTime(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
A Time object.
Exceptions
SQLServerException
Remarks
This getTime method is specified by the getTime method in the java.sql.CallableStatement interface.
See the chart titled "Getter Method Conversions" in Understanding Data Type Conversions to see which SQL
Server data types can be retrieved with this method.
See Also
getTime Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getTime Method (int, java.util.Calendar)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Time getTime(int index,
java.util.Calendar cal)
Parameters
index
An int that indicates the parameter index.
cal
A Calendar object.
Return Value
A Time object.
Exceptions
SQLServerException
Remarks
This getTime method is specified by the getTime method in the java.sql.CallableStatement interface.
See the chart titled "Getter Method Conversions" in Understanding Data Type Conversions to see which SQL
Server data types can be retrieved with this method.
See Also
getTime Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getTime Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Time getTime(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
A Time object.
Exceptions
SQLServerException
Remarks
This getTime method is specified by the getTime method in the java.sql.CallableStatement interface.
See the chart titled "Getter Method Conversions" in Understanding Data Type Conversions to see which SQL
Server data types can be retrieved with this method.
See Also
getTime Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getTime Method ( java.lang.String,
java.util.Calendar)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Time getTime(java.lang.String sCol,
java.util.Calendar cal)
Parameters
sCol
A String that contains the parameter name.
cal
A Calendar object.
Return Value
A Time object.
Exceptions
SQLServerException
Remarks
This getTime method is specified by the getTime method in the java.sql.CallableStatement interface.
See the chart titled "Getter Method Conversions" in Understanding Data Type Conversions to see which SQL
Server data types can be retrieved with this method.
See Also
getTime Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getTimestamp Method
(SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getTimestamp Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Timestamp getTimestamp(int index)
Parameters
index
An int that indicates the parameter index.
Return Value
A Timestamp object.
Exceptions
SQLServerException
Remarks
This getTimestamp method is specified by the getTimestamp method in the java.sql.CallableStatement interface.
This method returns values only from SQL Server datetime and smalldatetime columns.
See Also
getTimestamp Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getTimestamp Method (int, java.util.Calendar)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Timestamp getTimestamp(int index,
java.util.Calendar cal)
Parameters
index
An int that indicates the parameter index.
cal
A Calendar object.
Return Value
A Timestamp object.
Exceptions
SQLServerException
Remarks
This getTimestamp method is specified by the getTimestamp method in the java.sql.CallableStatement interface.
This method returns values only from SQL Server datetime and smalldatetime columns.
See Also
getTimestamp Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getTimestamp Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Timestamp getTimestamp(java.lang.String sCol)
Parameters
sCol
A String that contains the parameter name.
Return Value
A Timestamp object.
Exceptions
SQLServerException
Remarks
This getTimestamp method is specified by the getTimestamp method in the java.sql.CallableStatement interface.
This method returns values only from SQL Server datetime and smalldatetime columns.
See Also
getTimestamp Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getTimestamp Method ( java.lang.String,
java.util.Calendar)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Timestamp getTimestamp(java.lang.String name,
java.util.Calendar cal)
Parameters
name
A String that contains the parameter name.
cal
A Calendar object.
Return Value
A Timestamp object.
Exceptions
SQLServerException
Remarks
This getTimestamp method is specified by the getTimestamp method in the java.sql.CallableStatement interface.
This method returns values only from SQL Server datetime and smalldatetime columns.
See Also
getTimestamp Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getURL Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getURL Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.net.URL getURL(int n)
Parameters
n
An int that indicates the parameter index.
Return Value
A URL object.
Exceptions
SQLServerException
Remarks
This getURL method is specified by the getURL method in the java.sql.CallableStatement interface.
See Also
getURL Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
getURL Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.net.URL getURL(java.lang.String s)
Parameters
s
A String that contains the parameter name.
Return Value
A URL object.
Exceptions
SQLServerException
Remarks
This getURL method is specified by the getURL method in the java.sql.CallableStatement interface.
See Also
getURL Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
isWrapperFor Method
(SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isWrapperFor(Class iface)
Parameters
iface
A class defining an interface.
Return Value
true if this object implements the interface or wraps an object that implements the interface. Otherwise, false .
Exceptions
SQLServerException
Remarks
The isWrapperFor method and the unwrap method are defined by the java.sql.Wrapper interface, which is
introduced in JDBC 4.0.
If this method returns true , calling unwrap with the same argument will succeed.
For more information, see Wrappers and Interfaces.
See Also
unwrap Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
registerOutParameter Method
(SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
registerOutParameter (int, int) Registers the OUT parameter in the specified ordinal position
to the given JDBC type.
registerOutParameter (int, int, int) Registers the OUT parameter in the specified ordinal position
to the given JDBC type and scale.
registerOutParameter (int, int, java.lang.String) Registers the OUT parameter in the specified ordinal position
to the given JDBC type and type name.
registerOutParameter (java.lang.String, int) Registers the OUT parameter with the specified name to the
given JDBC type.
registerOutParameter (java.lang.String, int, int) Registers the OUT parameter with the specified name to the
given JDBC type and scale.
registerOutParameter (java.lang.String, int, java.lang.String) Registers the OUT parameter with the specified name to the
given JDBC type and type name.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
registerOutParameter Method (int, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void registerOutParameter(int index,
int sqlType)
Parameters
index
An int that indicates the ordinal position of the parameter.
sqlType
A JDBC type code as defined in java.sql.Types.
Exceptions
SQLServerException
Remarks
This registerOutParameter method is specified by the registerOutParameter method in the
java.sql.CallableStatement interface.
Beginning with SQL Server JDBC Driver 3.0, when sqlType is of type java.sql.Types.TIME, the behavior of this
method is modified by the sendTimeAsDatetime connection property (Setting the Connection Properties) and
SQLServerDataSource.setSendTimeAsDatetime.
For more information, see Configuring How java.sql.Time Values are Sent to the Server.
See Also
registerOutParameter Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
registerOutParameter Method (int, int, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void registerOutParameter(int index,
int sqlType,
int scale)
Parameters
index
An int that indicates the ordinal position of the parameter.
sqlType
A JDBC type code as defined in java.sql.Types.
scale
An int that indicates the number of digits to be placed to the right of the decimal point.
Exceptions
SQLServerException
Remarks
This registerOutParameter method is specified by the registerOutParameter method in the
java.sql.CallableStatement interface.
Beginning with SQL Server JDBC Driver 3.0, when sqlType is of type java.sql.Types.TIME, the behavior of this
method is modified by the sendTimeAsDatetime connection property (Setting the Connection Properties) and
SQLServerDataSource.setSendTimeAsDatetime.
For more information, see Configuring How java.sql.Time Values are Sent to the Server.
See Also
registerOutParameter Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
registerOutParameter Method (int, int,
java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void registerOutParameter(int index,
int sqlType,
java.lang.String typeName)
Parameters
index
An int that indicates the ordinal position of the parameter.
sqlType
A JDBC type code as defined in java.sql.Types.
typeName
A String that contains the fully qualified SQL type name.
Exceptions
SQLServerException
Remarks
This registerOutParameter method is specified by the registerOutParameter method in the
java.sql.CallableStatement interface.
Beginning with SQL Server JDBC Driver 3.0, when sqlType is of type java.sql.Types.TIME, the behavior of this
method is modified by the sendTimeAsDatetime connection property (Setting the Connection Properties) and
SQLServerDataSource.setSendTimeAsDatetime.
For more information, see Configuring How java.sql.Time Values are Sent to the Server.
See Also
registerOutParameter Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
registerOutParameter Method ( java.lang.String, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void registerOutParameter(java.lang.String s,
int n)
Parameters
s
A String that contains the parameter name.
n
A JDBC type code as defined in java.sql.Types.
Exceptions
SQLServerException
Remarks
This registerOutParameter method is specified by the registerOutParameter method in the
java.sql.CallableStatement interface.
See Also
registerOutParameter Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
registerOutParameter Method ( java.lang.String, int,
int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void registerOutParameter(java.lang.String s,
int n,
int n1)
Parameters
s
A String that contains the parameter name.
sqlType
A JDBC type code as defined in java.sql.Types.
scale
An int that indicates the number of digits to be placed to the right of the decimal point.
Exceptions
SQLServerException
Remarks
This registerOutParameter method is specified by the registerOutParameter method in the
java.sql.CallableStatement interface.
See Also
registerOutParameter Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
registerOutParameter Method ( java.lang.String, int,
java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void registerOutParameter(java.lang.String s,
int n,
java.lang.String s1)
Parameters
s
A String that contains the parameter name.
n
A JDBC type code as defined in java.sql.Types.
s1
A String that contains the fully qualified SQL type name.
Exceptions
SQLServerException
Remarks
This registerOutParameter method is specified by the registerOutParameter method in the
java.sql.CallableStatement interface.
See Also
registerOutParameter Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setAsciiStream (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setAsciiStream Method (java.lang.String, java.io.InputStream) Sets the designated parameter to the specified input stream.
setAsciiStream Method (java.lang.String, java.io.InputStream, Sets the designated parameter to the specified input stream,
int) which will have the specified number of bytes.
setAsciiStream Method (java.lang.String, java.io.InputStream, Sets the designated parameter number to specified input
long) stream, which will have the specified number of bytes.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setAsciiStream Method ( java.lang.String,
java.io.InputStream)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setAsciiStream(java.lang.String parameterName,
java.io.InputStream x)
Parameters
parameterName
A String that contains the parameter name.
x
An InputStream object.
Exceptions
SQLServerException
Remarks
This setAsciiStream method is specified by the setAsciiStream method in the java.sql.PreparedStatement
interface.
See Also
setAsciiStream (SQLServerCallableStatement)
SQLServerCallableStatement Members
setAsciiStream Method ( java.lang.String,
java.io.InputStream, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setAsciiStream(java.lang.String parameterName,
java.io.InputStream value,
int length)
Parameters
parameterName
A String that contains the parameter name.
value
An InputStream object.
length
An int that indicates the length in number of bytes.
Exceptions
SQLServerException
Remarks
This setAsciiStream method is specified by the setAsciiStream method in the java.sql.CallableStatement interface.
If the length of the stream is different than that specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
setAsciiStream Method ( java.lang.String, java.io.InputStream) when the application wants to update the column
from a stream whose length is unknown.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setAsciiStream Method ( java.lang.String,
java.io.InputStream, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setAsciiStream(java.lang.String parameterName,
java.io.InputStream x,
long length)
Parameters
parameterName
A String that contains the parameter name.
x
An InputStream object.
length
A long that indicates the number of bytes.
Exceptions
SQLServerException
Remarks
This setAsciiStream method is specified by the setAsciiStream method in the java.sql.PreparedStatement
interface.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
setAsciiStream Method ( java.lang.String, java.io.InputStream) when the application wants to update the column
from a stream whose length is unknown.
See Also
setAsciiStream (SQLServerCallableStatement)
SQLServerCallableStatement Members
setBigDecimal Method
(SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setBigDecimal(java.lang.String sCol,
java.math.BigDecimal bd)
Parameters
sCol
A String that contains the parameter name.
bd
A BigDecimal object.
Exceptions
SQLServerException
Remarks
This setBigDecimal method is specified by the setBigDecimal method in the java.sql.CallableStatement interface.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setBinaryStream (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setBinaryStream Method (java.lang.String, Sets the designated parameter to the specified input stream.
java.io.InputStream)
setBinaryStream Method (java.lang.String, Sets the designated parameter to the specified input stream,
java.io.InputStream, int) which will have the specified number of bytes.
setBinaryStream Method (java.lang.String, Sets the designated parameter to the specified input stream,
java.io.InputStream, long) which will have the specified number of bytes.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setBinaryStream Method ( java.lang.String,
java.io.InputStream)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setBinaryStream(java.lang.String parameterName,
java.io.InputStream x)
Parameters
parameterName
A String that contains the name of the parameter.
x
An InputStream object.
Exceptions
SQLServerException
Remarks
This setBinaryStream method is specified by the setBinaryStream method in the java.sql.CallableStatement
interface.
See Also
setBinaryStream (SQLServerCallableStatement)
SQLServerCallableStatement Members
setBinaryStream Method ( java.lang.String,
java.io.InputStream, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setBinaryStream(java.lang.String parameterName,
java.io.InputStream value,
int length)
Parameters
parameterName
A String that contains the name of the parameter.
value
An InputStream object.
length
An int that indicates the length in number of bytes.
Exceptions
SQLServerException
Remarks
This setBinaryStream method is specified by the setBinaryStream method in the java.sql.CallableStatement
interface.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
setBinaryStream Method ( java.lang.String, java.io.InputStream) when the application wants to update the
column from a stream whose length is unknown.
See Also
setBinaryStream (SQLServerCallableStatement)
SQLServerCallableStatement Members
setBinaryStream Method ( java.lang.String,
java.io.InputStream, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setBinaryStream(java.lang.String parameterName,
java.io.InputStream x,
long length)
Parameters
parameterName
A String that contains the name of the parameter.
x
An InputStream object.
length
A long that indicates the length in the number of bytes.
Exceptions
SQLServerException
Remarks
This setBinaryStream method is specified by the setBinaryStream method in the java.sql.CallableStatement
interface.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
setBinaryStream Method ( java.lang.String, java.io.InputStream) when the application wants to update the
column from a stream whose length is unknown.
See Also
setBinaryStream (SQLServerCallableStatement)
SQLServerCallableStatement Members
setBoolean Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setBoolean(java.lang.String sCol,
boolean b)
Parameters
sCol
A String that contains the parameter name.
b
A boolean value, either true or false .
Exceptions
SQLServerException
Remarks
This setBoolean method is specified by the setBoolean method in the java.sql.CallableStatement interface.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setByte Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setByte(java.lang.String sCol,
byte b)
Parameters
sCol
A String that contains the parameter name.
b
A byte value.
Exceptions
SQLServerException
Remarks
This setByte method is specified by the setByte method in the java.sql.CallableStatement interface.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setBytes Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setBytes(java.lang.String sCol,
byte[] b)
Parameters
sCol
A String that contains the parameter name.
b
An array of byte values.
Exceptions
SQLServerException
Remarks
In a previous version of the driver, you could use SQLServerCallableStatement.setBytes to convert values
between byte arrays and SQL Server data type date , time , datetime2 , or datetimeoffset . Now, using this
method with those data types will cause an exception indicating that the conversion is not supported.
This setBytes method is specified by the setBytes method in the java.sql.CallableStatement interface.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setCharacterStream Method
(SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setCharacterStream Method (java.lang.String, java.io.Reader) Sets the designated parameter to the specified java.io.Reader
object.
setCharacterStream Method (java.lang.String, java.io.Reader, Sets the designated parameter to the specified java.io.Reader
int) object, which is the specified number of characters long.
setCharacterStream Method (java.lang.String, java.io.Reader, Sets the designated parameter to the specified java.io.Reader
long) object, which is the specified number of characters long.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setCharacterStream Method ( java.lang.String,
java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setCharacterStream(java.lang.String parameterName,
java.io.Reader reader)
Parameters
parameterName
A String that contains the parameter name.
reader
A Reader object that contains the Unicode data.
Exceptions
SQLServerException
Remarks
This setCharacterStream method is specified by the setCharacterStream method in the
java.sql.CallableStatement interface.
See Also
setCharacterStream Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
setCharacterStream Method ( java.lang.String,
java.io.Reader, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setCharacterStream(java.lang.String parameterName,
java.io.Reader value,
int length)
Parameters
parameterName
A String that contains the name of the parameter.
value
A Reader object that contains the Unicode data.
length
An int that indicates the length in number of characters.
Exceptions
SQLServerException
Remarks
This setCharacterStream method is specified by the setCharacterStream method in the
java.sql.CallableStatement interface.
If the length of the stream is different than that specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
setCharacterStream Method ( java.lang.String, java.io.Reader) when the application wants to update the column
from a stream whose length is unknown.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setCharacterStream Method ( java.lang.String,
java.io.Reader, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setCharacterStream(java.lang.String parameterName
java.io.Reader reader,
long length)
Parameters
parameterName
A String that contains the parameter name.
reader
A Reader object that contains the Unicode data.
length
A long that indicates the number of characters in the stream.
Exceptions
SQLServerException
Remarks
This setCharacterStream method is specified by the setCharacterStream method in the
java.sql.CallableStatement interface.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
setCharacterStream Method ( java.lang.String, java.io.Reader) when the application wants to update the column
from a stream whose length is unknown.
See Also
setCharacterStream Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
setClob Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setClob Method (java.lang.String, java.sql.Clob) Sets the designated parameter to the specified Clob object.
setClob Method (java.lang.String, java.io.Reader) Sets the designated parameter to the specified Reader
object.
setClob Method (java.lang.String, java.io.Reader, long) Sets the designated parameter to the specified Reader
object, which is the specified number of characters long.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setClob Method ( java.lang.String, java.sql.Clob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setClob(java.lang.String parameterName,
java.sql.Clob x)
Parameters
parameterName
A String that contains the parameter name.
x
A Clob object.
Exceptions
SQLServerException
Remarks
This setClob method is specified by the setClob method in the java.sql.CallableStatement interface.
See Also
setClob Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
setClob Method ( java.lang.String, java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setClob(java.lang.String parameterName,
java.io.Reader reader)
Parameters
parameterName
A String that contains the parameter name.
reader
A Reader object.
Exceptions
SQLServerException
Remarks
This setClob method is specified by the setClob method in the java.sql.CallableStatement interface.
See Also
setClob Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
setClob Method ( java.lang.String, java.io.Reader,
long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setClob(java.lang.String parameterName,
java.io.Reader value,
long length)
Parameters
parameterName
A String that contains the parameter name.
value
A Reader object.
length
A long that indicates the number of characters in the stream.
Exceptions
SQLServerException
Remarks
This setClob method is specified by the setClob method in the java.sql.CallableStatement interface.
See Also
setClob Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
setDate Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setDate (java.lang.String, java.sql.Date) Sets the designated parameter to the given date value.
setDate (java.lang.String, java.sql.Date, java.util.Calendar) Sets the designated parameter to the given date and
calendar values.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setDate Method ( java.lang.String, java.sql.Date)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setDate(java.lang.String sCol,
java.sql.Date d)
Parameters
sCol
A String that contains the parameter name.
d
A Date object.
Exceptions
SQLServerException
Remarks
This setDate method is specified by the setDate method in the java.sql.CallableStatement interface.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setDate Method ( java.lang.String, java.sql.Date,
java.util.Calendar)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setDate(java.lang.String sCol,
java.sql.Date x,
java.util.Calendar c)
Parameters
n
An int that indicates the parameter number.
x
A Date object.
c
A Calendar object.
Exceptions
SQLServerException
Remarks
This setDate method is specified by the setDate method in the java.sql.CallableStatement interface.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setDateTimeOffset Method
(SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setDateTimeOffset(String sCol, microsoft.sql.DateTimeOffset t)
Parameters
sCol
The name of a column.
t
The DateTimeOffset Class object.
Exceptions
SQLServerException
Remarks
You can retrieve a DateTimeOffset Class value with SQLServerCallableStatement.getDateTimeOffset.
setDateTimeOffset takes the ordinal of the column.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setDouble Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setDouble(java.lang.String sCol,
double d)
Parameters
sCol
A String that contains the parameter name.
d
A double value.
Exceptions
SQLServerException
Remarks
This setDouble method is specified by the setDouble method in the java.sql.CallableStatement interface.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setFloat Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setFloat(java.lang.String sCol,
float f)
Parameters
sCol
A String that contains the parameter name.
f
A float value.
Exceptions
SQLServerException
Remarks
This setFloat method is specified by the setFloat method in the java.sql.CallableStatement interface.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setInt Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setInt(java.lang.String sCol,
int i)
Parameters
sCol
A String that contains the parameter name.
i
An int value.
Exceptions
SQLServerException
Remarks
This setInt method is specified by the setInt method in the java.sql.CallableStatement interface.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setLong Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setLong(java.lang.String sCol,
long l)
Parameters
sCol
A String that contains the parameter name.
l
A long value.
Exceptions
SQLServerException
Remarks
This setLong method is specified by the setLong method in the java.sql.CallableStatement interface.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setNCharacterStream Method
(SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setNCharacterStream Method (java.lang.String, Sets the designated parameter to the specified Reader
java.io.Reader) object.
setNCharacterStream Method (java.lang.String, Sets the designated parameter to the specified Reader
java.io.Reader, long) object, which is the specified number of characters long.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setNCharacterStream Method ( java.lang.String,
java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setNCharacterStream(java.lang.String parameterName,
java.io.Reader value)
Parameters
parameterName
A String that indicates the parameter name.
value
A Reader object.
Exceptions
SQLServerException
Remarks
This setNCharacterStream method is specified by the setNCharacterStream method in the
java.sql.CallableStatement interface.
This method should be used for NCHAR , NVARCHAR , NTEXT , and XML data types.
See Also
setNCharacterStream Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
setNCharacterStream Method ( java.lang.String,
java.io.Reader, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setNCharacterStream(java.lang.String parameterName,
java.io.Reader value,
long length)
Parameters
parameterName
A String that indicates the parameter name.
value
A Reader object.
length
A long that indicates the number of characters in the stream.
Exceptions
SQLServerException
Remarks
This setNCharacterStream method is specified by the setNCharacterStream method in the
java.sql.CallableStatement interface.
This method should be used for NCHAR , NVARCHAR , NTEXT , and XML data types.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
setNCharacterStream Method ( java.lang.String, java.io.Reader) when the application wants to update the column
from a stream whose length is unknown.
See Also
setNCharacterStream Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
setNClob Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setNClob Method (java.lang.String, java.sql.NClob) Sets the designated parameter to the specified NClob object.
setNClob Method (java.lang.String, java.io.Reader) Sets the designated parameter to the specified Reader
object.
setNClob Method (java.lang.String, java.io.Reader, long) Sets the designated parameter to the specified Reader
object, which is the specified number of characters long.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setNClob Method ( java.lang.String, java.sql.NClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setNClob(java.lang.String parameterName,
java.sql.NClob value)
Parameters
parameterName
A String that contains the parameter name.
value
A NClob object.
Exceptions
SQLServerException
Remarks
This method should be used for NCHAR , NVARCHAR , NTEXT , and XML parameter data types.
This setNClob method is specified by the setNClob method in the java.sql.CallableStatement interface.
See Also
setNClob Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
setNClob Method ( java.lang.String, java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setNClob(java.lang.String parameterName,
java.io.Reader reader)
Parameters
parameterName
A String that contains the parameter name.
reader
A Reader object.
Exceptions
SQLServerException
Remarks
This method should be used for NCHAR , NVARCHAR , NTEXT , and XML parameter data types.
This setNClob method is specified by the setNClob method in the java.sql.CallableStatement interface.
See Also
setNClob Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
setNClob Method ( java.lang.String, java.io.Reader,
long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setNClob(java.lang.String parameterName,
java.io.Reader reader,
long length)
Parameters
parameterName
A String that contains the parameter name.
reader
A Reader object.
length
A long that indicates the number of characters in the stream.
Exceptions
SQLServerException
Remarks
This method should be used for NCHAR , NVARCHAR , NTEXT , and XML parameter data types.
This setNClob method is specified by the setNClob method in the java.sql.CallableStatement interface.
See Also
setNClob Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
setNull Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setNull (java.lang.String, int) Sets the designated parameter to a null value, given the type
of parameter to set.
setNull (java.lang.String, int, java.lang.String) Sets the designated parameter to a null value, given the type
and name of the parameter to set.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setNull Method ( java.lang.String, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setNull(java.lang.String sCol,
int nType)
Parameters
sCol
A String that contains the parameter name.
nType
A JDBC type code that is defined by java.sql.Types.
Exceptions
SQLServerException
Remarks
This setNull method is specified by the setNull method in the java.sql.CallableStatement interface.
See Also
setNull Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setNull Method ( java.lang.String, int,
java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setNull(java.lang.String sCol,
int nType,
java.lang.String sTypeName)
Parameters
sCol
A String contthat contains aining the parameter name.
nType
A JDBC type code that is defined by java.sql.Types.
sTypeName
A String that indicates the fully qualified name of the parameter that is being set.
Exceptions
SQLServerException
Remarks
This setNull method is specified by the setNull method in the java.sql.CallableStatement interface.
See Also
setNull Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setNString Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setNString(java.lang.String parameterName, java.lang.String value)
Parameters
parameterName
A String that indicates the parameter name.
value
A String object.
Exceptions
SQLServerException
Remarks
This method should be used for NCHAR , NVARCHAR , NTEXT , and XML data types.
This setNString method is specified by the setNString method in the java.sql.CallableStatement interface.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setObject Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setObject (java.lang.String, java.lang.Object) Sets the value of the designated parameter using the given
object.
setObject (java.lang.String, java.lang.Object, int) Sets the value of the designated parameter using the given
object and target type.
setObject (java.lang.String, java.lang.Object, int, int) Sets the value of the designated parameter using the given
object, target type, and scale.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setObject Method ( java.lang.String,
java.lang.Object)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setObject(java.lang.String sCol,
java.lang.Object o)
Parameters
sCol
A String that contains the parameter name.
o
An Object value.
Exceptions
SQLServerException
Remarks
This setObject method is specified by the setObject method in the java.sql.CallableStatement interface.
This method converts the specified parameter to a CHAR if a NULL is given, before sending it to the database. If
the parameter is declared as a binary, varbinary or image SQL type, then an exception will be thrown when the
statement is executed.
Beginning with SQL Server JDBC Driver 3.0, the behavior of this method is modified by the
sendTimeAsDatetime connection property (Setting the Connection Properties) and
SQLServerDataSource.setSendTimeAsDatetime.
For more information, see Configuring How java.sql.Time Values are Sent to the Server.
See Also
setObject Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setObject Method ( java.lang.String,
java.lang.Object, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setObject(java.lang.String sCol,
java.lang.Object o,
int n)
Parameters
sCol
A String that contains the parameter name.
o
An Object value.
n
An int that indicates the target type as defined in java.sql.Types.
Exceptions
SQLServerException
Remarks
This setObject method is specified by the setObject method in the java.sql.CallableStatement interface.
Beginning with SQL Server JDBC Driver 3.0, the behavior of this method is modified by the
sendTimeAsDatetime connection property (Setting the Connection Properties) and
SQLServerDataSource.setSendTimeAsDatetime.
For more information, see Configuring How java.sql.Time Values are Sent to the Server.
See Also
setObject Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setObject Method ( java.lang.String,
java.lang.Object, int, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setObject(java.lang.String sCol,
java.lang.Object o,
int n,
int m)
Parameters
sCol
A String that contains the parameter name.
o
An Object value.
n
An int that indicates the target type as defined in java.sql.Types.
m
An int that indicates the number of digits to the right of the decimal point. This parameter is ignored for all
types except for NUMERIC and DECIMAL.
Exceptions
SQLServerException
Remarks
This setObject method is specified by the setObject method in the java.sql.CallableStatement interface.
Beginning with SQL Server JDBC Driver 3.0, the behavior of this method is modified by the
sendTimeAsDatetime connection property (Setting the Connection Properties) and
SQLServerDataSource.setSendTimeAsDatetime.
For more information, see Configuring How java.sql.Time Values are Sent to the Server.
See Also
setObject Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setShort Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setShort(java.lang.String sCol,
short s)
Parameters
sCol
A String that contains the parameter name.
s
A shor t value.
Exceptions
SQLServerException
Remarks
This setShort method is specified by the setShort method in the java.sql.CallableStatement interface.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setSQLXML Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setSQLXML(java.lang.String parameterName,
java.sql.SQLXML xmlObject)
Parameters
parameterName
An String that indicates the parameter name.
xmlObject
A SQLXML object that contains the parameter value.
Exceptions
SQLServerException
Remarks
This setSQLXML method is specified by the setSQLXML method in the java.sql.CallableStatement interface.
See Also
SQLServerCallableStatement Members
setString Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setString(java.lang.String sCol,
java.lang.String s)
Parameters
sCol
A String that contains the name of the parameter.
s
A String value.
Exceptions
SQLServerException
Remarks
This setString method is specified by the setString method in the java.sql.CallableStatement interface.
String to binary conversions are performed only when Microsoft JDBC Driver for SQL Server knows the
destination type is binary. In cases where the JDBC driver does not know the underlying type, it will pass the
String literal and return a server error if the server cannot perform the conversion.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setTime Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setTime (java.lang.String, java.sql.Time) Sets the designated parameter to the given time value.
setTime (java.lang.String, java.sql.Time, java.util.Calendar) Sets the designated parameter to the given time and
calendar values.
See Also
SQLServerCallableStatement Methods
SQLServerCallableStatement Class
setTime Method ( java.lang.String, java.sql.Time)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setTime(java.lang.String sCol,
java.sql.Time t)
Parameters
sCol
A String that contains the parameter name.
t
A Time object.
Exceptions
SQLServerException
Remarks
This setTime method is specified by the setTime method in the java.sql.CallableStatement interface.
Beginning with SQL Server JDBC Driver 3.0, the behavior of this method is modified by the
sendTimeAsDatetime connection property (Setting the Connection Properties) and
SQLServerDataSource.setSendTimeAsDatetime.
For more information, see Configuring How java.sql.Time Values are Sent to the Server.
See Also
setTime Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setTime Method ( java.lang.String, java.sql.Time,
java.util.Calendar)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setTime(java.lang.String sCol,
java.sql.Time x,
java.util.Calendar c)
Parameters
sCol
A String that contains the parameter name.
x
A Time object.
c
A Calendar object.
Exceptions
SQLServerException
Remarks
This setTime method is specified by the setTime method in the java.sql.CallableStatement interface.
Beginning with SQL Server JDBC Driver 3.0, the behavior of this method is modified by the
sendTimeAsDatetime connection property (Setting the Connection Properties) and
SQLServerDataSource.setSendTimeAsDatetime.
For more information, see Configuring How java.sql.Time Values are Sent to the Server.
See Also
setTime Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setTimestamp Method
(SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setTimestamp (java.lang.String, java.sql.Timestamp) Sets the designated parameter to the given timestamp
value.
setTimestamp (java.lang.String, java.sql.Timestamp, Sets the designated parameter to the given timestamp and
java.util.Calendar) calendar values.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setTimestamp Method ( java.lang.String,
java.sql.Timestamp)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setTimestamp(java.lang.String sCol,
java.sql.Timestamp t)
Parameters
sCol
A String that contains the parameter name.
t
A Timestamp object.
Exceptions
SQLServerException
Remarks
This setTimestamp method is specified by the setTimestamp method in the java.sql.CallableStatement interface.
See Also
setTimestamp Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setTimestamp Method ( java.lang.String,
java.sql.Timestamp, java.util.Calendar)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setTimestamp(java.lang.String sCol,
java.sql.Timestamp x,
java.util.Calendar c)
Parameters
sCol
A String that contains the parameter name.
x
A Timestamp object.
c
A Calendar object.
Exceptions
SQLServerException
Remarks
This setTimestamp method is specified by the setTimestamp method in the java.sql.CallableStatement interface.
See Also
setTimestamp Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
setURL Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setURL(java.lang.String sCol,
java.net.URL u)
Parameters
sCol
A String that contains the name of the parameter.
u
A URL object.
Exceptions
SQLServerException
Remarks
This setURL method is specified by the setURL method in the java.sql.CallableStatement interface.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
wasNull Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean wasNull()
Return Value
true if the last parameter read was null. Otherwise, false .
Exceptions
SQLServerException
Remarks
This wasNull method is specified by the wasNull method in the java.sql.CallableStatement interface.
See Also
SQLServerCallableStatement Members
SQLServerCallableStatement Class
unwrap Method (SQLServerCallableStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public <T> T unwrap(Class<T> iface)
Parameters
iface
A class of type T defining an interface.
Return Value
An object that implements the specified interface.
Exceptions
SQLServerException
Remarks
The unwrap method is defined by the java.sql.Wrapper interface, which is introduced in the JDBC 4.0 Spec.
Applications might need to access extensions to the JDBC API that are specific to the Microsoft JDBC Driver for
SQL Server. The unwrap method supports unwrapping to public classes that this object extends, if the classes
expose vendor extensions.
SQLServerCallableStatement implements ISQLServerPreparedStatement, which is extended from the
ISQLServerStatement. When this method is called, the object unwraps to the following classes:
SQLServerStatement, SQLServerPreparedStatement, and SQLServerCallableStatement.
For more information, see Wrappers and Interfaces.
The following code example demonstrates how to use the isWrapperFor and unwrap methods to check the
driver extensions and invoke the vendor-specific methods, such as setResponseBuffering and
getResponseBuffering.
public static void executeStoredProcedure(Connection con) {
try {
CallableStatement cstmt =
con.prepareCall("{call dbo.stored_proc_name(?, ?)}");
if (cstmt.isWrapperFor(
com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.class)) {
// The CallableStatement object can unwrap to
// SQLServerCallableStatement.
SQLServerCallableStatement SQLcstmt =
cstmt.unwrap(
com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.class);
SQLcstmt.setResponseBuffering("adaptive");
System.out.println("Response buffering mode has been set to " +
SQLcstmt.getResponseBuffering());
}
if (cstmt.isWrapperFor(
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.class)) {
// The CallableStatement object can unwrap to
// SQLServerPreparedStatement.
SQLServerPreparedStatement SQLpstmt =
cstmt.unwrap(
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.class);
SQLpstmt.setResponseBuffering("adaptive");
System.out.println("Response buffering mode has been set to " +
SQLpstmt.getResponseBuffering());
}
if (cstmt.isWrapperFor(
com.microsoft.sqlserver.jdbc.SQLServerStatement.class)) {
See Also
isWrapperFor Method (SQLServerCallableStatement)
SQLServerCallableStatement Members
SQLServerCallableStatement Class
SQLServerClob Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public class SQLServerClob
Remarks
A CLOB is stored in SQL Server as a TEXT or NTEXT data type.
See Also
SQLServerClob Members
JDBC Driver API Reference
SQLServerClob Members
4/27/2022 • 2 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
Fields
None.
Inherited Fields
None.
Methods
NAME DESC RIP T IO N
free This method frees the CLOB object and releases the
resources that it holds.
setString Writes the given string to the Clob starting at the specified
position.
Inherited Methods
C L A SS IN H ERIT ED F RO M M ET H O DS
See Also
SQLServerClob Class
SQLServerClob Constructors
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method has been deprecated in JDBC Driver version 2.0. Instead, use the createClob method of the
SQLServerConnection class.
Syntax
public SQLServerClob(SQLServerConnection connection,
java.lang.String data)
Parameters
connection
A SQLServerConnection object.
data
The CLOB data.
See Also
SQLServerClob Constructors
SQLServerClob Members
SQLServerClob Class
SQLServerClob Methods
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void free()
Exceptions
SQLServerException
Remarks
This free method is specified by the free method in the java.sql.Clob interface.
See Also
SQLServerClob Methods
SQLServerClob Members
SQLServerClob Class
getAsciiStream Method (SQLServerClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.InputStream getAsciiStream()
Return Value
An input stream that contains the CLOB data.
Exceptions
SQLServerException
Remarks
This getAsciiStream method is specified by the getAsciiStream method in the java.sql.Clob interface.
Always returns a stream of bytes and assumes that the data in the CLOB is in an ASCII format because it has no
way of knowing if it is in Unicode or any other multi-byte code page.
See Also
SQLServerClob Methods
SQLServerClob Members
SQLServerClob Class
getCharacterStream Method (SQLServerClob)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getCharacterStream Method (long, long) Returns the Clob data as a java.io.Reader object or as a
stream of characters with the specified position and length.
See Also
SQLServerClob Methods
SQLServerClob Members
SQLServerClob Class
getCharacterStream Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.Reader getCharacterStream()
Return Value
A Reader object that contains the CLOB data.
Exceptions
SQLServerException
Remarks
This getCharacterStream method is specified by the getCharacterStream method in the java.sql.Clob interface.
See Also
SQLServerClob Methods
SQLServerClob Members
SQLServerClob Class
getCharacterStream Method (long, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.Reader getCharacterStream(long pos,
long length)
Parameters
pos
A long that indicates the offset to the first character of the partial value to be retrieved.
length
A long that indicates the length in characters of the partial value to be retrieved.
Return Value
A Reader object that contains the Clob data.
Exceptions
SQLServerException
Remarks
This getCharacterStream method is specified by the getCharacterStream method in the java.sql.Clob interface.
See Also
getCharacterStream Method (SQLServerClob)
SQLServerClob Methods
SQLServerClob Members
getSubString Method (SQLServerClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getSubString(long pos,
int length)
Parameters
pos
The first character of the substring to be extracted. The first character is at position 1.
length
The number of consecutive characters to be copied.
Return Value
A String that is the specified substring in the CLOB.
Exceptions
SQLServerException
Remarks
This getSubString method is specified by the getSubString method in the java.sql.Clob interface.
Trying to get zero characters from a null or zero-length CLOB returns an empty string. Trying to get any length
of characters at any position other than position 1 in a zero-length CLOB will cause a position exception to be
thrown.
See Also
SQLServerClob Methods
SQLServerClob Members
SQLServerClob Class
length Method (SQLServerClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public long length()
Return Value
The length of the CLOB in number characters.
Exceptions
SQLServerException
Remarks
This length method is specified by the length method in the java.sql.Clob interface.
See Also
SQLServerClob Methods
SQLServerClob Members
SQLServerClob Class
position Method (SQLServerClob)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
position (java.sql.Clob, long) Returns the character position of the specified CLOB object
in the CLOB based on the given starting position.
position (java.lang.String, long) Returns the character position of the specified substring in
the CLOB based on the given starting position.
See Also
SQLServerClob Methods
SQLServerClob Members
SQLServerClob Class
position Method ( java.sql.Clob, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public long position(java.sql.Clob searchstr,
long start)
Parameters
searchstr
The substring to search for.
start
The position at which to begin searching. The first position is 1.
Return Value
The position at which the substring appears, or -1 if it is not present. The first position is 1.
Exceptions
SQLServerException
Remarks
This position method is specified by the position method in the java.sql.Clob interface.
See Also
position Method (SQLServerClob)
SQLServerClob Methods
SQLServerClob Members
SQLServerClob Class
position Method ( java.lang.String, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public long position(java.lang.String searchstr,
long start)
Parameters
searchstr
The substring for which to search.
start
The position at which to begin searching; the first position is 1.
Return Value
The position at which the substring appears or -1 if it is not present; the first position is 1.
Exceptions
SQLServerException
Remarks
This position method is specified by the position method in the java.sql.Clob interface.
See Also
position Method (SQLServerClob)
SQLServerClob Methods
SQLServerClob Members
SQLServerClob Class
setAsciiStream Method (SQLServerClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.OutputStream setAsciiStream(long pos)
Parameters
pos
The position at which to start writing to the CLOB object.
Return Value
The stream to which ASCII encoded characters can be written.
Exceptions
java.sql.SQLException
Remarks
This setAsciiStream method is specified by the setAsciiStream method in the java.sql.Clob interface.
Character data in the CLOB is overwritten by the output stream starting at the given position and can overrun
the initial length of the CLOB. Specifying a position+1 value will append ASCII characters. Specifying a
position+2 or greater (or zero or less) value will cause a position error to be thrown.
See Also
SQLServerClob Methods
SQLServerClob Members
SQLServerClob Class
setCharacterStream Method (SQLServerClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.Writer setCharacterStream(long pos)
Parameters
pos
The position at which to start writing to the CLOB object.
Return Value
A stream to which Unicode encoded characters can be written.
Exceptions
java.sql.SQLException
Remarks
This setCharacterStream method is specified by the setCharacterStream method in the java.sql.Clob interface.
Character data in the CLOB is overwritten by the writer starting at the specified position and can over-run the
initial length of the CLOB. Specifying a position+1 value will append characters. Specifying a position+2 or
greater (or zero or less) value will cause a position error to be thrown.
See Also
SQLServerClob Methods
SQLServerClob Members
SQLServerClob Class
setString Method (SQLServerClob)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setString (long, java.lang.String) Writes the given stringto the CLOB starting at the given
position.
setString (long, java.lang.String, int, int) Writes the given string to the CLOB starting at the given
position, based on the given offset and length.
See Also
SQLServerClob Methods
SQLServerClob Members
SQLServerClob Class
setString Method (long, java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int setString(long pos,
java.lang.String s)
Parameters
pos
The position at which to start writing to the CLOB.
s
The String to be written to the CLOB.
Return Value
The number of characters written.
Exceptions
java.sql.SQLException
Remarks
This setString method is specified by the setString method in the java.sql.Clob interface.
Character data is overwritten starting at the specified position and can over-run the initial length of the CLOB.
Specifying a position+1 value will append the string. Specifying a position+2 or greater (or zero or less) values
will cause a position error to be thrown.
See Also
setString Method (SQLServerClob)
SQLServerClob Methods
SQLServerClob Members
SQLServerClob Class
setString Method (long, java.lang.String, int, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int setString(long pos,
java.lang.String str,
int offset,
int len)
Parameters
pos
The position at which to start writing to the CLOB.
str
The string to be written to the CLOB.
offset
The offset within the string to start reading the characters from.
len
The number of characters to be written.
Return Value
The number of characters written.
Exceptions
java.sql.SQLException
Remarks
This setString method is specified by the setString method in the java.sql.Clob interface.
Character data is overwritten starting at the specified position and can overwrite the initial length of the CLOB.
Specifying a position+1 value will append the string. Specifying a position+2 or greater (or zero or less) value
will cause a position error to be thrown.
See Also
setString Method (SQLServerClob)
SQLServerClob Methods
SQLServerClob Members
SQLServerClob Class
truncate Method (SQLServerClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void truncate(long len)
Parameters
len
The length, in characters, to which the CLOB should be truncated.
Exceptions
java.sql.SQLException
Remarks
This truncate method is specified by the truncate method in the java.sql.Clob interface.
See Also
SQLServerClob Methods
SQLServerClob Members
SQLServerClob Class
SQLServerConnection Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public class SQLServerConnection
Remarks
SQLServerConnection supports JDBC connection pooling and can be either a physical JDBC connection or a
logical JDBC connection. SQLServerConnection manages transaction control for all statements that were created
from it, and it can participate in XA distributed transactions managed via a XAResource adapter.
SQLServerConnection manages a pool of prepared statement handles. Prepared statements are prepared once
and are typically run many times with different data values for their parameters. Prepared statements are also
maintained across logical (pooled) connection closes.
NOTE
SQLServerConnection is not thread safe. However, multiple statements that are created from a single connection can be
processed simultaneously in concurrent threads.
See Also
SQLServerConnection Members
JDBC Driver API Reference
SQLServerConnection Members
4/27/2022 • 3 minutes to read • Edit Online
Constructors
None.
Fields
NAME DESC RIP T IO N
Inherited Fields
C L A SS IN H ERIT ED F RO M : DESC RIP T IO N
Methods
NAME DESC RIP T IO N
getClientConnectionID Method (SQLServerConnection) Gets the connection ID of the most recent connection
attempt, regardless of whether the attempt succeeded or
failed.
getStatementPoolingCacheSize Returns the size of the prepared statement cache for this
connection.
nativeSQL Converts the given SQL statement into the native SQL
grammar of the database server.
setStatementPoolingCacheSize Sets the size of the prepared statement cache for this
connection.
setTypeMap Installs the given TypeMap object as the type map for this
SQLServerConnection object.
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerConnection Class
SQLServerConnection Methods
4/27/2022 • 2 minutes to read • Edit Online
See Also
SQLServerConnection Class
clearWarnings Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void clearWarnings()
Exceptions
SQLServerException
Remarks
This clearWarnings method is specified by the clearWarnings method in the java.sql.Connection interface.
See Also
SQLServerConnection Members
SQLServerConnection Class
close Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void close()
Exceptions
SQLServerException
Remarks
This close method is specified by the close method in the java.sql.Connection interface.
Calling the close method in the middle of a transaction causes the transaction to be rolled back.
See Also
SQLServerConnection Members
SQLServerConnection Class
closeUnreferencedPreparedStatementHandles
Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void closeUnreferencedPreparedStatementHandles()
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerConnection Members
SQLServerConnection Class
commit Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void commit()
Exceptions
SQLServerException
Remarks
This commit method is specified by the commit method in the java.sql.Connection interface.
This method should be used only when auto-commit mode has been disabled.
Note that this method will fail and throw an exception if the client starts a manual transaction and then for some
reason SQL Server rolls back the manual transaction. For example, an exception is thrown if the client calls a
stored procedure that explicitly calls ROLLBACK TRANSACTION, and then the client calls the commit method. In
addition, if SQL Server raises an error of sufficient severity (16 or higher) to roll back the client initiated manual
transaction; a subsequent call to the commit method will throw an exception.
See Also
SQLServerConnection Members
SQLServerConnection Class
createBlob Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Blob createBlob()
Return Value
A Blob object.
Exceptions
SQLServerException
Remarks
This createBlob method is specified by the createBlob method in the java.sql.Connection interface.
This method replaces the need for SQLServerBlob Constructor (SQLServerConnection, byte).
See Also
SQLServerConnection Members
SQLServerConnection Class
createClob Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Clob createClob()
Return Value
A Clob object.
Exceptions
SQLServerException
Remarks
This createClob method is specified by the createClob method in the java.sql.Connection interface.
This method replaces the need for SQLServerClob Constructor (SQLServerConnection, java.lang.String).
See Also
SQLServerConnection Members
SQLServerConnection Class
createNClob Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.NClob createNClob()
Return Value
A NClob object.
Exceptions
SQLServerException
Remarks
This createNClob method is specified by the createNClob method in the java.sql.Connection interface.
See Also
SQLServerConnection Members
SQLServerConnection Class
createStatement Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerConnection Members
SQLServerConnection Class
createStatement Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Statement createStatement()
Return Value
The Statement object.
Exceptions
SQLServerException
Remarks
This createStatement method is specified by the createStatement method in the java.sql.Connection interface.
See Also
createStatement Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
createStatement Method (int, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Statement createStatement(int resultSetType,
int resultSetConcurrency)
Parameters
resultSetType
The int value representing the result set type.
resultSetConcurrency
The int value representing the result set concurrency type.
Return Value
The Statement object.
Exceptions
SQLServerException
Remarks
This createStatement method is specified by the createStatement method in the java.sql.Connection interface.
See Also
createStatement Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
createStatement Method (int, int, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Statement createStatement(int nType,
int nConcur,
int nHold)
Parameters
resultSetType
The int value that represents the result set type.
nConcur
The int value that represents the result set concurrency type.
nHold
The int value that represents the holdability.
Return Value
The Statement object.
Exceptions
SQLServerException
Remarks
This createStatement method is specified by the createStatement method in the java.sql.Connection interface.
See Also
createStatement Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
createSQLXML Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.SQLXML createSQLXML()
Return Value
A SQLXML object.
Exceptions
SQLServerException
Remarks
This createSQLXML method is specified by the createSQLXML method in the java.sql.Connection interface.
See Also
SQLServerConnection Members
SQLServerConnection Class
getAutoCommit Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getAutoCommit()
Return Value
true if auto-commit mode is enabled, false if it is not.
Exceptions
SQLServerException
Remarks
This getAutoCommit method is specified by the getAutoCommit method in the java.sql.Connection interface.
See Also
SQLServerConnection Members
SQLServerConnection Class
getCatalog Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getCatalog()
Return Value
A String that contains the catalog name.
Exceptions
SQLServerException
Remarks
This getCatalog method is specified by the getCatalog method in the java.sql.Connection interface.
Returns the current catalog property of the SQLServerConnection object, or null if it is not set. The catalog
property is set explicitly with the setCatalog method, or is implicitly updated by reading the environment change
on TDS for the current catalog.
See Also
SQLServerConnection Members
SQLServerConnection Class
getClientConnectionID Method
(SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public Java.util.UUID SQLServerConnection.getClientConnectionID();
Return Value
A 16-byte GUID representing the connection ID of the most recent connection attempt. Or, NULL if there is a
failure after the connection request is initiated and the pre-login handshake.
Exceptions
SQLServerException
Remarks
For more information about accessing diagnostic information in the extended events log, see Accessing
Diagnostic Information in the Extended Events Log.
The following sample shows how to get the connection ID:
The following sample shows another way to get the connection ID:
getClientConnectionID works regardless of which version of the server you connect to, but extended events
logs and entry on connectivity ring buffer errors will not be present in SQL Server 2008 R2 and earlier.
You can locate the connection ID in the extended events log to see if the failure was on the server if the extended
event for logging connection ID is enabled. You can also locate the connection ID in the connection ring buffer
(Connectivity troubleshooting in SQL Server 2008 with the Connectivity Ring Buffer) for certain connection
errors. If the connection ID is not in the connection ring buffer, you can assume a network error.
See Also
SQLServerConnection Members
SQLServerConnection Class
getClientInfo Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getClientInfo Method () Retrieves a list that contains the name and current value of
each client information property supported by the JDBC
driver.
getClientInfo Method (java.lang.String) Retrieves the value of a specified client information property.
See Also
SQLServerConnection Members
SQLServerConnection Class
getClientInfo Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.util.Properties getClientInfo()
Return Value
A Properties object that contains the name and current value of each of the client information properties
supported by the driver.
Exceptions
SQLServerException
Remarks
This getClientInfo method is specified by the getClientInfo method in the java.sql.Connection interface.
The Microsoft JDBC Driver for SQL Server does not support any client information properties. As a result, this
method returns an empty Properties object.
Similarly, applications can use the getClientInfoProperties method of the SQLServerDatabaseMetaData class to
retrieve a list of the client information properties that the driver supports. The getClientInfoProperties method
returns an empty result set.
See Also
getClientInfo Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
getClientInfo Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getClientInfo (java.lang.String name)
Parameters
name
A String that contains the name of the client information property to retrieve.
Return Value
A String that contains the value of the client information property.
Exceptions
SQLServerException
Remarks
This getClientInfo method is specified by the getClientInfo method in the java.sql.Connection interface.
The Microsoft JDBC Driver for SQL Server does not support any client info properties. As a result, this method
returns null .
Similarly, applications can use the getClientInfoProperties method of the SQLServerDatabaseMetaData class to
retrieve a list of the client information properties that the driver supports. The getClientInfoProperties method
returns an empty result set.
See Also
getClientInfo Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
getDisableStatementPooling Method
(SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getDisableStatementPooling()
Return Value
A boolean that contains the value of disableStatementPooling connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerConnection Members
SQLServerConnection Class
getDiscardedServerPreparedStatementCount
Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getDiscardedServerPreparedStatementCount()
Return Value
An int that contains the number of currently outstanding prepared statement unprepare actions.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerConnection Members
SQLServerConnection Class
getEnablePrepareOnFirstPreparedStatementCall
Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getEnablePrepareOnFirstPreparedStatementCall()
Return Value
A boolean that contains the value of enablePrepareOnFirstPreparedStatementCall connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerConnection Members
SQLServerConnection Class
getHoldability Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getHoldability()
Return Value
An int value that contains one of the following holdability levels:
HOLD_CURSORS_OVER_COMMIT
CLOSE_CURSORS_AT_COMMIT
Exceptions
SQLServerException
Remarks
This getHoldability method is specified by the getHoldability method in the java.sql.Connection interface.
See Also
SQLServerConnection Members
SQLServerConnection Class
getMetaData Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.DatabaseMetaData getMetaData()
Return Value
The DatabaseMetaData object.
Exceptions
SQLServerException
Remarks
This getMetaData method is specified by the getMetaData method in the java.sql.Connection interface.
See Also
SQLServerConnection Members
SQLServerConnection Class
getServerPreparedStatementDiscardThreshold
Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getServerPreparedStatementDiscardThreshold()
Return Value
An int that contains the value of ser verPreparedStatementDiscardThreshold connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerConnection Members
SQLServerConnection Class
getStatementHandleCacheEntryCount Method
(SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getStatementHandleCacheEntryCount()
Return Value
An int that contains the current number of pooled prepared statement handles.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerConnection Members
SQLServerConnection Class
getStatementPoolingCacheSize Method
(SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getStatementPoolingCacheSize()
Return Value
An int that contains the value of statementPoolingCacheSize connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerConnection Members
SQLServerConnection Class
getTransactionIsolation Method
(SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getTransactionIsolation()
Return Value
An int value that contains one of the following isolation levels:
TRANSACTION_NONE
TRANSACTION_READ_UNCOMMITTED
TRANSACTION_READ_COMMITTED
TRANSACTION_REPEATABLE_READ
TRANSACTION_SERIALIZABLE
TRANSACTION_SNAPSHOT = 0x1000
Exceptions
SQLServerException
Remarks
This getTransactionIsolation method is specified by the getTransactionIsolation method in the
java.sql.Connection interface.
See Also
SQLServerConnection Members
SQLServerConnection Class
getTypeMap Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported by the Microsoft JDBC Driver for SQL Server.
Syntax
public java.util.Map getTypeMap()
Return Value
A Map object.
Exceptions
SQLServerException
Remarks
This getTypeMap method is specified by the getTypeMap method in the java.sql.Connection interface.
See Also
SQLServerConnection Members
SQLServerConnection Class
getWarnings Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.SQLWarning getWarnings()
Return Value
A SQLWarning object.
Exceptions
SQLServerException
Remarks
This getWarnings method is specified by the getWarnings method in the java.sql.Connection interface.
Subsequent warnings are chained to the first SQLWarning and called with the getNextWarning method. If called
on a closed connection, an exception will be thrown.
See Also
SQLServerConnection Members
SQLServerConnection Class
isClosed Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isClosed()
Return Value
true if the connection is close, false if it is not.
Exceptions
SQLServerException
Remarks
This isClosed method is specified by the isClosed method in the java.sql.Connection interface.
Verifies the state of the called SQLServerConnection object. A connection is closed if the close method has been
called on it, or if certain fatal errors have occurred. This method will return true only when it is called after the
close method has been called.
See Also
SQLServerConnection Members
SQLServerConnection Class
isReadOnly Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported by the Microsoft JDBC Driver for SQL Server.
Syntax
public boolean isReadOnly()
Return Value
true if the connection is in read-only mode, false if it is not.
Exceptions
SQLServerException
Remarks
This isReadOnly method is specified by the isReadOnly method in the java.sql.Connection interface.
See Also
SQLServerConnection Members
SQLServerConnection Class
isStatementPoolingEnabled Method
(SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isStatementPoolingEnabled()
Return Value
A boolean that contains the flag indicating whether statement pooling is enabled or not.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerConnection Members
SQLServerConnection Class
isValid Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isValid(int timeout)
Parameters
timeout
An int that specifies the number of seconds to wait for validating the connection.
Return Value
true if the connection is valid; false if the connection is not valid or the validity of the connection cannot be
determined before the timeout expires.
Exceptions
SQLServerException
Remarks
This isValid method is specified by the isValid method in the java.sql.Connection interface.
See Also
SQLServerConnection Members
SQLServerConnection Class
nativeSQL Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported by the Microsoft JDBC Driver for SQL Server.
Syntax
public java.lang.String nativeSQL(java.lang.String sql)
Parameters
sql
A String containing an SQL statement.
Return Value
A String containing the converted SQL statement.
Exceptions
SQLServerException
Remarks
This nativeSQL method is specified by the nativeSQL method in the java.sql.Connection interface.
See Also
SQLServerConnection Members
SQLServerConnection Class
prepareCall Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
prepareCall (java.lang.String, int, int, int) Creates a SQLServerCallableStatement object that generates
SQLServerResultSet objects with the given type, concurrency,
and holdability.
See Also
SQLServerConnection Members
SQLServerConnection Class
prepareCall Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.CallableStatement prepareCall(java.lang.String sql)
Parameters
sql
A String containing an SQL statement.
Return Value
A CallableStatement object.
Exceptions
SQLServerException
Remarks
This prepareCall method is specified by the prepareCall method in the java.sql.Connection interface.
See Also
prepareCall Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
prepareCall Method ( java.lang.String, int, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.CallableStatement prepareCall(java.lang.String sql,
int resultSetType,
int resultSetConcurrency)
Parameters
sql
A String containing an SQL statement.
resultSetType
An int that indicates the result set type.
resultSetConcurrency
An int that indicates the result set concurrency type.
Return Value
A CallableStatement object.
Exceptions
SQLServerException
Remarks
This prepareCall method is specified by the prepareCall method in the java.sql.Connection interface.
See Also
prepareCall Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
prepareCall Method ( java.lang.String, int, int, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.CallableStatement prepareCall(java.lang.String sql,
int nType,
int nConcur,
int nHold)
Parameters
sql
A String containing an SQL statement.
nType
An int that indicates the result set type.
nConcur
An int that indicates the result set concurrency type.
nHold
An int that indicates the result set holdability.
Return Value
A CallableStatement object.
Exceptions
SQLServerException
Remarks
This prepareCall method is specified by the prepareCall method in the java.sql.Connection interface.
See Also
prepareCall Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
prepareStatement Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerConnection Members
SQLServerConnection Class
prepareStatement Method ( java.lang.String, int[])
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.PreparedStatement prepareStatement(java.lang.String sql,
int[] columnIndexes)
Parameters
sql
A String that contains an SQL statement.
columnIndexes
An array of ints.
Return Value
A PreparedStatement object.
Exceptions
SQLServerException
Remarks
This prepareStatement method is specified by the prepareStatement method in the java.sql.Connection interface.
See Also
prepareStatement Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
prepareStatement Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Creates a SQLServerPreparedStatement object for sending parameterized SQL statements to the database.
Syntax
public java.sql.PreparedStatement prepareStatement(java.lang.String sql)
Parameters
sql
A String containing an SQL statement.
Return Value
A PreparedStatement object.
Exceptions
SQLServerException
Remarks
This prepareStatement method is specified by the prepareStatement method in the java.sql.Connection interface.
See Also
prepareStatement Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
prepareStatement Method ( java.lang.String, int, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.PreparedStatement prepareStatement(java.lang.String sSql,
int resultSetType,
int resultSetConcurrency)
Parameters
sSql
A String containing an SQL statement.
resultSetType
An int that indicates the result set type.
resultSetConcurrency
An int that indicates the result set concurrency type.
Return Value
A PreparedStatement object.
Exceptions
SQLServerException
Remarks
This prepareStatement method is specified by the prepareStatement method in the java.sql.Connection interface.
See Also
SQLServerConnection Methods
SQLServerConnection Members
SQLServerConnection Class
prepareStatement Method ( java.lang.String, int, int,
int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.PreparedStatement prepareStatement(java.lang.String sql,
int nType,
int nConcur,
int nHold)
Parameters
sql
A String containing an SQL statement.
nType
An int that indicates the result set type.
nConcur
An int that indicates the result set concurrency type.
nHold
An int that indicates the result set holdability.
Return Value
A PreparedStatement object.
Exceptions
SQLServerException
Remarks
This prepareStatement method is specified by the prepareStatement method in the java.sql.Connection interface.
See Also
prepareStatement Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
prepareStatement Method ( java.lang.String,
java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.PreparedStatement prepareStatement(java.lang.String sql,
java.lang.String[] columnNames)
Parameters
sql
A String containing an SQL statement.
columnNames
A String array of column names.
Return Value
A PreparedStatement object.
Exceptions
SQLServerException
Remarks
This prepareStatement method is specified by the prepareStatement method in the java.sql.Connection interface.
See Also
prepareStatement Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
releaseSavepoint Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported by the Microsoft JDBC Driver for SQL Server.
Syntax
public void releaseSavepoint(java.sql.Savepoint savepoint)
Parameters
savepoint
The SavePoint object to remove.
Exceptions
SQLServerException
Remarks
This releaseSavepoint method is specified by the releaseSavepoint method in the java.sql.Connection interface.
See Also
SQLServerConnection Members
SQLServerConnection Class
rollback Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerConnection Members
SQLServerConnection Class
rollback Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void rollback()
Exceptions
SQLServerException
Remarks
This rollBack method is specified by the rollBack method in the java.sql.Connection interface.
This method should be used only when auto-commit mode has been disabled.
See Also
rollback Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
rollback Method ( java.sql.Savepoint)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void rollback(java.sql.Savepoint s)
Parameters
s
The SavePoint object to rollback to.
Exceptions
SQLServerException
Remarks
This rollBack method is specified by the rollBack method in the java.sql.Connection interface.
This method should be used only when auto-commit mode has been disabled.
See Also
rollback Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
setAutoCommit Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setAutoCommit(boolean value)
Parameters
value
true to enable autocommit mode for the connection, false to disable it.
Exceptions
SQLServerException
Remarks
This setAutoCommit method is specified by the setAutoCommit method in the java.sql.Connection interface.
If a connection is in autocommit mode, then all its SQL statements are run and committed as individual
transactions. Otherwise, its SQL statements are grouped into transactions that are ended by a call to either the
commit method or the rollback method. By default, new connections are in autocommit mode.
The commit occurs when the statement completes or the next run occurs, whichever comes first. When
statements return a SQLServerResultSet object, the statement completes when the last row of the result set has
been retrieved, or when the result set has been closed. In advanced cases, a single statement might return
multiple results in addition to output parameter values. In these cases, the commit occurs when all results and
output parameter values have been retrieved.
When the autocommit mode is false , the JDBC driver will implicitly start a new transaction after each commit.
NOTE
If this method is called during a transaction, the transaction is committed.
See Also
SQLServerConnection Members
SQLServerConnection Class
setCatalog Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setCatalog(java.lang.String catalog)
Parameters
catalog
A String that contains the catalog name.
Exceptions
SQLServerException
Remarks
This setCatalog method is specified by the setCatalog method in the java.sql.Connection interface.
The catalog argument is escaped by the Microsoft JDBC Driver for SQL Server automatically. Using this method
sets the catalog property for the Connection object. It is not set implicitly in any other way.
See Also
SQLServerConnection Members
SQLServerConnection Class
setClientInfo Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setClientInfo Method (java.util.Properties) Sets the value of the connection's client information
properties.
setClientInfo Method (java.lang.String, java.lang.String) Sets the value of the specified client information property.
See Also
SQLServerConnection Members
SQLServerConnection Class
setClientInfo Method ( java.util.Properties)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setClientInfo (java.util.Properties properties)
Parameters
properties
A Properties object that contains the list of client information properties to set.
Exceptions
SQLServerException
Remarks
This setClientInfo method is specified by the setClientInfo method in the java.sql.Connection interface.
The Microsoft JDBC Driver for SQL Server does not support any client information properties. This method
generates warnings if the properties input parameter does not refer to an empty property set. In other words,
this method generates warnings for the properties that the application wants to set. Applications should use
getWarnings method of the SQLServerConnection class to retrieve each warning.
See Also
setClientInfo Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
setClientInfo Method ( java.lang.String,
java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setClientInfo (java.lang.String name,
java.lang.String value)
Parameters
name
A String that contains the name of the client information property to set.
value
A String that contains the value to set the client information property to.
Exceptions
SQLServerException
Remarks
This setClientInfo method is specified by the setClientInfo method in the java.sql.Connection interface.
The Microsoft JDBC Driver for SQL Server does not support any client information properties. In the 2.0 JDBC
Driver, this method generates a warning for a property. Applications should use getWarnings method of the
SQLServerConnection class to retrieve a warning.
See Also
setClientInfo Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
setDisableStatementPooling Method
(SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setDisableStatementPooling(boolean disableStatementPooling)
Parameters
disableStatementPooling
The new value of the disableStatementPooling connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerConnection Members
SQLServerConnection Class
setEnablePrepareOnFirstPreparedStatementCall
Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setEnablePrepareOnFirstPreparedStatementCall(boolean enablePrepareOnFirstPreparedStatementCall)
Parameters
enablePrepareOnFirstPreparedStatementCall
The new value of the enablePrepareOnFirstPreparedStatementCall connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerConnection Members
SQLServerConnection Class
setHoldability Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setHoldability(int nNewHold)
Parameters
nNewHold
An int value that contains one of the following holdability levels:
HOLD_CURSORS_OVER_COMMIT
CLOSE_CURSORS_AT_COMMIT
Exceptions
SQLServerException
Remarks
This setHoldability method is specified by the setHoldability method in the java.sql.Connection interface.
See Also
SQLServerConnection Members
SQLServerConnection Class
setReadOnly Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not supported by the Microsoft JDBC Driver for SQL Server.
Syntax
public void setReadOnly(boolean readOnly)
Parameters
readOnly
true if the connection is to be read-only. Otherwise, false .
Exceptions
SQLServerException
Remarks
This setReadOnly method is specified by the setReadOnly method in the java.sql.Connection interface.
See Also
SQLServerConnection Members
SQLServerConnection Class
setSavepoint Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setSavepoint (java.lang.String) Creates a savepoint with the given name in the current
transaction and returns the new SQLServerSavepoint object
that represents it.
See Also
SQLServerConnection Members
SQLServerConnection Class
setSavepoint Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Savepoint setSavepoint()
Return Value
A SavePoint object.
Exceptions
SQLServerException
Remarks
This setSavePoint method is specified by the setSavePoint method in the java.sql.Connection interface.
See Also
setSavepoint Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
setSavepoint Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Savepoint setSavepoint(java.lang.String sName)
Parameters
sName
A String value that contains the name of the savepoint.
Return Value
A SavePoint object.
Exceptions
SQLServerException
Remarks
This setSavePoint method is specified by the setSavePoint method in the java.sql.Connection interface.
The sName argument is automatically escaped by the Microsoft JDBC Driver for SQL Server.
See Also
setSavepoint Method (SQLServerConnection)
SQLServerConnection Members
SQLServerConnection Class
setServerPreparedStatementDiscardThreshold
Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setServerPreparedStatementDiscardThreshold(boolean thresholdValue)
Parameters
thresholdValue
The new value of the ser verPreparedStatementDiscardThreshold connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerConnection Members
SQLServerConnection Class
setStatementPoolingCacheSize Method
(SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setStatementPoolingCacheSize(int statementPoolingCacheSize)
Parameters
statementPoolingCacheSize
The new value of the statementPoolingCacheSize connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerConnection Members
SQLServerConnection Class
setTransactionIsolation Method
(SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setTransactionIsolation(int level)
Parameters
level
An int value that contains one of the following isolation levels:
TRANSACTION_READ_UNCOMMITTED
TRANSACTION_READ_COMMITTED
TRANSACTION_REPEATABLE_READ
TRANSACTION_SERIALIZABLE
TRANSACTION_SNAPSHOT = 0x1000
Exceptions
SQLServerException
Remarks
This setTransactionIsolation method is specified by the setTransactionIsolation method in the java.sql.Connection
interface.
Transactions are not committed if this method is called in the middle of a transaction.
See Also
SQLServerConnection Members
SQLServerConnection Class
setTypeMap Method (SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported by the Microsoft JDBC Driver for SQL Server.
Syntax
public void setTypeMap(java.util.Map map)
Parameters
map
A TypeMap object.
Exceptions
SQLServerException
Remarks
This setTypeMap method is specified by the setTypeMap method in the java.sql.Connection interface.
See Also
SQLServerConnection Members
SQLServerConnection Class
ISQLServerConnection Fields
4/27/2022 • 2 minutes to read • Edit Online
See Also
SQLServerConnection Class
TRANSACTION_SNAPSHOT Field
(SQLServerConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public static final int TRANSACTION_SNAPSHOT
Field Value
An int value.
See Also
SQLServerConnection Members
SQLServerConnection Class
SQLServerConnectionPoolDataSource Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public class SQLServerConnectionPoolDataSource
Remarks
SQLServerConnectionPoolDataSource is typically used in Java Application Server environments that support
built-in connection pooling and require a ConnectionPoolDataSource to provide physical connections, such as
Java Platform, Enterprise Edition (Java EE) application servers that provide JDBC 3.0 API spec connection
pooling.
See Also
SQLServerConnectionPoolDataSource Members
JDBC Driver API Reference
SQLServerConnectionPoolDataSource Members
4/27/2022 • 4 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
Fields
None.
Inherited Fields
None.
Methods
NAME DESC RIP T IO N
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerConnectionPoolDataSource Class
SQLServerConnectionPoolDataSource Constructors
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public SQLServerConnectionPoolDataSource()
See Also
SQLServerConnectionPoolDataSource Constructors
SQLServerConnectionPoolDataSource Members
SQLServerConnectionPoolDataSource Class
SQLServerConnectionPoolDataSource Methods
4/27/2022 • 2 minutes to read • Edit Online
See Also
SQLServerConnectionPoolDataSource Class
getPooledConnection Method
(SQLServerConnectionPoolDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getPooledConnection (java.lang.String, java.lang.String) Tries to establish a physical database connection that can be
used as a pooled connection based on the given user name
and password.
See Also
SQLServerConnectionPoolDataSource Methods
SQLServerConnectionPoolDataSource Members
SQLServerConnectionPoolDataSource Class
getPooledConnection Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public javax.sql.PooledConnection getPooledConnection()
Return Value
A SQLServerPooledConnection object.
Exceptions
java.sql.SQLException
Remarks
This getPooledConnection method is specified by the getPooledConnection method in the
javax.sql.ConnectionPoolDataSource interface.
See Also
getPooledConnection
SQLServerConnectionPoolDataSource Methods
SQLServerConnectionPoolDataSource Members
SQLServerConnectionPoolDataSource Class
getPooledConnection Method ( java.lang.String,
java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public javax.sql.PooledConnection getPooledConnection(java.lang.String user,
java.lang.String password)
Parameters
user
A String that contains the user name.
passwword
A String that contains the password.
Return Value
A SQLServerPooledConnection object.
Exceptions
java.sql.SQLException
Remarks
This getPooledConnection method is specified by the getPooledConnection method in the
javax.sql.ConnectionPoolDataSource interface.
See Also
getPooledConnection
SQLServerConnectionPoolDataSource Methods
SQLServerConnectionPoolDataSource Members
SQLServerConnectionPoolDataSource Class
getReference Method
(SQLServerConnectionPoolDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public javax.naming.Reference getReference()
Return Value
A Reference object.
Remarks
This getReference method is specified by the getReference method in the javax.naming.Referenceable interface.
It overrides the getReference method of the SQLServerDataSource class.
See Also
SQLServerConnectionPoolDataSource Methods
SQLServerConnectionPoolDataSource Members
SQLServerConnectionPoolDataSource Class
isWrapperFor Method
(SQLServerConnectionPoolDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isWrapperFor(Class iface)
Parameters
iface
A class defining an interface.
Return Value
true if this object implements the interface or wraps an object that implements the interface. Otherwise, false .
Exceptions
SQLServerException
Remarks
The isWrapperFor method and the unwrap method are defined by the java.sql.Wrapper interface, which is
introduced in the JDBC 4.0 Spec.
If this method returns true, calling unwrap with the same argument will succeed.
For more information, see Wrappers and Interfaces.
See Also
unwrap Method (SQLServerConnectionPoolDataSource)
SQLServerConnectionPoolDataSource Methods
SQLServerConnectionPoolDataSource Members
SQLServerConnectionPoolDataSource Class
unwrap Method
(SQLServerConnectionPoolDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public <T> T unwrap(Class<T> iface)
Parameters
iface
A class of type T defining an interface.
Return Value
An object that implements the specified interface.
Exceptions
SQLServerException
Remarks
The unwrap method is defined by the java.sql.Wrapper interface, which is introduced in the JDBC 4.0 Spec.
Applications might need to access extensions to the JDBC API that are specific to the Microsoft JDBC Driver for
SQL Server. The unwrap method supports unwrapping to public classes that this object extends, if the classes
expose vendor extensions.
The SQLServerConnectionPoolDataSource class extends the SQLServerDataSource class. When this method is
called, the object unwraps to the SQLServerDataSource class and the SQLServerConnectionPoolDataSource
class.
For more information, see Wrappers and Interfaces.
See Also
SQLServerConnectionPoolDataSource Methods
SQLServerConnectionPoolDataSource Members
SQLServerConnectionPoolDataSource Class
SQLServerDatabaseMetaData Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final class SQLServerDatabaseMetaData
See Also
SQLServerDatabaseMetaData Members
JDBC Driver API Reference
SQLServerDatabaseMetaData Members
4/27/2022 • 12 minutes to read • Edit Online
Constructors
None.
Fields
None.
Inherited Fields
NAME DESC RIP T IO N
Methods
NAME DESC RIP T IO N
allProceduresAreCallable Retrieves whether the current user has permissions to call all
the procedures returned by the getProcedures method.
allTablesAreSelectable Retrieves whether the current user has permissions to use all
the tables returned by the getTables method in a SELECT
statement.
NAME DESC RIP T IO N
autoCommitFailureClosesAllResultSets Indicates whether the JDBC driver closes all the open result
sets, including the holdable ones, when an auto-commit is
enabled and an exception is raised.
getCatalogSeparator Retrieves the String that this database uses as the separator
between a catalog and table name.
getJDBCMajorVersion Retrieves the major JDBC version number for this driver.
getJDBCMinorVersion Retrieves the minor JDBC version number for this driver.
getSchemas Retrieves the schema names that are available in the current
database.
getTableTypes Retrieves the table types that are available in the current
database.
NAME DESC RIP T IO N
getTypeInfo Retrieves a description of all the standard SQL types that are
supported by the current database.
othersInsertsAreVisible Retrieves whether inserts that are made by others are visible.
ownUpdatesAreVisible Retrieves whether the result set's own updates are visible.
usesLocalFilePerTable Retrieves whether this database uses a file for each table.
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerDatabaseMetaData Class
SQLServerDatabaseMetaData Methods
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean allProceduresAreCallable()
Return Value
true if the user has permissions to call all the procedures. Otherwise, false .
Exceptions
SQLServerException
Remarks
This allProceduresAreCallable method is specified by the allProceduresAreCallable method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
allTablesAreSelectable Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean allTablesAreSelectable()
Return Value
true if the user has permissions to call use all the tables. Otherwise, false .
Exceptions
SQLServerException
Remarks
This allTablesAreSelectable method is specified by the allTablesAreSelectable method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
autoCommitFailureClosesAllResultSets Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean autoCommitFailureClosesAllResultSets()
Return Value
true if all the open result sets, including the holdable ones, are closed when an auto-commit is enabled and an
exception is raised. Otherwise, false .
Exceptions
SQLServerException
Remarks
This autoCommitFailureClosesAllResultSets method is specified by the autoCommitFailureClosesAllResultSets
method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
dataDefinitionCausesTransactionCommit Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean dataDefinitionCausesTransactionCommit()
Return Value
true if the DDL statement forces a commit. Otherwise, false .
Exceptions
SQLServerException
Remarks
This dataDefinitionCausesTransactionCommit method is specified by the
dataDefinitionCausesTransactionCommit method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
dataDefinitionIgnoredInTransactions Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean dataDefinitionIgnoredInTransactions()
Return Value
true if DDL statements are ignored within transactions. Otherwise, false .
Exceptions
SQLServerException
Remarks
This dataDefinitionIgnoredInTransactions method is specified by the dataDefinitionIgnoredInTransactions
method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
deletesAreDetected Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean deletesAreDetected(int type)
Parameters
type
An int that indicates the result set type, which can be one of the following values as defined in java.sql.ResultSet
or SQLServerResultSet:
java.sql.ResultSet Types
TYPE_FORWARD_ONLY
TYPE_SCROLL_SENSITIVE
TYPE_SCROLL_INSENSITIVE
SQLServerResultSet Types
TYPE_SS_SCROLL_STATIC
TYPE_SS_SCROLL_KEYSET
TYPE_SS_DIRECT_FORWARD_ONLY
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY
TYPE_SS_SCROLL_DYNAMIC
Return Value
true if a gap replaces the deleted row. false if the deleted row is removed.
When using the Microsoft JDBC Driver for SQL Server with a SQL Server database, this method returns true for
TYPE_SS_SCROLL_KEYSET cursors and false for all other result set types.
Exceptions
SQLServerException
Remarks
This deletesAreDetected method is specified by the deletesAreDetected method in the
java.sql.DatabaseMetaData interface.
NOTE
SQL Server detects deleted rows for all updatable cursor types, although the detection is transient for forward and
dynamic cursors.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
doesMaxRowSizeIncludeBlobs Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean doesMaxRowSizeIncludeBlobs()
Return Value
true if the return value includes the data types. Otherwise, false .
Exceptions
SQLServerException
Remarks
This doesMoxRowSizeIncludeBlobs method is specified by the doesMoxRowSizeIncludeBlobs method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getAttributes Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported by the Microsoft JDBC Driver for SQL Server. If called, it will always return an
empty result set.
Syntax
public java.sql.ResultSet getAttributes(java.lang.String catalog,
java.lang.String schemaPattern,
java.lang.String typeNamePattern,
java.lang.String attributeNamePattern)
Parameters
catalog
A String that contains the catalog name.
schemaPattern
A String that contains the schema name pattern.
typeNamePattern
A String that contains the type name pattern.
attributePattern
A String that contains the attribute name pattern.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getAttributes method is specified by the getAttributes method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getBestRowIdentifier Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getBestRowIdentifier(java.lang.String catalog,
java.lang.String schema,
java.lang.String table,
int scope,
boolean nullable)
Parameters
catalog
A String that contains the catalog name.
schema
A String that contains the schema name.
table
A String that contains the table name.
scope
An int that indicates the scope of interest. Values can include the following:
bestRowTemporary (0)
bestRowTransaction (1)
bestRowSession (2)
nullable
true to include nullable columns. Otherwise, false .
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getBestRowIdentifier method is specified by the getBestRowIdentifier method in the
java.sql.DatabaseMetaData interface.
The result set returned by the getBestRowIdentifier method will contain the following information:
bestRowTemporary (0)
bestRowTransaction (1)
bestRowSession (2)
bestRowUnknown (0)
bestRowNotPseudo (1)
bestRowPseudo (2)
Example
The following example demonstrates how to use the getBestRowIdentifier method to return information about
the best row identifier for the Person.Contact table in the sample database.
public static void executeGetBestRowIdentifier(Connection con) {
try {
DatabaseMetaData dbmd = con.getMetaData();
ResultSet rs = dbmd.getBestRowIdentifier(null, "Person", "Contact", 0, true);
ResultSetMetaData rsmd = rs.getMetaData();
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getCatalogs Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getCatalogs()
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getCatalogs method is specified by the getCatalogs method in the java.sql.DatabaseMetaData interface.
NOTE
On Azure SQL Database, you should connect to the master database to call
SQLSer verDatabaseMetaData.getCatalogs . SQL Database does not support returning the entire set of catalogs
from a user database. SQLSer verDatabaseMetaData.getCatalogs uses the sys.databases view to get the catalogs.
Please refer to the discussion of permissions in sys.database_usage (Azure SQL Database) to understand
SQLSer verDatabaseMetaData.getCatalogs behavior on SQL > On Azure SQL Database, you should connect to the
master database to call SQLSer verDatabaseMetaData.getCatalogs . SQL Database does not support returning the
entire set of catalogs from a user database. SQLSer verDatabaseMetaData.getCatalogs uses the sys.databases view
to get the catalogs. Please refer to the discussion of permissions in sys.database_usage (Azure SQL Database) to
understand SQLSer verDatabaseMetaData.getCatalogs behavior on SQL Database. .
The result set returned by the getCatalogs method will contain the following information:
Example
The following example demonstrates how to use the getCatalogs method to return the names of all the
databases that are contained in Microsoft SQL Server, including the system databases.
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getCatalogSeparator Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getCatalogSeparator()
Return Value
A String that contains the catalog separator.
Exceptions
SQLServerException
Remarks
This getCatalogSeparator method is specified by the getCatalogSeparator method in the
java.sql.DatabaseMetaData interface.
When using the Microsoft JDBC Driver for SQL Server with a SQL Server database, this method returns a period
(".") as the catalog separator.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getCatalogTerm Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getCatalogTerm()
Return Value
A String that contains the catalog term.
Exceptions
SQLServerException
Remarks
This getCatalogTerm method is specified by the getCatalogTerm method in the java.sql.DatabaseMetaData
interface.
When using the Microsoft JDBC Driver for SQL Server with a SQL Server database, this method will return the
term "database".
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getClientInfoProperties Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getClientInfoProperties()
Return Value
A ResultSet object.
Exceptions
SQLServerException
Remarks
This getClientInfoProperties method is specified by the getClientInfoProperties method in the
java.sql.DatabaseMetaData interface.
NOTE
This method returns an empty result set. The driver supports setting only the applicationName and sets the
applicationName only at connection time. SQL Server does not support updating the client application information
after the connection is established.
See Also
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getColumnPrivileges Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getColumnPrivileges(java.lang.String catalog,
java.lang.String schema,
java.lang.String table,
java.lang.String col)
Parameters
catalog
A String that contains the catalog name.
schema
A String that contains the schema name.
table
A String that contains the table name.
col
A String that contains the column name pattern.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getColumnPrivileges method is specified by the getColumnPrivileges method in the
java.sql.DatabaseMetaData interface.
The result set returned by the getColumnPrivileges method will contain the following information:
NOTE
For more information about the data returned by the getColumnPrivileges method, see "sp_column_privileges (Transact-
SQL)" in SQL Server Books Online.
Example
The following example demonstrates how to use the getColumnPrivileges method to return the access rights for
the FirstName column in the Person.Contact table in the sample database.
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getColumns Method
(SQLServerDatabaseMetaData)
4/27/2022 • 5 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getColumns(java.lang.String catalog,
java.lang.String schema,
java.lang.String table,
java.lang.String col)
Parameters
catalog
A String that contains the catalog name.
schema
A String that contains the schema name pattern.
table
A String that contains the table name pattern.
col
A String that contains the column name pattern.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getColumns method is specified by the getColumns method in the java.sql.DatabaseMetaData interface.
The result set returned by the getColumns method will contain the following information:
columnNoNulls (0)
columnNullable (1)
(1) This column will not be present if you are connecting to SQL Server 2005 (9.x).
NOTE
For more information about the data returned by the getColumns method, see "sp_columns (Transact-SQL)" in SQL Server
Books Online.
In the MicrosoftSQL Server JDBC Driver 3.0, you will see the following behavior changes from earlier versions of
the JDBC Driver:
The DATA_TYPE column has the following changes:
SQ L SERVER DATA T Y P E RET URN T Y P E IN JDB C DRIVER 2. 0 RET URN T Y P E IN JDB C DRIVER 3. 0
user-defined type less than or equal to 8 kB (result set and parameter Actual size returned by the stored
8 kB metadata) procedure.
SQ L SERVER DATA T Y P E RET URN T Y P E IN JDB C DRIVER 2. 0 RET URN T Y P E IN JDB C DRIVER 3. 0
varchar(max) -10 -9
nvarchar(max) -1 -9
user-defined type larger than 8 kB Not available in JDBC Driver 2.0 -151
geography -4 -151
geometry -4 -151
hierarchyid -4 -151
time -9 92
date -9 91
datetime2 -9 93
datetimeoffset -9 -155
Example
The following example demonstrates how to use the getColumns method to return information for the
Person.Contact table in the sample database.
import java.sql.*;
public class c1 {
public static void main(String[] args) {
String connectionUrl =
"jdbc:sqlserver://localhost:1433;databaseName=AdventureWorks;integratedsecurity=true";
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con = DriverManager.getConnection(connectionUrl);
DatabaseMetaData dbmd = con.getMetaData();
rs = dbmd.getColumns("AdventureWorks", "Person", "Contact", "FirstName");
if (r.next())
for (int i = 0 ; i < noofcols ; i++ )
System.out.println(rm.getColumnName( i + 1 ) + ": \t\t" + r.getString( i + 1 ));
}
catch (Exception e) {}
finally {}
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getConnection Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Connection getConnection()
Return Value
A SQLServerConnection object.
Exceptions
SQLServerException
Remarks
This getConnection method is specified by the getConnection method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getCrossReference Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getCrossReference(java.lang.String cat1,
java.lang.String schem1,
java.lang.String tab1,
java.lang.String cat2,
java.lang.String schem2,
java.lang.String tab2)
Parameters
cat1
A String that contains the catalog name of the table that contains the primary key.
schem1
A String that contains the schema name of the table that contains the primary key.
tab1
A String that contains the table name of the table that contains the primary key.
cat2
A String that contains the catalog name of the table that contains the foreign key.
schem2
A String that contains the schema name of the table that contains the foreign key.
tab2
A String that contains the table name of the table that contains the foreign key.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getCrossReference method is specified by the getCrossReference method in the java.sql.DatabaseMetaData
interface.
The result set returned by the getCrossReference method will contain the following information:
importedKeyNoAction (3)
importedKeyCascade (0)
importedKeySetNull (2)
importedKeySetDefault (4)
importedKeyRestrict (1)
importedKeyNoAction (3)
importedKeyCascade (0)
importedKeySetNull (2)
importedKeySetDefault (4)
importedKeyRestrict (1)
NAME TYPE DESC RIP T IO N
importedKeyInitiallyDeferred (5)
importedKeyInitiallyImmediate (6)
importedKeyNotDeferrable (7)
NOTE
For more information about the data returned by the getCrossReference method, see "sp_fkeys (Transact-SQL)" in SQL
Server Books Online.
Example
The following example demonstrates how to use the getCrossReference method to return information about the
primary and foreign key relationship between the Person.Contact and HumanResources.Employee tables in the
sample database.
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getDatabaseMajorVersion Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getDatabaseMajorVersion()
Return Value
An int that indicates the database major version.
Exceptions
SQLServerException
Remarks
This getDatabaseMajorVersion method is specified by the getDatabaseMajorVersion method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getDatabaseMinorVersion Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getDatabaseMinorVersion()
Return Value
An int that indicates the database minor version.
Exceptions
SQLServerException
Remarks
This getDatabaseMinorVersion method is specified by the getDatabaseMinorVersion method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getDatabaseProductName Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getDatabaseProductName()
Return Value
A String that contains the database product name.
Exceptions
SQLServerException
Remarks
This getDatabaseProductName method is specified by the getDatabaseProductName method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getDatabaseProductVersion Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getDatabaseProductVersion()
Return Value
A String that contains the database product version number.
Exceptions
SQLServerException
Remarks
This getDatabaseProductVersion method is specified by the getDatabaseProductVersion method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getDefaultTransactionIsolation Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getDefaultTransactionIsolation()
Return Value
An int that indicates the default transaction isolation level.
Exceptions
SQLServerException
Remarks
This getDefaultTransactionIsolation method is specified by the getDefaultTransactionIsolation method in the
java.sql.DatabaseMetaData interface.
When using the Microsoft JDBC Driver for SQL Server with a SQL Server database, this method returns either a
value of TRANSACTION_READ_COMMITTED, or the int value 2.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getDriverMajorVersion Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getDriverMajorVersion()
Return Value
An int that indicates the JDBC driver major version.
Exceptions
SQLServerException
Remarks
This getDriverMajorVersion method is specified by the getDriverMajorVersion method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getDriverMinorVersion Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getDriverMinorVersion()
Return Value
An int that indicates the JDBC driver minor version.
Exceptions
SQLServerException
Remarks
This getDriverMinorVersion method is specified by the getDriverMinorVersion method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getDriverName Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getDriverName()
Return Value
A String that contains the JDBC driver name.
Exceptions
SQLServerException
Remarks
This getDriverName method is specified by the getDriverName method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getDriverVersion Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getDriverVersion()
Return Value
A String that contains the JDBC driver version.
Exceptions
SQLServerException
Remarks
This getDriverVersion method is specified by the getDriverVersion method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getExportedKeys Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getExportedKeys(java.lang.String cat,
java.lang.String schema,
java.lang.String table)
Parameters
cat
A String that contains the catalog name.
schema
A String that contains the schema name.
table
A String that contains the table name.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getExportedKeys method is specified by the getExportedKeys method in the java.sql.DatabaseMetaData
interface.
The result set returned by the getExportedKeys method will contain the following information:
importedKeyNoAction (3)
importedKeyCascade (0)
importedKeySetNull (2)
importedKeySetDefault (4)
importedKeyRestrict (1)
importedKeyNoAction (3)
importedKeyCascade (0)
importedKeySetNull (2)
importedKeySetDefault (4)
importedKeyRestrict (1)
importedKeyInitiallyDeferred (5)
importedKeyInitiallyImmediate (6)
importedKeyNotDeferrable (7)
NOTE
For more information about the data returned by the getExportedKeys method, see "sp_fkeys (Transact-SQL)" in SQL
Server Books Online.
Example
The following example demonstrates how to use the getExportedKeys method to return information about all
the foreign keys that reference the primary keys of the Person.Contact table in the sample database.
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getExtraNameCharacters Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getExtraNameCharacters()
Return Value
A String that contains the extra characters.
Exceptions
SQLServerException
Remarks
This getExtraNameCharacters method is specified by the getExtraNameCharacters method in the
java.sql.DatabaseMetaData interface.
When using the Microsoft JDBC Driver for SQL Server with a SQL Server database, this method returns the $, #,
and @ extra characters.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getFunctions Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public ResultSet getFunctions(java.lang.String catalog,
java.lang.String schemaPattern,
java.lang.String functionNamePattern)
Parameters
catalog
The name of a catalog in the database. If it is an empty string "", the result includes the functions without a
catalog. If it is null , the catalog name is not used for search.
schemaPattern
The name of a schema. If it is an empty string "", the result includes the functions without a schema. If it is null ,
the schema name is not used for search.
functionNamePattern
The name of a function.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getFunctions method is specified by the getFunctions method in the java.sql.DatabaseMetaData interface.
This method returns only the system and user functions that match the specified schema and function name.
IMPORTANT
The returned result set can contain functions that the calling user does not have permissions to execute.
SQL_PT_UNKNOWN (0)
SQL_PT_PROCEDURE (1)
SQL_PT_FUNCTION (2)
All the descriptions in the returned result set are ordered by FUNCTION_CAT, FUNCTION_SCHEM,
FUNCTION_NAME, and SPECIFIC_NAME.
See Also
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getFunctionColumns Method
(SQLServerDatabaseMetaData)
4/27/2022 • 3 minutes to read • Edit Online
Syntax
public ResultSet getFunctionColumns(java.lang.String catalog,
java.lang.String schemaPattern,
java.lang.String functionNamePattern
java.lang.String columnNamePattern)
Parameters
catalog
A String that contains the catalog name. If it is an empty string "", the result includes the functions without a
catalog. If it is null , the catalog name is not used for search.
schemaPattern
A String that contains the schema name pattern. If it is an empty string "", the result includes the functions
without a schema. If it is null , the schema name is not used for search.
functionNamePattern
A String that contains the name of a function.
columnNamePattern
A String that contains the name of a parameter.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getFunctionColumns method is specified by the getFunctionColumns method in the
java.sql.DatabaseMetaData interface.
This method returns only the functions and parameters matching the specified schema, function name, and
parameter name within the specified catalog.
Each row in the result set includes the following columns for a parameter description, a column description, or a
return type:
NAME TYPE DESC RIP T IO N
functionColumnUnknown (0):
Unknown type.
functionColumnInOut (2):
Input/Output parameter.
functionNullableUnknown (2):
Unknown.
See Also
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getIdentifierQuoteString Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getIdentifierQuoteString()
Return Value
A String that contains the quote identifiers.
Exceptions
SQLServerException
Remarks
This getIdentifierQuoteString method is specified by the getIdentifierQuoteString method in the
java.sql.DatabaseMetaData interface.
When using the Microsoft JDBC Driver with a SQL Server database, this method returns double quotation
marks ("").
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getImportedKeys Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getImportedKeys(java.lang.String cat,
java.lang.String schema,
java.lang.String table)
Parameters
cat
A String that contains the catalog name.
schema
A String that contains the schema name.
table
A String that contains the table name.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getImportedKeys method is specified by the getImportedKeys method in the java.sql.DatabaseMetaData
interface.
The result set returned by the getImportedKeys method will contain the following information:
importedKeyNoAction (3)
importedKeyCascade (0)
importedKeySetNull (2)
importedKeySetDefault (4)
importedKeyRestrict (1)
importedKeyNoAction (3)
importedKeyCascade (0)
importedKeySetNull (2)
importedKeySetDefault (4)
importedKeyRestrict (1)
importedKeyInitiallyDeferred (5)
importedKeyInitiallyImmediate (6)
importedKeyNotDeferrable (7)
NOTE
For more information about the data returned by the getImportedKeys method, see "sp_fkeys (Transact-SQL)" in SQL
Server Books Online.
Example
The following example demonstrates how to use the getImportedKeys method to return information about all
the primary keys that reference the foreign keys of the Person.Address table in the sample database.
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getIndexInfo Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getIndexInfo(java.lang.String cat,
java.lang.String schema,
java.lang.String table,
boolean unique,
boolean approximate)
Parameters
cat
A String that contains the catalog name.
schema
A String that contains the schema name.
table
A String that contains the table name.
unique
true if only indexes for unique values are returned. false if all indexes are returned.
approximate
true if the results reflect approximate or out-of-date values. false if the results are accurate.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getIndexInfo method is specified by the getIndexInfo method in the java.sql.DatabaseMetaData interface.
The result set returned by the getIndexInfo method will contain the following information:
NAME TYPE DESC RIP T IO N
tableIndexStatistic (0)
tableIndexClustered (1)
tableIndexHashed (2)
tableIndexOther (3)
A (ascending)
D (descending)
Example
The following example demonstrates how to use the getIndexInfo method to return information about the
indexes and statistics of the Person.Contact table in the sample database.
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getJDBCMajorVersion Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getJDBCMajorVersion()
Return Value
An int that indicates the major JDBC version.
Exceptions
SQLServerException
Remarks
This getJDBCMajorVersion method is specified by the getJDBCMajorVersion method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getJDBCMinorVersion Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getJDBCMinorVersion()
Return Value
An int that indicates the minor JDBC version.
Exceptions
SQLServerException
Remarks
This getJDBCMinorVersion method is specified by the getJDBCMinorVersion method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxBinaryLiteralLength Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxBinaryLiteralLength()
Return Value
An int that indicates the maximum number of hexadecimal characters.
Exceptions
SQLServerException
Remarks
This getMaxBinaryLiteralLength method is specified by the getMaxBinaryLiteralLength method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxCatalogNameLength Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxCatalogNameLength()
Return Value
An int that indicates the maximum number of characters allowed.
Exceptions
SQLServerException
Remarks
This getMaxCatalogNameLength method is specified by the getMaxCatalogNameLength method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxCharLiteralLength Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxCharLiteralLength()
Return Value
An int that indicates the maximum number of characters allowed.
Exceptions
SQLServerException
Remarks
This getMaxCharLiteralLength method is specified by the getMaxCharLiteralLength method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxColumnNameLength Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxColumnNameLength()
Return Value
An int that indicates the maximum number of characters allowed.
Exceptions
SQLServerException
Remarks
This getMaxColumnNameLength method is specified by the getMaxColumnNameLength method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxColumnsInGroupBy Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxColumnsInGroupBy()
Return Value
An int that indicates the maximum number of columns allowed.
Exceptions
SQLServerException
Remarks
This getMaxColumnsInGroupBy method is specified by the getMaxColumnsInGroupBy method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxColumnsInIndex Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxColumnsInIndex()
Return Value
An int that indicates the maximum number of columns allowed.
Exceptions
SQLServerException
Remarks
This getMaxColumnsInIndex method is specified by the getMaxColumnsInIndex method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxColumnsInOrderBy Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxColumnsInOrderBy()
Return Value
An int that indicates the maximum number of columns allowed.
Exceptions
SQLServerException
Remarks
This getMaxColumnsInOrderBy method is specified by the getMaxColumnsInOrderBy method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxColumnsInSelect Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxColumnsInSelect()
Return Value
An int that indicates the maximum number of columns allowed.
Exceptions
SQLServerException
Remarks
This getMaxColumnsInSelect method is specified by the getMaxColumnsInSelect method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxColumnsInTable Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxColumnsInTable()
Return Value
An int that indicates the maximum number of columns allowed.
Exceptions
SQLServerException
Remarks
This getMaxColumnsInTable method is specified by the getMaxColumnsInTable method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxConnections Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxConnections()
Return Value
An int that indicates the maximum number of concurrent connections allowed.
Exceptions
SQLServerException
Remarks
This getMaxConnections method is specified by the getMaxConnections method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxCursorNameLength Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxCursorNameLength()
Return Value
An int that indicates the maximum number of characters allowed.
Exceptions
SQLServerException
Remarks
This getMaxCursorNameLength method is specified by the getMaxCursorNameLength method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxIndexLength Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxIndexLength()
Return Value
An int that indicates the maximum number of bytes allowed.
Exceptions
SQLServerException
Remarks
This getMaxIndexLength method is specified by the getMaxIndexLength method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxProcedureNameLength Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxProcedureNameLength()
Return Value
An int that indicates the maximum number of characters allowed.
Exceptions
SQLServerException
Remarks
This getMaxProcedureNameLength method is specified by the getMaxProcedureNameLength method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxRowSize Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxRowSize()
Return Value
An int that indicates the maximum number of bytes allowed.
Exceptions
SQLServerException
Remarks
This getMaxRowSize method is specified by the getMaxRowSize method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxSchemaNameLength Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxSchemaNameLength()
Return Value
An int that indicates the maximum number of characters allowed.
Exceptions
SQLServerException
Remarks
This getMaxSchemaNameLength method is specified by the getMaxSchemaNameLength method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxStatementLength Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxStatementLength()
Return Value
An int that indicates the maximum number of characters allowed.
Exceptions
SQLServerException
Remarks
This getMaxStatementLength method is specified by the getMaxStatementLength method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxStatements Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxStatements()
Return Value
An int that indicates the maximum number of active statements allowed.
Exceptions
SQLServerException
Remarks
This getMaxStatements method is specified by the getMaxStatements method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxTableNameLength Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxTableNameLength()
Return Value
An int that indicates the maximum number of characters allowed.
Exceptions
SQLServerException
Remarks
This getMaxTableNameLength method is specified by the getMaxTableNameLength method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxTablesInSelect Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxTablesInSelect()
Return Value
An int that indicates the maximum number of tables allowed.
Exceptions
SQLServerException
Remarks
This getMaxTablesInSelect method is specified by the getMaxTablesInSelect method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getMaxUserNameLength Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMaxUserNameLength()
Return Value
An int that indicates the maximum number of characters allowed.
Exceptions
SQLServerException
Remarks
This getMaxUserNameLength method is specified by the getMaxUserNameLength method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getNumericFunctions Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getNumericFunctions()
Return Value
A String that contains the available math functions.
Exceptions
SQLServerException
Remarks
This getNumericFunctions method is specified by the getNumericFunctions method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getPrimaryKeys Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getPrimaryKeys(java.lang.String cat,
java.lang.String schema,
java.lang.String table)
Parameters
cat
A String that contains the catalog name.
schema
A String that contains the schema name.
table
A String that contains the table name.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getPrimaryKeys method is specified by the getPrimaryKeys method in the java.sql.DatabaseMetaData
interface.
The result set returned by the getPrimaryKeys method will contain the following information:
NOTE
For more information about the data returned by the getPrimaryKeys method, see "sp_pkeys (Transact-SQL)" in SQL
Server Books Online.
Example
The following example demonstrates how to use the getPrimaryKeys method to return information about the
primary keys of the Person.Contact table in the sample database.
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getProcedureColumns Method
(SQLServerDatabaseMetaData)
4/27/2022 • 3 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getProcedureColumns(java.lang.String sCatalog,
java.lang.String sSchema,
java.lang.String proc,
java.lang.String col)
Parameters
sCatalog
A String that contains the catalog name. Providing a null to this parameter indicates that the catalog name does
not need to be used.
sSchema
A String that contains the schema name pattern. Providing a null to this parameter indicates that the schema
name does not need to be used.
proc
A String that contains the procedure name pattern.
col
A String that contains the column name pattern. Providing a null to this parameter returns a row for each
column.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getProcedureColumns method is specified by the getProcedureColumns method in the
java.sql.DatabaseMetaData interface.
The result set returned by the getProcedureColumns method will contain the following information:
NAME TYPE DESC RIP T IO N
procedureColumnUnknown (0)
procedureColumnIn (1)
procedureColumnInOut (2)
procedureColumnOut (4)
procedureColumnReturn (5)
procedureColumnResult (3)
procedureNoNulls (0)
procedureNullable (1)
procedureNullableUnknown (2)
NOTE
For more information about the data returned by the getProcedureColumns method, see "sp_sproc_columns (Transact-
SQL)" in SQL Server Books Online.
Example
The following example demonstrates how to use the getProcedureColumns method to return information about
the uspGetBillOfMaterials stored procedure in the sample database.
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getProcedures Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getProcedures(java.lang.String sCatalog,
java.lang.String sSchema,
java.lang.String proc)
Parameters
sCatalog
A String that contains the catalog name. Providing a null to this parameter indicates that the catalog name does
not need to be used.
sSchema
A String that contains the schema name pattern. Providing a null to this parameter indicates that the schema
name does not need to be used.
proc
A String that contains the procedure name pattern.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getProcedures method is specified by the getProcedures method in the java.sql.DatabaseMetaData
interface.
The result set returned by the getProcedures method will contain the following information:
SQL_PT_UNKNOWN (0)
SQL_PT_PROCEDURE (1)
SQL_PT_FUNCTION (2)
NOTE
For more information about the data returned by the getProcedures method, see "sp_stored_procedures (Transact-SQL)"
in SQL Server Books Online.
Example
The following example demonstrates how to use the getProcedures method to return information about the
uspGetBillOfMaterials stored procedure in the sample database.
public static void executeGetProcedures(Connection con) {
try {
DatabaseMetaData dbmd = con.getMetaData();
ResultSet rs = dbmd.getProcedures(null, null, "uspGetBillOfMaterials");
ResultSetMetaData rsmd = rs.getMetaData();
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getProcedureTerm Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getProcedureTerm()
Return Value
A String that contains the procedure term.
Exceptions
SQLServerException
Remarks
This getProcedureTerm method is specified by the getProcedureTerm method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getResultSetHoldability Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getResultSetHoldability()
Return Value
An int that indicates the default holdability.
Exceptions
SQLServerException
Remarks
This getResultSetHoldability method is specified by the getResultSetHoldability method in the
java.sql.DatabaseMetaData interface.
When using the Microsoft JDBC Driver for SQL Server with a SQL Server database, this methods returns 1,
which is equivalent to the ResultSet.HOLD_CURSORS_OVER_COMMIT constant.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getRowIdLifetime Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.RowIdLifetime getRowIdLifetime()
Return Value
A RowIdLifetime object.
NOTE
In the JDBC Driver version 2.0 release, this method returns java.sql.RowIdLifetime.ROWID_UNSUPPORTED value.
Exceptions
SQLServerException
Remarks
This getRowIdLifetime method is specified by the getRowIdLifetime method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getSchemas Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getSchemas Method () Retrieves the schema names that are available in the current
database.
getSchemas Method (String, String) Retrieves the schema names that are available in the current
database by using the specified catalog name and the
schema name.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getSchemas Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getSchemas()
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getSchemas method is specified by the getSchemas method in the java.sql.DatabaseMetaData interface.
The result set returned by the getSchemas method contains the following information:
The results are ordered by TABLE_CATALOG, and then TABLE_SCHEM. Each row has TABLE_SCHEM as the first
column and TABLE_CATALOG as the second column.
NOTE
For more information about the data returned by the getSchemas method, see "sys.schemas (Transact-SQL)" in SQL
Server Books Online.
Example
The following example demonstrates how to use the getSchemas method to return information about the
catalog and its associated schema names in SQL Server when the connection argument specifies the database
to be used.
public static void executeGetSchemas(Connection con) {
try {
DatabaseMetaData dbmd = con.getMetaData();
ResultSet rs = dbmd.getSchemas();
ResultSetMetaData rsmd = rs.getMetaData();
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getSchemas Method (String, String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public ResultSet getSchemas(java.lang.String catalog,
java.lang.String schemaPattern)
Parameters
catalog
The name of a catalog in the database. If it is an empty string "", the result includes the schemas without a
catalog. If it is null , the catalog name is not used for search.
schemaPattern
The name of a schema. If it is null , the schema name is not used for search.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getSchemas method is specified by the getSchemas method in the java.sql.DatabaseMetaData interface.
The result set returned by the getSchemas method contains the following information:
The results are ordered by TABLE_CATALOG and then TABLE_SCHEM. Each row has TABLE_SCHEM as the first
column and TABLE_CATALOG as the second column.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getSchemaTerm Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getSchemaTerm()
Return Value
A String that contains the preferred term.
Exceptions
SQLServerException
Remarks
This getSchemaTerm method is specified by the getSchemaTerm method in the java.sql.DatabaseMetaData
interface.
When using the Microsoft JDBC Driver for SQL Server with a SQL Server database, this method returns
"schema" as the preferred term.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getSearchStringEscape Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getSearchStringEscape()
Return Value
A String that contains the escape wildcard character String.
Exceptions
SQLServerException
Remarks
This getSearchStringEscape method is specified by the getSearchStringEscape method in the
java.sql.DatabaseMetaData interface.
This method is used only for metadata pattern searches. It returns "\". A String search pattern can escape
wildcards ("%" and "_") and provide them as literals by prepending a backslash. This translates "\%" to "[%]" and
"\_" to "[_]".
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getSQLKeywords Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getSQLKeywords()
Return Value
A String that contains the SQL keywords.
Exceptions
SQLServerException
Remarks
This getSQLKeywords method is specified by the getSQLKeywords method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getSQLStateType Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getSQLStateType()
Return Value
An int that indicates the type of SQLSTATE, which can be one of the following values:
For Java Runtime Environment version 5.0: If the xopenStates connection property is set to true , this
method returns DatabaseMetaData.sqlStateXOpen. Otherwise, DatabaseMetaData.sqlStateSQL99.
For Java Runtime Environment version 6.0: If the xopenStates connection property is set to true , this
method returns DatabaseMetaData.sqlStateXOpen. Otherwise, DatabaseMetaData.sqlStateSQL.
Exceptions
SQLServerException
Remarks
This getSQLStateType method is specified by the getSQLStateType method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getStringFunctions Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getStringFunctions()
Return Value
A String that contains the String functions.
Exceptions
SQLServerException
Remarks
This getStringFunctions method is specified by the getStringFunctions method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getSuperTables Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported with the Microsoft JDBC Driver for SQL Server. When used, this method will
always return an empty result set.
Syntax
public java.sql.ResultSet getSuperTables(java.lang.String catalog,
java.lang.String schemaPattern,
java.lang.String tableNamePattern)
Parameters
catalog
A String that contains the catalog name.
schemaPattern
A String that contains the schema name pattern.
tableNamePattern
A String that contains the table name pattern.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getSuperTables method is specified by the getSuperTables method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getSuperTypes Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported with the Microsoft JDBC Driver for SQL Server. When used, this method will
always return an empty result set.
Syntax
public java.sql.ResultSet getSuperTypes(java.lang.String catalog,
java.lang.String schemaPattern,
java.lang.String typeNamePattern)
Parameters
catalog
A String that contains the catalog name.
schemaPattern
A String that contains the schema name pattern.
tableNamePattern
A String that contains the table name pattern.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getSuperTypes method is specified by the getSuperTypes method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getSystemFunctions Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getSystemFunctions()
Return Value
A String that contains the list of system functions.
Exceptions
SQLServerException
Remarks
This getSystemFunctions method is specified by the getSystemFunctions method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getTablePrivileges Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getTablePrivileges(java.lang.String catalog,
java.lang.String schema,
java.lang.String table)
Parameters
catalog
A String that contains the catalog name. Providing a null to this parameter indicates that the catalog name does
not need to be used.
schema
A String that contains the schema name pattern. Providing a null to this parameter indicates that the schema
name does not need to be used.
table
A String that contains the table name pattern.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getTablePrivileges method is specified by the getTablePrivileges method in the java.sql.DatabaseMetaData
interface.
The result set returned by the getTablePrivileges method will contain the following information:
NOTE
For more information about the data returned by the getTablePrivileges method, see "sp_table_privileges (Transact-SQL)"
in SQL Server Books Online.
Example
The following example demonstrates how to use the getTablePrivileges method to return the access rights for
the Person.Contact table in the sample database.
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getTables Method (SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getTables(java.lang.String catalog,
java.lang.String schema,
java.lang.String table,
java.lang.String[] types)
Parameters
catalog
A String that contains the catalog name. Providing a null to this parameter indicates that the catalog name does
not need to be used.
schema
A String that contains the schema name pattern. Providing a null to this parameter indicates that the schema
name does not need to be used.
tableName
A String that contains the table name pattern.
types
An array of strings that contain the types of tables to include. Null indicates that all types of tables should be
included.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getTables method is specified by the getTables method in the java.sql.DatabaseMetaData interface.
The result set returned by the getTables method will contain the following information:
NOTE
For more information about the data returned by the getTables method, see "sp_tables (Transact-SQL)" in SQL Server
Books Online.
Example
The following example demonstrates how to use the getTables method to return the table description
information for the Person.Contact table in the sample database.
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getTableTypes Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getTableTypes()
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getTableTypes method is specified by the getTableTypes method in the java.sql.DatabaseMetaData interface.
The result set returned by the getTableTypes method will contain the following information:
NOTE
For more information about the data returned by the getTableTypes method, see "sp_tables (Transact-SQL)" in SQL Server
Books Online.
Example
The following example demonstrates how to use the getTableTypes method to return the table type information
in the sample database, given that the database is specified in the connection String.
public static void executeGetTableTypes(Connection con) {
try {
DatabaseMetaData dbmd = con.getMetaData();
ResultSet rs = dbmd.getTableTypes();
ResultSetMetaData rsmd = rs.getMetaData();
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getTimeDateFunctions Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getTimeDateFunctions()
Return Value
A String that contains a list of the time and date functions.
Exceptions
SQLServerException
Remarks
This getTimeDateFunctions method is specified by the getTimeDateFunctions method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getTypeInfo Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getTypeInfo()
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getTypeInfo method is specified by the getTypeInfo method in the java.sql.DatabaseMetaData interface.
The result set returned by the getTypeInfo method will contain the following information:
typeNoNulls (0)
typeNullable (1)
typeNullableUnknown (2)
typePredNone (0)
typePredChar (1)
typePredBasic (2)
typeSeachable (3)
NOTE
For more information about the data returned by the getTypeInfo method, see "sp_datatype_info (Transact-SQL)" in SQL
Server Books Online.
Example
The following example demonstrates how to use the getTypeInfo method to return information about the data
types used in a SQL Server 2005 (9.x) (or later) database.
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getUDTs Method (SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported with Microsoft JDBC Driver for SQL Server. When used, this method will always
return an empty result set.
Syntax
public java.sql.ResultSet getUDTs(java.lang.String catalog,
java.lang.String schemaPattern,
java.lang.String typeNamePattern,
int[] types)
Parameters
catalog
A String that contains the catalog name.
schemaPattern
A String that contains the schema name pattern.
typeNamePattern
A String that contains the type name pattern.
types
An array of ints that contain the data types to include. Null indicates that all types should be included.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getUDTs method is specified by the getUDTs method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getURL Method (SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getURL()
Return Value
A String that contains the URL.
Exceptions
SQLServerException
Remarks
This getURL method is specified by the getURL method in the java.sql.DatabaseMetaData interface.
When using the Microsoft JDBC Driver for SQL Server with a SQL Server database, this method returns a String
value that contains the following information:
A URL value of "jdbc:sqlserver://"
Optional connection properties, such as ser verName , instanceName , and por tNumber
Other connection properties set by the user and all connection properties with non-empty or non-null
driver default values except userName , password , and integratedSecurity .
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getUserName Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getUserName()
Return Value
A String that contains the user name.
Exceptions
SQLServerException
Remarks
This getUserName method is specified by the getUserName method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
getVersionColumns Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet getVersionColumns(java.lang.String catalog,
java.lang.String schema,
java.lang.String table)
Parameters
catalog
A String that contains the catalog name.
schema
A String that contains the schema name pattern.
table
A String that contains the table name.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This getVersionColumns method is specified by the getVersionColumns method in the
java.sql.DatabaseMetaData interface.
The result set returned by the getVersionColumns method will contain the following information:
versionColumnUnknown (0)
versionColumnNotPseudo (1)
versionColumnPseudo (2)
NOTE
For more information about the data returned by the getVersionColumns method, see "sp_datatype_info (Transact-SQL)"
in SQL Server Books Online.
Example
The following example demonstrates how to use the getVersionColumns method to return information about
the columns that are automatically updated in the Person.Contact table in the sample database.
catch (Exception e) {
e.printStackTrace();
}
}
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
insertsAreDetected Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean insertsAreDetected(int type)
Parameters
type
An integer that indicates the result set type, which can be one of the following values as defined in
java.sql.ResultSet or SQLServerResultSet:
java.sql.ResultSet Types
TYPE_FORWARD_ONLY
TYPE_SCROLL_SENSITIVE
TYPE_SCROLL_INSENSITIVE
SQLServerResultSet Types
TYPE_SS_SCROLL_STATIC
TYPE_SS_SCROLL_KEYSET
TYPE_SS_DIRECT_FORWARD_ONLY
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY
TYPE_SS_SCROLL_DYNAMIC
Return Value
true if the row insert can be detected. Otherwise, false .
Exceptions
SQLServerException
Remarks
This insertsAreDetected method is specified by the insertsAreDetected method in the java.sql.DatabaseMetaData
interface.
NOTE
SQL Server does not detect inserted rows for any cursor type.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
isCatalogAtStart Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isCatalogAtStart()
Return Value
true if the catalog name is first. Otherwise, false .
Exceptions
SQLServerException
Remarks
This isCatalogAtStart method is specified by the isCatalogAtStart method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
isReadOnly Method (SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isReadOnly()
Return Value
true if the database is in read-only mode. Otherwise, false .
Exceptions
SQLServerException
Remarks
This isReadOnly method is specified by the isReadOnly method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
locatorsUpdateCopy Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean locatorsUpdateCopy()
Return Value
true if updates are made to a copy. false if updates are made directly.
Exceptions
java.sql.SQLException
Remarks
This locatorsUpdateCopy method is specified by the locatorsUpdateCopy method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
nullPlusNonNullIsNull Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean nullPlusNonNullIsNull()
Return Value
true if the concatenations are supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This nullPlusNonNullIsNull method is specified by the nullPlusNonNullIsNull method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
nullsAreSortedAtEnd Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean nullsAreSortedAtEnd()
Return Value
true if sorted at the end. Otherwise, false .
Exceptions
SQLServerException
Remarks
This nullsAreSortedAtEnd method is specified by the nullsAreSortedAtEnd method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
nullsAreSortedAtStart Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean nullsAreSortedAtStart()
Return Value
true if sorted at the start. Otherwise, false .
Exceptions
SQLServerException
Remarks
This nullsAreSortedAtStart method is specified by the nullsAreSortedAtStart method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
nullsAreSortedHigh Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean nullsAreSortedHigh()
Return Value
true if the values are sorted high. Otherwise, false .
Exceptions
SQLServerException
Remarks
This nullsAreSortedHigh method is specified by the nullsAreSortedHigh method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
nullsAreSortedLow Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean nullsAreSortedLow()
Return Value
true if the values are sorted low. Otherwise, false .
Exceptions
SQLServerException
Remarks
This nullsAreSortedLow method is specified by the nullsAreSortedLow method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
othersDeletesAreVisible Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean othersDeletesAreVisible(int type)
Parameters
type
An int that indicates the result set type, which can be one of the following values as defined in java.sql.ResultSet
or SQLServerResultSet:
java.sql.ResultSet Types
TYPE_FORWARD_ONLY
TYPE_SCROLL_SENSITIVE
TYPE_SCROLL_INSENSITIVE
SQLServerResultSet Types
TYPE_SS_SCROLL_STATIC
TYPE_SS_SCROLL_KEYSET
TYPE_SS_DIRECT_FORWARD_ONLY
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY
TYPE_SS_SCROLL_DYNAMIC
Return Value
true if the deletes are visible. Otherwise, false .
Exceptions
SQLServerException
Remarks
This othersDeletesAreVisible method is specified by the othersDeletesAreVisible method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
othersInsertsAreVisible Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean othersInsertsAreVisible(int type)
Parameters
type
An int that indicates the result set type, which can be one of the following values as defined in java.sql.ResultSet
or SQLServerResultSet:
java.sql.ResultSet Types
TYPE_FORWARD_ONLY
TYPE_SCROLL_SENSITIVE
TYPE_SCROLL_INSENSITIVE
SQLServerResultSet Types
TYPE_SS_SCROLL_STATIC
TYPE_SS_SCROLL_KEYSET
TYPE_SS_DIRECT_FORWARD_ONLY
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY
TYPE_SS_SCROLL_DYNAMIC
Return Value
true if the inserts are visible. Otherwise, false .
Exceptions
SQLServerException
Remarks
This othersInsertsAreVisible method is specified by the othersInsertsAreVisible method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
othersUpdatesAreVisible Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean othersUpdatesAreVisible(int type)
Parameters
type
An int that indicates the result set type, which can be one of the following values as defined in java.sql.ResultSet
or SQLServerResultSet:
java.sql.ResultSet Types
TYPE_FORWARD_ONLY
TYPE_SCROLL_SENSITIVE
TYPE_SCROLL_INSENSITIVE
SQLServerResultSet Types
TYPE_SS_SCROLL_STATIC
TYPE_SS_SCROLL_KEYSET
TYPE_SS_DIRECT_FORWARD_ONLY
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY
TYPE_SS_SCROLL_DYNAMIC
Return Value
true if the updates are visible. Otherwise, false .
Exceptions
SQLServerException
Remarks
This othersUpdatesAreVisible method is specified by the othersUpdatesAreVisible method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
ownDeletesAreVisible Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean ownDeletesAreVisible(int type)
Parameters
type
An int that indicates the result set type, which can be one of the following values as defined in java.sql.ResultSet
or SQLServerResultSet:
java.sql.ResultSet Types
TYPE_FORWARD_ONLY
TYPE_SCROLL_SENSITIVE
TYPE_SCROLL_INSENSITIVE
SQLServerResultSet Types
TYPE_SS_SCROLL_STATIC
TYPE_SS_SCROLL_KEYSET
TYPE_SS_DIRECT_FORWARD_ONLY
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY
TYPE_SS_SCROLL_DYNAMIC
Return Value
true if the deletes are visible. Otherwise, false .
Exceptions
SQLServerException
Remarks
This ownDeletesAreVisible method is specified by the ownDeletesAreVisible method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
ownInsertsAreVisible Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean ownInsertsAreVisible(int type)
Parameters
type
An int that indicates the result set type, which can be one of the following values as defined in java.sql.ResultSet
or SQLServerResultSet:
java.sql.ResultSet Types
TYPE_FORWARD_ONLY
TYPE_SCROLL_SENSITIVE
TYPE_SCROLL_INSENSITIVE
SQLServerResultSet Types
TYPE_SS_SCROLL_STATIC
TYPE_SS_SCROLL_KEYSET
TYPE_SS_DIRECT_FORWARD_ONLY
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY
TYPE_SS_SCROLL_DYNAMIC
Return Value
true if the inserts are visible. Otherwise, false .
Exceptions
SQLServerException
Remarks
This ownInsertsAreVisible method is specified by the ownInsertsAreVisible method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
ownUpdatesAreVisible Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean othersUpdatesAreVisible(int type)
Parameters
type
An integer that indicates the result set type, which can be one of the following values as defined in
java.sql.ResultSet or SQLServerResultSet:
java.sql.ResultSet Types
TYPE_FORWARD_ONLY
TYPE_SCROLL_SENSITIVE
TYPE_SCROLL_INSENSITIVE
SQLServerResultSet Types
TYPE_SS_SCROLL_STATIC
TYPE_SS_SCROLL_KEYSET
TYPE_SS_DIRECT_FORWARD_ONLY
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY
TYPE_SS_SCROLL_DYNAMIC
Return Value
true if the updates are visible. Otherwise, false .
Exceptions
SQLServerException
Remarks
This ownUpdatesAreVisible method is specified by the ownUpdatesAreVisible method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
storesLowerCaseIdentifiers Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean storesLowerCaseIdentifiers()
Return Value
true if the identifiers are stored in lowercase. Otherwise, false .
Exceptions
SQLServerException
Remarks
This storesLowerCaseIdentifiers method is specified by the storesLowerCaseIdentifiers method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
storesLowerCaseQuotedIdentifiers Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean storesLowerCaseQuotedIdentifiers()
Return Value
true if the identifiers are stored in lowercase. Otherwise, false .
Exceptions
SQLServerException
Remarks
This storesLowerCaseQuotedIdentifiers method is specified by the storesLowerCaseQuotedIdentifiers method in
the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
storesMixedCaseIdentifiers Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean storesMixedCaseIdentifiers()
Return Value
true if the identifiers are stored in mixed case. Otherwise, false .
Exceptions
SQLServerException
Remarks
This storesMixedCaseIdentifiers method is specified by the storesMixedCaseIdentifiers method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
storesMixedCaseQuotedIdentifiers Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean storesMixedCaseQuotedIdentifiers()
Return Value
true if the identifiers are stored in mixed case. Otherwise, false .
Exceptions
SQLServerException
Remarks
This storesMixedCaseQuotedIdentifiers method is specified by the storesMixedCaseQuotedIdentifiers method in
the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
storesUpperCaseIdentifiers Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean storesUpperCaseIdentifiers()
Return Value
true if the identifiers are stored in uppercase. Otherwise, false .
Exceptions
SQLServerException
Remarks
This storesUpperCaseIdentifiers method is specified by the storesUpperCaseIdentifiers method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
storesUpperCaseQuotedIdentifiers Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean storesUpperCaseQuotedIdentifiers()
Return Value
true if the identifiers are stored in uppercase. Otherwise, false .
Exceptions
SQLServerException
Remarks
This storesUpperCaseQuotedIdentifiers method is specified by the storesUpperCaseQuotedIdentifiers method in
the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsAlterTableWithAddColumn Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsAlterTableWithAddColumn()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsAlterTableWithAddColumn method is specified by the supportsAlterTableWithAddColumn method
in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsAlterTableWithDropColumn Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsAlterTableWithDropColumn()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsAlterTableWithDropColumn method is specified by the supportsAlterTableWithDropColumn
method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsANSI92EntryLevelSQL Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsANSI92EntryLevelSQL()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsANSI92EntryLevelSQL method is specified by the supportsANSI92EntryLevelSQL method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsANSI92FullSQL Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsANSI92FullSQL()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsANSI92FullSQL method is specified by the supportsANSI92FullSQL method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsANSI92IntermediateSQL Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsANSI92IntermediateSQL()
Return value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsANSI92IntermediateSQL method is specified by the supportsANSI92IntermediateSQL method in
the java.sql.DatabaseMetaData interface.
See also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsBatchUpdates Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsBatchUpdates()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsBatchUpdates method is specified by the supportsBatchUpdates method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsCatalogsInDataManipulation Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsCatalogsInDataManipulation()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsCatalogInDataManipulation method is specified by the supportsCatalogInDataManipulation
method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsCatalogsInIndexDefinitions Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsCatalogsInIndexDefinitions()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsCatalogsInIndexDefinitions method is specified by the supportsCatalogsInIndexDefinitions method
in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsCatalogsInPrivilegeDefinitions Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsCatalogsInPrivilegeDefinitions()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsCatalogsInPrivilegeDefinitions method is specified by the supportsCatalogsInPrivilegeDefinitions
method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsCatalogsInProcedureCalls Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsCatalogsInProcedureCalls()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsCatalogsInProcedureCalls method is specified by the supportsCatalogsInProcedureCalls method in
the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsCatalogsInTableDefinitions Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsCatalogsInTableDefinitions()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsCatalogsInTableDefinitions method is specified by the supportsCatalogsInTableDefinitions method
in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsColumnAliasing Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsColumnAliasing()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsColumnAliasing method is specified by the supportsColumnAliasing method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsConvert Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
supportsConvert (int, int) Retrieves whether this database supports the CONVERT for
two given SQL types.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsConvert Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsConvert()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsConvert method is specified by the supportsConvert method in the java.sql.DatabaseMetaData
interface.
See Also
supportsConvert Method (SQLServerDatabaseMetaData)
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsConvert Method (int, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsConvert(int fromType,
int toType)
Parameters
fromType
The JDBC type to convert from.
toType
The JDBC type to convert to.
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsConvert method is specified by the supportsConvert method in the java.sql.DatabaseMetaData
interface.
See Also
supportsConvert Method (SQLServerDatabaseMetaData)
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsCoreSQLGrammar Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsCoreSQLGrammar()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsCoreSQLGrammer method is specified by the supportsCoreSQLGrammer method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsCorrelatedSubqueries Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsCorrelatedSubqueries()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsCorelatedSubqueries method is specified by the supportsCorelatedSubqueries method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsDataDefinitionAndDataManipulationTransactions
Method (SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsDataDefinitionAndDataManipulationTransactions()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This suportsDataDefinitionAndDataManipulationTransactions method is specified by the
suportsDataDefinitionAndDataManipulationTransactions method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsDataManipulationTransactionsOnly Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsDataManipulationTransactionsOnly()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsDataManipulationTransactionsOnly method is specified by the
supportsDataManipulationTransactionsOnly method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsDifferentTableCorrelationNames Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsDifferentTableCorrelationNames()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsDifferentTableCorrelationNames method is specified by the
supportsDifferentTableCorrelationNames method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsExpressionsInOrderBy Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsExpressionsInOrderBy()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsExpressionsInOrderBy method is specified by the supportsExpressionsInOrderBy method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsExtendedSQLGrammar Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsExtendedSQLGrammar()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsExtendedSQLGrammer method is specified by the supportsExtendedSQLGrammer method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsFullOuterJoins Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsFullOuterJoins()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsFullOuterJoins method is specified by the supportsFullOuterJoins method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsGetGeneratedKeys Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsGetGeneratedKeys()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsGetGeneratedKeys method is specified by the supportsGetGeneratedKeys method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsGroupBy Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsGroupBy()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsGroupBy method is specified by the supportsGroupBy method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsGroupByBeyondSelect Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsGroupByBeyondSelect()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsGroupByBeyondSelect method is specified by the supportsGroupByBeyondSelect method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsGroupByUnrelated Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsGroupByUnrelated()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsGroupByUnrelated method is specified by the supportsGroupByUnrelated method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsIntegrityEnhancementFacility Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsIntegrityEnhancementFacility()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsIntegrityEnhancementFacility method is specified by the supportsIntegrityEnhancementFacility
method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsLikeEscapeClause Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsLikeEscapeClause()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsLikeEscapeClause method is specified by the supportsLikeEscapeClause method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsLimitedOuterJoins Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsLimitedOuterJoins()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsLimitedOuterJoins method is specified by the supportsLimitedOuterJoins method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsMinimumSQLGrammar Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsMinimumSQLGrammar()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsMinimumSQLGrammer method is specified by the supportsMinimumSQLGrammer method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsMixedCaseIdentifiers Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsMixedCaseIdentifiers()
Return Value
true if the identifiers are stored in mixed case. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsMixedCaseIdentifiers method is specified by the supportsMixedCaseIdentifiers method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsMixedCaseQuotedIdentifiers Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsMixedCaseQuotedIdentifiers()
Return Value
true if the identifiers are stored in mixed case. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsMixedCaseQuotedIdentifiers method is specified by the supportsMixedCaseQuotedIdentifiers
method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsMultipleOpenResults Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsMultipleOpenResults()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsMultipleOpenResults method is specified by the supportsMultipleOpenResults method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsMultipleResultSets Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsMultipleResultSets()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsMultipleResultSets method is specified by the supportsMultipleResultSets method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsMultipleTransactions Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsMultipleTransactions()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsMultipleTransactions method is specified by the supportsMultipleTransactions method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsNamedParameters Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsNamedParameters()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsNamedParameters method is specified by the supportsNamedParameters method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsNonNullableColumns Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsNonNullableColumns()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsNonNullableColumns method is specified by the supportsNonNullableColumns method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsOpenCursorsAcrossCommit Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsOpenCursorsAcrossCommit()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsOpenCursorsAcrossCommit method is specified by the supportsOpenCursorsAcrossCommit
method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsOpenCursorsAcrossRollback Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsOpenCursorsAcrossRollback()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsOpenCursorsAcrossRollback method is specified by the supportsOpenCursorsAcrossRollback
method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsOpenStatementsAcrossCommit Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsOpenStatementsAcrossCommit()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsOpenStatementsAcrossCommit method is specified by the
supportsOpenStatementsAcrossCommit method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsOpenStatementsAcrossRollback Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsOpenStatementsAcrossRollback()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsOpenStatementsAcrossRollback method is specified by the
supportsOpenStatementsAcrossRollback method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsOrderByUnrelated Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsOrderByUnrelated()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsOrderByUnrelated method is specified by the supportsOrderByUnrelated method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsOuterJoins Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsOuterJoins()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsOuterJoins method is specified by the supportsOuterJoins method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsPositionedDelete Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsPositionedDelete()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsPositionedDelete method is specified by the supportsPositionedDelete method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsPositionedUpdate Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsPositionedUpdate()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsPositionedUpdate method is specified by the supportsPositionedUpdate method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsResultSetConcurrency Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsResultSetConcurrency(int type,
int concurrency)
Parameters
type
An int that indicates the result set type, which can be one of the following values as defined in java.sql.ResultSet
or SQLServerResultSet:
java.sql.ResultSet Types
TYPE_FORWARD_ONLY
TYPE_SCROLL_SENSITIVE
TYPE_SCROLL_INSENSITIVE
SQLServerResultSet Types
TYPE_SS_SCROLL_STATIC
TYPE_SS_SCROLL_KEYSET
TYPE_SS_DIRECT_FORWARD_ONLY
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY
TYPE_SS_SCROLL_DYNAMIC
concurrency
An int that indicates the result set concurrency level, which can be one of the following values as defined in
java.sql.ResultSet or SQLServerResultSet:
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsResultSetConcurrency method is specified by the supportsResultSetConcurrency method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsResultSetHoldability Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsResultSetHoldability(int holdability)
Parameters
holdability
An int that indicates the result set holdability, which can be one of the following values:
ResultSet.HOLD_CURSORS_OVER_COMMIT
ResultSet.CLOSE_CURSORS_AT_COMMIT
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsResultSetHoldability method is specified by the supportsResultSetHoldability method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsResultSetType Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsResultSetType(int type)
Parameters
type
An int that indicates the result set type, which can be one of the following values as defined in java.sql.ResultSet
or SQLServerResultSet:
java.sql.ResultSet Types
TYPE_FORWARD_ONLY
TYPE_SCROLL_SENSITIVE
TYPE_SCROLL_INSENSITIVE
SQLServerResultSet Types
TYPE_SS_SCROLL_STATIC
TYPE_SS_SCROLL_KEYSET
TYPE_SS_DIRECT_FORWARD_ONLY
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY
TYPE_SS_SCROLL_DYNAMIC
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsResultSetType method is specified by the supportsResultSetType method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsSavepoints Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsSavepoints()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsSavepoints method is specified by the supportsSavepoints method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsSchemasInDataManipulation Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsSchemasInDataManipulation()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsSchemasInDataManipulation method is specified by the supportsSchemasInDataManipulation
method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsSchemasInIndexDefinitions Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsSchemasInIndexDefinitions()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsSchemasInIndexDefinitions method is specified by the supportsSchemasInIndexDefinitions
method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsSchemasInPrivilegeDefinitions Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsSchemasInPrivilegeDefinitions()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsSchemasInPrivilegeDefinitions method is specified by the supportsSchemasInPrivilegeDefinitions
method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsSchemasInProcedureCalls Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsSchemasInProcedureCalls()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsSchemasInProcedureCalls method is specified by the supportsSchemasInProcedureCalls method
in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsSchemasInTableDefinitions Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsSchemasInTableDefinitions()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsSchemasInTableDefinitions method is specified by the supportsSchemasInTableDefinitions method
in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsSelectForUpdate Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsSelectForUpdate()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsSelectForUpdate method is specified by the supportsSelectForUpdate method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsStatementPooling Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsStatementPooling()
Return Value
true if supported. Otherwise, false .
Exceptions
java.sql.SQLException
Remarks
This supportsStatementPooling method is specified by the supportsStatementPooling method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsStoredProcedures Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsStoredProcedures()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsStoredProcedures method is specified by the supportsStoredProcedures method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsStoredFunctionsUsingCallSyntax Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsStoredFunctionsUsingCallSyntax()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsStoredFunctionsUsingCallSyntax method is specified by the
supportsStoredFunctionsUsingCallSyntax method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsSubqueriesInComparisons Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsSubqueriesInComparisons()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsSubqueriesInComparisons method is specified by the supportsSubqueriesInComparisons method
in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsSubqueriesInExists Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsSubqueriesInExists()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsSubqueriesInExists method is specified by the supportsSubqueriesInExists method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsSubqueriesInIns Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsSubqueriesInIns()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsSubqueriesInIns method is specified by the supportsSubqueriesInIns method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsSubqueriesInQuantifieds Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsSubqueriesInQuantifieds()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsSubqueriesInQuantifieds method is specified by the supportsSubqueriesInQuantifieds method in
the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsTableCorrelationNames Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsTableCorrelationNames()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsTableCorrelationNames method is specified by the supportsTableCorrelationNames method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsTransactionIsolationLevel Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsTransactionIsolationLevel(int level)
Parameters
level
An int that indicates the transaction isolation level.
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsTransactionIsolationLevel method is specified by the supportsTransactionIsolationLevel method in
the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsTransactions Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsTransactions()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsTransactions method is specified by the supportsTransactions method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsUnion Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsUnion()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsUnion method is specified by the supportsUnion method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
supportsUnionAll Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean supportsUnionAll()
Return Value
true if supported. Otherwise, false .
Exceptions
SQLServerException
Remarks
This supportsUnionAll method is specified by the supportsUnionAll method in the java.sql.DatabaseMetaData
interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
updatesAreDetected Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean updatesAreDetected(int type)
Parameters
type
An int that indicates the result set type, which can be one of the following values as defined in java.sql.ResultSet
or SQLServerResultSet:
java.sql.ResultSet Types
TYPE_FORWARD_ONLY
TYPE_SCROLL_SENSITIVE
TYPE_SCROLL_INSENSITIVE
SQLServerResultSet Types
TYPE_SS_SCROLL_STATIC
TYPE_SS_SCROLL_KEYSET
TYPE_SS_DIRECT_FORWARD_ONLY
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY
TYPE_SS_SCROLL_DYNAMIC
Return Value
true if the row update can be detected. Otherwise, false .
Exceptions
SQLServerException
Remarks
This updatesAreDetected method is specified by the updatesAreDetected method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
usesLocalFilePerTable Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean usesLocalFilePerTable()
Return Value
true uses a file for each table. Otherwise, false .
Exceptions
SQLServerException
Remarks
This usesLocalFilePerTable method is specified by the usesLocalFilePerTable method in the
java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
usesLocalFiles Method
(SQLServerDatabaseMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean usesLocalFiles()
Return Value
true if the database uses local files. Otherwise, false .
Exceptions
SQLServerException
Remarks
This usesLocalFiles method is specified by the usesLocalFiles method in the java.sql.DatabaseMetaData interface.
See Also
SQLServerDatabaseMetaData Methods
SQLServerDatabaseMetaData Members
SQLServerDatabaseMetaData Class
SQLServerDataSource Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public class SQLServerDataSource
Remarks
This class supports unwrapping to SQLServerDataSource class, the ISQLServerDataSource interface, and the
DataSource interface. For more information, see Wrappers and Interfaces.
See Also
SQLServerDataSource Members
JDBC Driver API Reference
SQLServerDataSource Members
4/27/2022 • 4 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
Fields
None.
Inherited Fields
None.
Methods
NAME DESC RIP T IO N
getConnection Tries to establish a connection with the data source that this
SQLServerDataSource object represents.
getHostNameInCertificate Returns the host name used in validating the SQL Server
Transport Layer Security (TLS), previously known as Secure
Sockets Layer (SSL), certificate.
getSelectMethod Returns the default cursor type used for all result sets
created by using this SQLServerDataSource object.
getStatementPoolingCacheSize Returns the size of the prepared statement cache for this
connection.
getUser Returns the user name used to connect the data source.
setHostNameInCertificate Sets the host name to be used in validating the SQL Server
Transport Layer Security (TLS), previously known as Secure
Sockets Layer (SSL), certificate.
NAME DESC RIP T IO N
setLogWriter Sets a character output stream to be used for all logging and
tracing messages.
setPortNumber Sets the port number used to communicate with SQL Server.
setSelectMethod Sets the default cursor type used for all result sets created
by using this SQLServerDataSource object.
setStatementPoolingCacheSize Sets the size of the prepared statement cache for this
connection.
setTrustStorePassword Sets the password that is used to check the integrity of the
trustStore data.
setUser Sets the user name used to connect the data source.
setWorkstationID Sets the name of the client computer used to connect to the
data source.
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerDataSource Class
SQLServerDataSource Constructors
4/27/2022 • 2 minutes to read • Edit Online
See Also
SQLServerDataSource Class
SQLServerDataSource Constructor ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public SQLServerDataSource()
See Also
SQLServerDataSource Members
SQLServerDataSource Class
SQLServerDataSource Methods
4/27/2022 • 2 minutes to read • Edit Online
See Also
SQLServerDataSource Class
getApplicationIntent Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getApplicationIntent();
Return Value
Returns the value of the applicationIntent connection property.
Remarks
For more information about the applicationIntent connection property, see Setting the Connection Properties.
See Also
SQLServerDataSource.setApplicationIntent
SQLServerDataSource Members
SQLServerDataSource Class
getApplicationName Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getApplicationName()
Return Value
A String that contains the application name, or " Microsoft JDBC Driver for SQL Server" if no value is set.
Remarks
The application name is used to identify the specific application in various SQL Server profiling and logging
tools. If the application name is not set, the getApplicationName method returns the non-localized string "
Microsoft JDBC Driver for SQL Server".
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getConnection Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getConnection () Tries to establish a connection with the data source that this
SQLServerDataSource object represents.
getConnection (java.lang.String, java.lang.String) Tries to establish a connection with the data source that this
SQLServerDataSource object represents by using the given
user name and password.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getConnection Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Connection getConnection()
Return Value
A SQLServerConnection object.
Exceptions
java.sql.SQLException
Remarks
This getConnection method is specified by the getConnection method in the javax.sql.DataSource interface.
See Also
getConnection Method (SQLServerDataSource)
SQLServerDataSource Members
SQLServerDataSource Class
getConnection Method ( java.lang.String,
java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Connection getConnection(java.lang.String username,
java.lang.String password)
Parameters
username
A String that contains the user name.
password
A String that contains the password.
Return Value
A SQLServerConnection object.
Exceptions
java.sql.SQLException
Remarks
This getConnection method is specified by the getConnection method in the javax.sql.DataSource interface.
Calling the getConnection method with a non-null user name or password will replace the user name and
password properties that are set on the SQLServerDataSource class when initializing the SQLServerConnection
object. For example, if the caller has called setUser and setPassword on the data source, and then calls
getConnection and supplies a non-null user name or a non-null password, the user name and password set by
setUser and setPassword will be replaced by the user name and password passed into getConnection.
NOTE
The user name and password that are set inside the URL by using a call to the setURL method will not be changed in this
case.
See Also
getConnection Method (SQLServerDataSource)
SQLServerDataSource Members
SQLServerDataSource Class
getDatabaseName Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getDatabaseName()
Return Value
A String that contains the database name or null if no value is set.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getDescription Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getDescription()
Return Value
A String that contains the data source description or null if no value is set.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getDisableStatementPooling Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getDisableStatementPooling();
Return Value
A boolean that contains the value of disableStatementPooling connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getEnablePrepareOnFirstPreparedStatementCall
Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getEnablePrepareOnFirstPreparedStatementCall();
Return Value
Returns the boolean value of the enablePrepareOnFirstPreparedStatementCall connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getEncrypt Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getEncypt()
Return Value
true if encrypt is enabled. Otherwise, false .
Remarks
If the encrypt property is set to true , the Microsoft JDBC Driver for SQL Server ensures that SQL Server uses
TLS encryption for all data sent between the client and the server if the server has a certificate installed.
If the encrypt property is unspecified or set to false , the driver will not enforce the SQL Server to support TLS
encryption. If the SQL Server instance is not configured to force the TLS encryption, a connection is established
without any encryption. If the SQL Server instance is configured to force the TLS encryption, the Microsoft JDBC
Driver for SQL Server will automatically enable TLS encryption when running on properly configured Java
Virtual Machine (JVM), or else the connection is terminated and the driver will raise an error. If the encryption
property is not set, the getEncrypt method returns the default value of false .
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getFailoverPartner Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public string getFailoverPartner()
Return Value
A String that contains the name of the failover partner, or null if none is set.
Remarks
The value returned by this method reflects the failover partner name set using the setFailoverPartner method.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getHostNameInCertificate Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getHostNameInCertificate()
Return Value
A String that contains the host name, or null if no value is set.
Remarks
The host name is used to validate the SQL Server TLS/SSL certificate value when the communication layer is
encrypted using TLS/SSL.
If the host name is not set, the getHostNameInCertificate method returns null.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getInstanceName Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getInstanceName()
Return Value
A String that contains the instance name, or null if no value is set.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getLastUpdateCount Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getLastUpdateCount()
Return Value
true if lastUpdateCount is enabled. Otherwise, false .
Remarks
If the lastUpdateCount property is set to true , the Microsoft JDBC Driver for SQL Server will return only the last
update count from an SQL statement passed to the server. If the lastUpdateCount property is set to false , the
driver will return all update counts including those returned by any triggers that may have fired. If the
lastUpdateCount property is not set, the getLastUpdateCount method returns the default value of true .
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getLockTimeout Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getLockTimeout()
Return Value
An int value that contains the number of milliseconds that the database will wait.
Remarks
The lock time out is the number of milliseconds to wait before the database reports a lock time out. The default
value of -1 means that it will wait indefinitely. If specified, this value will be the default for all statements on the
connection.
NOTE
A value of 0 means no wait. If the lockTimeout property is not set, the getLockTimeout method returns the default value
of -1.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getLoginTimeout Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getLoginTimeout()
Return Value
An int value that represents the number of seconds to wait.
Remarks
If the application does not specify a timeout value explicitly, this method returns a default value of 15 seconds.
This getLoginTimeout method is specified by the getLoginTimeout method in the javax.sql.DataSource interface.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getLogWriter Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.PrintWriter getLogWriter()
Return Value
A PrintWriter object.
Remarks
This getLogWriter method is specified by the getLogWriter method in the javax.sql.DataSource interface.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getMultiSubnetFailover Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getMultiSubnetFailover();
Return Value
Returns true or false, depending on the current setting of the connection property.
Remarks
For more information about the multiSubnetFailover connection property, see Setting the Connection
Properties.
See Also
SQLServerDataSource.setMultiSubnetFailover
SQLServerDataSource Members
SQLServerDataSource Class
getPacketSize Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getPacketSize()
Return Value
An int value containing the current network packet size.
Remarks
If the packetSize property is not set, the getPacketSize method returns the default value of 8000.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getPortNumber Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getPortNumber()
Return Value
An int value that contains the current port number.
Remarks
The port number is the TCP/IP port number that is used when opening a socket connection to SQL Server. If the
portNumber property is not set, the getPortNumber method returns the default value of 1433.
NOTE
The setPortNumber method does not do any range checking on the port value passed in. You can pass tort numbers that
are not valid, like 99999, without triggering an error.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getReference Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public javax.naming.Reference getReference()
Return Value
A Reference object.
Remarks
This getReference method is specified by the getReference method in the javax.naming.Referenceable interface.
Prior to SQL Server JDBC Driver 3.0, if SQLServerDataSource.setTrustStorePassword was called on a
SQLServerDataSource object, the password would be present in the object returned by
SQLServerDataSource.getReference, allowing the object to be used to make additional connections. In JDBC
Driver 3.0, you will need to set the password on the object returned by SQLServerDataSource.getReference
before you make connections with the object.
Also, if you set SQLServerDataSource.setTrustStorePassword before binding the data source properties, you
must call SQLServerDataSource.setTrustStorePassword before getting the connection. For example,
ds1.setTrustStorePassword("XXXXX");
Connection con = ds1.getConnection("user", "XXXXXX");
ctx.rebind(jndiName, ds1);
SQLServerDataSource ds2 = (SQLServerDataSource) ctx.lookup(jndiName);
ds2.setTrustStorePassword("XXXXX"); // reset the truststore password
con = ds2.getConnection("user", "XXXXXX"); // provide userid and password again
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getResponseBuffering Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getResponseBuffering()
Return Value
A String that contains a lower-case full or adaptive .
Remarks
The full value specifies reading the entire result from the server at run time.
The adaptive value specifies buffering the minimum possible data when necessary. The adaptive value is the
default buffering mode.
For more information about using the response buffering mode, see Using Adaptive Buffering.
See Also
setResponseBuffering Method (SQLServerDataSource)
SQLServerDataSource Members
SQLServerDataSource Class
getSelectMethod Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getSelectMethod()
Return Value
A String value that contains the default cursor type.
Remarks
The selectMethod property specifies the default cursor type that is used for a result set. This property is useful
when you are dealing with large result sets and do not want to store the entire result set in memory on the
client side. By setting the property to "cursor," you can create a server-side cursor that can fetch smaller chunks
of data at a time. If the selectMethod property is not set, getSelectMethod returns the default value of "direct".
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getSendStringParametersAsUnicode Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getSendStringParametersAsUnicode()
Return Value
true if string parameters are sent to the server in UNICODE format. Otherwise, false .
Remarks
If the sendStringParametersAsUnicode property is set to true , which is the default value, string parameters are
sent to the server in UNICODE format. If sendStringParametersAsUnicode is set to false , string parameters are
sent to the server in an ASCII/MBCS format, not in UNICODE. If sendStringParametersAsUnicode is not set,
getSendStringParametersAsUnicode returns the default value of true .
For more information about the sendStringParametersAsUnicode connection property, see Setting the
Connection Properties.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getServerName Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getServerName()
Return Value
A String that contains the server name or null if no value is set.
Remarks
The server name is the host name of the target computer that is running SQL Server. If the getServerName
property is not set, getServerName returns the default value of null.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getServerPreparedStatementDiscardThreshold
Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getServerPreparedStatementDiscardThreshold();
Return Value
Returns the int value of the ser verPreparedStatementDiscardThreshold connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getStatementPoolingCacheSize Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getStatementPoolingCacheSize();
Return Value
The int value of the statementPoolingCacheSize connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getTrustManagerClass Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getTrustManagerClass()
Return Value
A String that contains the value of the TrustManagerClass connection property, or null if no value is set.
Remarks
If the TrustManagerClass property is not set, the getTrustManagerClass method returns null.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getTrustManagerConstructorArg Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getTrustManagerConstructorArg()
Return Value
A String that contains the value of the TrustManagerConstructorArg connection property, or null if no value is
set.
Remarks
If the TrustManagerClass property is not set, the getTrustManagerConstructorArg method returns null.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getTrustServerCertificate Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getTrustServerCertificate()
Return Value
true if trustServerCertificate is enabled. Otherwise, false .
Remarks
If the trustServerCertificate property is set to true , the SQL Server Transport Layer Security (TLS), previously
known as Secure Sockets Layer (SSL), certificate is automatically trusted when the communication layer is
encrypted using TLS. In other words, the Microsoft JDBC Driver for SQL Server will not validate the SQL Server
TLS/SSL certificate. The default value is false .
If the trustServerCertificate property is set to false , the Microsoft JDBC Driver for SQL Server will validate the
server TLS/SSL certificate.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getTrustStore Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getTrustStore()
Return Value
A String that contains the path (including file name) to the certificate trustStore file, or null if no value is set.
Remarks
If the trustStore property is not set, the getTrustStore method returns null.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getURL Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getURL()
Return Value
A String that contains the URL.
Remarks
For security reasons, you should not include the password in the URL that is supplied to the setURL method. The
reason for this is that third-party Java Application Servers will very often display the value set for the URL
property in their data source configuration user interface. Instead, use the setPassword method to set the
password value. Java Application Servers will not display a password that is set in their data source in the
configuration user interface.
NOTE
If the setURL method is not called before calling the getURL method, getURL returns the default value of
"jdbc:sqlserver://".
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getSendTimeAsDatetime Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getSendTimeAsDatetime();
Return Value
true if java.sql.Time values will be sent to the server as a SQL Server datetime type. false if java.sql.Time
values will be sent to the server as a SQL Server time type.
Remarks
See Setting the Connection Properties for more information about the sendTimeAsDatetime connection
property.
SQLServerDataSource.setSendTimeAsDatetime lets you programmatically set the sendTimeAsDatetime
connection property.
For more information, see Configuring How java.sql.Time Values are Sent to the Server.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getUser Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getUser()
Return Value
A String that contains the user name.
Remarks
The setUser method sets the user name that will be used when connecting to the instance of SQL Server. If user
name value is not set, the getUser method returns the default value of null.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getWorkstationID Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getWorkstationID()
Return Value
A String that contains the client computer name.
Remarks
The workstationID is the name of the client computer or workstation. If the workstationID property is not set, the
default value is constructed by calling InetAddress.getLocalHost().getHostName() method. If getHostName
returns a blank value, the getHostAddress().toString() method is called.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
getXopenStates Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getXopenStates()
Return Value
true if converting SQL states to XOPEN compliant states is enabled. Otherwise, false .
Remarks
If the xopenStates property is set to true , the Microsoft JDBC Driver for SQL Server will convert SQL states to
XOPEN compliant states. The default is false , which causes the JDBC driver to generate SQL 99 state codes. If
xopenStates is not set, the getXopenStates method returns the default value of false .
See Also
SQLServerDataSource Members
SQLServerDataSource Class
isWrapperFor Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isWrapperFor(Class iface)
Parameters
iface
A class defining an interface.
Return Value
true if this object implements the interface or wraps an object that implements the interface. Otherwise, false .
Exceptions
SQLServerException
Remarks
The isWrapperFor method and the unwrap method are defined by the java.sql.Wrapper interface, which is
introduced in the JDBC 4.0 Spec.
If this method returns true, calling unwrap with the same argument will succeed.
For more information, see Wrappers and Interfaces.
See Also
unwrap Method (SQLServerDataSource)
SQLServerDataSource Members
SQLServerDataSource Class
setApplicationIntent Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setApplicationIntent(java.lang.String applicationIntent);
Parameters
applicationIntent
The new value of the applicationIntent connection property.
Remarks
For more information about the applicationIntent connection property, see Setting the Connection Properties.
See Also
SQLServerDataSource.getApplicationIntent
SQLServerDataSource Members
SQLServerDataSource Class
setApplicationName Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setApplicationName(java.lang.String applicationName)
Parameters
applicationName
A String that contains the name of the application.
Remarks
The application name is used to identify the specific application in various SQL Server profiling and logging
tools. If the application name is not set, the getApplicationName method returns the non-localized string "
Microsoft JDBC Driver for SQL Server".
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setAuthenticationScheme (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setAuthenticationScheme(String authenticationScheme);
Parameters
authenticationScheme
Values are "JavaKerberos" and the default "NativeAuthentication" . For more information, see Using
Kerberos Integrated Authentication to Connect to SQL Server.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setDatabaseName Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setDatabaseName(java.lang.String databaseName)
Parameters
databaseName
A String that contains the database name.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setDescription Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setDescription(java.lang.String description)
Parameters
description
A String that contains the description.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setDisableStatementPooling Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setDisableStatementPooling(boolean disableStatementPooling);
Parameters
disableStatementPooling
The new value of the disableStatementPooling connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setEnablePrepareOnFirstPreparedStatementCall
Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setEnablePrepareOnFirstPreparedStatementCall(boolean enablePrepareOnFirstPreparedStatementCall);
Parameters
enablePrepareOnFirstPreparedStatementCall
The new value of the enablePrepareOnFirstPreparedStatementCall connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setEncrypt Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setEncypt(boolean encrypt)
Parameters
encrypt
true if the Transport Layer Security (TLS), previously known as Secure Sockets Layer (SSL), encryption is
enabled between the client and the SQL Server. Otherwise, false .
Remarks
If the encrypt property is set to true , the Microsoft JDBC Driver for SQL Server ensures that SQL Server uses
TLS encryption for all data sent between the client and server if the server has a certificate installed. The default
value is false .
The JDBC driver detects the Java Virtual Machine (JVM) it is running on when trying to establish a TLS
handshake.
If the encrypt property is set to true , the Microsoft JDBC Driver for SQL Server uses the JVM's default JSSE
security provider to negotiate TLS encryption with SQL Server. The default security provider may not support all
of the features required to negotiate TLS encryption successfully. For example, the default security provider may
not support the size of the RSA public key used in the SQL Server TLS/SSL certificate. In this case, the default
security provider might raise an error that will cause the JDBC driver to terminate the connection. In order to
resolve this issue, do one of the following:
Configure the SQL Server with a server certificate that has a smaller RSA public key
Configure the JVM to use a different JSSE security provider in the "<java-
home>/lib/security/java.security" security properties file
Use a different JVM
If the encrypt property is unspecified or set to false , the driver will not enforce the SQL Server to support TLS
encryption. If the SQL Server instance is not configured to force the TLS encryption, a connection is established
without any encryption. If the SQL Server instance is configured to force the TLS encryption, the Microsoft JDBC
Driver for SQL Server will automatically enable TLS encryption when running on properly configured JVM, or
else the connection is terminated and the driver will raise an error.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setFailoverPartner Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setFailoverPartner(java.lang.String serverName)
Parameters
serverName
A String that contains the failover server name.
Remarks
The value set by this method is used in the case of an initial connection failure to the principal server; after the
initial connection is made, this value is ignored. The setDatabaseName method should also be used in
conjunction with this method or an exception will be thrown.
The driver does not support specifying the port number of the failover server when the failover server name is
set. However, calling the setServerName method and the setInstanceName method with the setFailoverPartner
method is supported.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setHostNameInCertificate Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setHostNameInCertificate(java.lang.String hostNameInCertificate)
Parameters
hostNameInCertificate
A String that contains the host name.
Remarks
The hostNameInCertificate value is used to validate the SQL Server TLS/SSL certificate when the
communication layer is encrypted by using TLS. The default value is null.
If the hostNameInCertificate property is set to null or unspecified, the Microsoft JDBC Driver for SQL Server will
use the serverName property value to validate against the SQL Server TLS/SSL certificate. If the
hostNameInCertificate property is set to a string or an empty string "", the driver will use that value to validate
the server TLS/SSL certificate.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setInstanceName Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setInstanceName(java.lang.String instanceName)
Parameters
instanceName
A String that contains the instance name.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setIntegratedSecurity Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setIntegratedSecurity(boolean enable)
Parameters
enable
true if integratedSecurity is enabled. Otherwise, false .
Remarks
Set to "true " to indicate that Windows credentials will be used by SQL Server to authenticate the user of the
application. If "true ", the Microsoft JDBC Driver for SQL Server will search the local computer credential cache
for credentials that have already been provided at the computer or network logon. If "false ", the username and
password must be supplied.
NOTE
This property is only supported on Microsoft Windows operating systems.
For more information about using integrated authentication, see Building the Connection URL.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setLastUpdateCount Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setLastUpdateCount(boolean lastUpdateCount)
Parameters
lastUpdateCount
true if lastUpdateCount is enabled. Otherwise, false .
Remarks
If the lastUpdateCount property is set to true , Microsoft JDBC Driver for SQL Server will return only the last
update count from an SQL statement passed to the server. If the lastUpdateCount property is set to false , the
driver will return all update counts including those returned by any triggers that may have fired. If the
lastUpdateCount property is not set, the getLastUpdateCount method returns the default value of true .
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setLockTimeout Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setLockTimeout(int lockTimeout)
Parameters
lockTimeout
An int value that contains the number of milliseconds to wait.
Remarks
The lock time out is the number of milliseconds to wait before the database reports a lock time out. The default
value of -1 means that it will wait indefinitely. If specified, this value will be the default for all statements on the
connection.
NOTE
A value of 0 means no wait. If the lockTimeout property is not set, the getLockTimeout method returns the default value
of -1.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setLoginTimeout Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setLoginTimeout(int loginTimeout)
Parameters
loginTimeout
An int value that represents the number of seconds to wait. Zero means that the timeout is the default system
timeout, which is specified as 15 seconds by default.
Remarks
This setLoginTimeout method is specified by the setLoginTimeout method in the javax.sql.DataSource interface.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setLogWriter Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setLogWriter(java.io.PrintWriter out)
Parameters
out
A PrintWriter object.
Remarks
This setLogWriter method is specified by the setLogWriter method in the javax.sql.DataSource interface.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setMultiSubnetFailover Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setMultiSubnetFailover(boolean multiSubnetFailover);
Parameters
multiSubnetFailover
The new value of the multiSubnetFailover connection property.
Remarks
For more information about the multiSubnetFailover connection property, see Setting the Connection
Properties.
See Also
SQLServerDataSource.getMultiSubnetFailover
SQLServerDataSource Members
SQLServerDataSource Class
setPacketSize Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setPacketSize(int packetSize)
Parameters
packetSize
An int value containing the network packet size.
Remarks
The acceptable range of values of this property is [-1 | 0 | 512..32767]. If this property is set to a value outside
the acceptable range, an exception will occur.
The application might want to set the packetSize property while connecting with Transport Layer Security (TLS),
previously known as Secure Sockets Layer (SSL), encryption. The Microsoft JDBC Driver for SQL Server
negotiates the packet size with the server. If the encrypt property is set to "true " and the negotiated packet size
is larger than the Java Virtual Machine (JVM)'s default security provider's TLS record size, the driver will raise an
error and terminate the connection.
In addition, the application might want to set the packetSize property without requesting the TLS encryption. In
this case, if the server requires the client to support TLS encryption, the driver checks the JVM's default security
provider's TLS record size. If the packetSize property is larger than the JVM's default security provider's TLS
record size, the driver will raise an error and terminate the connection.
For more information about using TLS, see Using encryption.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setPassword Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setPassword(java.lang.String password)
Parameters
password
A String that contains the password.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setPortNumber Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setPortNumber(int portNumber)
Parameters
portNumber
An int value that contains the port number.
Remarks
The port number is the TCP/IP port number that is used when opening a socket connection to SQL Server. If the
portNumber property is not set, the getPortNumber method returns the default value of 1433.
NOTE
The setPortNumber method does not do any range checking on the port value passed in. You can pass a port number
that is not valid, like 99999, without triggering an error.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setResponseBuffering Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setResponseBuffering(java.lang.String value)
Parameters
value
A String that contains the buffering and streaming mode. The valid mode can be one of the following case-
insensitive Strings: full or adaptive .
Remarks
The full value specifies reading the entire result from the server at run time.
The adaptive value specifies buffering the minimum possible data when necessary. The adaptive value is the
default buffering mode.
For more information about using the response buffering mode, see Using Adaptive Buffering.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setSelectMethod Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setSelectMethod(java.lang.String selectMethod)
Parameters
selectMethod
A String value that contains the default cursor type.
Remarks
The selectMethod is the default cursor type that is used for a result set. This property is useful when you are
dealing with large result sets and do not want to store the whole result set in memory on the client side. By
setting the property to "cursor," you can create a server-side cursor that can fetch smaller chunks of data at a
time. If the selectMethod property is not set, getSelectMethod returns the default value of "direct".
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setSendStringParametersAsUnicode Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setSendStringParametersAsUnicode(boolean sendStringParametersAsUnicode)
Parameters
sendStringParametersAsUnicode
true if string parameters are sent to the server in UNICODE format. Otherwise, false .
Remarks
If the sendStringParametersAsUnicode property is set to true , which is the default value, string parameters are
sent to the server in UNICODE format. If sendStringParametersAsUnicode is set to false string parameters are
sent to the server in an ASCII/MBCS format, not in UNICODE. If sendStringParametersAsUnicode is not set,
getSendStringParametersAsUnicode returns the default value of true .
For more information about the sendStringParametersAsUnicode connection property, see Setting the
Connection Properties.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setSendTimeAsDatetime Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setSendTimeAsDatetime(boolean sendTimeAsDateTime)
Parameters
sendTimeAsDateTime
A Boolean value. When true, causes java.sql.Time values to be sent to the server as SQL Server datetime types.
When false, causes java.sql.Time values to be sent to the server as SQL Server time types.
Remarks
SQLServerDataSource.getSendTimeAsDatetime returns the setting of the sendTimeAsDatetime connection
property.
For more information on the sendTimeAsDatetime connection property, see Setting the Connection
Properties.
For more information, see Configuring How java.sql.Time Values are Sent to the Server.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setServerName Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setServerName(java.lang.String serverName)
Parameters
serverName
A String that contains the server name.
Remarks
The server name is the host name of the target computer that is running SQL Server. If the serverName
property is not set, getServerName returns the default value of null.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setServerPreparedStatementDiscardThreshold
Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setServerPreparedStatementDiscardThreshold(int enablePrepareOnFirstPreparedStatementCall);
Parameters
serverPreparedStatementDiscardThreshold
The new value of the ser verPreparedStatementDiscardThreshold connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setStatementPoolingCacheSize Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setStatementPoolingCacheSize(boolean statementPoolingCacheSize);
Parameters
statementPoolingCacheSize
The new value of the statementPoolingCacheSize connection property.
Exceptions
SQLServerException
Remarks
This method is available from JDBC driver version 6.4 and onward.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setTrustManagerClass Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setTrustManagerClass(java.lang.String trustManagerClass)
Parameters
trustManagerClass
A String that contains the fully qualified class name of a custom javax.net.ssl.TrustManager.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setTrustManagerConstructorArg Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setTrustManagerConstructorArg(java.lang.String trustManagerClass)
Parameters
trustManagerClass
A String that contains the fully qualified class name of a custom javax.net.ssl.TrustManager.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setTrustServerCertificate Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setTrustServerCertificate(boolean trustServerCertificate)
Parameters
trustServerCertificate
true if the server Transport Layer Security (TLS), previously known as Secure Sockets Layer (SSL), certificate
should be automatically trusted when the communication layer is encrypted using TLS. Otherwise, false .
Remarks
If the trustServerCertificate property is set to true , the SQL Server TLS/SSL certificate is automatically trusted
when the communication layer is encrypted using TLS. In other words, the Microsoft JDBC Driver for SQL Server
will not validate the SQL Server TLS/SSL certificate. The default value is false .
If the trustServerCertificate property is set to false , the Microsoft JDBC Driver for SQL Server will validate the
server TLS/SSL certificate.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setTrustStore Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setTrustStore(java.lang.String trustStore)
Parameters
trustStore
A String that contains the path (including file name) to the certificate trustStore file.
Remarks
If the trustStore property is unspecified or set to null, the Microsoft JDBC Driver for SQL Server will rely on the
trust manager factory's look up rules to determine which certificate store to use. The default SunX509
TrustManagerFactory tries to find the trust material in the following locations in this order:
1. A file specified by the "javax.net.ssl.trustStore" Java Virtual Machine (JVM) system property.
2. "<java-home>/lib/security/jssecacerts" file.
3. "<java-home>/lib/security/cacerts" file.
For more information, see the SunX509 TrustManager Interface documentation on the Sun Microsystems Web
site.
If the trustStore property is set to a string or an empty string "", the driver will use that value to find the
trustStore file to validate the server TLS/SSL certificate.
The trustStorePassword property can be specified along with the trustStore property and its value is used to
open the trustStore file. For more information, see setTrustStorePassword.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setTrustStorePassword Method
(SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setTrustStorePassword(java.lang.String trustStorePassword)
Parameters
trustStorePassword
A String that contains the password that is used to check the integrity of the trustStore data.
Remarks
The trustStorePassword property can be specified along with the trustStore property and its value is used to
check the integrity of the trustStore file.
If the trustStore property is set but the trustStorePassword property is not set, the integrity of the trustStore is
not checked.
When both trustStore and trustStorePassword properties are unspecified, the driver will use the Java Virtual
Machine (JVM) system properties, "javax.net.ssl.trustStore" and "javax.net.ssl.trustStorePassword". If the
"javax.net.ssl.trustStorePassword" system property is not specified, the integrity of the trustStore is not checked.
If the trustStore property is not set but the trustStorePassword property is set, the JDBC driver will use the file
specified by the "javax.net.ssl.trustStore" as a trust store and the integrity of the trust store is checked by using
the specified trustStorePassword. This might be needed when the client application does not want to store the
password in the JVM system property.
For more information, see Setting the Connection Properties.
Beginning in JDBC Driver 3.0, if you set SQLServerDataSource.setTrustStorePassword before binding the data
source properties, you must call SQLServerDataSource.setTrustStorePassword before getting the connection.
For more information, see SQLServerDataSource.getReference.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setURL Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setURL(java.lang.String url)
Parameters
url
A String that contains the URL.
Remarks
For security reasons, you should not include the password in the URL supplied to the setURL method. The
reason for this is that third-party Java Application Servers will very often display the value set for the URL
property in their data source configuration user interface. Instead, use the setPassword method to set the
password value. Java Application Servers will not display a password that is set in their data source in the
configuration user interface.
NOTE
If the setURL method is not called before calling the getURL method, getURL returns the default value of
"jdbc:sqlserver://".
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setUser Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setUser(java.lang.String user)
Parameters
user
A String that contains the user name.
Remarks
The setUser method sets the user name that will be used to connect to SQL Server. If user name value is not set,
the getUser method returns the default value of null.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setWorkstationID Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setWorkstationID(java.lang.String workstationID)
Parameters
workstationID
A String that contains the client computer name.
Remarks
The workstationID is the name of the client computer or workstation. If the workstationID property is not set, the
default value is constructed by calling InetAddress.getLocalHost().getHostName() method. If getHostName
returns a blank value, the getHostAddress().toString() method is called.
See Also
SQLServerDataSource Members
SQLServerDataSource Class
setXopenStates Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setXopenStates(boolean xopenStates)
Parameters
xopenStates
true if converting SQL states to XOPEN compliant states is enabled. Otherwise, false .
Remarks
If the xopenStates property is set to true , the Microsoft JDBC Driver for SQL Server will convert SQL states to
XOPEN compliant states. The default is false , which causes the JDBC driver to generate SQL 99 state codes. If
xopenStates is not set, the getXopenStates method returns the default value of false .
See Also
SQLServerDataSource Members
SQLServerDataSource Class
unwrap Method (SQLServerDataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public <T> T unwrap(Class<T> iface)
Parameters
iface
A class of type T defining an interface.
Return Value
An object that implements the specified interface.
Exceptions
SQLServerException
Remarks
The unwrap method is defined by the java.sql.Wrapper interface, which is introduced in the JDBC 4.0 Spec.
Applications might need to access extensions to the JDBC API that are specific to the Microsoft JDBC Driver for
SQL Server. The unwrap method supports unwrapping to public classes that this object extends if the classes
expose vendor extensions.
When this method is called, the object unwraps to the SQLServerDataSource class.
For more information, see Wrappers and Interfaces.
See Also
isWrapperFor Method (SQLServerDataSource)
SQLServerDataSource Members
SQLServerDataSource Class
SQLServerDataSourceObjectFactory Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public class SQLServerDataSourceObjectFactory
Remarks
This method is inherited by all the data source classes. As part of its support for the Referenceable interface,
Microsoft JDBC Driver for SQL Server exposes this class that implements an ObjectFactory. Java Application
Servers will call getReference on a data source class, and this will create a Reference object that internally uses
the class name as its class factory.
When the Java Application Server has to dereference the Reference object, it creates an instance of the
SQLServerDataSourceObjectFactory object and calls the getObjectInstance method, passing in the Reference
object, to retrieve the data source instance.
See Also
SQLServerDataSourceObjectFactory Members
JDBC Driver API Reference
SQLServerDataSourceObjectFactory Members
4/27/2022 • 2 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
Fields
None.
Inherited Fields
None.
Methods
NAME DESC RIP T IO N
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerDataSourceObjectFactory Class
SQLServerDataSourceObjectFactory Constructors
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public SQLServerDataSourceObjectFactory()
See Also
SQLServerDataSourceObjectFactory Constructors
SQLServerDataSourceObjectFactory Members
SQLServerDataSourceObjectFactory Class
SQLServerDataSourceObjectFactory Methods
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.Object getObjectInstance(java.lang.Object ref,
javax.naming.Name name,
javax.naming.Context c,
java.util.Hashtable h)
Parameters
ref
An Object value.
name
The name of the object.
c
The context relative to the specified name.
h
The environment that is used in creating the object.
Return Value
An Object value.
Exceptions
java.sql.SQLException
Remarks
This getObjectInstance method is specified by the getObjectInstance method in the
javax.naming.spi.ObjectFactory interface.
See Also
SQLServerDataSourceObjectFactory Methods
SQLServerDataSourceObjectFactory Members
SQLServerDataSourceObjectFactory Class
SQLServerDriver Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final class SQLServerDriver
See Also
SQLServerDriver Members
JDBC Driver API Reference
SQLServerDriver Members
4/27/2022 • 2 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
Fields
None.
Inherited Fields
None.
Methods
NAME DESC RIP T IO N
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerDriver Class
SQLServerDriver Constructors
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public SQLServerDriver()
See Also
SQLServerDriver Constructors
SQLServerDriver Members
SQLServerDriver Class
SQLServerDriver Methods
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean acceptsURL(java.lang.String url)
Parameters
url
A String value containing the URL used to connect to the database.
Return Value
true if the given URL is valid. Otherwise, false .
Exceptions
SQLServerException
Remarks
This acceptsURL method is specified by the acceptsURL method in the java.sql.Driver interface.
See Also
SQLServerDriver Methods
SQLServerDriver Members
SQLServerDriver Class
connect Method (SQLServerDriver)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Connection connect(java.lang.String Url,
java.util.Properties suppliedProperties)
Parameters
Url
A String value that contains the URL that is used to connect to the database.
suppliedProperties
A set of string value pairs used as connection arguments.
Return Value
A Connection object.
Exceptions
SQLServerException
Remarks
This connect method is specified by the connect method in the java.sql.Driver interface.
See Also
SQLServerDriver Methods
SQLServerDriver Members
SQLServerDriver Class
getMajorVersion Method (SQLServerDriver)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMajorVersion()
Return Value
An int that contains the major version number of the JDBC driver.
Remarks
This getMajorVersion method is specified by the getMajorVersion method in the java.sql.Driver interface.
See Also
SQLServerDriver Methods
SQLServerDriver Members
SQLServerDriver Class
getMinorVersion Method (SQLServerDriver)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getMinorVersion()
Return Value
An int that contains the minor version number of the JDBC driver.
Remarks
This getMinorVersion method is specified by the getMinorVersion method in the java.sql.Driver interface.
See Also
SQLServerDriver Methods
SQLServerDriver Members
SQLServerDriver Class
getPropertyInfo Method (SQLServerDriver)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.DriverPropertyInfo[] getPropertyInfo(java.lang.String Url,
java.util.Properties Info)
Parameters
Url
A String value that contains the URL that is used to connect to the database.
Info
A list of property value pairs, null on first use.
Return Value
An array of DriverPropertyInfo objects.
Exceptions
SQLServerException
Remarks
This getPropertyInfo method is specified by the getPropertyInfo method in the java.sql.Driver interface.
See Also
SQLServerDriver Methods
SQLServerDriver Members
SQLServerDriver Class
jdbcCompliant Method (SQLServerDriver)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean jdbcCompliant()
Return Value
true if the JDBC driver meets the minimum requirements. Otherwise, false .
Remarks
This jdbcCompliant method is specified by the jdbcCompliant method in the java.sql.Driver interface.
See Also
SQLServerDriver Methods
SQLServerDriver Members
SQLServerDriver Class
SQLServerException Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final class SQLServerException
Remarks
The SQLServerException class handles both SQL 92 and XOPEN state codes. They are switchable by using a
user-specified connection property. Exceptions are written to any open log files that have been specified.
See Also
SQLServerException Members
JDBC Driver API Reference
SQLServerException Members
4/27/2022 • 2 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
Fields
None.
Inherited Fields
None.
Methods
None.
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerException Class
SQLServerException Constructors
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public SQLServerException(java.lang.Object obj,
java.lang.String errText,
java.lang.String errState,
int errNum,
boolean bStack)
Parameters
obj
The IO buffer that generated the exception.
errText
A string containing the error text.
sqlState
An enum object that contains the SQL state.
errNum
An int that contain the error code for the exception.
bStack
A boolean that indicates if the stack trace should be generated.
See Also
SQLServerException Constructors
SQLServerException Members
SQLServerException Class
SQLServerException Constructor ( java.lang.Object,
java.lang.String, java.lang.String, StreamError,
boolean)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public SQLServerException(java.lang.Object obj,
java.lang.String errText,
java.lang.String errState,
StreamError streamError,
boolean bStack)
Parameters
obj
The IO buffer that generated the exception.
errText
A string containing the error text.
sqlState
An enum object that contains the SQL state.
streamError
A StreamError object that contains details about the error.
bStack
A boolean that indicates if the stack trace should be generated.
See Also
SQLServerException Constructors
SQLServerException Members
SQLServerException Class
SQLServerException Constructor ( java.lang.String,
SQLState, DriverError, java.lang.Throwable)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public SQLServerException(java.lang.String errText,
SQLState sqlState,
DriverError driverError,
java.lang.Throwable cause)
Parameters
errText
A string that holds the error text.
sqlState
An enum object that holds the SQL state.
driverError
An enum object that holds the driver error.
cause
A throwable object that holds the cause of the exception.
See Also
SQLServerException Constructors
SQLServerException Members
SQLServerException Class
SQLServerException Constructor ( java.lang.String,
java.lang.String, int, java.lang.Throwable)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public SQLServerException(java.lang.String errText,
SQLState errState,
int errNum,
java.lang.Throwable cause)
Parameters
errText
A string containing the error text.
errState
A string containing the state of the error.
errNum
An int that contains the error code for the exception.
cause
A throwable object that contains the cause of the exception.
See Also
SQLServerException Constructors
SQLServerException Members
SQLServerException Class
SQLServerException Constructor ( java.lang.String,
java.lang.Throwable)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public SQLServerException(java.lang.String errText,
java.lang.Throwable cause)
Parameters
errText
A string containing the error text.
cause
A throwable object that contains the cause of the exception.
See Also
SQLServerException Constructors
SQLServerException Members
SQLServerException Class
SQLServerException Methods
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public class SQLServerNClob
See Also
SQLServerNClob Members
JDBC Driver API Reference
SQLServerNClob Members
4/27/2022 • 2 minutes to read • Edit Online
Constructors
None.
Fields
None.
Inherited Fields
None.
Methods
NAME DESC RIP T IO N
free This method frees the NCLOB object and releases the
resources that it holds.
Inherited Methods
C L A SS IN H ERIT ED F RO M M ET H O DS
See Also
SQLServerClob Class
SQLServerNClob Methods
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void free()
Exceptions
SQLServerException
Remarks
This free method is specified by the free method in the java.sql.NClob interface.
See Also
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
getAsciiStream Method (SQLServerNClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.InputStream getAsciiStream()
Return Value
An InputStream object that contains the NCLOB data.
Exceptions
SQLServerException
Remarks
This getAsciiStream method is specified by the getAsciiStream method in the java.sql.SQLServerNClob interface.
See Also
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
getCharacterStream Method (SQLServerNClob)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getCharacterStream Method (long, long) (SQLServerNClob) Retrieves the NCLOB data as a Reader object or as a
stream of characters with the specified position and length.
See Also
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
getCharacterStream Method (long, long)
(SQLServerNClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.Reader getCharacterStream(long pos,
long length)
Parameters
pos
A long that indicates the offset to the first character of the partial value to be retrieved.
length
A long that indicates the length in characters of the partial value to be retrieved.
Return Value
A Reader object that contains the NCLOB data.
Exceptions
SQLServerException
Remarks
This getCharacterStream method is specified by the getCharacterStream method in the java.sql.NClob interface.
See Also
getCharacterStream Method (SQLServerNClob)
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
getSubString Method (SQLServerNClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getSubString(long pos,
int length)
Parameters
pos
The first character of the substring to be extracted. The first character is at position 1.
length
The number of consecutive characters to be copied.
Return Value
A String that is the specified substring in the NCLOB .
Exceptions
SQLServerException
Remarks
This getSubString method is specified by the getSubString method in the java.sql.NClob interface.
Trying to get zero characters from a null or zero-length NCLOB returns an empty string. Trying to get any length
of characters at any position other than position 1 in a zero-length NCLOB will cause a position exception to be
thrown.
See Also
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
length Method (SQLServerNClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public long length()
Return Value
The length of the NClob in number of characters.
Exceptions
SQLServerException
Remarks
This length method is specified by the length method in the java.sql.NClob interface.
See Also
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
position Method (SQLServerNClob)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
position Method (java.sql.NClob, long) Retrieves the character position at which the specified
NClob object searchstr appears in this NClob object.
position Method (java.lang.String, long) (SQLServerNClob) Retrieves the character position at which the specified
substring searchstr appears in the NCLOB value
represented by this NClob object.
See Also
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
position Method ( java.sql.NClob, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
long position(java.sql.NClob searchstr,
long start)
Parameters
searchstr
A NClob object for which to search.
start
The position at which to begin searching; the first position is 1.
Return Value
The position at which the substring appears, or -1 if it is not present. The first position is 1.
Exceptions
SQLServerException
Remarks
This position method is specified by the position method in the java.sql.NClob interface.
See Also
position Method (SQLServerNClob)
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
position Method ( java.lang.String, long)
(SQLServerNClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public long position(java.lang.String searchstr,
long start)
Parameters
searchstr
The substring for which to search.
start
The position at which to begin searching; the first position is 1.
Return Value
The position at which the substring appears, or -1 if it is not present. The first position is 1.
Exceptions
SQLServerException
Remarks
This position method is specified by the position method in the java.sql.NClob interface.
See Also
position Method (SQLServerNClob)
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
setAsciiStream Method (SQLServerNClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.OutputStream setAsciiStream(long pos)
Parameters
pos
The position at which to start writing to the NCLOB object; the first position is 1.
Return Value
An OutputStream object that represents the stream to which ASCII encoded characters can be written.
Exceptions
SQLServerException
Remarks
This setAsciiStream method is specified by the setAsciiStream method in the java.sql.NClob interface.
See Also
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
setCharacterStream Method (SQLServerNClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.Writer setCharacterStream(long pos)
Parameters
pos
The position at which to start writing to the NCLOB value; the first position is 1.
Return Value
A Writer object that represents the stream to which Unicode encoded characters can be written.
Exceptions
SQLServerException
Remarks
This setCharacterStream method is specified by the setCharacterStream method in the java.sql.NClob interface.
See Also
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
setString Method (SQLServerNClob)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setString Method (long, java.lang.String) (SQLServerNClob) Writes the specified String to the NCLOB starting at the
specified position.
setString Method (long, java.lang.String, int, int) Writes the specified string to the NCLOB starting at the
(SQLServerNClob) specified position, and based on the specified offset and
length.
See Also
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
setString Method (long, java.lang.String)
(SQLServerNClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int setString(long pos,
java.lang.String str)
Parameters
pos
The position at which to start writing to the NCLOB ; the first position is 1.
str
The String to be written to the NCLOB .
Return Value
The number of characters written.
Exceptions
SQLServerException
Remarks
This setString method is specified by the setString method in the java.sql.NClob interface.
See Also
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
setString Method (long, java.lang.String, int, int)
(SQLServerNClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
int setString(long pos,
java.lang.String str,
int offset,
int len)
Parameters
pos
The position at which to start writing to the NCLOB ; the first position is 1.
str
The String to be written to the NCLOB .
offset
The offset into str to start reading the characters to be written.
len
The number of characters to be written.
Exceptions
SQLServerException
Remarks
This setString method is specified by the setString method in the java.sql.NClob interface.
See Also
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
truncate Method (SQLServerNClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void truncate(long len)
Parameters
len
The length, in characters, to which the NCLOB value should be truncated.
Exceptions
SQLServerException
Remarks
This truncate method is specified by the truncate method in the java.sql.NClob interface.
See Also
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
SQLServerParameterMetaData Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public class SQLServerParameterMetaData
Remarks
To retrieve parameter metadata, prepared statements are run with SET FMT ONLY. Callable statements call
sp_sproc_columns to retrieve names and metadata for the procedure parameters.
See Also
SQLServerParameterMetaData Members
JDBC Driver API Reference
SQLServerParameterMetaData Members
4/27/2022 • 2 minutes to read • Edit Online
Constructors
None.
Fields
None.
Inherited Fields
NAME DESC RIP T IO N
Methods
NAME DESC RIP T IO N
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerParameterMetaData Class
SQLServerParameterMetaData Methods
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getParameterClassName(int param)
Parameters
param
An int that indicates parameter index.
Return Value
A String that contains the fully-qualified class name.
Exceptions
SQLServerException
Remarks
This getParameterClassName method is specified by the getParameterClassName method in the
java.sql.ParameterMetaData interface.
See Also
SQLServerParameterMetaData Methods
SQLServerParameterMetaData Members
SQLServerParameterMetaData Class
getParameterCount Method
(SQLServerParameterMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getParameterCount()
Return Value
An int that indicates the number of parameters.
Exceptions
SQLServerException
Remarks
This getParameterCount method is specified by the getParameterCount method in the
java.sql.ParameterMetaData interface.
See Also
SQLServerParameterMetaData Methods
SQLServerParameterMetaData Members
SQLServerParameterMetaData Class
getParameterMode Method
(SQLServerParameterMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getParameterMode(int param)
Parameters
param
An int that indicates parameter index.
Return Value
An int that indicates the mode of the designated parameter, which can be one of the following values:
ParameterMetaData.parameterModeIn
ParameterMetaData.parameterModeInOut
ParameterMetaData.parameterModeOut
ParameterMetaData.parameterModeUnknown
Exceptions
SQLServerException
Remarks
This getParameterMode method is specified by the getParameterMode method in the
java.sql.ParameterMetaData interface.
See Also
SQLServerParameterMetaData Methods
SQLServerParameterMetaData Members
SQLServerParameterMetaData Class
getParameterType Method
(SQLServerParameterMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getParameterType(int param)
Parameters
param
An int that indicates parameter index.
Return Value
An int that indicates the JDBC type code as defined in java.sql.Types.
Exceptions
SQLServerException
Remarks
This getParameterType method is specified by the getParameterType method in the java.sql.ParameterMetaData
interface.
See Also
SQLServerParameterMetaData Methods
SQLServerParameterMetaData Members
SQLServerParameterMetaData Class
getParameterTypeName Method
(SQLServerParameterMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getParameterTypeName(int param)
Parameters
param
An int that indicates parameter index.
Return Value
A String that contains type name.
Exceptions
SQLServerException
Remarks
This getParameterTypeName method is specified by the getParameterTypeName method in the
java.sql.ParameterMetaData interface.
See Also
SQLServerParameterMetaData Methods
SQLServerParameterMetaData Members
SQLServerParameterMetaData Class
getPrecision Method
(SQLServerParameterMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getPrecision(int param)
Parameters
param
An int that indicates parameter index.
Return Value
An int that indicates the precision of the designated parameter.
Exceptions
SQLServerException
Remarks
This getPrecision method is specified by the getPrecision method in the java.sql.ParameterMetaData interface.
For number types, this method gets the number of decimal digits. For character types, it gets the maximum
length in characters. For binary types, it gets the maximum length in bytes. Where the number of digits is
unknown, this method returns "0".
See Also
SQLServerParameterMetaData Methods
SQLServerParameterMetaData Members
SQLServerParameterMetaData Class
getScale Method (SQLServerParameterMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getScale(int param)
Parameters
param
An int that indicates parameter index.
Return Value
In int that indicates the scale of the designated parameter.
Exceptions
SQLServerException
Remarks
This getScale method is specified by the getScale method in the java.sql.ParameterMetaData interface.
This method gets column digits to the right of the decimal point. For types that do not have a decimal point, this
method returns "0".
See Also
SQLServerParameterMetaData Methods
SQLServerParameterMetaData Members
SQLServerParameterMetaData Class
isNullable Method (SQLServerParameterMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int isNullable(int param)
Parameters
param
An int that indicates parameter index.
Return Value
An int that indicates the nullability of the designated parameter, which can be one of the following values:
ParameterMetaData.parameterNoNulls
ParameterMetaData.parameterNullable
ParameterMetaData.parameterNullabilityUnknown
Exceptions
SQLServerException
Remarks
This isNullable method is specified by the isNullable method in the java.sql.ParameterMetaData interface.
See Also
SQLServerParameterMetaData Methods
SQLServerParameterMetaData Members
SQLServerParameterMetaData Class
isSigned Method (SQLServerParameterMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isSigned(int param)
Parameters
param
An int that indicates parameter index.
Return Value
true if the designated parameter can contain signed numbers. Otherwise, false .
Exceptions
SQLServerException
Remarks
This isSigned method is specified by the isSigned method in the java.sql.ParameterMetaData interface.
See Also
SQLServerParameterMetaData Methods
SQLServerParameterMetaData Members
SQLServerParameterMetaData Class
SQLServerPooledConnection Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final class SQLServerPoolingDataSource
Remarks
The SQLServerPooledConnection class provides methods for the connection pool manager to manage the
connection pool. Applications typically do not instantiate these connections directly.
See Also
SQLServerPooledConnection Members
JDBC Driver API Reference
SQLServerPooledConnection Members
4/27/2022 • 2 minutes to read • Edit Online
Constructors
None.
Fields
None.
Inherited Fields
None.
Methods
NAME DESC RIP T IO N
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerPooledConnection Class
SQLServerPooledConnection Methods
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void addConnectionEventListener(javax.sql.ConnectionEventListener listener)
Parameters
listener
A ConnectionEventListener object.
Remarks
This addConnectionEventListener method is specified by the addConnectionEventListener method in the
javax.sql.PooledConnection interface.
See Also
SQLServerPooledConnection Methods
SQLServerPooledConnection Members
SQLServerPooledConnection Class
close Method (SQLServerPooledConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void close()
Exceptions
java.sql.SQLException
Remarks
This close method is specified by the close method in the javax.sql.PooledConnection interface.
See Also
SQLServerPooledConnection Methods
SQLServerPooledConnection Members
SQLServerPooledConnection Class
getConnection Method
(SQLServerPooledConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Connection getConnection()
Return Value
A Connection object.
Exceptions
java.sql.SQLException
Remarks
This getConnection method is specified by the getConnection method in the javax.sql.PooledConnection
interface.
See Also
SQLServerPooledConnection Methods
SQLServerPooledConnection Members
SQLServerPooledConnection Class
removeConnectionEventListener Method
(SQLServerPooledConnection)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void removeConnectionEventListener(javax.sql.ConnectionEventListener listener)
Parameters
listener
A ConnectionEventListener object.
Remarks
This removeConnectionEventListener method is specified by the removeConnectionEventListener method in the
javax.sql.PooledConnection interface.
See Also
SQLServerPooledConnection Methods
SQLServerPooledConnection Members
SQLServerPooledConnection Class
SQLServerPreparedStatement Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public class SQLServerPreparedStatement
Remarks
SQLServerPreparedStatement provides methods that let you supply parameters as any native Java type and
many Java object types. SQLServerPreparedStatement prepares a statement by using the SQL Server
sp_prepare stored procedure, and then reuses the returned statement handle for each subsequent running of
the statement, typically using different parameters provided by the user.
SQLServerPreparedStatement supports batching, where a set of prepared statements are run in a single
database round trip, to improve runtime performance.
This class supports unwrapping to SQLServerPreparedStatement class, ISQLServerPreparedStatement interface,
java.sql.PreparedStatement interface, and the classes and interfaces supported by SQLServerStatement for
unwrapping. For more information, see Wrappers and Interfaces.
See Also
SQLServerPreparedStatement Members
JDBC Driver API Reference
SQLServerPreparedStatement Members
4/27/2022 • 5 minutes to read • Edit Online
Constructors
None.
Fields
None.
Inherited Fields
C L A SS IN H ERIT ED F RO M : M ET H O DS
Methods
NAME DESC RIP T IO N
execute Runs the SQL statement in this Statement object, which can
be any kind of SQL statement.
NAME DESC RIP T IO N
executeQuery Runs the SQL query in this Statement object and returns the
SQLServerResultSet object that is generated by the query.
setNull Sets the designated parameter to a null value, given the type
of parameter to set.
setObject Sets the value of the designated parameter using the given
object.
NAME DESC RIP T IO N
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerPreparedStatement Class
SQLServerPreparedStatement Methods
4/27/2022 • 2 minutes to read • Edit Online
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
addBatch Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
addBatch (java.lang.String) Adds the given SQL command to the current list of
commands for this SQLServerPreparedStatement object.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
addBatch Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void addBatch()
Exceptions
SQLServerException
Remarks
This addBatch method is specified by the addBatch method in the java.sql.PreparedStatement interface.
See Also
addBatch Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
addBatch Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void addBatch(java.lang.String sql)
Parameters
sql
A String that contains an SQL statement.
Exceptions
SQLServerException
Remarks
This addBatch method is specified by the addBatch method in the java.sql.Statement interface.
Calling this method will result in an exception since the SQL statement for the SQLServerPreparedStatement
object is specified when the object is created.
See Also
addBatch Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
clearBatch Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void clearBatch()
Exceptions
SQLServerException
Remarks
This clearBatch method is specified by the clearBatch method in the java.sql.Statement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
clearParameters Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void clearParameters()
Exceptions
SQLServerException
Remarks
This clearParameters method is specified by the clearParameters method in the java.sql.PreparedStatement
interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
close Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void close()
Exceptions
SQLServerException
Remarks
This close method is specified by the close method in the java.sql.Statement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
execute Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
execute (java.lang.String) Runs the given SQL statement, which can return multiple
results.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
execute Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean execute()
Return Value
true if the statement returns a result set. false if it returns an update count or no result.
Exceptions
SQLServerException
Remarks
This execute method is specified by the execute method in the java.sql.PreparedStatement interface.
See Also
execute Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
execute Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final boolean execute(java.lang.String sql)
Parameters
sql
A String that contains an SQL statement.
Return Value
true if the statement returns a result set. false if it returns an update count or no result.
Exceptions
SQLServerException
Remarks
This execute method is specified by the execute method in the java.sql.Statement interface.
This method overrides the execute method that is found in the SQLServerStatement class.
Calling this method will result in an exception since the SQL statement for the SQLServerPreparedStatement
object is specified when the object is created.
See Also
execute Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
executeBatch Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int[] executeBatch()
Return Value
An array of ints that contains the update counts.
Exceptions
SQLServerException
java.sql.BatchUpdateException
Remarks
This executeBatch method is specified by the executeBatch method in the java.sql.Statement interface.
This method overrides SQLServerStatement.executeBatch.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
executeQuery Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
executeQuery (java.lang.String) Runs the given SQL statement and returns a single
SQLServerResultSet object.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
executeQuery Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet executeQuery()
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This executeQuery method is specified by the executeQuery method in the java.sql.PreparedStatement interface.
See Also
executeQuery Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
executeQuery Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.sql.ResultSet executeQuery(java.lang.String sql)
Parameters
sql
A String that contains an SQL statement.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This executeQuery method is specified by the executeQuery method in the java.sql.Statement interface.
This method overrides the executeQuery method that is found in the SQLServerStatement class.
Calling this method will result in an exception since the SQL statement for the SQLServerPreparedStatement
object is specified when the object is created.
SQLServerException is thrown if the given SQL statement produces anything other than a single
SQLServerResultSet object.
See Also
executeQuery Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
executeUpdate Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
executeUpdate (java.lang.String) Runs the given SQL statement, which can be an INSERT,
UPDATE, MERGE, or DELETE statement; or an SQL statement
that returns nothing, such as an SQL DDL statement.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
executeUpdate Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int executeUpdate()
Return Value
An int that indicates the number of rows affected, or 0 if using a DDL statement.
Exceptions
SQLServerException
Remarks
This executeUpdate method is specified by the executeUpdate method in the java.sql.PreparedStatement
interface.
See Also
executeUpdate Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
executeUpdate Method ( java.lang.String, int[])
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final int executeUpdate(java.lang.String sql,
int[] columnIndexes)
Parameters
sql
A String that contains an SQL statement.
columnIndexes
An array of ints that indicate the column indexes of the auto-generated keys that should be made available.
Return Value
An int that indicates the number of rows affected, or 0 if using a DDL statement.
Exceptions
SQLServerException
Remarks
This executeUpdate method is specified by the executeUpdate method in the java.sql.Statement interface.
If executing a stored procedure results in an update count that is greater than one, or that generates more than
one result set, use the execute method to execute the stored procedure.
See Also
executeUpdate Method (SQLServerStatement)
SQLServerStatement Members
SQLServerStatement Class
executeUpdate Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Runs the given SQL statement, which can be an INSERT, UPDATE, MERGE, or DELETE statement; or an SQL
statement that returns nothing, such as an SQL DDL statement.
Syntax
public final int executeUpdate(java.lang.String sql)
Parameters
sql
A String that contains the SQL statement.
Return Value
An int that indicates the number of rows affected, or 0 if using a DDL statement.
Exceptions
SQLServerException
Remarks
This executeUpdate method is specified by the executeUpdate method in the java.sql.PreparedStatement
interface.
Calling this method will result in an exception since the SQL statement for the SQLServerPreparedStatement
object is specified when the object is created.
See Also
executeUpdate Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
getMetaData Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.sql.ResultSetMetaData getMetaData()
Return Value
A ResultSetMetaData object.
Exceptions
SQLServerException
Remarks
This getMetaData method is specified by the getMetaData method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
getParameterMetaData Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.sql.ParameterMetaData getParameterMetaData()
Return Value
A SQLServerParameterMetaData object.
Exceptions
SQLServerException
Remarks
This getParameterMetaData method is specified by the getParameterMetaData method in the
java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
isWrapperFor Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isWrapperFor(Class iface)
Parameters
iface
A class defining an interface.
Return Value
true if this object implements the interface or wraps an object that implements the interface. Otherwise, false .
Exceptions
SQLServerException
Remarks
The isWrapperFor method and the unwrap method are defined by the java.sql.Wrapper interface, which is
introduced in the JDBC 4.0 Spec.
If this method returns true, calling unwrap with the same argument will succeed.
For more information, see Wrappers and Interfaces.
See Also
unwrap Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setArray Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setArray(int i,
java.sql.Array x)
Parameters
i
An int that indicates the parameter number.
x
An Array object.
Exceptions
SQLServerException
Remarks
This setArray method is specified by the setArray method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setAsciiStream Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setAsciiStream Method (int, java.io.InputStream) Sets the designated parameter number to the specified
java.io.InputStream object.
setAsciiStream Method (int, java.io.InputStream, int) Sets the designated parameter number to the specified
java.io.InputStream object with the specified number of
bytes.
setAsciiStream Method (int, java.io.InputStream, long) Sets the designated parameter number to the specified
java.io.InputStream object with the specified number of
bytes.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setAsciiStream Method (int, java.io.InputStream)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setAsciiStream(int parameterIndex,
java.io.InputStream x)
Parameters
parameterIndex
An int that indicates the parameter number.
x
A java.io.InputStream object.
Exceptions
SQLServerException
Remarks
This setAsciiStream method is specified by the setAsciiStream method in the java.sql.PreparedStatement
interface.
See Also
setAsciiStream Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
setAsciiStream Method (int, java.io.InputStream, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setAsciiStream(int n,
java.io.InputStream x,
int length)
Parameters
n
An int that indicates the parameter number.
x
An InputStream object.
length
The number of bytes.
Exceptions
SQLServerException
Remarks
This setAsciiStream method is specified by the setAsciiStream method in the java.sql.PreparedStatement
interface.
If the length of the stream is different than that specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
setAsciiStream Method (int, java.io.InputStream) when the application wants to update the column from a
stream whose length is unknown.
See Also
setAsciiStream Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
setAsciiStream Method (int, java.io.InputStream,
long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setAsciiStream(int parameterIndex,
java.io.InputStream x,
long length)
Parameters
parameterIndex
An int that indicates the parameter number.
x
A java.io.InputStream object.
length
A long that indicates the number of bytes.
Exceptions
SQLServerException
Remarks
This setAsciiStream method is specified by the setAsciiStream method in the java.sql.PreparedStatement
interface.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
setAsciiStream Method (int, java.io.InputStream) when the application wants to update the column from a
stream whose length is unknown.
See Also
setAsciiStream Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
setBigDecimal Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setBigDecimal(int n,
java.math.BigDecimal x)
Parameters
n
An int that indicates the parameter number.
x
A BigDecimal object.
Exceptions
SQLServerException
Remarks
This setBigDecimal method is specified by the setBigDecimal method in the java.sql.PreparedStatement
interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setBinaryStream Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setBinaryStream Method (int, java.io.InputStream) Sets the designated parameter to the specified input stream.
setBinaryStream Method (int, java.io.InputStream, int) Sets the designated parameter to the specified input stream,
which will have the specified number of bytes.
setBinaryStream Method (int, java.io.InputStream, long) Sets the designated parameter to the specified input stream,
which will have the specified number of bytes.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setBinaryStream Method (int, java.io.InputStream)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setAsciiStream(int parameterIndex,
java.io.InputStream x)
Parameters
parameterIndex
An int that indicates the parameter number.
x
A java.io.InputStream object.
Exceptions
SQLServerException
Remarks
This setBinaryStream method is specified by the setBinaryStream method in the java.sql.PreparedStatement
interface.
See Also
setBinaryStream Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
setBinaryStream Method (int, java.io.InputStream,
int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setBinaryStream(int n,
java.io.InputStream x,
int length)
Parameters
n
An int that indicates the parameter number.
x
An InputStream object.
length
An int that indicates the number of bytes.
Exceptions
SQLServerException
Remarks
This setBinaryStream method is specified by the setBinaryStream method in the java.sql.PreparedStatement
interface.
If the length of the stream is different from what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
setBinaryStream Method (int, java.io.InputStream) when the application wants to update the column from a
stream whose length is unknown.
See Also
setBinaryStream Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
setBinaryStream Method (int, java.io.InputStream,
long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setBinaryStream(int parameterIndex,
java.io.InputStream x,
long length)
Parameters
parameterIndex
An int that indicates the parameter number.
x
A java.io.InputStream object.
length
A long that indicates the number of bytes.
Exceptions
SQLServerException
Remarks
This setBinaryStream method is specified by the setBinaryStream method in the java.sql.PreparedStatement
interface.
If the length of the stream is different from what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
setBinaryStream Method (int, java.io.InputStream) when the application wants to update the column from a
stream whose length is unknown.
See Also
setBinaryStream Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
setBlob Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setBlob(int i,
java.sql.Blob x)
Parameters
i
An int that indicates the parameter number.
x
A Blob object.
Exceptions
SQLServerException
Remarks
This setBlob method is specified by the setBlob method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setBoolean Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setBoolean(int n,
boolean x)
Parameters
n
An int that indicates the parameter number.
x
A boolean value, either true or false .
Exceptions
SQLServerException
Remarks
This setboolean method is specified by the setboolean method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setByte Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setByte(int n,
byte x)
Parameters
n
An int that indicates the parameter number.
x
A byte value.
Exceptions
SQLServerException
Remarks
This setByte method is specified by the setByte method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setBytes Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setBytes(int n,
byte[] x)
Parameters
n
An int that indicates the parameter number.
x
An array of bytes.
Exceptions
SQLServerException
Remarks
This setBytes method is specified by the setBytes method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setCharacterStream Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setCharacterStream Method (int, java.io.Reader) Sets the designated parameter to the specified java.io.Reader
object.
setCharacterStream Method (int, java.io.Reader, int) Sets the designated parameter to the specified java.io.Reader
object, which is the specified number of characters long.
setCharacterStream Method (int, java.io.Reader, long) Sets the designated parameter to the specified java.io.Reader
object, which is the specified number of characters long.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setCharacterStream Method (int, java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This feature is introduced starting with the MicrosoftSQL Server JDBC Driver version 2.0.
Syntax
public final void setCharacterStream(int parameterIndex,
java.io.Reader reader)
Parameters
parameterIndex
An int that indicates the parameter number.
reader
The java.io.Reader object that contains the Unicode data.
Exceptions
SQLServerException
Remarks
This setCharacterStream method is specified by the setCharacterStream method in the
java.sql.PreparedStatement interface.
See Also
setCharacterStream Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
setCharacterStream Method (int, java.io.Reader, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setCharacterStream(int n,
java.io.Reader reader,
int length)
Parameters
n
An int that indicates the parameter number.
reader
A Reader object.
length
The number of characters.
Exceptions
SQLServerException
Remarks
This setCharacterStream method is specified by the setCharacterStream method in the
java.sql.PreparedStatement interface.
If the length of the stream is different than that specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
setCharacterStream Method (int, java.io.Reader) when the application wants to update the column from a stream
whose length is unknown.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setCharacterStream Method (int, java.io.Reader,
long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setCharacterStream(int parameterIndex,
java.io.Reader reader,
long length)
Parameters
parameterIndex
An int that indicates the parameter number.
reader
The java.io.Reader object that contains the Unicode data.
length
A long that indicates the number of characters in the stream.
Exceptions
SQLServerException
Remarks
This setCharacterStream method is specified by the setCharacterStream method in the
java.sql.PreparedStatement interface.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
setCharacterStream Method (int, java.io.Reader) when the application wants to update the column from a stream
whose length is unknown.
See Also
setCharacterStream Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
setClob Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setClob Method (int, java.io.Reader) Sets the designated parameter to a java.sql.Clob object.
setClob Method (int, java.sql.Clob) Sets the designated parameter to the given java.sql.Clob
object.
setClob Method (int, java.io.Reader, long) Sets the designated parameter to a java.sql.Clob object,
which is the specified number of characters long.
Remarks
No server driver behavior. For details see JSE 6 API spec.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setClob Method (int, java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setClob(int parameterIndex,
java.io.Reader reader)
Parameters
parameterIndex
An int that indicates the parameter index.
reader
A Reader object.
Exceptions
SQLServerException
Remarks
This setClob method is specified by the setClob method in the java.sql.PreparedStatement interface.
See Also
setClob Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
setClob Method (int, java.sql.Clob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setClob(int parameterIndex,
java.sql.Clob clobValue)
Parameters
parameterIndex
An int that indicates the parameter number.
clobValue
A Clob object.
Exceptions
SQLServerException
Remarks
This setClob method is specified by the setClob method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Methods
SQLServerPreparedStatement Class
setClob Method (int, java.io.Reader, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setClob(int parameterIndex,
java.io.Reader reader,
long length)
Parameters
parameterIndex
An int that indicates the parameter index.
reader
A Reader object.
length
A long that indicates the number of characters in the parameter value.
Remarks
This setClob method is specified by the setClob method in the java.sql.PreparedStatement interface.
Exceptions
SQLServerException
See Also
setClob Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
setDate Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setDate (int, java.sql.Date) Sets the designated parameter to the given date value.
setDate (int, java.sql.Date, java.util.Calendar) Sets the designated parameter to the given date and
calendar values.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setDate Method (int, java.sql.Date)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setDate(int n,
java.sql.Date x)
Parameters
n
An int that indicates the parameter number.
x
A Date object.
Exceptions
SQLServerException
Remarks
This setDate method is specified by the setDate method in the java.sql.PreparedStatement interface.
See Also
setDate Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setDate Method (int, java.sql.Date,
java.util.Calendar)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setDate(int n,
java.sql.Date x,
java.util.Calendar cal)
Parameters
n
An int that indicates the parameter number.
x
A Date object.
cal
A Calendar object.
Exceptions
SQLServerException
Remarks
This setDate method is specified by the setDate method in the java.sql.PreparedStatement interface.
See Also
setDate Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setDouble Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setDouble(int n,
double x)
Parameters
n
An int that indicates the parameter number.
x
A double value.
Exceptions
SQLServerException
Remarks
This setDouble method is specified by the setDouble method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setDateTimeOffset Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setDateTimeOffset(int n, microsoft.sql.DateTimeOffset x)
Parameters
n
The zero-based ordinal of a column.
x
The DateTimeOffset Class object.
Exceptions
SQLServerException
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setFloat Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setFloat(int n,
float x)
Parameters
n
An int that indicates the parameter number.
x
A float value.
Exceptions
SQLServerException
Remarks
This setFloat method is specified by the setFloat method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setInt Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setInt(int n,
int value)
Parameters
n
An int that indicates the parameter number.
value
An int value.
Exceptions
SQLServerException
Remarks
This setInt method is specified by the setInt method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setLong Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setLong(int n,
long x)
Parameters
n
An int that indicates the parameter number.
x
A long value.
Exceptions
SQLServerException
Remarks
This setLong method is specified by the setLong method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setNCharacterStream Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setNCharacterStream Method (int, java.io.Reader) Sets the designated parameter to the specified java.io.Reader
object.
setNCharacterStream Method (int, java.io.Reader, long) Sets the designated parameter to the specified java.io.Reader
object.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setNCharacterStream Method (int, java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setNCharacterStream(int parameterIndex,
java.io.Reader value)
Parameters
parameterIndex
An int that indicates the parameter index.
value
A Reader object that contains the parameter value.
Exceptions
SQLServerException
Remarks
This setNCharacterStream method is specified by the setNCharacterStream method in the
java.sql.PreparedStatement interface.
This method should be used for NCHAR , NVARCHAR , NTEXT , and XML data types.
See Also
setNCharacterStream Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
setNCharacterStream Method (int, java.io.Reader,
long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setNCharacterStream(int parameterIndex,
java.io.Reader value,
long length)
Parameters
parameterIndex
An int that indicates the parameter index.
value
A Reader object that contains the parameter value.
length
A long that indicates the number of characters in the parameter value.
Exceptions
SQLServerException
Remarks
This setNCharacterStream method is specified by the setNCharacterStream method in the
java.sql.PreparedStatement interface.
This method should be used for NCHAR , NVARCHAR , NTEXT , and XML data types.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
setNCharacterStream Method (int, java.io.Reader) when the application wants to update the column from a
stream whose length is unknown.
See Also
setNCharacterStream Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
setNClob Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setNClob Method (int, java.sql.NClob) Sets the designated parameter to the specified
java.sql.NClob object.
setNClob Method (int, java.io.Reader) Sets the designated parameter to the specified java.io.Reader
object.
setNClob Method (int, java.io.Reader, long) Sets the designated parameter to the specified java.io.Reader
object, which is the specified number of characters long.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setNClob Method (int, java.sql.NClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setNClob(int parameterIndex,
java.sql.NClob value)
Parameters
parameterIndex
An int that indicates the parameter index.
value
A NClob object that indicates the parameter value.
Exceptions
SQLServerException
Remarks
This setNClob method is specified by the setNClob method in the java.sql.PreparedStatement interface.
See Also
setNClob Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
setNClob Method (int, java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setNClob(int parameterIndex,
java.io.Reader reader)
Parameters
parameterIndex
An int that indicates the parameter index.
reader
A Reader object that indicates the parameter value.
Exceptions
SQLServerException
Remarks
This setNClob method is specified by the setNClob method in the java.sql.PreparedStatement interface.
See Also
setNClob Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
setNClob Method (int, java.io.Reader, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setNClob(int parameterIndex,
java.io.Reader reader,
long length)
Parameters
parameterIndex
An int that indicates the parameter index.
reader
A Reader object that indicates the parameter value.
length
An long that indicates the number of characters in the parameter value.
Exceptions
SQLServerException
Remarks
This setNClob method is specified by the setNClob method in the java.sql.PreparedStatement interface.
See Also
setNClob Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
setNString Method (int, java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setNString(int parameterIndex,
java.lang.String value)
Parameters
parameterIndex
An int that indicates the parameter index.
value
A String object that contains the parameter value.
Exceptions
SQLServerException
Remarks
This method should be used for NCHAR , NVARCHAR , NTEXT , and XML data types.
This setNString method is specified by the setNString method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
setNull Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setNull (int, int) Sets the designated parameter to a null value, given the type
of parameter to set.
setNull (int, int, java.lang.String) Sets the designated parameter to a null value, given the type
and name of the parameter to set.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setNull Method (int, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setNull(int index,
int jdbcType)
Parameters
index
An int that indicates the parameter number.
jdbcType
A JDBC type code that is defined by java.sql.Types.
Exceptions
SQLServerException
Remarks
This setNull method is specified by the setNull method in the java.sql.PreparedStatement interface.
See Also
setNull Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setNull Method (int, int, java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setNull(int paramIndex,
int sqlType,
java.lang.String typeName)
Parameters
paramIndex
An int that indicates the parameter number.
sqlType
A JDBC type code defined by java.sql.Types.
typeName
A String that indicates the fully qualified name of the parameter that is being set.
Exceptions
SQLServerException
Remarks
This setNull method is specified by the setNull method in the java.sql.PreparedStatement interface.
See Also
setNull Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setObject Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setObject (int, java.lang.Object) Sets the value of the designated parameter by using the
given object.
setObject (int, java.lang.Object, int) Sets the value of the designated parameter by using the
given object and target type.
setObject (int, java.lang.Object, int, int) Sets the value of the designated parameter by using the
given object, target type, and scale.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setObject Method (int, java.lang.Object)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setObject(int index,
java.lang.Object obj)
Parameters
index
An int that indicates the parameter number.
obj
An object.
Exceptions
SQLServerException
Remarks
This setObject method is specified by the setObject method in the java.sql.PreparedStatement interface.
Before calling this setObject method, the application might set the specified parameter by using one of the
following methods:
The set<Type> methods of the SQLServerPreparedStatement class or the SQLServerCallableStatement
class
The setNull methods of the SQLServerPreparedStatement class or the SQLServerCallableStatement class
The registerOutParameter method of the SQLServerCallableStatement class
In such a case, the type of the parameter is automatically set. If the application calls this setObject method with
an obj value NULL, the driver assumes that the type of the parameter is one that is set by the previously called
method.
If the obj value is NULL and no type information for that parameter can be determined, this setObject method
converts the specified parameter to a CHAR before sending it to the database.
Beginning with SQL Server JDBC Driver 3.0, the behavior of this method is modified by the
sendTimeAsDatetime connection property (Setting the Connection Properties) and
SQLServerDataSource.setSendTimeAsDatetime.
For more information, see Configuring How java.sql.Time Values are Sent to the Server.
See Also
setObject Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setObject Method (int, java.lang.Object, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setObject(int n,
java.lang.Object obj,
int targetSqlType)
Parameters
n
An int that indicates the parameter number.
obj
An object.
targetSqlType
An int that indicates the target type as defined in java.sql.Types.
Exceptions
SQLServerException
Remarks
This setObject method is specified by the setObject method in the java.sql.PreparedStatement interface.
Beginning with SQL Server JDBC Driver 3.0, the behavior of this method is modified by the
sendTimeAsDatetime connection property (Setting the Connection Properties) and
SQLServerDataSource.setSendTimeAsDatetime.
For more information, see Configuring How java.sql.Time Values are Sent to the Server.
See Also
setObject Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setObject Method (int, java.lang.Object, int, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setObject(int n,
java.lang.Object obj,
int targetSqlType,
int scale)
Parameters
n
An int that indicates the parameter number.
obj
An object.
targetSqlType
An int that indicates the target type as defined in java.sql.Types.
scale
An int that indicates the number of digits to the right of the decimal point. This parameter is ignored for all
types other than NUMERIC and DECIMAL.
Exceptions
SQLServerException
Remarks
This setObject method is specified by the setObject method in the java.sql.PreparedStatement interface.
Beginning with SQL Server JDBC Driver 3.0, the behavior of this method is modified by the
sendTimeAsDatetime connection property (Setting the Connection Properties) and
SQLServerDataSource.setSendTimeAsDatetime.
For more information, see Configuring How java.sql.Time Values are Sent to the Server.
See Also
setObject Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setRef Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setRef(int i,
java.sql.Ref x)
Parameters
i
An int that indicates the parameter number.
x
A Ref object.
Exceptions
SQLServerException
Remarks
This setRef method is specified by the setRef method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setShort Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setShort(int index,
short x)
Parameters
index
An int that indicates the parameter number.
x
A shor t value.
Exceptions
SQLServerException
Remarks
This setShort method is specified by the setShort method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setSQLXML Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setSQLXML(int parameterIndex,
java.sql.SQLXML xmlObject)
Parameters
parameterIndex
An int that indicates the parameter index.
xmlObject
A SQLXML object that contains the parameter value.
Exceptions
SQLServerException
Remarks
This setSQLXML method is specified by the setSQLXML method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
setString Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setString(int index,
java.lang.String str)
Parameters
index
An int that indicates the parameter number.
str
A String value.
Exceptions
SQLServerException
Remarks
This setString method is specified by the setString method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setTime Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setTime (int, java.sql.Time) Sets the designated parameter to the given time value.
setTime (int, java.sql.Time, java.util.Calendar) Sets the designated parameter to the given time and
calendar values.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setTime Method (int, java.sql.Time)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setTime(int n,
java.sql.Time x)
Parameters
n
An int that indicates the parameter number.
x
A Time object.
Exceptions
SQLServerException
Remarks
This setTime method is specified by the setTime method in the java.sql.PreparedStatement interface.
Beginning with SQL Server JDBC Driver 3.0, the behavior of this method is modified by the
sendTimeAsDatetime connection property (Setting the Connection Properties) and
SQLServerDataSource.setSendTimeAsDatetime.
For more information, see Configuring How java.sql.Time Values are Sent to the Server.
See Also
setTime Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setTime Method (int, java.sql.Time,
java.util.Calendar)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setTime(int n,
java.sql.Time x,
java.util.Calendar cal)
Parameters
n
An int that indicates the parameter number.
x
A Time object.
cal
A Calendar object.
Exceptions
SQLServerException
Remarks
This setTime method is specified by the setTime method in the java.sql.PreparedStatement interface.
Beginning with SQL Server JDBC Driver 3.0, the behavior of this method is modified by the
sendTimeAsDatetime connection property (Setting the Connection Properties) and
SQLServerDataSource.setSendTimeAsDatetime.
For more information, see Configuring How java.sql.Time Values are Sent to the Server.
See Also
setTime Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setTimestamp Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
setTimestamp (int, java.sql.Timestamp) Sets the designated parameter to the given timestamp
value.
setTimestamp (int, java.sql.Timestamp, java.util.Calendar) Sets the designated parameter to the given timestamp and
calendar values.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setTimestamp Method (int, java.sql.Timestamp)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setTimestamp(int n,
java.sql.Timestamp x)
Parameters
n
An int that indicates the parameter number.
x
A Timestamp object.
Exceptions
SQLServerException
Remarks
This setTimestamp method is specified by the setTimestamp method in the java.sql.PreparedStatement interface.
See Also
setTimestamp Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setTimestamp Method (int, java.sql.Timestamp,
java.util.Calendar)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setTimestamp(int n,
java.sql.Timestamp x,
java.util.Calendar cal)
Parameters
n
An int that indicates the parameter number.
x
An Timestamp object.
cal
A Calendar object.
Exceptions
SQLServerException
Remarks
This setTimestamp method is specified by the setTimestamp method in the java.sql.PreparedStatement interface.
See Also
setTimestamp Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setUnicodeStream Method
(SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method has been deprecated from the JDBC specification, and calling it will cause a "not implemented" exception to
be thrown.
Syntax
public final void setUnicodeStream(int n,
java.io.InputStream x,
int length)
Parameters
n
An int that indicates the parameter number.
x
An InputStream object.
length
The number of bytes.
Exceptions
SQLServerException
Remarks
This setUnicodeStream method is specified by the setUnicodeStream method in the java.sql.PreparedStatement
interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
setURL Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setURL(int parameterIndex,
java.net.URL x)
Parameters
parameterindex
An int that indicates the parameter number.
x
A URL object.
Exceptions
SQLServerException
Remarks
This setURL method is specified by the setURL method in the java.sql.PreparedStatement interface.
See Also
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
unwrap Method (SQLServerPreparedStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public <T> T unwrap(Class<T> iface)
Parameters
iface
A class of type T defining an interface.
Return Value
An object that implements the specified interface.
Exceptions
SQLServerException
Remarks
The unwrap method is defined by the java.sql.Wrapper interface, which is introduced in the JDBC 4.0 Spec.
Applications might need to access extensions to the JDBC API that are specific to the Microsoft JDBC Driver for
SQL Server. The unwrap method supports unwrapping to public classes that this object extends, if the classes
expose vendor extensions.
When this method is called, the object unwraps to the following classes: SQLServerStatement and
SQLServerPreparedStatement.
For example code, see unwrap Method (SQLServerCallableStatement).
For more information, see Wrappers and Interfaces.
See Also
isWrapperFor Method (SQLServerPreparedStatement)
SQLServerPreparedStatement Members
SQLServerPreparedStatement Class
SQLServerResource Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public class SQLServerResource
See Also
SQLServerResource Members
JDBC Driver API Reference
SQLServerResource Members
4/27/2022 • 2 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
Fields
None.
Inherited Fields
NAME DESC RIP T IO N
java.util.ResourceBundle parent
Methods
NAME DESC RIP T IO N
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerResource Class
SQLServerResource Constructors
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public SQLServerResource()
See Also
SQLServerResource Constructors
SQLServerResource Members
SQLServerResource Class
SQLServerResource Methods
4/27/2022 • 2 minutes to read • Edit Online
Syntax
protected java.lang.Object[][] getContents()
Return Value
A multi-dimensional array of Object values.
See Also
SQLServerResource Methods
SQLServerResource Members
SQLServerResource Class
SQLServerResultSet Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final class SQLServerResultSet
Remarks
There are two types of result sets: client-side and server-side.
Client-side result sets are used when the results can fit in the client process memory. These results provide the
fastest performance and are read by the Microsoft JDBC Driver for SQL Server in their entirety from the
database. These result sets do not impose additional load on the database by incurring the overhead of creating
server-side cursors. However, these types of result sets are not updatable.
Server-side result sets can be used when the results do not fit in the client process memory or when the result
set is to be updatable. With this type of result set, the JDBC driver creates a server-side cursor and fetches rows
of the result set transparently as the user scrolls through it.
The SQLServerResultSet class provides many methods to let you update the result set with any native Java data
type and many Java object types.
This class supports unwrapping to SQLServerResultSet class, ISQLServerResultSet interface, and
java.sql.ResultSet interface. For more information, see Wrappers and Interfaces.
See Also
SQLServerResultSet Members
JDBC Driver API Reference
SQLServerResultSet Members
4/27/2022 • 7 minutes to read • Edit Online
Constructors
None.
Fields
NAME DESC RIP T IO N
Inherited Fields
C L A SS IN H ERIT ED F RO M : DESC RIP T IO N
Methods
NAME DESC RIP T IO N
findColumn Retrieves the index of the first matching column for the
specified column name in this SQLServerResultSet object.
getObject Gets the value of the designated column in the current row
of this SQLServerResultSet object as an object in the Java
programming language.
isAfterLast Retrieves whether the cursor is after the last row in this
SQLServerResultSet object.
isBeforeFirst Retrieves whether the cursor is before the first row in this
SQLServerResultSet object.
next Moves the cursor down one row from its current position.
refreshRow Refreshes the current row with its most recent value in the
database.
relative Moves the cursor the given amount of rows, relative to the
current row, in either a positive or a negative direction.
setFetchSize Gives the JDBC driver a hint as to the number of rows that
should be fetched from the database when more rows are
needed for this SQLServerResultSet object.
NAME DESC RIP T IO N
wasNull Verifies whether the last value read was a null value.
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerResultSet Class
SQLServerResultSet Methods
4/27/2022 • 2 minutes to read • Edit Online
See Also
SQLServerResultSet Class
absolute Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean absolute(int row)
Parameters
row
An int that indicates the row number to move to. Can be positive, negative, or 0.
Return Value
true if the cursor is moved to the given position. false if it is before the first row or after the last row.
Exceptions
SQLServerException
Remarks
This absolute method is specified by the absolute method in the java.sql.ResultSet interface.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
afterLast Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void afterLast()
Exceptions
SQLServerException
Remarks
This afterLast method is specified by the afterLast method in the java.sql.ResultSet interface.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
beforeFirst Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void beforeFirst()
Exceptions
SQLServerException
Remarks
This beforeFirst method is specified by the beforeFirst method in the java.sql.ResultSet interface.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
cancelRowUpdates Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void cancelRowUpdates()
Exceptions
SQLServerException
Remarks
This cancelRowUpdates method is specified by the cancelRowUpdates method in the java.sql.ResultSet interface.
This method can be called after calling an updater method and before calling the updateRow method to roll
back the updates that were made to a row. If no updates have been made or updateRow has already been called,
this method has no effect.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
clearWarnings Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently implemented by the Microsoft JDBC Driver for SQL Server. If called, it will always return null.
Syntax
public void clearWarnings()
Exceptions
SQLServerException
Remarks
This clearWarnings method is specified by the clearWarnings method in the java.sql.ResultSet interface.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
close Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void close()
Exceptions
SQLServerException
Remarks
This close method is specified by the close method in the java.sql.ResultSet interface.
A SQLServerResultSet object is automatically closed by the SQLServerStatement object that generated it when
that SQLServerStatement object is closed, re-run, or used to retrieve the next result from a sequence of multiple
results. A SQLServerResultSet object is also automatically closed when it is garbage collected.
When executing a statement that produces a single large forward-only, read-only result set, you might only be
interested in some initial set of rows in the returned result set. In this case, the application might call the cancel
method of the associated statement object before closing the result set in order to minimize the processing time
needed to discard the remaining unnecessary rows. We recommend considering the tradeoff between the
processing time that would be saved and the time and the additional round trip to the server needed to cancel
the execution when deciding whether to use this technique or not.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
deleteRow Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void deleteRow()
Exceptions
SQLServerException
Remarks
This deleteRow method is specified by the deleteRow method in the java.sql.ResultSet interface.
This method cannot be called when the cursor is on the insert row.
When using keyset cursors, this method leaves a gap in the result set. You can test for this gap by using the
rowDeleted method. The row numbers of the rows in the result set do not change.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
finalize Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void finalize()
Remarks
Closes the result set if the application does not. This method exists only to conform to the JDBC specification.
Because the Java Virtual Machine (JVM) does not guarantee when a finalizer will have a chance to run,
applications that neglect to explicitly close their result sets could still deadlock on another statement that is
using the same connection and is blocked on a common server resource, such as row locks.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
findColumn Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int findColumn(java.lang.String columnName)
Parameters
columnName
A String that contains the name of the column.
Return Value
An int that indicates the column index.
Exceptions
SQLServerException
Remarks
This findColumn method is specified by the findColumn method in the java.sql.ResultSet interface.
If there are multiple columns with the same name, the findColumn method returns the first case-sensitive
match. If there is no case-sensitive match, this method returns the first case-insensitive match.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
first Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean first()
Return Value
true if the cursor is moved to the first row. Otherwise, false .
Exceptions
SQLServerException
Remarks
This first method is specified by the first method in the java.sql.ResultSet interface.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getArray Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getArray Method (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as an Array
object.
getArray Method (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as an Array
object.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getArray Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Array getArray(int i)
Parameters
i
An int that indicates the column index.
Return Value
An Array object.
Exceptions
SQLServerException
Remarks
This getArray method is specified by the getArray method in the java.sql.ResultSet interface.
See Also
getArray Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getArray Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Array getArray(java.lang.String colName)
Parameters
colName
A String that contains the column name.
Return Value
An Array object.
Exceptions
SQLServerException
Remarks
This getArray method is specified by the getArray method in the java.sql.ResultSet interface.
See Also
getArray Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getAsciiStream Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getAsciiStream (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a stream of
ASCII characters.
getAsciiStream (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a stream of
ASCII characters.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getAsciiStream Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.InputStream getAsciiStream(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
An InputStream object.
Exceptions
SQLServerException
Remarks
This getAsciiStream method is specified by the getAsciiStream method in the java.sql.ResultSet interface.
See Also
getAsciiStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getAsciiStream Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.InputStream getAsciiStream(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
An InputStream object.
Exceptions
SQLServerException
Remarks
This getAsciiStream method is specified by the getAsciiStream method in the java.sql.ResultSet interface.
See Also
getAsciiStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getBigDecimal Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getBigDecimal Method (int) (SQLServerResultSet) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a
java.math.BigDecimal with full precision.
getBigDecimal Method (int, int) (SQLServerResultSet) (Deprecated) Retrieves the value of the designated column
index in the current row of this SQLServerResultSet object
using the given scale.
getBigDecimal Method (java.lang.String) Retrieves the value of the designated column name in the
(SQLServerResultSet) current row of this SQLServerResultSet object as a
java.math.BigDecimal with full precision.
getBigDecimal Method (java.lang.String, int) (Deprecated) Retrieves the value of the designated column
(SQLServerResultSet) name in the current row of this SQLServerResultSet object
using the given scale.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getBigDecimal Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.math.BigDecimal getBigDecimal(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A BigDecimal object.
Exceptions
SQLServerException
Remarks
This getBigDecimal method is specified by the getBigDecimal method in the java.sql.ResultSet interface.
See Also
getBigDecimal Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getBigDecimal Method (int, int)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method has been deprecated from the JDBC specification. Instead, you should use the getBigDecimal (int) method.
Syntax
public java.math.BigDecimal getBigDecimal(int columnIndex,
int scale)
Parameters
columnIndex
An int that indicates the column index.
scale
An int that indicates the number of digits to the right of the decimal point.
Return Value
A BigDecimal object.
Exceptions
SQLServerException
Remarks
This getBigDecimal method is specified by the getBigDecimal method in the java.sql.ResultSet interface.
See Also
getBigDecimal Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getBigDecimal Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.math.BigDecimal getBigDecimal(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
A BigDecimal object.
Exceptions
SQLServerException
Remarks
This getBigDecimal method is specified by the getBigDecimal method in the java.sql.ResultSet interface.
See Also
getBigDecimal Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getBigDecimal Method ( java.lang.String, int)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method has been deprecated from the JDBC specification. Instead, you should use the getBigDecimal
(java.lang.String) method.
Syntax
public java.math.BigDecimal getBigDecimal(java.lang.String columnName,
int scale)
Parameters
columnName
A String that contains the column name.
scale
An int that indicates the number of digits to the right of the decimal point.
Return Value
A BigDecimal object.
Exceptions
SQLServerException
Remarks
This getBigDecimal method is specified by the getBigDecimal method in the java.sql.ResultSet interface.
See Also
getBigDecimal Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getBinaryStream Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getBinaryStream (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a binary
stream of uninterpreted bytes.
getBinaryStream (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a binary
stream of uninterpreted bytes.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getBinaryStream Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.InputStream getBinaryStream(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
An InputStream object.
Exceptions
SQLServerException
Remarks
This getBinaryStream method is specified by the getBinaryStream method in the java.sql.ResultSet interface.
This method can be used only with SQL Server data types of binary, varbinary, varbinary(max), and image.
Trying to use it with other data types will cause an exception to be thrown.
After this method gets the value as a stream, the value can then be read in chunks from the stream. This method
is particularly suitable for retrieving large LONGVARBINARY values.
NOTE
All the data in the returned stream must be read before getting the value of any other column. The next call to a getter
method implicitly closes the stream. Also, a stream can return 0 when the method InputStream.available is called, whether
there is data available or not.
See Also
getBinaryStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getBinaryStream Method (long, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.InputStream getBinaryStream(long pos, long length)
Parameters
pos
The offset to the first byte of the partial value to be retrieved.
length
The length in bytes of the partial value to be retrieved.
Return Value
An input stream that contains the BLOB data.
Exceptions
SQLServerException
Remarks
This getBinaryStream method is specified by the getBinaryStream method in the java.sql.Blob interface.
See Also
SQLServerBlob Methods
SQLServerBlob Members
SQLServerBlob Class
getBinaryStream Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.InputStream getBinaryStream(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
An InputStream object.
Exceptions
SQLServerException
Remarks
This getBinaryStream method is specified by the getBinaryStream method in the java.sql.ResultSet interface.
This method can be used only with SQL Server data types of binary, varbinary, varbinary(max), and image.
Trying to use it with other data types will cause an exception to be thrown.
After this method gets the value as a stream, the value can then be read in chunks from the stream. This method
is particularly suitable for retrieving large LONGVARBINARY values.
NOTE
All the data in the returned stream must be read before getting the value of any other column. The next call to a getter
method implicitly closes the stream. Also, a stream can return 0 when the method InputStream.available is called, whether
there is data available or not.
See Also
getBinaryStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getBlob Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getBlob (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a Blob
object in the Java programming language.
getBlob (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a Blob
object in the Java programming language.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getBlob Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Blob getBlob(int i)
Parameters
i
An int that indicates the column index.
Return Value
A Blob object.
Exceptions
SQLServerException
Remarks
This getBlob method is specified by the getBlob method in the java.sql.ResultSet interface.
See Also
getBlob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getBlob Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Blob getBlob(java.lang.String colName)
Parameters
colName
A String that contains the column name.
Return Value
A Blob object.
Exceptions
SQLServerException
Remarks
This getBlob method is specified by the getBlob method in the java.sql.ResultSet interface.
See Also
getBlob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getBoolean Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getBoolean (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a boolean
in the Java programming language.
getBoolean (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a boolean
in the Java programming language.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getBoolean Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getBoolean(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A boolean value.
Exceptions
SQLServerException
Remarks
This getBoolean method is specified by the getBoolean method in the java.sql.ResultSet interface.
This method is supported only on number and character data types. It converts values "1", 1, and "true " to true ,
and values "0", 0, and "false " to false . For all other values the behavior is undefined.
See Also
getBoolean Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getBoolean Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean getBoolean(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
A boolean value.
Exceptions
SQLServerException
Remarks
This getBoolean method is specified by the getBoolean method in the java.sql.ResultSet interface.
This method is supported only on number and character data types. It converts values "1", 1, and "true " to true ,
and values "0", 0, and "false " to false . For all other values the behavior is undefined.
See Also
getBoolean Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getByte Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getByte (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a byte in
the Java programming language.
getByte (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a byte in
the Java programming language.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getByte Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public byte getByte(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A byte value.
Exceptions
SQLServerException
Remarks
This getByte method is specified by the getByte method in the java.sql.ResultSet interface.
This method is supported only on SQL Server data types that can safely return a byte value, such as tinyint and
bit. All other data types will cause an exception to be thrown.
See Also
getByte Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getByte Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public byte getByte(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
A byte value.
Exceptions
SQLServerException
Remarks
This getByte method is specified by the getByte method in the java.sql.ResultSet interface.
This method is supported only on SQL Server data types that can safely return a byte value, such as tinyint and
bit. All other data types will cause an exception to be thrown.
See Also
getByte Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getBytes Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getBytes (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a byte
array in the Java programming language.
getBytes (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a byte
array in the Java programming language.
Remarks
In a previous version of the Microsoft JDBC Driver for SQL Server, you could use SQLServerResultSet.getBytes
to convert values between byte arrays and SQL Server data type date , time , datetime2 , or datetimeoffset .
Now, using this method with those data types will cause an exception indicating that the conversion is not
supported.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getBytes Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public byte[] getBytes(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
An array of byte values.
Exceptions
SQLServerException
Remarks
This getBytes method is specified by the getBytes method in the java.sql.ResultSet interface.
This method supports retrieving all columns as a raw read of bytes from the server. It returns an array of bytes
directly from the server, in the format that is stored on the server.
In a previous version of the Microsoft JDBC Driver for SQL Server, you could use SQLServerResultSet.getBytes
to convert values between byte arrays and SQL Server data type date , time , datetime2 , or datetimeoffset .
Now, using this method with those data types will cause an exception indicating that the conversion is not
supported.
See Also
getBytes Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getBytes Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public byte[] getBytes(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
An array of byte values.
Exceptions
SQLServerException
Remarks
This getBytes method is specified by the getBytes method in the java.sql.ResultSet interface.
This method supports retrieving all columns as a raw read of bytes from the server. It returns an array of bytes
directly from the server, in the format that is stored on the server.
In a previous version of the Microsoft JDBC Driver for SQL Server, you could use SQLServerResultSet.getBytes
to convert values between byte arrays and SQL Server data type date , time , datetime2 , or datetimeoffset .
Now, using this method with those data types will cause an exception indicating that the conversion is not
supported.
See Also
getBytes Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getCharacterStream Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getCharacterStream (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a
java.io.Reader object.
getCharacterStream (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a
java.io.Reader object.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getCharacterStream Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.Reader getCharacterStream(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A Reader object.
Exceptions
SQLServerException
Remarks
This getCharacterStream method is specified by the getCharacterStream method in the java.sql.ResultSet
interface.
This method will read only SQL Server Unicode character data types such as nchar, nvarchar, nvarchar(max), and
ntext. All other data types, including the ASCII character types, will cause an exception to be thrown. To read the
ASCII data types, use the getAsciiStream method.
See Also
getCharacterStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getCharacterStream Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.Reader getCharacterStream(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
A Reader object.
Exceptions
SQLServerException
Remarks
This getCharacterStream method is specified by the getCharacterStream method in the java.sql.ResultSet
interface.
This method will read only SQL Server Unicode character data types such as nchar, nvarchar, nvarchar(max), and
ntext. All other data types, including the ASCII character types, will cause an exception to be thrown. To read the
ASCII data types, use the getAsciiStream method.
See Also
getCharacterStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getCharacterStream Method () (SQLServerNClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.Reader getCharacterStream()
Exceptions
SQLServerException
Return Value
A Reader object that contains the NCLOB data.
Remarks
This getCharacterStream method is specified by the getCharacterStream method in the java.sql.NClob interface.
See Also
getCharacterStream Method (SQLServerNClob)
SQLServerNClob Methods
SQLServerNClob Members
SQLServerNClob Class
getClob Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getClob (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a Clob
object in the Java programming language.
getClob (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a Clob
object in the Java programming language.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getClob Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Clob getClob(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A Clob object.
Exceptions
SQLServerException
Remarks
This getClob method is specified by the getClob method in the java.sql.ResultSet interface.
See Also
getClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getClob Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Clob getClob(java.lang.String colName)
Parameters
colName
A String that contains the column name.
Return Value
A Clob object.
Exceptions
SQLServerException
Remarks
This getClob method is specified by the getClob method in the java.sql.ResultSet interface.
See Also
getClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getConcurrency Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getConcurrency()
Return Value
An int that indicates the concurrency type, which can be one of the following values:
ResultSet.CONCUR_READ_ONLY
ResultSet.CONCUR_UPDATABLE
Exceptions
SQLServerException
Remarks
This getConcurrency method is specified by the getConcurrency method in the java.sql.ResultSet interface.
The concurrency used is determined by the SQLServerStatement object that created the result set.
This method can be used to determine the actual concurrency. If the application selected CONCUR_READ_ONLY
or CONCUR_UPDATABLE, these will be returned. If the application used default concurrency,
CONCUR_READ_ONLY will be returned.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getCursorName Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported by the Microsoft JDBC Driver for SQL Server. If called, an exception will be thrown.
Syntax
public java.lang.String getCursorName()
Return Value
A String that contains the cursor name.
Exceptions
SQLServerException
Remarks
This getCursorName method is specified by the getCursorName method in the java.sql.ResultSet interface.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getDate Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getDate Method (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a
java.sql.Date object in the Java programming language.
getDate (int, java.util.Calendar) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a
java.sql.Date object in the Java programming language,
using the given Calendar object.
getDate (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a
java.sql.Date object in the Java programming language.
getDate (java.lang.String, java.util.Calendar) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a
java.sql.Date object in the Java programming language,
using the given Calendar object.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getDate Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Date getDate(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A Date object.
Exceptions
SQLServerException
Remarks
This getDate method is specified by the getDate method in the java.sql.ResultSet interface.
This method returns a valid date part of a SQL Server datetime or smalldatetime data type, with the time part
set to the Java time baseline of 00:00 (midnight).
See Also
getDate Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getDate Method (int, java.util.Calendar)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Date getDate(int columnIndex,
java.util.Calendar cal)
Parameters
columnIndex
An int that indicates the column index.
cal
A Calendar object.
Return Value
A Date object.
Exceptions
SQLServerException
Remarks
This getDate method is specified by the getDate method in the java.sql.ResultSet interface.
This method returns a valid date part of a SQL Server datetime or smalldatetime data type, with the time part
set to the Java time baseline of 00:00 (midnight) in the supplied Calendar's timezone.
See Also
getDate Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getDate Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Date getDate(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
A Date object.
Exceptions
SQLServerException
Remarks
This getDate method is specified by the getDate method in the java.sql.ResultSet interface.
This method returns a valid date part of a SQL Server datetime or smalldatetime data type, with the time part
set to the Java time baseline of 00:00 (midnight).
See Also
getDate Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getDate Method ( java.lang.String,
java.util.Calendar) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Date getDate(java.lang.String colName,
java.util.Calendar cal)
Parameters
colName
A String that contains the column name.
cal
A Calendar object.
Return Value
A Date object.
Exceptions
SQLServerException
Remarks
This getDate method is specified by the getDate method in the java.sql.ResultSet interface.
This method returns a valid date part of a SQL Server datetime or smalldatetime data type, with the time part
set to the Java time baseline of 00:00 (midnight) in the supplied Calendar's timezone.
See Also
getDate Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getDateTimeOffset (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
setDateTimeOffset(int, java.sql.DateTimeOffset) (SQLServerStatement)
getDateTimeOffset(int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public microsoft.sql.DateTimeOffset getDateTimeOffset(int columnIndex)
Parameters
columnIndex
The column ordinal.
Return Value
A DateTimeOffset Class object.
Exceptions
SQLServerException
Remarks
You can update a DateTimeOffset Class value with SQLServerResultSet.updateDateTimeOffset.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getDateTimeOffset( java.lang.string)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public microsoft.sql.DateTimeOffset getDateTimeOffset(String columnName)
Parameters
columnName
The name of the column.
Return Value
A DateTimeOffset Class object.
Exceptions
SQLServerException
Remarks
You can update a DateTimeOffset Class value with SQLServerResultSet.updateDateTimeOffset.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getDouble Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getDouble (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a double in
the Java programming language.
getDouble (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a double in
the Java programming language.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getDouble Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public double getDouble(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A double value.
Exceptions
SQLServerException
Remarks
This getDouble method is specified by the getDouble method in the java.sql.ResultSet interface.
This method returns all number-based data types with Java double fidelity.
See Also
getDouble Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getDouble Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public double getDouble(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
A double value.
Exceptions
SQLServerException
Remarks
This getDouble method is specified by the getDouble method in the java.sql.ResultSet interface.
This method returns all number-based data types with Java double fidelity.
See Also
getDouble Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getFetchDirection Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getFetchDirection()
Return Value
An int that indicates the current fetch direction.
Exceptions
SQLServerException
Remarks
This getFetchDirection method is specified by the getFetchDirection method in the java.sql.ResultSet interface.
This method returns FETCH_FORWARD for forward-only cursors, the last setting made by a call to the
setFetchDirection method for other cursor types, and will return FETCH_UNKNOWN these cursor types if the
setFetchDirection method has never been called.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getFetchSize Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getFetchSize()
Return Value
An int that indicates the current fetch size.
Exceptions
SQLServerException
Remarks
This getFetchSize method is specified by the getFetchSize method in the java.sql.ResultSet interface.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getFloat Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getFloat (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a float in
the Java programming language.
getFloat (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a float in
the Java programming language.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getFloat Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public float getFloat(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A float value.
Exceptions
SQLServerException
Remarks
This getFloat method is specified by the getFloat method in the java.sql.ResultSet interface.
This method returns all number-based types with Java float fidelity.
See Also
getFloat Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getFloat Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public float getFloat(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
A float value.
Exceptions
SQLServerException
Remarks
This getFloat method is specified by the getFloat method in the java.sql.ResultSet interface.
This method returns all number-based types with Java float fidelity.
See Also
getFloat Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getHoldability Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getHoldability()
Return Value
An int value that contains one of the following holdability levels:
HOLD_CURSORS_OVER_COMMIT
CLOSE_CURSORS_AT_COMMIT
Exceptions
SQLServerException
Remarks
This getHoldability method is specified by the getHoldability method in the java.sql.ResultSet interface.
To set the result set holdability, applications can use the setHoldability method of the SQLServerConnection
class. After the setHoldability method is called and the statement object and its result set object are created and
the statement is executed, the application may need to change the holdability again.
For server cursors, when connected to SQL Server 2005 or later, setting holdability affects only the holdability of
new result sets that are yet to be created on that connection. However, with SQL Server 2000, setting holdability
affects the holdability of both existing result sets and new result sets that are yet to be created on that
connection.
When the holdability is reset and the getHoldability method is called on the previously created result set object,
the value returned by this method may be different than the holdability value returned by the following
methods: Statement.getResultSetHoldability, Connection.getHoldability, or
DatabaseMetaData.getResultSetHoldability.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getInt Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getInt (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as an int in
the Java programming language.
getInt (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as an int in
the Java programming language.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getInt Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getInt(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
An int value.
Exceptions
SQLServerException
Remarks
This getInt method is specified by the getInt method in the java.sql.ResultSet interface.
This method is supported only on SQL Server data types that can safely return an integer value such as int,
smallint, tinyint, and bit. Using this method on any other data types will cause an exception to be thrown.
See Also
getInt Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getInt Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getInt(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
An int value.
Exceptions
SQLServerException
Remarks
This getInt method is specified by the getInt method in the java.sql.ResultSet interface.
This method is supported only on SQL Server data types that can safely return an integer value such as int,
smallint, tinyint, and bit. Using this method on any other data types will cause an exception to be thrown.
See Also
getInt Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getLong Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getLong (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a long in
the Java programming language.
getLong (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a long in
the Java programming language.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getLong Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public long getLong(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A long value.
Exceptions
SQLServerException
Remarks
This getLong method is specified by the getLong method in the java.sql.ResultSet interface.
This method is supported only on SQL Server data types that can safely return an integer value such as bigint,
int, smallint, tinyint, and bit. Using this method on any other data types will cause an exception to be thrown.
See Also
getLong Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getLong Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public long getLong(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
A long value.
Exceptions
SQLServerException
Remarks
This getLong method is specified by the getLong method in the java.sql.ResultSet interface.
This method is supported only on SQL Server data types that can safely return an integer value such as bigint,
int, smallint, tinyint, and bit. Using this method on any other data types will cause an exception to be thrown.
See Also
getLong Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getMetaData Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSetMetaData getMetaData()
Return Value
A SQLServerResultSetMetaData object.
Exceptions
SQLServerException
Remarks
This getMetaData method is specified by the getMetaData method in the java.sql.ResultSet interface.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getNCharacterStream Method
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getNCharacterStream Method (int) (SQLServerResultSet) Retrieves the value of the designated column in the current
row of the SQLServerResultSet object as a Reader object.
getNCharacterStream Method (java.lang.String) Retrieves the value of the designated column in the current
(SQLServerResultSet) row of the SQLServerResultSet object as a Reader object.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getNCharacterStream Method (int)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.Reader getNCharacterStream(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A Reader object.
Exceptions
SQLServerException
Remarks
This getNCharacterStream method is specified by the getNCharacterStream method in the java.sql.ResultSet
interface.
This method can be used to retrieve the value of an nvarchar , nchar , nvarchar(max) , ntext , or xml column in
the current row of this SQLServerResultSet object. If you try to use this method to retrieve values of other data
types, an exception will be thrown.
See Also
getNCharacterStream Method (SQLServerResultSet)
SQLServerResultSet Members
getNCharacterStream Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.io.Reader getNCharacterStream(java.lang.String columnLabel)
Parameters
columnLabel
A String that contains the column label.
Return Value
A Reader object.
Exceptions
SQLServerException
Remarks
This getNCharacterStream method is specified by the getNCharacterStream method in the java.sql.ResultSet
interface.
This method can be used to retrieve the value of an nvarchar , nchar , nvarchar(max) , ntext , or xml column in
the current row of this SQLServerResultSet object. If you try to use this method to retrieve values of other data
types, an exception will be thrown.
See Also
getNCharacterStream Method (SQLServerResultSet)
SQLServerResultSet Members
getNClob Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getNClob Method (int) (SQLServerResultSet) Retrieves the value of the designated column in the current
row of the SQLServerResultSet object as an NClob object in
the Java programming language.
getNClob Method (java.lang.String) (SQLServerResultSet) Retrieves the value of the designated column in the current
row of the SQLServerResultSet object as an NClob object in
the Java programming language.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getNClob Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.NClob getNClob(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A NClob object.
Exceptions
SQLServerException
Remarks
This getNClob method is specified by the getNClob method in the java.sql.ResultSet interface.
This method is supported only on nvarchar(max) , ntext , and xml columns. Using this method on any other
data types will cause an exception to be thrown.
See Also
getNClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getNClob Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.NClob getNClob(java.lang.String columnLabel)
Parameters
columnLabel
A String that contains the column label.
Return Value
A NClob object.
Exceptions
SQLServerException
Remarks
This getNClob method is specified by the getNClob method in the java.sql.ResultSet interface.
This method is supported only on nvarchar(max) , ntext , and xml columns. Using this method on any other
data types will cause an exception to be thrown.
See Also
getNClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getNString Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getNString Method (int) (SQLServerResultSet) Retrieves the value of the designated column in the current
row of the SQLServerResultSet object as a String in the Java
programming language.
getNString Method (java.lang.String) (SQLServerResultSet) Retrieves the value of the designated column in the current
row of the SQLServerResultSet object as a String in the Java
programming language.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getNString Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getNString(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A String object.
Exceptions
SQLServerException
Remarks
This getNString method is specified by the getNString method in the java.sql.SQLServerResultSet interface.
This method can be used to retrieve the value of an nvarchar , nchar , nvarchar(max) , ntext , or xml column in
the current row of this SQLServerResultSet object. If you try to use this method to retrieve values of other data
types, an exception will be thrown.
See Also
getNString Method (SQLServerResultSet)
SQLServerResultSet Members
getNString Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getNString(java.lang.String columnLabel)
Parameters
columnLabel
A String that contains the column label.
Return Value
A String object.
Exceptions
SQLServerException
Remarks
This getNString method is specified by the getNString method in the java.sql.SQLServerResultSet interface.
This method can be used to retrieve the value of an nvarchar , nchar , nvarchar(max) , ntext , or xml column in
the current row of this SQLServerResultSet object. If you try to use this method to retrieve values of other data
types, an exception will be thrown.
See Also
getNString Method (SQLServerResultSet)
SQLServerResultSet Members
getObject Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getObject (int) Gets the value of the designated column index in the current
row of this SQLServerResultSet object as an object in the
Java programming language.
getObject (int, java.util.Map) Gets the value of the designated column index in the current
row of this SQLServerResultSet object as an object in the
Java programming language, using the given Map object.
getObject (java.lang.String) Gets the value of the designated column name in the
current row of this SQLServerResultSet object as an object in
the Java programming language.
getObject (java.lang.String, java.util.Map) Gets the value of the designated column name in the
current row of this SQLServerResultSet object as an object in
the Java programming language, using the given Map
object.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getObject Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.Object getObject(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
An Object value.
Exceptions
SQLServerException
Remarks
This getObject method is specified by the getObject method in the java.sql.ResultSet interface.
This method will return the value of the given column as a Java object. The type of the Java object will be the
default Java object type corresponding to the SQL type of the column, following the mapping for built-in types
that is specified in the JDBC specification. If the value is an SQL NULL, the driver returns a Java null.
This method can also be used to read database-specific abstract data types. In the JDBC 2.0 API, the behavior of
the getObject method is extended to materialize data of SQL user-defined types. When a column contains a
structured or distinct value, the behavior of this method is as if it were a call to
getObject(columnIndex, this.getStatement().getConnection().getTypeMap()) .
See Also
getObject Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getObject Method (int, java.util.Map)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported by the Microsoft JDBC Driver for SQL Server. Using this method will always return
the default mapping.
Syntax
public java.lang.Object getObject(int i,
java.util.Map map)
Parameters
i
An int that indicates the column index.
map
A Map object.
Return Value
An Object value.
Exceptions
SQLServerException
Remarks
This getObject method is specified by the getObject method in the java.sql.ResultSet interface.
This method will return the value of the given column as a Java object. The type of the Java object will be the
default Java object type corresponding to the SQL type of the column, following the mapping for built-in types
that is specified in the JDBC specification. If the value is an SQL NULL, the driver returns a Java null.
This method can also be used to read database-specific abstract data types. In the JDBC 2.0 API, the behavior of
the getObject method is extended to materialize data of SQL user-defined types. When a column contains a
structured or distinct value, the behavior of this method is as if it were a call to
getObject(columnIndex, this.getStatement().getConnection().getTypeMap()) .
See Also
getObject Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getObject Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.Object getObject(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
An Object value.
Exceptions
SQLServerException
Remarks
This getObject method is specified by the getObject method in the java.sql.ResultSet interface.
This method will return the value of the given column as a Java object. The type of the Java object will be the
default Java object type corresponding to the SQL type of the column, following the mapping for built-in types
that is specified in the JDBC specification. If the value is an SQL NULL, the driver returns a Java null.
This method can also be used to read database-specific abstract data types. In the JDBC 2.0 API, the behavior of
the getObject method is extended to materialize data of SQL user-defined types. When a column contains a
structured or distinct value, the behavior of this method is as if it were a call to
getObject(columnIndex, this.getStatement().getConnection().getTypeMap()) .
See Also
getObject Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getObject Method ( java.lang.String, java.util.Map)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported by the Microsoft JDBC Driver for SQL Server. Using this method will always return
the default mapping.
Syntax
public java.lang.Object getObject(java.lang.String colName,
java.util.Map map)
Parameters
colName
A String that contains the column name.
map
A Map object.
Return Value
An Object value.
Exceptions
SQLServerException
Remarks
This getObject method is specified by the getObject method in the java.sql.ResultSet interface.
This method will return the value of the given column as a Java object. The type of the Java object will be the
default Java object type corresponding to the SQL type of the column, following the mapping for built-in types
that is specified in the JDBC specification. If the value is an SQL NULL, the driver returns a Java null.
This method can also be used to read database-specific abstract data types. In the JDBC 2.0 API, the behavior of
the getObject method is extended to materialize data of SQL user-defined types. When a column contains a
structured or distinct value, the behavior of this method is as if it were a call to
getObject(columnIndex, this.getStatement().getConnection().getTypeMap()) .
See Also
getObject Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getRef Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getRef (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a Ref object
in the Java programming language.
getRef (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a Ref object
in the Java programming language.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getRef Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Ref getRef(int i)
Parameters
i
An int that indicates the column index.
Return Value
A Ref object.
Exceptions
SQLServerException
Remarks
This getRef method is specified by the getRef method in the java.sql.ResultSet interface.
See Also
getRef Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getRef Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Ref getRef(java.lang.String colName)
Parameters
colName
A String that contains the column name.
Return Value
A Ref object.
Exceptions
SQLServerException
Remarks
This getRef method is specified by the getRef method in the java.sql.ResultSet interface.
See Also
getRef Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getRow Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getRow()
Return Value
An int that indicates the current row number, 0 if there is no row.
Exceptions
SQLServerException
Remarks
This getRow method is specified by the getRow method in the java.sql.ResultSet interface.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getShort Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getShort (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a shor t in
the Java programming language.
getShort (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a shor t in
the Java programming language.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getShort Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public short getShort(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A shor t value.
Exceptions
SQLServerException
Remarks
This getShort method is specified by the getShort method in the java.sql.ResultSet interface.
This method is only supported on SQL Server data types that can safely return an integer value such as smallint,
tinyint, and bit. Using this method on any other data types will cause an exception to be thrown.
See Also
getShort Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getShort Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public short getShort(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
A shor t value.
Exceptions
SQLServerException
Remarks
This getShort method is specified by the getShort method in the java.sql.ResultSet interface.
This method is supported only on SQL Server data types that can safely return an integer value such as smallint,
tinyint, and bit. Using this method on any other data types will cause an exception to be thrown.
See Also
getShort Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getSQLXML Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getSQLXML Method (int) (SQLServerResultSet) Retrieves the value of a designated column in the current
row of the SQLServerResultSet object as a SQLXML object.
getSQLXML Method (java.lang.String) Retrieves the value of a designated column in the current
row of the SQLServerResultSet object as a SQLXML object.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getSQLXML Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.sql.SQLXML getSQLXML(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
ASQLXMLobject.
Exceptions
SQLServerException
Remarks
This getSQLXML method is specified by the getSQLXML method in the java.sql.ResultSet interface.
See Also
getSQLXML Method (SQLServerResultSet)
SQLServerResultSet Members
getSQLXML Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.sql.SQLXML getSQLXML(java.lang.String columnLabel)
Parameters
columnName
A String that indicates the column label.
Return Value
ASQLXMLobject.
Exceptions
SQLServerException
Remarks
This getSQLXML method is specified by the getSQLXML method in the java.sql.ResultSet interface.
See Also
getSQLXML Method (SQLServerResultSet)
SQLServerResultSet Members
getStatement Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Statement getStatement()
Return Value
A SQLServerStatement object.
Exceptions
SQLServerException
Remarks
This getStatement method is specified by the getStatement method in the java.sql.ResultSet interface.
If the result set was generated some other way, such as by a SQLServerDatabaseMetaData method, this method
returns null.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getString Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getString (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a String in
the Java programming language.
getString (java.lang.String)) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a String in
the Java programming language.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getString Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getString(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A String value.
Exceptions
SQLServerException
Remarks
This getString method is specified by the getString method in the java.sql.ResultSet interface.
All columns in SQL Server can be returned as a String. This means that a String representation of all number-
based and character-based types, and a hex-string representation of binary columns such as binary, varbinary,
varbinary(max), image, timestamp, and uniqueidentifier, can be returned.
Location-sensitive types such as money, smallmoney, datetime, smalldatetime, float, real, decimal, and numeric
will return the canonical toString() format for the underlying value of the type.
User-defined types are returned as hexadecimal String values.
See Also
getString Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getString Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getString(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
A String value.
Exceptions
SQLServerException
Remarks
This getString method is specified by the getString method in the java.sql.ResultSet interface.
All columns in SQL Server can be returned as a String. This means that a String representation of all number-
based and character-based types, and a hex-string representation of binary columns such as binary, varbinary,
varbinary(max), image, timestamp, and uniqueidentifier, can be returned.
Location sensitive types such as money, smallmoney, datetime, smalldatetime, float, real, decimal, and numeric
will return the canonical toString() format for the underlying value of the type.
User defined types are returned as hexadecimal String values.
See Also
getString Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getTime Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getTime (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a
java.sql.Time object in the Java programming language.
getTime (int, java.util.Calendar) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a
java.sql.Time object in the Java programming language,
using the given Calendar object.
getTime (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a
java.sql.Time object in the Java programming language.
getTime (java.lang.String, java.util.Calendar) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a
java.sql.Time object in the Java programming language,
using the given Calendar object.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getTime Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Time getTime(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A Time object.
Exceptions
SQLServerException
Remarks
This getTime method is specified by the getTime method in the java.sql.ResultSet interface.
This method returns a valid time part of a SQL Server datetime or smalldatetime data type, with the date part
set to the Java baseline date of 1970/01/01.
See Also
getTime Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getTime Method (int, java.util.Calendar)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Time getTime(int columnIndex,
java.util.Calendar cal)
Parameters
columnIndex
An int that indicates the column index.
cal
A Calendar object.
Return Value
A Time object.
Exceptions
SQLServerException
Remarks
This getTime method is specified by the getTime method in the java.sql.ResultSet interface.
This method returns a valid time part of a SQL Server datetime or smalldatetime data type, with the date part
set to the Java baseline date of 1970/01/01 in the supplied Calendar's timezone.
See Also
getTime Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getTime Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Time getTime(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
A Time object.
Exceptions
SQLServerException
Remarks
This getTime method is specified by the getTime method in the java.sql.ResultSet interface.
This method returns a valid time part of a SQL Server datetime or smalldatetime data type, with the date part
set to the Java baseline date of 1970/01/01.
See Also
getTime Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getTime Method ( java.lang.String,
java.util.Calendar) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Time getTime(java.lang.String colName,
java.util.Calendar cal)
Parameters
colName
A String that contains the column name.
cal
A Calendar object.
Return Value
A Time object.
Exceptions
SQLServerException
Remarks
This getTime method is specified by the getTime method in the java.sql.ResultSet interface.
This method returns a valid time part of a SQL Server datetime or smalldatetime data type, with the date part
set to the Java baseline date of 1970/01/01 in the supplied Calendar's timezone.
See Also
getTime Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getTimestamp Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getTimestamp (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a
java.sql.Timestamp object in the Java programming
language.
getTimestamp (int, java.util.Calendar) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a
java.sql.Timestamp object in the Java programming
language, using a Calendar object.
getTimestamp (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a
java.sql.Timestamp object in the Java programming
language.
getTimestamp (java.lang.String, java.util.Calendar) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a
java.sql.Timestamp object in the Java programming
language, using a Calendar object.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getTimestamp Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Timestamp getTimestamp(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A Timestamp object.
Exceptions
SQLServerException
Remarks
This getTimestamp method is specified by the getTimestamp method in the java.sql.ResultSet interface.
This method returns values only from SQL Server datetime and smalldatetime columns.
See Also
getTimestamp Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getTimestamp Method (int, java.util.Calendar)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Timestamp getTimestamp(int columnIndex,
java.util.Calendar cal)
Parameters
columnIndex
An int that indicates the column index.
cal
A Calendar object.
Return Value
A Timestamp object.
Exceptions
SQLServerException
Remarks
This getTimestamp method is specified by the getTimestamp method in the java.sql.ResultSet interface.
This method returns values only from SQL Server datetime and smalldatetime columns.
See Also
getTimestamp Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getTimestamp Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Timestamp getTimestamp(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
A Timestamp object.
Exceptions
SQLServerException
Remarks
This getTimestamp method is specified by the getTimestamp method in the java.sql.ResultSet interface.
This method returns values only from SQL Server datetime and smalldatetime columns.
See Also
getTimestamp Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getTimestamp Method ( java.lang.String,
java.util.Calendar) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.Timestamp getTimestamp(java.lang.String colName,
java.util.Calendar cal)
Parameters
colName
A String that contains the column name.
cal
A Calendar object.
Return Value
A Timestamp object.
Exceptions
SQLServerException
Remarks
This getTimestamp method is specified by the getTimestamp method in the java.sql.ResultSet interface.
This method returns values only from SQL Server datetime and smalldatetime columns.
See Also
getTimestamp Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getType Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getType()
Return Value
An int that indicates the current cursor type, which can be one of the following values:
ResultSet.TYPE_FORWARD_ONLY
ResultSet.TYPE_SCROLL_INSENSITIVE
ResultSet.TYPE_SCROLL_SENSITIVE
Exceptions
SQLServerException
Remarks
This getType method is specified by the getType method in the java.sql.ResultSet interface.
This method can be used to determine the actual cursor type. If the application selected TYPE_FORWARD_ONLY
or used a default cursor type, TYPE_FORWARD_ONLY will be returned.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getUnicodeStream Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method has been deprecated from the JDBC specification, and calling it will cause a "not implemented" exception to
be thrown. Instead, you should use the getCharacterStream method.
Overload List
NAME DESC RIP T IO N
getUnicodeStream Method (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a stream of
Unicode characters.
getUnicodeStream Method (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a stream of
Unicode characters.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getUnicodeStream Method (int)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method has been deprecated from the JDBC specification, and calling it will cause a "not implemented" exception to
be thrown. Instead, you should use the getCharacterStream method.
Syntax
public java.io.InputStream getUnicodeStream(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
An InputStream object.
Exceptions
SQLServerException
Remarks
This getUnicodeString method is specified by the getUnicodeString method in the java.sql.ResultSet interface.
See Also
getUnicodeStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getUnicodeStream Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method has been deprecated from the JDBC specification, and calling it will cause a "not implemented" exception to
be thrown. Instead, you should use the getCharacterStream method.
Syntax
public java.io.InputStream getUnicodeStream(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Return Value
An InputStream object.
Exceptions
SQLServerException
Remarks
This getUnicodeString method is specified by the getUnicodeString method in the java.sql.ResultSet interface.
See Also
getUnicodeStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getURL Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getURL (int) Retrieves the value of the designated column index in the
current row of this SQLServerResultSet object as a URL
object.
getURL (java.lang.String) Retrieves the value of the designated column name in the
current row of this SQLServerResultSet object as a URL
object.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
getURL Method (int) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.net.URL getURL(int columnIndex)
Parameters
columnIndex
An int that indicates the column index.
Return Value
A URL object.
Exceptions
SQLServerException
Remarks
This getURL method is specified by the getURL method in the java.sql.ResultSet interface.
See Also
getURL Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getURL Method ( java.lang.String)
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.net.URL getURL(java.lang.String sColumn)
Parameters
sColumn
A String that contains the column name.
Return Value
A URL object.
Exceptions
SQLServerException
Remarks
This getURL method is specified by the getURL method in the java.sql.ResultSet interface.
See Also
getURL Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
getWarnings Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported by the Microsoft JDBC Driver for SQL Server. If called this method will always
return a null value.
Syntax
public java.sql.SQLWarning getWarnings()
Return Value
An SQLWarning object.
Exceptions
SQLServerException
Remarks
This getWarnings method is specified by the getWarnings method in the java.sql.ResultSet interface.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
insertRow Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void insertRow()
Exceptions
SQLServerException
Remarks
This insertRow method is specified by the insertRow method in the java.sql.ResultSet interface.
The cursor must be on the insert row when this method is called. After this method is called, the cursor remains
on the insert row and the result set remains in insert mode.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
isAfterLast Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isAfterLast()
Return Value
true if the cursor is after the last row. false if the cursor is at any other position or if the result set contains no
rows.
Exceptions
SQLServerException
Remarks
This isAfterLast method is specified by the isAfterLast method in the java.sql.ResultSet interface.
If this method is used with dynamic cursors, including forward-only read-only cursors, and the selectMethod
connection property is set to "cursor", an exception will occur.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
isBeforeFirst Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isBeforeFirst()
Return Value
true if the cursor is before the first row. false if the cursor is at any other position or if the result set contains no
rows.
Exceptions
SQLServerException
Remarks
This isBeforeFirst method is specified by the isBeforeFirst method in the java.sql.ResultSet interface.
If this method is used with dynamic cursors, including forward-only read-only cursors, and the selectMethod
connection property is set to "cursor", an exception will occur.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
isClosed Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isClosed()
Return Value
true if this SQLServerResultSet object is closed, false if it is still open.
Exceptions
SQLServerException
Remarks
This isClosed method is specified by the isClosed method in the java.sql.ResultSet interface.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
isFirst Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isFirst()
Return Value
true if the cursor is on the first row. false if the cursor is at any other position or if the result set contains no
rows.
Exceptions
SQLServerException
Remarks
This isFirst method is specified by the isFirst method in the java.sql.ResultSet interface.
If this method is used with forward and dynamic cursors, an exception is thrown.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
isLast Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isLast()
Return Value
true if the cursor is on the last row. false if the cursor is at any other position or if the result set contains no
rows.
Exceptions
SQLServerException
Remarks
This isLast method is specified by the isLast method in the java.sql.ResultSet interface.
If this method is used with forward and dynamic cursors, an exception is thrown.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
last Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean last()
Return Value
true if the new current row is valid. false if there are no more rows to process.
Exceptions
SQLServerException
Remarks
This last method is specified by the last method in the java.sql.ResultSet interface.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
moveToCurrentRow Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void moveToCurrentRow()
Exceptions
SQLServerException
Remarks
This moveToCurrentRow method is specified by the moveToCurrentRow method in the java.sql.ResultSet
interface.
This method has no effect if the cursor is not on the insert row.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
moveToInsertRow Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void moveToInsertRow()
Exceptions
SQLServerException
Remarks
This moveToInsertRow method is specified by the moveToInsertRow method in the java.sql.ResultSet interface.
The current cursor position is remembered while the cursor is positioned on the insert row. The insert row is a
special row that is associated with an updatable result set. It is essentially a buffer where a new row can be
constructed by calling the updater methods before adding the row to the result set.
Only the updater, getter, and insertRow methods can be called when the cursor is on the insert row. All the
columns in a result set must be given a value each time this method is called, and before calling insertRow. An
updater method must be called before a getter method can be called on a column value.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
next Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean next()
Return Value
true if the new current row is valid. false if there are no more rows to process.
Exceptions
SQLServerException
Remarks
This next method is specified by the next method in the java.sql.ResultSet interface.
A result set cursor is initially positioned before the first row. The first call to the next method makes the first row
the current row, the second call makes the second row the current row, and so on.
If an input stream is open for the current row, a call to the next method will implicitly close it. A warning chain
for the SQLServerResultSet object is cleared when a new row is read.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
previous Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean previous()
Return Value
true if the new current row is valid. false if there are no more rows to process.
Exceptions
SQLServerException
Remarks
This previous method is specified by the previous method in the java.sql.ResultSet interface.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
refreshRow Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void refreshRow()
Exceptions
SQLServerException
Remarks
This refreshRow method is specified by the refreshRow method in the java.sql.ResultSet interface.
This method cannot be called when the cursor is on the insert row.
This method provides a way for an application to explicitly tell the JDBC driver to refetch rows from the
database. An application might need to call this method when the Microsoft JDBC Driver for SQL Server is
caching or prefetching to fetch the latest value of a row from the database. The JDBC driver might actually
refresh multiple rows at the same time if the fetch size is greater than one.
All values are refetched subject to the transaction isolation level and cursor sensitivity. If this method is called
after calling an updater method, but before calling the updateRow method, the updates made to the row are
lost. Calling this method frequently will probably slow performance.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
relative Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean relative(int nRows)
Parameters
nRows
An int that indicates the number of rows to move.
Return Value
true if the cursor is on a row. Otherwise, false .
Exceptions
SQLServerException
Remarks
This relative method is specified by the relative method in the java.sql.ResultSet interface.
Trying to move beyond the first or last row in the result set positions the cursor before or after the first or last
row. Calling relative(0) is valid, but does not change the cursor position.
Calling the method relative(1) is identical to calling the next method. Calling the method relative(-1) is
identical to calling the previous method.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
rowDeleted Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean rowDeleted()
Return Value
true if a row was deleted and deletions are detected. Otherwise, false .
Exceptions
SQLServerException
Remarks
This rowDeleted method is specified by the rowDeleted method in the java.sql.ResultSet interface.
A deleted row might leave a visible hole in a result set. This method can be used to detect holes in a result set.
The value that is returned depends on whether this SQLServerResultSet object can detect deletions.
NOTE
SQL Server detects deleted rows for all updatable cursor types, though the detection is transient for forward and dynamic
cursors.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
rowInserted Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean rowInserted()
Return Value
true if a row has had an insertion and insertions are detected. Otherwise, false .
Exceptions
SQLServerException
Remarks
This rowUpdated method is specified by the rowUpdated method in the java.sql.ResultSet interface.
The value that is returned depends on whether this SQLServerResultSet object can detect visible inserts.
NOTE
SQL Server does not detect inserted rows for any cursor type.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
rowUpdated Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean rowUpdated()
Return Value
true if both the row has been visibly updated by the owner or another user, and updates are detected.
Otherwise, false .
Exceptions
SQLServerException
Remarks
This rowUpdated method is specified by the rowUpdated method in the java.sql.ResultSet interface.
The value that is returned depends on whether or not the result set can detect updates.
NOTE
SQL Server does not detect updated rows for any cursor type.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
setFetchDirection Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported by the Microsoft JDBC Driver for SQL Server. If you use this method, the JDBC
driver remembers the setting, but currently does not act on it.
Syntax
public void setFetchDirection(int direction)
Parameters
direction
An int that indicates the suggested fetch direction. Can be one of the following values:
ResultSet.FETCH_FORWARD
ResultSet.FETCH_REVERSE
ResultSet.FETCH_UNKNOWN
Exceptions
SQLServerException
Remarks
This setFetchDirection method is specified by the setFetchDirection method in the java.sql.ResultSet interface.
The initial value of this method is determined by the SQLServerStatement object that produced this
SQLServerResultSet object. The fetch direction can be changed at any time.
NOTE
Using this method when the cursor type is forward-only has no effect.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
setFetchSize Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setFetchSize(int rows)
Parameters
rows
An int indicating the number of rows to fetch.
Exceptions
SQLServerException
Remarks
This setFetchSize method is specified by the setFetchSize method in the java.sql.ResultSet interface.
If the fetch size specified is zero, the JDBC driver ignores the value and estimates what the fetch size should be.
The default value is set by the SQLServerStatement object that created the result set. The fetch size can be
changed at any time.
This method changes the block fetch size for server cursors, and takes effect the next time the JDBC driver needs
to call sp_cursorfetch. Setting the fetch size to zero restores the default fetch size for the cursor type that is
currently in use
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateArray Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateArray (int, java.sql.Array) Updates the designated column with an Array object given
the column index.
updateArray (java.lang.String, java.sql.Array) Updates the designated column with an Array object given
the column name.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateArray Method (int, java.sql.Array)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateArray(int columnIndex,
java.sql.Array x)
Parameters
columnIndex
An int that indicates the column index.
x
An Array object.
Exceptions
SQLServerException
Remarks
This updateArray method is specified by the updateArray method in the java.sql.ResultSet interface.
See Also
updateArray Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateArray Method ( java.lang.String,
java.sql.Array)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateArray(java.lang.String columnName,
java.sql.Array x)
Parameters
columnName
A String that contains the column name.
x
An Array object.
Exceptions
SQLServerException
Remarks
This updateArray method is specified by the updateArray method in the java.sql.ResultSet interface.
See Also
updateArray Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateAsciiStream Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateAsciiStream Method (int, java.io.InputStream) Updates the designated column with an ASCII stream value.
updateAsciiStream (int, java.io.InputStream, int) Updates the designated column index with an ASCII stream
value specific to the column index.
updateAsciiStream Method (int, java.io.InputStream, long) Updates the designated column with an ASCII stream value,
which will have the specified number of bytes.
updateAsciiStream Method (java.lang.String, Updates the designated column with an ASCII stream value.
java.io.InputStream)
updateAsciiStream (java.lang.String, java.io.InputStream, int) Updates the designated column name with an ASCII stream
value, which will have the specified number of bytes.
updateAsciiStream Method (java.lang.String, Updates the designated column with an ASCII stream value,
java.io.InputStream, long) which will have the specified number of bytes.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateAsciiStream Method (int, java.io.InputStream)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateAsciiStream(int columnIndex,
java.io.InputStream x)
Parameters
columnIndex
An int that indicates the column index.
x
An InputStream object.
Exceptions
SQLServerException
Remarks
This updateAsciiStream method is specified by the updateAsciiStream method in the java.sql.ResultSet interface.
This method passes ASCII characters (bytes) from an InputStream object to convertible character columns,
which are the ASCII range [0x00 - 0x7F] of Unicode, and 874, 932, 936, 949, 950, and 1250 through 1258 code
pages. This method performs a conversion to the destination collation page. Trying to update an unconvertible
destination column will cause an exception to be thrown. For binary columns, raw bytes are passed.
Using this method for the image , text , and ntext SQL Server data types might impact performance.
See Also
updateAsciiStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateAsciiStream Method (int, java.io.InputStream,
int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateAsciiStream(int index,
java.io.InputStream x,
int length)
Parameters
index
An int that indicates the column index.
x
An InputStream object.
length
An int that indicates the length of the stream.
Exceptions
SQLServerException
Remarks
This updateAsciiStream method is specified by the updateAsciiStream method in the java.sql.ResultSet interface.
This method passes ASCII characters (bytes) from an InputStream object to convertible character columns,
which are the ASCII range [0x00 - 0x7F] of Unicode, and 874, 932, 936, 949, 950, and 1250 through 1258 code
pages. This method performs a conversion to the destination collation page. Trying to update an unconvertible
destination column will cause an exception to be thrown. For binary columns, raw bytes are passed.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
updateAsciiStream Method (int, java.io.InputStream) when the application wants to update the column from a
stream whose length is unknown.
See Also
updateAsciiStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateAsciiStream Method (int, java.io.InputStream,
long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateAsciiStream(int columnIndex,
java.io.InputStream x,
long length)
Parameters
columnIndex
An int that indicates the column index.
x
An InputStream object.
length
The length of the stream.
Exceptions
SQLServerException
Remarks
This updateAsciiStream method is specified by the updateAsciiStream method in the java.sql.ResultSet interface.
This method passes ASCII characters (bytes) from an InputStream object to convertible character columns,
which are the ASCII range [0x00 - 0x7F] of Unicode, and 874, 932, 936, 949, 950, and 1250 through 1258 code
pages. This method performs a conversion to the destination collation page. Trying to update an unconvertible
destination column will cause an exception to be thrown. For binary columns, raw bytes are passed.
If the length of the stream is different than that specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
updateAsciiStream Method (int, java.io.InputStream) when the application wants to update the column from a
stream whose length is unknown.
See Also
updateAsciiStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateAsciiStream Method ( java.lang.String,
java.io.InputStream)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateAsciiStream(java.lang.String columnLabel,
java.io.InputStream x)
Parameters
columnLabel
A String that contains the column label.
x
An InputStream object.
Exceptions
SQLServerException
Remarks
This updateAsciiStream method is specified by the updateAsciiStream method in the java.sql.ResultSet interface.
This method passes ASCII characters (bytes) from an InputStream object to convertible character columns,
which are the ASCII range [0x00 - 0x7F] of Unicode, and 874, 932, 936, 949, 950, and 1250 through 1258 code
pages. This method performs a conversion to the destination collation page. Trying to update an unconvertible
destination column will cause an exception to be thrown. For binary columns, raw bytes are passed.
Using this method for the image , text , and ntext SQL Server data types might impact performance.
See Also
updateAsciiStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateAsciiStream Method ( java.lang.String,
java.io.InputStream, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateAsciiStream(java.lang.String columnName,
java.io.InputStream x,
int length)
Parameters
columnName
A String that contains the column name.
x
An InputStream object.
length
An int that indicates the length of the stream.
Exceptions
SQLServerException
Remarks
This updateAsciiStream method is specified by the updateAsciiStream method in the java.sql.ResultSet interface.
This method passes ASCII characters (bytes) from an InputStream object to convertible character columns,
which are the ASCII range [0x00 - 0x7F] of Unicode, and 874, 932, 936, 949, 950, and 1250 through 1258 code
pages. This method performs a conversion to the destination collation page. Trying to update an unconvertible
destination column will cause an exception to be thrown. For binary columns, raw bytes are passed.
If the length of the stream is different than that specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
updateAsciiStream Method ( java.lang.String, java.io.InputStream) when the application wants to update the
column from a stream whose length is unknown.
See Also
updateAsciiStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateAsciiStream Method ( java.lang.String,
java.io.InputStream, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateAsciiStream(java.lang.String columnName,
java.io.InputStream streamValue,
long length)
Parameters
columnName
A String that contains the column name.
streamValue
An InputStream object.
length
The length of the stream.
Exceptions
SQLServerException
Remarks
This updateAsciiStream method is specified by the updateAsciiStream method in the java.sql.ResultSet interface.
This method passes ASCII characters (bytes) from an InputStream object to convertible character columns,
which are the ASCII range [0x00 - 0x7F] of Unicode, and 874, 932, 936, 949, 950, and 1250 through 1258 code
pages. This method performs a conversion to the destination collation page. Trying to update an unconvertible
destination column will cause an exception to be thrown. For binary columns, raw bytes are passed.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
updateAsciiStream Method ( java.lang.String, java.io.InputStream) when the application wants to update the
column from a stream whose length is unknown.
See Also
updateAsciiStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBigDecimal Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateBigDecimal (int, java.math.BigDecimal) Updates the designated column with a BigDecimal object
given the column index.
updateBigDecimal (java.lang.String, java.math.BigDecimal) Updates the designated column with a BigDecimal object
given the column name.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateBigDecimal Method (int,
java.math.BigDecimal)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBigDecimal(int index,
java.math.BigDecimal x)
Parameters
index
An int that indicates the column index.
x
A BigDecimal object.
Exceptions
SQLServerException
Remarks
This updateBigDecimal method is specified by the updateBigDecimal method in the java.sql.ResultSet interface.
See Also
updateBigDecimal Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBigDecimal Method ( java.lang.String,
java.math.BigDecimal)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBigDecimal(java.lang.String columnName,
java.math.BigDecimal x)
Parameters
columnName
A String that contains the column name.
x
A BigDecimal object.
Exceptions
SQLServerException
Remarks
This updateBigDecimal method is specified by the updateBigDecimal method in the java.sql.ResultSet interface.
See Also
updateBigDecimal Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBinaryStream Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateBinaryStream(int, java.io.InputStream) Updates the designated column with a binary stream value.
updateBinaryStream (int, java.io.InputStream, int) Updates the designated column with a binary stream value,
which will have the specified number of bytes.
updateBinaryStream(int, java.io.InputStream, long) Updates the designated column with a binary stream value,
which will have the specified number of bytes.
updateBinaryStream(java.lang.String, java.io.InputStream) Updates the designated column with a binary stream value.
updateBinaryStream (java.lang.String, java.io.InputStream, Updates the designated column with a binary stream value,
int) which will have the specified number of bytes.
updateBinaryStream(java.lang.String, java.io.InputStream, Updates the designated column with a binary stream value,
long) which will have the specified number of bytes.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateBinaryStream Method (int,
java.io.InputStream)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBinaryStream(int columnIndex,
java.io.InputStream x)
Parameters
columnIndex
An int that indicates the column index.
x
An InputStream object.
Exceptions
SQLServerException
Remarks
This updateBinaryStream method is specified by the updateBinaryStream method in the java.sql.ResultSet
interface.
Using this method for the image , text , and ntext SQL Server data types might impact the performance.
This method passes bytes from an InputStream object to selected SQL Server binary columns such as binary,
varbinary, varbinary(max), image, xml, and udt. Updating character columns is not supported with this method.
To update character columns with an InputStream, use the updateAsciiStream method.
See Also
updateBinaryStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBinaryStream Method (int,
java.io.InputStream, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBinaryStream(int columnIndex,
java.io.InputStream x,
int length)
Parameters
columnIndex
An int that indicates the column index.
x
An InputStream object.
length
An int that indicates the length of the stream.
Exceptions
SQLServerException
Remarks
This updateBinaryStream method is specified by the updateBinaryStream method in the java.sql.ResultSet
interface.
This method passes bytes from an InputStream object to selected SQL Server binary columns such as binary,
varbinary, varbinary(max), image, xml, and udt. Updating character columns is not supported with this method.
To update character columns with an InputStream, use the updateAsciiStream method.
If the length of the stream is different than that specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
updateBinaryStream Method (int, java.io.InputStream) when the application wants to update the column from a
stream whose length is unknown.
See Also
updateBinaryStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBinaryStream Method (int,
java.io.InputStream, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBinaryStream(int columnIndex,
java.io.InputStream x,
long length)
Parameters
columnIndex
An int that indicates the column index.
x
An InputStream object.
length
A long that indicates the length of the stream.
Exceptions
SQLServerException
Remarks
This updateBinaryStream method is specified by the updateBinaryStream method in the java.sql.ResultSet
interface.
This method passes bytes from an InputStream object to selected SQL Server binary columns such as binary,
varbinary, varbinary(max), image, xml, and udt. Updating character columns is not supported with this method.
To update character columns with an InputStream, use the updateAsciiStream method.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
updateBinaryStream Method (int, java.io.InputStream) when the application wants to update the column from a
stream whose length is unknown.
See Also
updateBinaryStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBinaryStream Method ( java.lang.String,
java.io.InputStream)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBinaryStream(java.lang.String columnLabel,
java.io.InputStream x)
Parameters
columnLabel
A String that contains the column label.
x
An InputStream object.
Exceptions
SQLServerException
Remarks
This updateBinaryStream method is specified by the updateBinaryStream method in the java.sql.ResultSet
interface.
Using this method for the image , text , and ntext SQL Server data types might impact the performance.
This method passes bytes from an InputStream object to selected SQL Server binary columns such as binary,
varbinary, varbinary(max), image, xml, and udt. Updating character columns is not supported with this method.
To update character columns with an InputStream, use the updateAsciiStream method.
See Also
updateBinaryStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBinaryStream Method ( java.lang.String,
java.io.InputStream, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBinaryStream(java.lang.String columnLabel,
java.io.InputStream x,
int length)
Parameters
columnLabel
AStringthat contains the column label.
x
An InputStream object.
length
An int that indicates the length of the stream.
Exceptions
SQLServerException
Remarks
This updateBinaryStream method is specified by the updateBinaryStream method in the java.sql.ResultSet
interface.
This method passes bytes from an InputStream object to selected SQL Server binary columns such as binary,
varbinary, varbinary(max), image, xml, and udt. Updating character columns is not supported with this method.
To update character columns with an InputStream, use the updateAsciiStream method.
If the length of the stream is different than that specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
updateBinaryStream Method ( java.lang.String, java.io.InputStream) when the application wants to update the
column from a stream whose length is unknown.
See Also
updateBinaryStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBinaryStream Method ( java.lang.String,
java.io.InputStream, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBinaryStream(java.lang.String columnLabel,
java.io.InputStream x,
long length)
Parameters
columnLabel
AStringthat contains the column label.
x
An InputStream object.
length
A long that indicates the length of the stream.
Exceptions
SQLServerException
Remarks
This updateBinaryStream method is specified by the updateBinaryStream method in the java.sql.ResultSet
interface.
This method passes bytes from an InputStream object to selected SQL Server binary columns such as binary,
varbinary, varbinary(max), image, xml, and udt. Updating character columns is not supported with this method.
To update character columns with an InputStream, use the updateAsciiStream method.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
updateBinaryStream Method ( java.lang.String, java.io.InputStream) when the application wants to update the
column from a stream whose length is unknown.
See Also
updateBinaryStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBlob Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateBlob (int, java.sql.Blob) Updates the designated column with a java.sql.Blob value.
updateBlob (int, java.io.InputStream) Updates the designated column using the specified input
stream.
updateBlob (int, java.io.InputStream, long) Updates the designated column using the specified input
stream, which will have the specified number of bytes.
updateBlob (java.lang.String, java.sql.Blob) Updates the designated column with a java.sql.Blob value.
updateBlob (java.lang.String, java.io.InputStream) Updates the designated column using the specified input
stream.
updateBlob (java.lang.String, java.io.InputStream, long) Updates the designated column using the specified input
stream, which will have the specified number of bytes.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateBlob Method (int, java.sql.Blob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBlob(int index,
java.sql.Blob x)
Parameters
index
An int that indicates the column index.
x
A Blob object.
Exceptions
SQLServerException
Remarks
This updateBlob method is specified by the updateBlob method in the java.sql.ResultSet interface.
See Also
updateBlob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBlob Method (int, java.io.InputStream)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBlob(int columnIndex,
java.io.InputStream inputStream)
Parameters
columnIndex
An int that indicates the column index.
inputStream
An InputStream object.
Exceptions
SQLServerException
Remarks
This updateBlob method is specified by the updateBlob method in the java.sql.ResultSet interface.
See Also
updateBlob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBlob Method (int, java.io.InputStream, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBlob(int columnIndex,
java.io.InputStream inputStream,
long length)
Parameters
columnIndex
An int that indicates the column index.
inputStream
An InputStream object.
length
A long that indicates the length of the stream.
Exceptions
SQLServerException
Remarks
This updateBlob method is specified by the updateBlob method in the java.sql.ResultSet interface.
See Also
updateBlob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBlob Method ( java.lang.String, java.sql.Blob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBlob(java.lang.String columnName,
java.sql.Blob x)
Parameters
columnName
A String that contains the column name.
x
A Blob object.
Exceptions
SQLServerException
Remarks
This updateBlob method is specified by the updateBlob method in the java.sql.ResultSet interface.
See Also
updateBlob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBlob Method ( java.lang.String,
java.io.InputStream)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBlob(java.lang.String columnLabel,
java.io.InputStream inputStream)
Parameters
columnLabel
A String that contains the column label.
inputStream
An InputStream object.
Exceptions
SQLServerException
Remarks
This updateBlob method is specified by the updateBlob method in the java.sql.ResultSet interface.
See Also
updateBlob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBlob Method ( java.lang.String,
java.io.InputStream, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBlob(java.lang.String columnLabel,
java.io.InputStream inputStream)
long length)
Parameters
columnLabel
A String that contains the column label.
inputStream
An InputStream object.
length
A long that indicates the length of the stream.
Exceptions
SQLServerException
Remarks
This updateBlob method is specified by the updateBlob method in the java.sql.ResultSet interface.
See Also
updateBlob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBoolean Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateBoolean (int, boolean) Updates the designated column with a boolean value given
the column index.
updateBoolean (java.lang.String, boolean) Updates the designated column with a boolean value given
the column name.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateBoolean Method (int, boolean)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBoolean(int index,
boolean x)
Parameters
index
An int that indicates the column index.
x
A boolean value.
Exceptions
SQLServerException
Remarks
This updateBoolean method is specified by the updateBoolean method in the java.sql.ResultSet interface.
See Also
updateBoolean Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBoolean Method ( java.lang.String, boolean)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBoolean(java.lang.String columnName,
boolean x)
Parameters
columnName
A String that contains the column name.
x
A boolean value.
Exceptions
SQLServerException
Remarks
This updateBoolean method is specified by the updateBoolean method in the java.sql.ResultSet interface.
See Also
updateBoolean Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateByte Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateByte (int, byte) Updates the designated column with a byte value given the
column index.
updateByte (java.lang.String, byte) Updates the designated column with a byte value given the
column name.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateByte Method (int, byte)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateByte(int index,
byte x)
Parameters
index
An int that indicates the column index.
x
A byte value.
Exceptions
SQLServerException
Remarks
This updateByte method is specified by the updateByte method in the java.sql.ResultSet interface.
See Also
updateByte Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateByte Method ( java.lang.String, byte)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateByte(java.lang.String columnName,
byte x)
Parameters
columnName
A String that contains the column name.
x
A byte value.
Exceptions
SQLServerException
Remarks
This updateByte method is specified by the updateByte method in the java.sql.ResultSet interface.
See Also
updateByte Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBytes Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateBytes (int, byte[]) Updates the designated column with an array of byte values
given the column index.
updateBytes (java.lang.String, byte[]) Updates the designated column with an array of byte values
given the column name.
Remarks
In a previous version of Microsoft JDBC Driver for SQL Server, you could use SQLServerResultSet.updateBytes
to convert values between byte arrays and SQL Server data type date , time , datetime2 , or datetimeoffset .
Now, using this method with those data types will cause an exception indicating that the conversion is not
supported.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateBytes Method (int, byte)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBytes(int index,
byte[] x)
Parameters
index
An int that indicates the column index.
x
An array of byte values.
Exceptions
SQLServerException
Remarks
This updateBytes method is specified by the updateBytes method in the java.sql.ResultSet interface.
In a previous version of Microsoft JDBC Driver for SQL Server, you could use SQLServerResultSet.updateBytes
to convert values between byte arrays and SQL Server data type date , time , datetime2 , or datetimeoffset .
Now, using this method with those data types will cause an exception indicating that the conversion is not
supported.
See Also
updateBytes Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateBytes Method ( java.lang.String, byte)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateBytes(java.lang.String columnName,
byte[] x)
Parameters
columnName
A String that contains the column name.
x
An array of byte values.
Exceptions
SQLServerException
Remarks
This updateBytes method is specified by the updateBytes method in the java.sql.ResultSet interface.
In a previous version of Microsoft JDBC Driver for SQL Server, you could use SQLServerResultSet.updateBytes
to convert values between byte arrays and SQL Server data type date , time , datetime2 , or datetimeoffset .
Now, using this method with those data types will cause an exception indicating that the conversion is not
supported.
See Also
updateBytes Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateCharacterStream Method
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateCharacterStream Method (int, java.io.Reader) Updates the designated column with a character stream
value.
updateCharacterStream (int, java.io.Reader, int) Updates the designated column with a character stream
value, which will have the specified number of characters.
updateCharacterStream Method (int, java.io.Reader, long) Updates the designated column with a character stream
value, which will have the specified number of characters.
updateCharacterStream Method (java.lang.String, Updates the designated column with a character stream
java.io.Reader) value.
updateCharacterStream (java.lang.String, java.io.Reader, int) Updates the designated column with a character stream
value, which will have the specified number of characters.
updateCharacterStream Method (java.lang.String, Updates the designated column with a character stream
java.io.Reader, long) value, which will have the specified number of characters.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateCharacterStream Method (int, java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateCharacterStream(int columnIndex,
java.io.Reader x)
Parameters
columnIndex
An int that indicates the column index.
x
A Reader object.
Exceptions
SQLServerException
Remarks
This updateCharacterStream method is specified by the updateCharacterStream method in the java.sql.ResultSet
interface.
This method passes Unicode characters from a Reader object to selected text and binary columns. This includes
all text columns and binar y , varbinar y , varbinar y(max) , image , and xml columns, but not udt columns.
Using this method for the image , text , and ntext SQL Server data types might impact performance.
See Also
updateCharacterStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateCharacterStream Method (int, java.io.Reader,
int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateCharacterStream(int columnIndex,
java.io.Reader readerValue,
int length)
Parameters
columnIndex
An int that indicates the column index.
readerValue
A Reader object.
length
An int that indicates the length of the stream.
Exceptions
SQLServerException
Remarks
This updateCharacterStream method is specified by the updateCharacterStream method in the java.sql.ResultSet
interface.
This method passes Unicode characters from a Reader object to selected text and binary columns. This includes
all text columns and binar y , varbinar y , varbinar y(max) , image , and xml columns, but not udt columns.
If the length of the stream is different than that specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
updateCharacterStream Method (int, java.io.Reader) when the application wants to update the column from a
stream whose length is unknown.
See Also
updateCharacterStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateCharacterStream Method (int, java.io.Reader,
long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateCharacterStream(int columnIndex,
java.io.Reader x,
long length)
Parameters
columnIndex
An int that indicates the column index.
x
A Reader object.
length
The length of the stream.
Exceptions
SQLServerException
Remarks
This updateCharacterStream method is specified by the updateCharacterStream method in the java.sql.ResultSet
interface.
This method passes Unicode characters from a Reader object to selected text and binary columns. This includes
all text columns and binary, varbinary, varbinary(max), image, and XML columns, but not UDT columns.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
updateCharacterStream Method (int, java.io.Reader) when the application wants to update the column from a
stream whose length is unknown.
See Also
updateCharacterStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateCharacterStream Method ( java.lang.String,
java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateCharacterStream(java.lang.String columnLabel,
java.io.Reader reader)
Parameters
columnLabel
A String that contains the column label.
reader
A Reader object.
Exceptions
SQLServerException
Remarks
This updateCharacterStream method is specified by the updateCharacterStream method in the java.sql.ResultSet
interface.
This method passes Unicode characters from a Reader object to selected text and binary columns. This includes
all text columns and binar y , varbinar y , varbinar y(max) , image , and xml columns, but not udt columns.
Using this method for the image , text , and ntext SQL Server data types might impact performance.
See Also
updateCharacterStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateCharacterStream Method ( java.lang.String,
java.io.Reader, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateCharacterStream(java.lang.String columnName,
java.io.Reader readerValue,
int length)
Parameters
columnName
A String that contains the column name.
readerValue
A Reader object.
length
An int that indicates the length of the stream.
Exceptions
SQLServerException
Remarks
This updateCharacterStream method is specified by the updateCharacterStream method in the java.sql.ResultSet
interface.
This method passes Unicode characters from a Reader object to selected text and binary columns. This includes
all text columns and binar y , varbinar y , varbinar y(max) , image , and xml columns, but not udt columns.
If the length of the stream is different than that specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
updateCharacterStream Method ( java.lang.String, java.io.Reader) when the application wants to update the
column from a stream whose length is unknown.
See Also
updateCharacterStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateCharacterStream Method ( java.lang.String,
java.io.Reader, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateCharacterStream(java.lang.String columnLabel,
java.io.Reader reader,
long length)
Parameters
columnLabel
A String that contains the column label.
reader
A Reader object.
length
The length of the stream.
Exceptions
SQLServerException
Remarks
This updateCharacterStream method is specified by the updateCharacterStream method in the java.sql.ResultSet
interface.
This method passes Unicode characters from a Reader object to selected text and binary columns. This includes
all text columns and binary, varbinary, varbinary(max), image, and XML columns, but not UDT columns.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
updateCharacterStream Method ( java.lang.String, java.io.Reader) when the application wants to update the
column from a stream whose length is unknown.
See Also
updateCharacterStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateClob Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateClob (int, java.sql.Clob) Updates the designated column with a java.sql.Clob value
given the column index.
updateClob Method (int, java.io.Reader) Updates the designated column using the specified Reader
object.
updateClob Method (java.lang.String, java.io.Reader, long) Updates the designated column using the specified Reader
object, which is the specified number of characters long.
updateClob (java.lang.String, java.sql.Clob) Updates the designated column with a java.sql.Clob value
given the column name.
updateClob Method (java.lang.String, java.io.Reader) Updates the designated column using the specified Reader
object.
updateClob Method (java.lang.String, java.io.Reader, long) Updates the designated column using the specified Reader
object, which is the specified number of characters long.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateClob Method (int, java.sql.Clob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateClob(int columnIndex,
java.sql.Clob clobValue)
Parameters
columnIndex
An int that indicates the column index.
clobValue
A Clob object.
Exceptions
SQLServerException
Remarks
This updateClob method is specified by the updateClob method in the java.sql.ResultSet interface.
See Also
updateClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateClob Method (int, java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateClob(int columnIndex,
java.io.Reader reader)
Parameters
columnIndex
An int that indicates the column index.
reader
A Reader object.
Exceptions
SQLServerException
Remarks
This updateClob method is specified by the updateClob method in the java.sql.ResultSet interface.
See Also
updateClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateClob Method (int, java.io.Reader, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateClob(int columnIndex,
java.io.Reader reader,
long length)
Parameters
columnIndex
An int that indicates the column index.
reader
A Reader object.
length
The number of characters in the parameter data.
Exceptions
SQLServerException
Remarks
This updateClob method is specified by the updateClob method in the java.sql.ResultSet interface.
See Also
updateClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateClob Method ( java.lang.String, java.sql.Clob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateClob(java.lang.String columnName,
java.sql.Clob clobValue)
Parameters
columnName
A String that contains the column name.
clobValue
A Clob object.
Exceptions
SQLServerException
Remarks
This updateClob method is specified by the updateClob method in the java.sql.ResultSet interface.
See Also
updateClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateClob Method ( java.lang.String,
java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateClob(java.lang.String columnLabel,
java.io.Reader reader)
Parameters
columnLabel
A String that contains the column label.
reader
A Reader object.
Exceptions
SQLServerException
Remarks
This updateClob method is specified by the updateClob method in the java.sql.ResultSet interface.
See Also
updateClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateClob Method ( java.lang.String,
java.io.Reader, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateClob(java.lang.String columnLabel,
java.io.Reader reader,
long length)
Parameters
columnLabel
A String that contains the column label.
reader
A Reader object.
length
The number of characters in the parameter data.
Exceptions
SQLServerException
Remarks
This updateClob method is specified by the updateClob method in the java.sql.ResultSet interface.
See Also
updateClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateDate Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateDate (int, java.sql.Date) Updates the designated column with a date value given the
column index.
updateDate (java.lang.String, java.sql.Date) Updates the designated column with a date value given the
column name.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateDate Method (int, java.sql.Date)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateDate(int index,
java.sql.Date x)
Parameters
index
An int that indicates the column index.
x
A date value.
Exceptions
SQLServerException
Remarks
This updateDate method is specified by the updateDate method in the java.sql.ResultSet interface.
See Also
updateDate Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateDate Method ( java.lang.String, java.sql.Date)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateDate(java.lang.String columnName,
java.sql.Date x)
Parameters
columnName
A String that contains the column name.
x
A date value.
Exceptions
SQLServerException
Remarks
This updateDate method is specified by the updateDate method in the java.sql.ResultSet interface.
See Also
updateDate Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateDateTimeOffset (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateDateTimeOffset(int,
microsoft.sql.DateTimeOffset) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateDateTimeOffset(int index, microsoft.sql.DateTimeOffset x)
Parameters
index
The zero-based ordinal of a column.
x
A DateTimeOffset Class object.
Exceptions
SQLServerException
Remarks
You can retrieve a DateTimeOffset Class value with SQLServerResultSet.getDateTimeOffset.
See Also
updateDateTimeOffset (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateDateTimeOffset(string,
microsoft.sql.DateTimeOffset) (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateDateTimeOffset(String columnName, microsoft.sql.DateTimeOffset x)
Parameters
columnName
The name of a column.
x
A DateTimeOffset Class object.
Exceptions
SQLServerException
Remarks
You can retrieve a DateTimeOffset Class value with SQLServerResultSet.getDateTimeOffset.
See Also
updateDateTimeOffset (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateDouble Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateDouble (int, double) Updates the designated column with a double value given
the column index.
updateDouble (java.lang.String, double) Updates the designated column with a double value given
the column name.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateDouble Method (int, double)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateDouble(int index,
double x)
Parameters
index
An int that indicates the column index.
x
A double value.
Exceptions
SQLServerException
Remarks
This updateDouble method is specified by the updateDouble method in the java.sql.ResultSet interface.
See Also
updateDouble Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateDouble Method ( java.lang.String, double)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateDouble(java.lang.String columnName,
double x)
Parameters
columnName
A String that contains the column name.
x
A double value.
Exceptions
SQLServerException
Remarks
This updateDouble method is specified by the updateDouble method in the java.sql.ResultSet interface.
See Also
updateDouble Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateFloat Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateFloat (int, float) Updates the designated column with a float value given the
column index.
updateFloat (java.lang.String, float) Updates the designated column with a float value given the
column name.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateFloat Method (int, float)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateFloat(int index,
float x)
Parameters
index
An int that indicates the column index.
x
A float value.
Exceptions
SQLServerException
Remarks
This updateFloat method is specified by the updateFloat method in the java.sql.ResultSet interface.
See Also
updateFloat Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateFloat Method ( java.lang.String, float)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateFloat(java.lang.String columnName,
float x)
Parameters
columnName
A String that contains the column name.
x
A float value.
Exceptions
SQLServerException
Remarks
This updateFloat method is specified by the updateFloat method in the java.sql.ResultSet interface.
See Also
updateFloat Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateInt Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateInt (int, int) Updates the designated column with an int value given the
column index.
updateInt (java.lang.String, int) Updates the designated column with an int value given the
column name.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateInt Method (int, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateInt(int index,
int x)
Parameters
index
An int that indicates the column index.
x
An int value.
Exceptions
SQLServerException
Remarks
This updateInt method is specified by the updateInt method in the java.sql.ResultSet interface.
See Also
updateInt Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateInt Method ( java.lang.String, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateInt(java.lang.String columnName,
int x)
Parameters
columnName
A String that contains the column name.
x
An int value.
Exceptions
SQLServerException
Remarks
This updateInt method is specified by the updateInt method in the java.sql.ResultSet interface.
See Also
updateInt Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateLong Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateLong (int, long) Updates the designated column with a long value given the
column index.
updateLong (java.lang.String, long) Updates the designated column with a long value given the
column name.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateLong Method (int, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateLong(int index,
long x)
Parameters
index
An int that indicates the column index.
x
A long value.
Exceptions
SQLServerException
Remarks
This updateLong method is specified by the updateLong method in the java.sql.ResultSet interface.
See Also
updateLong Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateLong Method ( java.lang.String, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateLong(java.lang.String columnName,
long x)
Parameters
columnName
A String that contains the column name.
x
A long value.
Exceptions
SQLServerException
Remarks
This updateLong method is specified by the updateLong method in the java.sql.ResultSet interface.
See Also
updateLong Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateNCharacterStream Method
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateNCharacterStream Method (int, java.io.Reader) Updates the designated column with a character stream
value.
updateNCharacterStream Method (int, java.io.Reader, long) Updates the designated column with a character stream
value, which will have the specified number of bytes.
updateNCharacterStream Method (java.lang.String, Updates the designated column with a character stream
java.io.Reader) value.
updateNCharacterStream Method (java.lang.String, Updates the designated column with a character stream
java.io.Reader, long) value, which will have the specified number of bytes.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateNCharacterStream Method (int,
java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateNCharacterStream(int columnIndex,
java.io.Reader x)
Parameters
columnIndex
An int that indicates the column index.
x
A Reader object.
Exceptions
SQLServerException
Remarks
This updateNCharacterStream method is specified by the updateNCharacterStream method in the
java.sql.ResultSet interface.
This method passes Unicode characters from a Reader object to selected nchar , nvarchar(max) , ntext and xml
columns. Using this method on other data type columns will throw an exception.
See Also
updateNCharacterStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateNCharacterStream Method (int,
java.io.Reader, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateNCharacterStream(int columnIndex,
java.io.Reader x,
long length)
Parameters
columnIndex
An int that indicates the column index.
x
A Reader object.
length
The length of the stream.
Exceptions
SQLServerException
Remarks
This updateNCharacterStream method is specified by the updateNCharacterStream method in the
java.sql.ResultSet interface.
This method passes Unicode characters from a Reader object to selected nchar , nvarchar(max) , ntext , and
xml columns. Using this method on other data type columns will throw an exception.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
updateNCharacterStream Method (int, java.io.Reader) when the application wants to update the column from a
stream whose length is unknown.
See Also
updateNCharacterStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateNCharacterStream Method ( java.lang.String,
java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateNCharacterStream(java.lang.String columnLabel,
java.io.Reader reader)
Parameters
columnLabel
A String that contains the column label.
reader
A Reader object.
Exceptions
SQLServerException
Remarks
This updateNCharacterStream method is specified by the updateNCharacterStream method in the
java.sql.ResultSet interface.
This method passes Unicode characters from a Reader object to selected nchar , nvarchar(max) , ntext and xml
columns. Using this method on other data type columns will throw an exception.
See Also
updateNCharacterStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateNCharacterStream Method ( java.lang.String,
java.io.Reader, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateNCharacterStream(java.lang.String columnLabel,
java.io.Reader reader,
long length)
Parameters
columnLabel
A String that contains the column label.
reader
A Reader object.
length
The length of the stream.
Exceptions
SQLServerException
Remarks
This updateNCharacterStream method is specified by the updateNCharacterStream method in the
java.sql.ResultSet interface.
This method passes Unicode characters from a Reader object to selected nchar , nvarchar(max) , ntext , and
xml columns. Using this method on other data type columns will throw an exception.
If the length of the stream is different than what is specified in the length parameter, the JDBC driver throws an
exception when the row is updated or inserted.
If the length of the stream is unknown, the length parameter may be set to -1 to indicate that the driver should
accept the stream regardless of its length. With sqljdbc4.jar, we recommend that you use the JDBC 4.0 method
updateNCharacterStream Method ( java.lang.String, java.io.Reader) when the application wants to update the
column from a stream whose length is unknown.
See Also
updateNCharacterStream Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateNClob Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateNClob Method (int, java.sql.NClob) Updates the designated column with an NClob value.
updateNClob Method (java.lang.String, java.sql.NClob) Updates the designated column with an NClob value.
updateNClob Method (int, java.io.Reader) Updates the designated column using the specified Reader
object.
updateNClob Method (int, java.io.Reader, long) Updates the designated column using the specified Reader
object, which is the specified number of characters long.
updateNClob Method (java.lang.String, java.io.Reader) Updates the designated column using the specified Reader
object.
updateNClob Method (java.lang.String, java.io.Reader, long) Updates the designated column using the specified Reader
object, which is the specified number of characters long.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateNClob Method (int, java.sql.NClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateNClob(int columnIndex,
java.sql.NClob nClob)
Parameters
columnIndex
An int that indicates the column index.
nClob
An NClob object.
Exceptions
SQLServerException
Remarks
This updateNClob method is specified by the updateNClob method in the java.sql.ResultSet interface.
This method is supported only on nvarchar(max) , ntext , and xml columns. Using this method on any other
data types will cause an exception to be thrown.
See Also
updateNClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateNClob Method (int, java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateNClob(int columnIndex,
java.io.Reader reader)
Parameters
columnIndex
An int that indicates the column index.
reader
A Reader object.
Exceptions
SQLServerException
Remarks
This updateNClob method is specified by the updateNClob method in the java.sql.ResultSet interface.
This method is supported only on nvarchar(max) , ntext , and xml columns. Using this method on any other
data types will cause an exception to be thrown.
See Also
updateNClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateNClob Method (int, java.io.Reader, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateNClob(int columnIndex,
java.io.Reader reader,
long length)
Parameters
columnIndex
An int that indicates the column index.
reader
A Reader object.
length
The number of characters in the parameter data.
Exceptions
SQLServerException
Remarks
This updateNClob method is specified by the updateNClob method in the java.sql.ResultSet interface.
This method is supported only on nvarchar(max) , ntext , and xml columns. Using this method on any other
data types will cause an exception to be thrown.
See Also
updateNClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateNClob Method ( java.lang.String,
java.sql.NClob)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateNClob(java.lang.String columnLabel,
java.sql.NClob x)
Parameters
columnLabel
A String that indicates the column label.
x
An NClob object.
Exceptions
SQLServerException
Remarks
This updateNClob method is specified by the updateNClob method in the java.sql.ResultSet interface.
This method is supported only on nvarchar(max) , ntext , and xml columns. Using this method on any other
data types will cause an exception to be thrown.
See Also
updateNClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateNClob Method ( java.lang.String,
java.io.Reader)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateNClob(java.lang.String columnLabel,
java.io.Reader reader)
Parameters
columnLabel
A String that indicates the column label.
reader
A Reader object.
Exceptions
SQLServerException
Remarks
This updateNClob method is specified by the updateNClob method in the java.sql.ResultSet interface.
This method is supported only on nvarchar(max) , ntext , and xml columns. Using this method on any other
data types will cause an exception to be thrown.
See Also
updateNClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateNClob Method ( java.lang.String,
java.io.Reader, long)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateNClob(java.lang.String columnLabel,
java.io.Reader reader,
long length)
Parameters
columnLabel
A String that indicates the column label.
reader
A Reader object.
length
The number of characters in the parameter data.
Exceptions
SQLServerException
Remarks
This updateNClob method is specified by the updateNClob method in the java.sql.ResultSet interface.
This method is supported only on nvarchar(max) , ntext , and xml columns. Using this method on any other
data types will cause an exception to be thrown.
See Also
updateNClob Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateNString Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateNString Method (int, java.lang.String) Updates the designated column with a String value using
the specified column index.
updateNString Method (java.lang.String, java.lang.String) Updates the designated column with a String value using
the specified column label.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateNString Method (int, java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateNString(int columnIndex,
java.lang.String nString)
Parameters
columnIndex
An int that indicates the column index.
nString
A String object.
Exceptions
SQLServerException
Remarks
This updateNString method is specified by the updateNString method in the java.sql.ResultSet interface.
This method passes Java String to selected nchar , nvarchar(max) , ntext , and xml columns. Using this method
on other data type columns will throw an exception.
See Also
updateNString Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateNString Method ( java.lang.String,
java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateNString(java.lang.String columnLabel,
java.lang.String nString)
Parameters
columnLabel
A String that contains the column label.
nString
A String object.
Exceptions
SQLServerException
Remarks
This updateNString method is specified by the updateNString method in the java.sql.ResultSet interface.
This method passes Java String to selected nchar , nvarchar(max) , ntext , and xml columns. Using this method
on other data type columns will throw an exception.
See Also
updateNString Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateNull Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateNull (int) Updates the designated column with a null value given the
column index.
updateNull (java.lang.String) Updates the designated column with a null value given the
column name.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateNull Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateNull(int index)
Parameters
index
An int that indicates the column index.
Exceptions
SQLServerException
Remarks
This updateNull method is specified by the updateNull method in the java.sql.ResultSet interface.
See Also
updateNull Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateNull Method ( java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateNull(java.lang.String columnName)
Parameters
columnName
A String that contains the column name.
Exceptions
SQLServerException
Remarks
This updateNull method is specified by the updateNull method in the java.sql.ResultSet interface.
See Also
updateNull Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateObject Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateObject (int, java.lang.Object) Updates the designated column with an Object value given
the column index.
updateObject (int, java.lang.Object, int) Updates the designated column with an Object value given
the column index and scale.
updateObject (java.lang.String, java.lang.Object) Updates the designated column with an Object value given
the column name.
updateObject (java.lang.String, java.lang.Object, int) Updates the designated column with an Object value given
the column name and scale.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateObject Method (int, java.lang.Object)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateObject(int index,
java.lang.Object obj)
Parameters
index
An int that indicates the column index.
obj
An Object value.
Exceptions
SQLServerException
Remarks
This updateObject method is specified by the updateObject method in the java.sql.ResultSet interface.
See Also
updateObject Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateObject Method (int, java.lang.Object, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateObject(int index,
java.lang.Object x,
int scale)
Parameters
index
An int that indicates the column index.
obj
An Object value.
scale
For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types, this is the number of digits after the decimal point.
For all other types, this value is ignored.
Exceptions
SQLServerException
See Also
updateObject Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateObject Method ( java.lang.String,
java.lang.Object)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateObject(java.lang.String columnName,
java.lang.Object x)
Parameters
columnName
A String that contains the column name.
obj
An Object value.
Exceptions
SQLServerException
Remarks
This updateObject method is specified by the updateObject method in the java.sql.ResultSet interface.
See Also
updateObject Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateObject Method ( java.lang.String,
java.lang.Object, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateObject(java.lang.String columnName,
java.lang.Object x,
int scale)
Parameters
columnName
A String that contains the column name.
obj
An Object value.
scale
For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types, this is the number of digits after the decimal point.
For all other types this value is ignored.
Exceptions
SQLServerException
Remarks
This updateObject method is specified by the updateObject method in the java.sql.ResultSet interface.
See Also
updateObject Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateRef Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateRef (int, java.sql.Ref) Updates the designated column with a java.sql.Ref value
given the column index.
updateRef (java.lang.String, java.sql.Ref) Updates the designated column with a java.sql.Ref value
given the column name.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateRef Method (int, java.sql.Ref )
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateRef(int columnIndex,
java.sql.Ref x)
Parameters
columnIndex
An int that indicates the column index.
x
A Ref object.
Exceptions
SQLServerException
Remarks
This updateRef method is specified by the updateRef method in the java.sql.ResultSet interface.
See Also
updateRef Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateRef Method ( java.lang.String, java.sql.Ref )
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateRef(java.lang.String columnName,
java.sql.Ref x)
Parameters
columnName
A String that contains the column name.
x
A Ref object.
Exceptions
SQLServerException
Remarks
This updateRef method is specified by the updateRef method in the java.sql.ResultSet interface.
See Also
updateRef Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateRow Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateRow()
Exceptions
SQLServerException
Remarks
This updateRow method is specified by the updateRow method in the java.sql.ResultSet interface.
This method cannot be called when the cursor is on the insert row.
If this method is called when no column values have changed, an exception will be thrown.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateShort Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateShort (int, short) Updates the designated column with a shor t value given
the column index.
updateShort (java.lang.String, short) Updates the designated column with a shor t value given
the column name.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateShort Method (int, short)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateShort(int index,
short x)
Parameters
index
An int that indicates the column index.
x
A shor t value.
Exceptions
SQLServerException
Remarks
This updateShort method is specified by the updateShort method in the java.sql.ResultSet interface.
See Also
updateShort Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateShort Method ( java.lang.String, short)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateShort(java.lang.String columnName,
short x)
Parameters
columnName
A String that contains the column name.
x
A shor t value.
Exceptions
SQLServerException
Remarks
This updateShort method is specified by the updateShort method in the java.sql.ResultSet interface.
See Also
updateShort Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateSQLXML Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateSQLXML Method (int, java.sql.SQLXML) Updates the designated column with a SQLXML value.
updateSQLXML Method (java.lang.String, java.sql.SQLXML) Updates the designated column with a SQLXML value.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateSQLXML Method (int, java.sql.SQLXML)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateSQLXML(int columnIndex,
java.sql.SQLXML xmlObject)
Parameters
columnIndex
An int that indicates the column index.
xmlObject
A SQLXML object.
Exceptions
SQLServerException
Remarks
This updateSQLXML method is specified by the updateSQLXML method in the java.sql.ResultSet interface.
See Also
updateSQLXML Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateSQLXML Method ( java.lang.String,
java.sql.SQLXML)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateSQLXML(java.lang.String columnLabel,
java.sql.SQLXML xmlObject)
Parameters
columnLabel
A String that indicates the column label.
xmlObject
A SQLXML object.
Exceptions
SQLServerException
Remarks
This updateSQLXML method is specified by the updateSQLXML method in the java.sql.ResultSet interface.
See Also
updateSQLXML Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateString Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateString (int, java.lang.String) Updates the designated column with a String value given
the column index.
updateString (java.lang.String, java.lang.String) Updates the designated column with a String value given
the column name.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateString Method (int, java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateString(int index,
java.lang.String x)
Parameters
index
An int that indicates the column index.
x
A String object.
Exceptions
SQLServerException
Remarks
This updateString method is specified by the updateString method in the java.sql.ResultSet interface.
See Also
updateString Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateString Method ( java.lang.String,
java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateString(java.lang.String columnName,
java.lang.String x)
Parameters
columnName
A String that contains the column name.
x
A String object.
Exceptions
SQLServerException
Remarks
This updateString method is specified by the updateString method in the java.sql.ResultSet interface.
See Also
updateString Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateTime Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateTime (int, java.sql.Time) Updates the designated column with a time value given the
column index.
updateTime (java.lang.String, java.sql.Time) Updates the designated column with a time value given the
column name.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateTime Method (int, java.sql.Time)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateTime(int index,
java.sql.Time x)
Parameters
index
An int that indicates the column index.
x
A time value.
Exceptions
SQLServerException
Remarks
This updateTime method is specified by the updateTime method in the java.sql.ResultSet interface.
See Also
updateTime Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateTime Method ( java.lang.String, java.sql.Time)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateTime(java.lang.String columnName,
java.sql.Time x)
Parameters
columnName
A String that contains the column name.
x
A time value.
Exceptions
SQLServerException
Remarks
This updateTime method is specified by the updateTime method in the java.sql.ResultSet interface.
See Also
updateTime Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateTimestamp Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
updateTimestamp (int, java.sql.Timestamp) Updates the designated column with a timestamp value
given the column index.
updateTimestamp (java.lang.String, java.sql.Timestamp) Updates the designated column with a timestamp value
given the column name.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
updateTimestamp Method (int, java.sql.Timestamp)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateTimestamp(int index,
java.sql.Timestamp x)
Parameters
index
An int that indicates the column index.
x
A timestamp value.
Exceptions
SQLServerException
Remarks
This updateTimestamp method is specified by the updateTimestamp method in the java.sql.ResultSet interface.
See Also
updateTimestamp Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
updateTimestamp Method ( java.lang.String,
java.sql.Timestamp)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void updateTimestamp(java.lang.String columnName,
java.sql.Timestamp x)
Parameters
columnName
A String that contains the column name.
x
A timestamp value.
Exceptions
SQLServerException
Remarks
This updateTimestamp method is specified by the updateTimestamp method in the java.sql.ResultSet interface.
See Also
updateTimestamp Method (SQLServerResultSet)
SQLServerResultSet Members
SQLServerResultSet Class
wasNull Method (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean wasNull()
Return Value
true if the last value read was null. Otherwise, false .
Exceptions
SQLServerException
Remarks
This wasNull method is specified by the wasNull method in the java.sql.ResultSet interface.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
SQLServerResultSet Fields
4/27/2022 • 2 minutes to read • Edit Online
See Also
SQLServerResultSet Class
CONCUR_SS_OPTIMISTIC_CC Field
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public static final int CONCUR_SS_OPTIMISTIC_CC
Field Value
An int value of 1008.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
CONCUR_SS_OPTIMISTIC_CCVAL Field
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public static final int CONCUR_SS_OPTIMISTIC_CCVAL
Field Value
An int value of 1010.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
CONCUR_SS_SCROLL_LOCKS Field
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public static final int CONCUR_SS_SCROLL_LOCKS
Field Value
An int value of 1009.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
TYPE_SS_DIRECT_FORWARD_ONLY Field
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public static final int TYPE_SS_DIRECT_FORWARD_ONLY
Field Value
An int value of 2003.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
TYPE_SS_SCROLL_DYNAMIC Field
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public static final int TYPE_SS_SCROLL_DYNAMIC
Field Value
An int value of 1006.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
TYPE_SS_SCROLL_KEYSET Field
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public static final int TYPE_SS_SCROLL_KEYSET
Field Value
An int value of 1005.
See Also
SQLServerResultSet Class
TYPE_SS_SCROLL_STATIC Field
(SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public static final int TYPE_SS_SCROLL_STATIC
Field Value
An int value of 1004.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY
Field (SQLServerResultSet)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public static final int TYPE_SS_SERVER_CURSOR_FORWARD_ONLY
Field Value
An int value of 2004.
See Also
SQLServerResultSet Members
SQLServerResultSet Class
SQLServerResultSetMetaData Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final class SQLServerResultSetMetaData
See Also
SQLServerResultSetMetaData Members
JDBC Driver API Reference
SQLServerResultSetMetaData Members
4/27/2022 • 2 minutes to read • Edit Online
Constructors
None.
Fields
None.
Inherited Fields
NAME DESC RIP T IO N
Methods
NAME DESC RIP T IO N
getCatalogName Gets the catalog name for the table that includes the
designated column.
getColumnLabel Gets the title that is suggested for use in printouts and
displays of the designated column.
getPrecision Get the number of decimal digits for the designated column.
NAME DESC RIP T IO N
getScale Gets the number of digits to the right of the decimal point
for the designated column.
getSchemaName Gets the table schema name for the designated column.
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerResultSetMetaData Class
SQLServerResultSetMetaData Methods
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getCatalogName(int column)
Parameters
column
An int that indicates the column index.
Return Value
A String that contains the catalog name.
Exceptions
SQLServerException
Remarks
This getCatalogName method is specified by the getCatalogName method in the java.sql.ResultSetMetaData
interface.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
getColumnClassName Method
(SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getColumnClassName(int column)
Parameters
column
An int that indicates the column index.
Return Value
A String that contains the fully-qualified name of the class.
Exceptions
SQLServerException
Remarks
This getColumnClassName method is specified by the getColumnClassName method in the
java.sql.ResultSetMetaData interface.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
getColumnCount Method
(SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getColumnCount()
Return Value
An int that indicates the number of columns.
Exceptions
SQLServerException
Remarks
This getColumnCount method is specified by the getColumnCount method in the java.sql.ResultSetMetaData
interface.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
getColumnDisplaySize Method
(SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getColumnDisplaySize(int column)
Parameters
column
An int that indicates the column index.
Return Value
An int that indicates the maximum width. If the width is not known, returns 0.
Exceptions
SQLServerException
Remarks
This getColumnDisplaySize method is specified by the getColumnDisplaySize method in the
java.sql.ResultSetMetaData interface.
Microsoft SQL Server JDBC Driver 3.0 has behavior changes in the COLUMN_SIZE column. See
SQLServerDatabaseMetaData.getColumns for more information.
See Also
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
getColumnLabel Method
(SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getColumnLabel(int column)
Parameters
column
An int that indicates the column index.
Return Value
A String that contains the title of the column.
Exceptions
SQLServerException
Remarks
This getColumnLabel method is specified by the getColumnLabel method in the java.sql.ResultSetMetaData
interface.
This method returns the alias name of the column. If that is not available, this method returns the column name.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
getColumnName Method
(SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getColumnName(int column)
Parameters
column
An int that indicates the column index.
Return Value
A String that contains the column name.
Exceptions
SQLServerException
Remarks
This getColumnName method is specified by the getColumnName method in the java.sql.ResultSetMetaData
interface.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
getColumnType Method
(SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getColumnType(int column)
Parameters
column
An int that indicates the column index.
Return Value
An int that indicates the JDBC type as defined in java.sql.Types.
Exceptions
SQLServerException
Remarks
This getColumnType method is specified by the getColumnType method in the java.sql.ResultSetMetaData
interface.
Microsoft SQL Server JDBC Driver 3.0 has behavior changes in the DATA_TYPE column. See
SQLServerDatabaseMetaData.getColumns for more information.
See Also
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
getColumnTypeName Method
(SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getColumnTypeName(int column)
Parameters
column
An int that indicates the column index.
Return Value
A String that contains the server name for the column.
Exceptions
SQLServerException
Remarks
This getColumnTypeName method is specified by the getColumnTypeName method in the
java.sql.ResultSetMetaData interface.
Microsoft SQL Server JDBC Driver 3.0 has behavior changes in the TYPE_NAME column. See
SQLServerDatabaseMetaData.getColumns for more information.
See Also
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
getPrecision Method
(SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getPrecision(int column)
Parameters
column
An int that indicates the column index.
Return Value
An int that indicates the precision of the column.
Exceptions
SQLServerException
Remarks
This getPrecision method is specified by the getPrecision method in the java.sql.ResultSetMetaData interface.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
getScale Method (SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getScale(int column)
Parameters
column
An int that indicates the column index.
Return Value
An int that indicates the scale of the column.
Exceptions
SQLServerException
Remarks
This getScale method is specified by the getScale method in the java.sql.ResultSetMetaData interface.
Microsoft SQL Server JDBC Driver 3.0 has behavior changes in the DECIMAL_DIGITS column. See
SQLServerDatabaseMetaData.getColumns for more information.
See Also
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
getSchemaName Method
(SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getSchemaName(int column)
Parameters
column
An int that indicates the column index.
Return Value
A String that contains the schema name.
Exceptions
SQLServerException
Remarks
This getSchemaName method is specified by the getSchemaName method in the java.sql.ResultSetMetaData
interface.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
getTableName Method
(SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getTableName(int column)
Parameters
column
An int that indicates the column index.
Return Value
A String that contains the table name.
Exceptions
SQLServerException
Remarks
This getTableName method is specified by the getTableName method in the java.sql.ResultSetMetaData
interface.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
isAutoIncrement Method
(SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isAutoIncrement(int column)
Parameters
column
An int that indicates the column index.
Return Value
true if the column is automatically numbered. Otherwise, false .
Exceptions
SQLServerException
Remarks
This isAutoIncrement method is specified by the isAutoIncrement method in the java.sql.ResultSetMetaData
interface.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
isCaseSensitive Method
(SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isCaseSensitive(int column)
Parameters
column
An int that indicates the column index.
Return Value
true if the column is case sensitive. Otherwise, false .
Exceptions
SQLServerException
Remarks
This isCaseSensitive method is specified by the isCaseSensitive method in the java.sql.ResultSetMetaData
interface.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
isCurrency Method (SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isCurrency(int column)
Parameters
column
An int that indicates the column index.
Return Value
true if the column is a cash value. Otherwise, false .
Exceptions
SQLServerException
Remarks
This isCurrency method is specified by the isCurrency method in the java.sql.ResultSetMetaData interface.
This method will return true only with SQL Server money and smallmoney data types.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
isDefinitelyWritable Method
(SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isDefinitelyWritable(int column)
Parameters
column
An int that indicates the column index.
Return Value
true if the column write will definitely succeed. Otherwise, false .
Exceptions
SQLServerException
Remarks
This isDefinitelyWritable method is specified by the isDefinitelyWritable method in the
java.sql.ResultSetMetaData interface.
NOTE
When using the Microsoft JDBC Driver for SQL Server with a SQL Server database, this method will always return false.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
isNullable Method (SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int isNullable(int column)
Parameters
column
An int that indicates the column index.
Return Value
true if the column can be null. Otherwise, false .
Exceptions
SQLServerException
Remarks
This isNullable method is specified by the isNullable method in the java.sql.ResultSetMetaData interface.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
isReadOnly Method (SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isReadOnly(int column)
Parameters
column
An int that indicates the column index.
Return Value
true if the column is read-only. Otherwise, false .
Exceptions
SQLServerException
Remarks
This isReadOnly method is specified by the isReadOnly method in the java.sql.ResultSetMetaData interface.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
isSearchable Method
(SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isSearchable(int column)
Parameters
column
An int that indicates the column index.
Return Value
true if the column the column can be used in a WHERE clause. Otherwise, false .
Exceptions
SQLServerException
Remarks
This isSearchable method is specified by the isSearchable method in the java.sql.ResultSetMetaData interface.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
isSigned Method (SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isSigned(int column)
Parameters
column
An int that indicates the column index.
Return Value
true if the column contains signed numbers. Otherwise, false .
Exceptions
SQLServerException
Remarks
This isSigned method is specified by the isSigned method in the java.sql.ResultSetMetaData interface.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
isSparseColumnSet Method
(SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isSparseColumnSet(int column)
Parameters
column
The (one-based) index of the column.
Return Value
true if a column in a result set is a sparse column set, otherwise false .
Remarks
This method does not retrieve information from the database.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
isWritable Method (SQLServerResultSetMetaData)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isWritable(int column)
Parameters
column
An int that indicates the column index.
Return Value
true if writes will succeed on the column. Otherwise, false .
Exceptions
SQLServerException
Remarks
This isWritable method is specified by the isWritable method in the java.sql.ResultSetMetaData interface.
See Also
SQLServerResultSetMetaData Methods
SQLServerResultSetMetaData Members
SQLServerResultSetMetaData Class
SQLServerSavepoint Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public class SQLServerSavepoint
See Also
SQLServerSavepoint Members
JDBC Driver API Reference
SQLServerSavepoint Members
4/27/2022 • 2 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
Fields
None.
Inherited Fields
None.
Methods
NAME DESC RIP T IO N
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerSavepoint Class
SQLServerSavepoint Constructors
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public SQLServerSavepoint(SQLServerConnection con,
java.lang.String sName)
Parameters
con
A SQLServerConnection object.
sName
A String that contains the name of the savepoint.
See Also
SQLServerSavepoint Constructors
SQLServerSavepoint Members
SQLServerSavepoint Class
SQLServerSavepoint Methods
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getLabel()
Return Value
A String that contains the name of the savepoint label.
See Also
SQLServerSavepoint Methods
SQLServerSavepoint Members
SQLServerSavepoint Class
getSavepointId Method (SQLServerSavepoint)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getSavepointId()
Return Value
An int value.
Exceptions
SQLServerException
Remarks
This getSavepointId method is specified by the getSavepointId method in the java.sql.Savepoint interface.
See Also
SQLServerSavepoint Methods
SQLServerSavepoint Members
SQLServerSavepoint Class
getSavepointName Method (SQLServerSavepoint)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.lang.String getSavepointName()
Return Value
A String that contains the name of the savepoint.
Exceptions
SQLServerException
Remarks
This getSavepointName method is specified by the getSavepointName method in the java.sql.Savepoint
interface.
See Also
SQLServerSavepoint Methods
SQLServerSavepoint Members
SQLServerSavepoint Class
isNamed Method (SQLServerSavepoint)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isNamed()
Return Value
true is the savepoint is named. Otherwise, false .
See Also
SQLServerSavepoint Methods
SQLServerSavepoint Members
SQLServerSavepoint Class
SQLServerStatement Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public class SQLServerStatement
Remarks
The SQLServerStatement class also provides a number of base class implementation methods for the JDBC
prepared statement and callable statements. The basic role of the SQLServerStatement class is to run SQL
statements, and then return update counts and result sets to the user application.
This class supports unwrapping to SQLServerStatement class, the ISQLServerStatement interface, and the
java.sql.Statement interface. For more information, see Wrappers and Interfaces.
See Also
SQLServerStatement Members
JDBC Driver API Reference
SQLServerStatement Members
4/27/2022 • 3 minutes to read • Edit Online
Constructors
None.
Fields
None.
Inherited Fields
NAME DESC RIP T IO N
Methods
NAME DESC RIP T IO N
execute Runs the given SQL statement, which can return multiple
results.
getFetchSize Retrieves the number of result set rows that is the default
fetch size for result set objects generated from this
SQLServerStatement object.
setCursorName Sets the SQL cursor name to the given String, which will be
used by subsequent execute methods.
setFetchSize Gives the JDBC driver a hint as to the number of rows that
should be fetched from the database when more rows are
needed.
setMaxRows Sets the limit for the maximum number of rows that any
SQLServerResultSet object can contain to the given number.
setQueryTimeout Sets the number of seconds the driver will wait for a
SQLServerStatement object to run to the given number of
seconds.
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerStatement Members
SQLServerStatement Class
addBatch Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void addBatch(java.lang.String sql)
Parameters
sql
A String that contains an SQL statement.
Exceptions
SQLServerException
Remarks
This addBatch method is specified by the addBatch method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
cancel Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void cancel()
Exceptions
SQLServerException
Remarks
This cancel method is specified by the cancel method in the java.sql.Statement interface.
When executing a statement that produces a single large forward-only, read-only result set, you might only be
interested in some initial set of rows in the returned result set. In this case, the application might call the cancel
method of the associated statement object before closing the result set in order to minimize the processing time
needed to discard the remaining unnecessary rows. We recommend considering the tradeoff between the
processing time that would be saved and the time and the additional round trip to the server needed to cancel
the execution when deciding whether to use this technique or not.
See Also
SQLServerStatement Members
SQLServerStatement Class
clearBatch Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void clearBatch()
Exceptions
SQLServerException
Remarks
This clearBatch method is specified by the clearBatch method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
clearWarnings Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void clearWarnings()
Exceptions
SQLServerException
Remarks
This clearWarnings method is specified by the clearWarnings method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
close Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void close()
Exceptions
SQLServerException
Remarks
This close method is specified by the close method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
execute Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
execute (java.lang.String) Runs the given SQL statement, which can return multiple
results.
execute (java.lang.String, int) Runs the given SQL statement, which can return multiple
results, and signals to Microsoft JDBC Driver for SQL Server
that any auto-generated keys should be made available for
retrieval.
execute (java.lang.String, int[]) Runs the given SQL statement, which can return multiple
results, and signals the JDBC driver that the auto-generated
keys that are indicated in the given array should be made
available for retrieval.
execute (java.lang.String, java.lang.String[]) Runs the given SQL statement, which can return multiple
results, and signals the JDBC driver that the auto-generated
keys that are indicated in the given array should be made
available for retrieval.
See Also
SQLServerStatement Members
SQLServerStatement Class
execute Method ( java.lang.String)
(SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean execute(java.lang.String sql)
Parameters
sql
A String that contains an SQL statement.
Return Value
true if the first result is a result set. Otherwise, false .
Exceptions
SQLServerException
Remarks
This execute method is specified by the execute method in the java.sql.Statement interface.
See Also
execute Method (SQLServerStatement)
SQLServerStatement Members
SQLServerStatement Class
execute Method ( java.lang.String, int[])
4/27/2022 • 2 minutes to read • Edit Online
Runs the given SQL statement, which can return multiple results, and signals Microsoft JDBC Driver for SQL
Server that the auto-generated keys that are indicated in the given array should be made available for retrieval.
Syntax
public final boolean execute(
java.lang.String sql,
int[] columnIndexes)
Parameters
sql
A String that contains an SQL statement.
columnIndexes
An array of int s that indicates the column indexes of the auto-generated keys that should be made available.
Return Value
true if the first result is a result set. Otherwise, false .
Exceptions
SQLServerException
Remarks
This execute method is specified by the execute method in the java.sql.Statement interface.
See Also
execute Method (SQLServerStatement)
SQLServerStatement members
SQLServerStatement class
execute Method ( java.lang.String, java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final boolean execute(java.lang.String sql,
java.lang.String[] columnNames)
Parameters
sql
A String that contains an SQL statement.
columnNames
An array of strings that indicates the column names of the auto-generated keys that should be made available.
Return Value
true if the first result is a result set. Otherwise, false .
Exceptions
SQLServerException
Remarks
This execute method is specified by the execute method in the java.sql.Statement interface.
See Also
execute Method (SQLServerStatement)
SQLServerStatement Members
SQLServerStatement Class
executeBatch Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int[] executeBatch()
Return Value
An array of int s that contain the update counts.
Exceptions
SQLServerException
java.sql.BatchUpdateException
Remarks
This executeBatch method is specified by the executeBatch method in the java.sql.Statement interface.
After submitting commands to the database, this method clears any command in the batch.
See Also
SQLServerStatement Members
SQLServerStatement Class
executeQuery Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public java.sql.ResultSet executeQuery(java.lang.String sql)
Parameters
sql
A String that contains an SQL statement.
Return Value
A SQLServerResultSet object.
Exceptions
SQLServerException
Remarks
This executeQuery method is specified by the executeQuery method in the java.sql.Statement interface.
SQLServerException is thrown if the given SQL statement produces anything other than a single
SQLServerResultSet object.
If executing a stored procedure results in an update count that is greater than one, or that generates more than
one result set, use the execute method to execute the stored procedure.
See Also
SQLServerStatement Members
SQLServerStatement Class
executeUpdate Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
executeUpdate (java.lang.String) Runs the given SQL statement, which can be an INSERT,
UPDATE, DELETE, or MERGE statement; or an SQL statement
that returns nothing, such as an SQL DDL statement.
executeUpdate (java.lang.String, int) Runs the given SQL statement and signals the Microsoft
JDBC Driver for SQL Server with the given flag about
whether the auto-generated keys produced by this
SQLServerStatement object should be made available for
retrieval.
executeUpdate (java.lang.String, int[]) Runs the given SQL statement and signals the JDBC driver
that the auto-generated keys that are indicated in the given
array should be made available for retrieval.
executeUpdate (java.lang.String, java.lang.String[]) Runs the given SQL statement and signals the JDBC driver
that the auto-generated keys that are indicated in the given
array should be made available for retrieval.
See Also
SQLServerStatement Members
SQLServerStatement Class
executeUpdate Method ( java.lang.String)
(SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int executeUpdate(java.lang.String sql)
Parameters
sql
A String that contains the SQL statement.
Return Value
An int that indicates the number of rows affected, or 0 if using a DDL statement.
Exceptions
SQLServerException
Remarks
This executeUpdate method is specified by the executeUpdate method in the java.sql.Statement interface.
If executing a stored procedure results in an update count that is greater than one, or that generates more than
one result set, use the execute method to execute the stored procedure.
See Also
executeUpdate Method (SQLServerStatement)
SQLServerStatement Members
SQLServerStatement Class
executeUpdate Method ( java.lang.String, int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final int executeUpdate(java.lang.String sql,
int flag)
Parameters
sql
A String that contains an SQL statement.
flag
An int value that indicates if auto-generated keys should be made available. It must be one of the following
constants:
RETURN_GENERATED_KEYS
NO_GENERATED_KEYS
Return Value
An int that indicates the number of rows affected, or 0 if using a DDL statement.
Exceptions
SQLServerException
Remarks
This executeUpdate method is specified by the executeUpdate method in the java.sql.Statement interface.
If executing a stored procedure results in an update count that is greater than one, or that generates more than
one result set, use the execute method to execute the stored procedure.
See Also
executeUpdate Method (SQLServerStatement)
SQLServerStatement Members
SQLServerStatement Class
executeUpdate Method ( java.lang.String,
java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final int executeUpdate(java.lang.String sql,
java.lang.String[] columnNames)
Parameters
sql
A String that contains an SQL statement.
columnNames
An array of type String that indicates which column names of the auto-generated keys should be made
available.
Return Value
An int that indicates the number of rows affected, 0 if using a DDL statement.
Exceptions
SQLServerException
Remarks
This executeUpdate method is specified by the executeUpdate method in the java.sql.Statement interface.
If executing a stored procedure results in an update count that is greater than one, or that generates more than
one result set, use the execute method to execute the stored procedure.
See Also
executeUpdate Method (SQLServerStatement)
SQLServerStatement Members
SQLServerStatement Class
getConnection Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.sql.Connection getConnection()
Exceptions
SQLServerException
Remarks
This getConnection method is specified by the getConnection method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
getFetchDirection Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently implemented by the Microsoft JDBC Driver for SQL Server. Therefore, it will always return
FETCH_UNKNOWN.
Syntax
public final int getFetchDirection()
Return Value
An int that indicates the fetch direction that is specified by the setFetchDirection method.
Exceptions
SQLServerException
Remarks
This getFetchDirection method is specified by the getFetchDirection method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
getFetchSize Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final int getFetchSize()
Return Value
An int that indicates the fetch size, which is specified by the setFetchSize method.
Exceptions
SQLServerException
Remarks
This getFetchSize method is specified by the getFetchSize method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
getGeneratedKeys Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.sql.ResultSet getGeneratedKeys()
Return Value
A ResultSet object.
Exceptions
SQLServerException
Remarks
This getGeneratedKeys method is specified by the getGeneratedKeys method in the java.sql.Statement interface.
For more information about how to use this method, see Using Auto Generated Keys.
See Also
SQLServerStatement Members
SQLServerStatement Class
getMaxFieldSize Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final int getMaxFieldSize()
Return Value
An int that indicates the maximum number of bytes that a column can contain, or 0 if there is no limit.
Exceptions
SQLServerException
Remarks
This getMaxFieldSize method is specified by the getMaxFieldSize method in the java.sql.Statement interface.
See Also
SQLServerStatement Methods
SQLServerStatement Class
getMaxRows Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final int getMaxRows()
Return Value
An int that indicates the maximum number of rows, or 0 if there is no limit.
Exceptions
SQLServerException
Remarks
This getMaxRows method is specified by the getMaxRows method in the java.sql.Statement interface.
This getMaxRows method always returns 0 for dynamic scrollable cursors.
See Also
SQLServerStatement Members
SQLServerStatement Class
getMoreResults Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
See Also
SQLServerStatement Members
SQLServerStatement Class
getMoreResults Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final boolean getMoreResults()
Return Value
true if the returned result is a result set. Otherwise, false .
Exceptions
SQLServerException
Remarks
This getMoreResults method is specified by the getMoreResults method in the java.sql.Statement interface.
Calling the getMoreResults method implicitly closes any currently open result set objects that are obtained with
the getResultSet method.
See Also
getMoreResults Method (SQLServerStatement)
SQLServerStatement Members
SQLServerStatement Class
getMoreResults Method (int)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final boolean getMoreResults(int mode)
Parameters
mode
An int that indicates how to handle currently open result set objects. Must be one of the following constants:
CLOSE_CURRENT_RESULT
KEEP_CURRENT_RESULT (not supported by the JDBC driver)
CLOSE_ALL_RESULTS
Return Value
true if the returned result is a result set. Otherwise, false .
Exceptions
SQLServerException
Remarks
This getMoreResults method is specified by the getMoreResults method in the java.sql.Statement interface.
If the getMoreResults method is called before results are retrieved, it behaves as specified by the mode
argument and moves to the next result.
NOTE
The JDBC driver does not support using the KEEP_CURRENT_RESULT constant. If it is used, an exception will be thrown.
See Also
getMoreResults Method (SQLServerStatement)
SQLServerStatement Members
SQLServerStatement Class
getQueryTimeout Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final int getQueryTimeout()
Return Value
An int that indicates the number of seconds that the JDBC driver will wait, or 0 if there is no limit.
Exceptions
SQLServerException
Remarks
This getQueryTimeout method is specified by the getQueryTimeout method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
getResponseBuffering Method
(SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.lang.String getResponseBuffering()
Return Value
A String that contains a lower-case full or adaptive .
Remarks
adaptive specifies buffering the minimum possible data when necessary.
full specifies reading the entire result from the server at run time.
adaptive is the default value in JDBC Driver version 2.0 and 3.0. full was the default prior to JDBC Driver
version 2.0.
For more information about using the response buffering mode, see Using Adaptive Buffering.
See Also
setResponseBuffering Method (SQLServerStatement)
SQLServerStatement Members
SQLServerStatement Class
getResultSet Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.sql.ResultSet getResultSet()
Return Value
A ResultSet object.
Exceptions
SQLServerException
Remarks
This getResultSet method is specified by the getResultSet method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
getResultSetConcurrency Method
(SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final int getResultSetConcurrency()
Return Value
An int that indicates the result set concurrency type.
Exceptions
SQLServerException
Remarks
This getResultSetConcurrency method is specified by the getResultSetConcurrency method in the
java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
getResultSetHoldability Method
(SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final int getResultSetHoldability()
Return Value
An int that indicates the result set holdability.
Exceptions
SQLServerException
Remarks
This getResultSetHoldability method is specified by the getResultSetHoldability method in the java.sql.Statement
interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
getResultSetType Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final int getResultSetType()
Return Value
An int that indicates the result set type.
Exceptions
SQLServerException
Remarks
This getResultSetType method is specified by the getResultSetType method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
getUpdateCount Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final int getUpdateCount()
Return Value
An int that contains the update count. If the returned result is a result set object or there are no more results, -1
is returned.
Exceptions
SQLServerException
Remarks
This getUpdateCount method is specified by the getUpdateCount method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
getWarnings Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final java.sql.SQLWarning getWarnings()
Return Value
An SQLWarning object.
Exceptions
SQLServerException
Remarks
This getWarnings method is specified by the getWarnings method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
isClosed Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isClosed()
Return Value
true if this SQLServerStatement object is closed, false if it is still open.
Exceptions
SQLServerException
Remarks
This isClosed method is specified by the isClosed method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
isPoolable Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isPoolable() throws SQLException
Return Value
true if the statement can be added to the user-provided statement pool; false otherwise.
Exceptions
SQLServerException
Remarks
setPoolable changes the poolable behavior of an object.
See Also
SQLServerStatement Members
SQLServerStatement Class
isWrapperFor Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isWrapperFor(Class iface)
Parameters
iface
A class defining an interface.
Return Value
true if this object implements the interface or wraps an object that implements the interface. Otherwise, false .
Exceptions
SQLServerException
Remarks
The isWrapperFor method and the unwrap method are defined by the java.sql.Wrapper interface, which is
introduced in JDBC 4.0.
If this method returns true, calling unwrap with the same argument will succeed.
For an example code, see Updating Large Data Sample.
For more information, see Wrappers and Interfaces.
See Also
unwrap Method (SQLServerStatement)
SQLServerStatement Members
SQLServerStatement Class
setCursorName Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
This method is not currently supported by the Microsoft JDBC Driver for SQL Server. Calling this method has no effect.
Syntax
public final void setCursorName(java.lang.String name)
Parameters
name
A String that contains the cursor name.
Exceptions
SQLServerException
Remarks
This setCursorName method is specified by the setCursorName method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
setDateTimeOffset(int, java.sql.DateTimeOffset)
(SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setDateTimeOffset(int parameterIndex, DateTimeOffset dateTime)
Parameters
parameterIndex
Index of the column to set.
dateTimeOffset
A DateTimeOffset object.
Exceptions
SQLServerException
Remarks
The DateTimeOffset format is "YYYY-MM-DD HH-MM-SS[.nnnnnnn] [+][-] HH:MM". Use the following table for
reference.
SQ L T Y P E IN SERT
See Also
getDateTimeOffset (SQLServerResultSet)
SQLServerStatement Members
SQLServerStatement Class
setEscapeProcessing Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
Escape processing for Microsoft JDBC Driver for SQL Server is always enabled. Setting this method to false has no effect.
Syntax
public final void setEscapeProcessing(boolean enable)
Parameters
enable
true to enable escape processing. Otherwise, false .
Exceptions
SQLServerException
Remarks
This setEscapeProcessing method is specified by the setEscapeProcessing method in the java.sql.Statement
interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
setFetchDirection Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
The JDBC driver currently ignores the hint that is given by this method.
Syntax
public final void setFetchDirection(int nDir)
Parameters
nDir
An int that indicates the row processing direction, which can be one of the following values:
FETCH_FORWARD
FETCH_REVERSE
FETCH_UNKNOWN
Exceptions
SQLServerException
Remarks
This setFetchDirection method is specified by the setFetchDirection method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
setFetchSize Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setFetchSize(int rows)
Parameters
rows
An int that indicates the number of rows to fetch.
Exceptions
SQLServerException
Remarks
This setFetchSize method is specified by the setFetchSize method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
setMaxFieldSize Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setMaxFieldSize(int max)
Parameters
max
An int that indicates the maximum number of bytes.
Exceptions
SQLServerException
Remarks
This setMaxFieldSize method is specified by the setMaxFieldSize method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
setMaxRows Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setMaxRows(int max)
Parameters
max
An int that indicates the maximum number of rows, or 0 if there is no limit.
Exceptions
SQLServerException
Remarks
This setMaxRows method is specified by the setMaxRows method in the java.sql.Statement interface.
This setMaxRows method has no effect for dynamic scrollable cursors. The application should use SELECT TOP N
SQL syntax to limit the number of rows returned from potentially large result sets.
When the setMaxRows method is called, the Microsoft JDBC Driver for SQL Server executes the SET
ROWCOUNT SQL statement when it runs the application's query. This causes the JDBC driver to limit the
maximum number of rows affected by all the Transact-SQL statements executed by that query, not just the
number of rows returned by that query. If the application needs to set a limit only on the top-level
SQLServerResultSet object, it should use SELECT TOP N SQL syntax in the query instead of the setMaxRows
method.
For more information about the SET ROWCOUNT SQL statement, see the "SET ROWCOUNT (Transact-SQL)"
topic in SQL Server Books Online.
See Also
SQLServerStatement Members
SQLServerStatement Class
setPoolable Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void setPoolable(boolean poolable) throws SQLException
Parameters
poolable
If true , requests that the statement be pooled. If false , requests that the statement not be pooled.
Exceptions
SQLServerException
Remarks
The value specified in the poolable parameter is a hint to the statement pool implementation indicating if the
application wants the statement to be pooled. The statement pool manager decides if it will use the hint.
A statement's pool value applies to both internal statement caches implemented by the driver and external
statement caches implemented by application servers and other applications.
By default, a SQLServerStatement object is not poolable when created. SQLServerPreparedStatement and
SQLServerCallableStatement objects are poolable when created.
SQLServerException is thrown if this method is called on a closed statement.
isPoolable returns a value indicating if the object is poolable.
See Also
SQLServerStatement Members
SQLServerStatement Class
setResponseBuffering Method
(SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setResponseBuffering(java.lang.String value)
Parameters
value
A String that contains the response buffering mode. The valid mode can be one of the following case-
insensitive Strings: full or adaptive .
Exceptions
SQLServerException
Remarks
adaptive specifies buffering the minimum possible data when necessary.
full specifies reading the entire result from the server at run time.
adaptive is the default value in JDBC Driver version 2.0 and 3.0. full was the default prior to JDBC Driver version
2.0.
The setResponseBuffering method allows you to override the responseBuffering connection String property
for the current SQLServerStatement object. For more information about using the response buffering mode, see
Using Adaptive Buffering.
If the application specifies an invalid parameter value to the setResponseBuffering method, a
SQLServerException is thrown.
See Also
SQLServerStatement Members
SQLServerStatement Class
Using Adaptive Buffering
setQueryTimeout Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public final void setQueryTimeout(int seconds)
Parameters
seconds
An int that indicates the number of seconds to wait, or 0 if there is no limit.
Exceptions
SQLServerException
Remarks
This setQueryTimeout method is specified by the setQueryTimeout method in the java.sql.Statement interface.
See Also
SQLServerStatement Members
SQLServerStatement Class
unwrap Method (SQLServerStatement)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public <T> T unwrap(Class<T> iface)
Parameters
iface
A class of type T defining an interface.
Return Value
An object that implements the specified interface.
Exceptions
SQLServerException
Remarks
The unwrap method is defined by the java.sql.Wrapper interface, which is introduced in the JDBC 4.0 Spec.
Applications might need to access extensions to the JDBC API that are specific to the Microsoft JDBC Driver for
SQL Server. The unwrap method supports unwrapping to public classes that this object extends, if the classes
expose vendor extensions.
When this method is called, the object unwraps to the SQLServerStatement class.
For example code, see Updating Large Data Sample, or unwrap Method (SQLServerCallableStatement).
For more information, see Wrappers and Interfaces.
See Also
isWrapperFor Method (SQLServerStatement)
SQLServerStatement Members
SQLServerStatement Class
SQLServerXAConnection Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public class SQLServerXAConnection
Remarks
A SQLServerXAConnection object can be enlisted in a distributed transaction by means of an
SQLServerXAResource object. A transaction manager, usually part of a middle tier server, manages a
SQLServerXAConnection object through the SQLServerXAResource object.
NOTE
Application programmers typically do not use this interface directly. It is primarily used by a transaction manager working
in the middle tier server.
See Also
SQLServerXAConnection Members
JDBC Driver API Reference
SQLServerXAConnection Members
4/27/2022 • 2 minutes to read • Edit Online
Constructors
None.
Fields
None.
Inherited Fields
None.
Methods
NAME DESC RIP T IO N
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerXAConnection Class
SQLServerXAConnection Methods
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public javax.transaction.xa.XAResource getXAResource()
Return Value
An XAResource object.
Exceptions
java.sql.SQLException
Remarks
This getXAResource method is specified by the getXAResource method in the javax.sql.XAConnection interface.
See Also
SQLServerXAConnection Methods
SQLServerXAConnection Members
SQLServerXAConnection Class
SQLServerXADataSource Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public class SQLServerXADataSource
Remarks
An object that implements the SQLServerXADataSource interface is typically registered with a naming service
that uses the Java Naming and Directory Interface (JNDI).
The SQLServerXADataSource class provides database connections for use in distributed (XA) transactions. The
SQLServerXADataSource class also supports connection pooling of physical connections. The
SQLServerXADataSource and SQLServerXAConnection interfaces, which are defined in the package javax.sql,
are implemented by SQL Server.
A SQLServerXAConnection object is a pooled connection that can participate in a distributed transaction. More
precisely, SQLServerXAConnection extends the SQLServerPooledConnection interface by adding the method
getXAResource. This method produces a SQLServerXAResource object that can be used by a transaction
manager to coordinate the work done on this connection with the other participants in the distributed
transaction. Because they extend the SQLServerPooledConnection interface, SQLServerXAConnection objects
support all the methods of SQLServerPooledConnection objects. They are reusable physical connections to an
underlying data source and produce logical connection handles that can be passed back to a JDBC application.
SQLServerXAConnection objects are produced by a SQLServerXADataSource object.
SQLServerConnectionPoolDataSource objects and SQLServerXADataSource objects are similar because they are
both implemented below a data source layer that is visible to the JDBC application. This architecture lets SQL
Server support distributed transactions in a way that is transparent to the application. SQLServerXADataSource
can be configured to integrate with Microsoft Distributed Transaction Coordinator (DTC) to provide true,
distributed transaction processing.
See Also
SQLServerXADataSource Members
JDBC Driver API Reference
SQLServerXADataSource Members
4/27/2022 • 4 minutes to read • Edit Online
Constructors
NAME DESC RIP T IO N
Fields
None.
Inherited Fields
None.
Methods
NAME DESC RIP T IO N
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataS getPooledConnection
ource
Syntax
public SQLServerXADataSource()
See Also
SQLServerXADataSource Constructors
SQLServerXADataSource Members
SQLServerXADataSource Class
SQLServerXADataSource Methods
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public javax.naming.Reference getReference()
Return Value
A Reference object.
Remarks
This getReference method is specified by the getReference method in the javax.naming.Referenceable interface.
See Also
SQLServerXADataSource Methods
SQLServerXADataSource Members
SQLServerXADataSource Class
getXAConnection Method
(SQLServerXADataSource)
4/27/2022 • 2 minutes to read • Edit Online
Overload List
NAME DESC RIP T IO N
getXAConnection (java.lang.String, java.lang.String) Tries to establish a physical database connection using the
given user name and password.
See Also
SQLServerXADataSource Methods
SQLServerXADataSource Members
SQLServerXADataSource Class
getXAConnection Method ()
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public javax.sql.XAConnection getXAConnection()
Return Value
An XAConnection object.
Exceptions
java.sql.SQLException
Remarks
This getXAConnection method is specified by the getXAConnection method in the javax.sql.XADataSource
interface.
NOTE
This method is typically called by XA connection pool implementations and not by regular JDBC application code.
See Also
getXAConnection Method (SQLServerXADataSource)
SQLServerXADataSource Methods
SQLServerXADataSource Members
SQLServerXADataSource Class
getXAConnection Method ( java.lang.String,
java.lang.String)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public javax.sql.XAConnection getXAConnection(java.lang.String user,
java.lang.String password)
Parameters
user
A String that contains the user name.
password
A String that contains the password.
Return Value
An XAConnection object.
Exceptions
java.sql.SQLException
Remarks
This getXAConnection method is specified by the getXAConnection method in the javax.sql.XADataSource
interface.
NOTE
This method is typically called by XA connection pool implementations and not by regular JDBC application code.
See Also
getXAConnection Method (SQLServerXADataSource)
SQLServerXADataSource Methods
SQLServerXADataSource Members
SQLServerXADataSource Class
isWrapperFor Method (SQLServerXADataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isWrapperFor(Class iface)
Parameters
iface
A class defining an interface.
Return Value
true if this object implements the interface or wraps an object that implements the interface. Otherwise, false .
Exceptions
SQLServerException
Remarks
The isWrapperFor method and the unwrap method are defined by the java.sql.Wrapper interface, which is
introduced in the JDBC 4.0 Spec.
If this method returns true, calling unwrap with the same argument will succeed.
For more information, see Wrappers and Interfaces.
See Also
unwrap Method (SQLServerXADataSource)
SQLServerXADataSource Methods
SQLServerXADataSource Members
SQLServerXADataSource Class
unwrap Method (SQLServerXADataSource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public <T> T unwrap(Class<T> iface)
Parameters
iface
A class of type T defining an interface.
Return Value
An object that implements the specified interface.
Exceptions
SQLServerException
Remarks
The unwrap method is defined by the java.sql.Wrapper interface, which is introduced in the JDBC 4.0 Spec.
Applications might need to access extensions to the JDBC API that are specific to the Microsoft JDBC Driver for
SQL Server. The unwrap method supports unwrapping to public classes that this object extends, if the classes
expose vendor extensions.
The SQLServerXADataSource class extends the SQLServerConnectionPoolDataSource class, which is extended
from the SQLServerDataSource class. When this method is called, the object unwraps to the following classes:
SQLServerDataSource, SQLServerConnectionPoolDataSource, and SQLServerXADataSource.
For more information, see Wrappers and Interfaces.
See Also
SQLServerXADataSource Methods
SQLServerXADataSource Members
SQLServerXADataSource Class
SQLServerXAResource Class
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public class SQLServerXAResource
Remarks
XA transactions are implemented in SQL Server by using Microsoft Distributed Transaction Manager (DTC). The
SQLServerXAResource class makes calls to a SQL Server extended dll named sqljdbc_xa.dll, which interfaces
with DTC. XA calls that are received by SQLServerXAResource (XA_START, XA_END, XA_PREPARE, and so forth)
are mapped to the corresponding calls to DTC functions.
See Also
SQLServerXAResource Members
JDBC Driver API Reference
SQLServerXAResource Members
4/27/2022 • 2 minutes to read • Edit Online
Constructors
None.
Fields
NAME DESC RIP T IO N
Inherited Fields
C L A SS IN H ERIT ED F RO M : M ET H O DS
Methods
NAME DESC RIP T IO N
getTransactionTimeout Obtains the current transaction timeout value set for this
SQLServerXAResource object.
rollback Requests that the resource manager roll back work done on
behalf of a transaction branch.
Inherited Methods
C L A SS IN H ERIT ED F RO M : M ET H O DS
See Also
SQLServerXAResource Class
SQLServerXAResource Methods
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void commit(javax.transaction.xa.Xid xid,
boolean onePhase)
Parameters
xid
An Xid object.
onePhase
A boolean value.
Exceptions
javax.transaction.xa.XAException
Remarks
This commit method is specified by the commit method in the javax.transaction.xa.XAResource interface.
See Also
SQLServerXAResource Methods
SQLServerXAResource Members
SQLServerXAResource Class
end Method (SQLServerXAResource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void end(javax.transaction.xa.Xid xid,
int flags)
Parameters
xid
An Xid object.
flags
An int value.
Exceptions
javax.transaction.xa.XAException
Remarks
This end method is specified by the end method in the javax.transaction.xa.XAResource interface.
See Also
SQLServerXAResource Methods
SQLServerXAResource Members
SQLServerXAResource Class
forget Method (SQLServerXAResource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void forget(javax.transaction.xa.Xid xid)
Parameters
xid
An Xid object.
Exceptions
javax.transaction.xa.XAException
Remarks
This forget method is specified by the forget method in the javax.transaction.xa.XAResource interface.
See Also
SQLServerXAResource Methods
SQLServerXAResource Members
SQLServerXAResource Class
getTransactionTimeout Method
(SQLServerXAResource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int getTransactionTimeout()
Exceptions
javax.transaction.xa.XAException
Remarks
This getTransactionTimeout method is specified by the getTransactionTimeout method in the
javax.transaction.xa.XAResource interface.
See Also
SQLServerXAResource Methods
SQLServerXAResource Members
SQLServerXAResource Class
isSameRM Method (SQLServerXAResource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean isSameRM(javax.transaction.xa.XAResource xares)
Parameters
xares
An XAResource object.
Return Value
true if the instances are the same. Otherwise, false .
Exceptions
javax.transaction.xa.XAException
Remarks
This commit method is specified by the commit method in the javax.transaction.xa.XAResource interface.
See Also
SQLServerXAResource Methods
SQLServerXAResource Members
SQLServerXAResource Class
prepare Method (SQLServerXAResource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public int prepare(javax.transaction.xa.Xid xid)
Parameters
xid
An Xid object.
Return Value
An int value.
Exceptions
javax.transaction.xa.XAException
Remarks
This prepare method is specified by the prepare method in the javax.transaction.xa.XAResource interface.
See Also
SQLServerXAResource Methods
SQLServerXAResource Members
SQLServerXAResource Class
recover Method (SQLServerXAResource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public javax.transaction.xa.Xid[] recover(int flags)
Parameters
flags
An int value that can take one of the following values: XAResource.TMSTARTRSCAN or
XAResource.TMENDRSCAN or XAResource.TMNOFLAGS or XAResource.TMSTARTTRSCAN |
XAResource.TMENDRSCAN.
Return Value
An Xid object.
Exceptions
javax.transaction.xa.XAException
Remarks
This recover method is specified by the recover method in the javax.transaction.xa.XAResource interface.
If the parameter flag is not XAResource.TMSTARTRSCAN or XAResource.TMSTARTRSCAN |
XAResource.TMENDRSCAN, a recovery scan must be in progress.
See Also
SQLServerXAResource Methods
SQLServerXAResource Members
SQLServerXAResource Class
rollback Method (SQLServerXAResource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void rollback(javax.transaction.xa.Xid xid)
Parameters
xid
An Xid object.
Exceptions
javax.transaction.xa.XAException
Remarks
This rollback method is specified by the rollback method in the javax.transaction.xa.XAResource interface.
See Also
SQLServerXAResource Methods
SQLServerXAResource Members
SQLServerXAResource Class
setTransactionTimeout Method
(SQLServerXAResource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public boolean setTransactionTimeout(int seconds)
Parameters
seconds
An int value.
Return Value
true if the timeout was successfully set. Otherwise, false .
Exceptions
javax.transaction.xa.XAException
Remarks
This setTransactionTimeout method is specified by the setTransactionTimeout method in the
javax.transaction.xa.XAResource interface.
See Also
SQLServerXAResource Methods
SQLServerXAResource Members
SQLServerXAResource Class
start Method (SQLServerXAResource)
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public void start(javax.transaction.xa.Xid xid,
int flags)
Parameters
xid
An Xid object.
flags
An int value.
Exceptions
javax.transaction.xa.XAException
Remarks
This start method is specified by the start method in the javax.transaction.xa.XAResource interface.
See Also
SQLServerXAResource Methods
SQLServerXAResource Members
SQLServerXAResource Class
SQLServerXAResource Fields
4/27/2022 • 2 minutes to read • Edit Online
Syntax
public static final int SSTRANSTIGHTLYCPLD
Field Value
An int value of 32768.
Remarks
Each transaction is identified by an XA branch transaction ID (XID) and a global transaction ID (GTRID). In order
to allow the applications to use tightly coupled XA transactions that have different XIDs but have the same
GTRID, you must set the SSTRANSTIGHTLYCPLD on the flags parameter of the XAResource.start method. For
more information about how to use this flag, see Understanding XA Transactions.
See Also
SQLServerXAResource Fields
SQLServerXAResource Members
SQLServerXAResource Class
Securing JDBC driver applications
4/27/2022 • 2 minutes to read • Edit Online
In this section
A RT IC L E DESC RIP T IO N
Application security Describes how to use Java policy permissions to help secure
a JDBC driver application.
See also
Overview of the JDBC driver
Securing connection strings
4/27/2022 • 2 minutes to read • Edit Online
Recommendations
It's recommended to not store the password together with the connection URL in application source code.
Instead, consider storing the password in a separate file that has restricted access. The access to that file can be
granted to the context under which the application is running.
Another approach is to store the encrypted password in a file. Make sure you use an encryption API that doesn't
require the key to be stored somewhere and isn't derived from the password of a user. For example, you might
consider using certificate-based public/private key pairs, or use an approach where two parties use a key
agreement protocol (Diffie-Hellman algorithm) to generate identical secret keys for encryption without ever
having to transmit the secret key.
If you take connection string information from an external source, such as a user supplying a user ID and
password, you must validate any input from the source to ensure that it follows the correct format and doesn't
contain extra parameters that affect your connection.
See also
Securing JDBC driver applications
Validating user input
4/27/2022 • 2 minutes to read • Edit Online
See also
Securing JDBC driver applications
Application security
4/27/2022 • 2 minutes to read • Edit Online
The following codebase should be restricted to the JDBC driver codebase to ensure that you grant the least
number of privileges.
NOTE
The code "file:/install_dir/lib/-" refers to the installation directory of the JDBC driver.
See also
Securing JDBC driver applications
Using encryption
4/27/2022 • 2 minutes to read • Edit Online
NOTE
The hostNameInCer tificate connection property is recommended to validate an TLS certificate.
In this section
A RT IC L E DESC RIP T IO N
Understanding encryption support Describes how the Microsoft JDBC Driver for SQL Server
supports TLS encryption.
Connecting with encryption Describes how to connect to a SQL Server database by using
the new TLS-specific connection properties.
Configuring the client for encryption Describes how to configure the default trust store at the
client-side and how to import a private certificate to the
client computer's trust store.
See also
Securing JDBC driver applications
Understanding encryption support
4/27/2022 • 8 minutes to read • Edit Online
NOTE
Make sure the value passed to ser verName exactly matches the Common Name (CN) or DNS name in the Subject
Alternate Name (SAN) in the server certificate for a TLS connection to succeed.
For more information about how to configure TLS for SQL Server, see Enable encrypted connections to the Database
Engine.
Remarks
To allow applications to use TLS encryption, the Microsoft JDBC Driver for SQL Server has introduced the
following connection properties starting with the version 1.2 release: encr ypt , trustSer verCer tificate ,
trustStore , trustStorePassword , and hostNameInCer tificate . For more information, see Setting the
connection properties.
The following table summarizes how the Microsoft JDBC Driver for SQL Server version behaves for possible TLS
connection scenarios. Each scenario uses a different set of TLS connection properties. The table includes:
blank : "The property doesn't exist in the connection string"
value : "The property exists in the connection string and its value is valid"
any : "It doesn't matter whether the property exists in the connection string or its value is valid"
NOTE
The same behavior applies for SQL Server user authentication and Windows integrated authentication.
P RO P ERT Y SET T IN GS B EH AVIO R
encr ypt = false or blank The driver won't force the server to support TLS encryption.
trustSer verCer tificate = any If the server has a self-signed certificate, the driver initiates
hostNameInCer tificate = any the TLS certificate exchange. The TLS certificate won't be
trustStore = any validated and only the credentials (in the login packet) are
trustStorePassword = any encrypted.
encr ypt = true The driver requests to use TLS encryption with the server.
trustSer verCer tificate = true
hostNameInCer tificate = any If the server requires the client to support TLS encryption or
trustStore = any if the server supports encryption, the driver will initiate the
trustStorePassword = any TLS certificate exchange. If the trustSer verCer tificate
property is set to "true", the driver won't validate the TLS
certificate.
encr ypt = true The driver requests to use TLS encryption with the server.
trustSer verCer tificate = false or blank
hostNameInCer tificate = blank If the server requires the client to support TLS encryption or
trustStore = blank if the server supports encryption, the driver will initiate the
trustStorePassword = blank TLS certificate exchange.
encr ypt = true The driver requests to use TLS encryption with the server.
trustSer verCer tificate = false or blank
hostNameInCer tificate = value If the server requires the client to support TLS encryption or
trustStore = blank if the server supports encryption, the driver will initiate the
trustStorePassword = blank TLS certificate exchange.
encr ypt = true The driver requests to use TLS encryption with the server.
trustSer verCer tificate = false or blank
hostNameInCer tificate = blank If the server requires the client to support TLS encryption or
trustStore = value if the server supports encryption, the driver will initiate the
trustStorePassword = value TLS certificate exchange.
The driver will use the trustStore property value to find the
certificate trustStore file and trustStorePassword property
value to check the integrity of the trustStore file.
encr ypt = true The driver requests to use TLS encryption with the server.
trustSer verCer tificate = false or blank
hostNameInCer tificate = blank If the server requires the client to support TLS encryption or
trustStore = blank if the server supports encryption, the driver will initiate the
trustStorePassword = value TLS certificate exchange.
encr ypt = true The driver requests to use TLS encryption with the server.
trustSer verCer tificate = false or blank
hostNameInCer tificate = blank If the server requires the client to support TLS encryption or
trustStore = value if the server supports encryption, the driver will initiate the
trustStorePassword = blank TLS certificate exchange.
encr ypt = true The driver requests to use TLS encryption with the server.
trustSer verCer tificate = false or blank
hostNameInCer tificate = value If the server requires the client to support TLS encryption or
trustStore = blank if the server supports encryption, the driver will initiate the
trustStorePassword = value TLS certificate exchange.
encr ypt = true The driver requests to use TLS encryption with the server.
trustSer verCer tificate = false or blank
hostNameInCer tificate = value If the server requires the client to support TLS encryption or
trustStore = value if the server supports encryption, the driver will initiate the
trustStorePassword = blank TLS certificate exchange.
encr ypt = true The driver requests to use TLS encryption with the server.
trustSer verCer tificate = false or blank
hostNameInCer tificate = value If the server requires the client to support TLS encryption or
trustStore = value if the server supports encryption, the driver will initiate the
trustStorePassword = value TLS certificate exchange.
The driver will use the trustStore property value to find the
certificate trustStore file and trustStorePassword property
value to check the integrity of the trustStore file. Also, the
driver will use the hostNameInCer tificate property value
to validate the TLS certificate.
If the encrypt property is set to true , the Microsoft JDBC Driver for SQL Server uses the JVM's default JSSE
security provider to negotiate TLS encryption with SQL Server. The default security provider may not support all
of the features required to negotiate TLS encryption successfully. For example, the default security provider may
not support the size of the RSA public key used in the SQL Server TLS certificate. In this case, the default security
provider might raise an error that will cause the JDBC driver to terminate the connection. To resolve this issue,
one of the following options can be used:
Configure the SQL Server with a server certificate that has a smaller RSA public key
Configure the JVM to use a different JSSE security provider in the "<java-home>/lib/security/java.security"
security properties file
Use a different JVM
See also
Using encryption
Securing JDBC driver applications
Connecting with encryption
4/27/2022 • 2 minutes to read • Edit Online
String connectionUrl =
"jdbc:sqlserver://localhost:1433;" +
"databaseName=AdventureWorks;integratedSecurity=true;" +
"encrypt=true;trustServerCertificate=true";
When the encr ypt property is set to true and the trustSer verCer tificate property is set to false , the
Microsoft JDBC Driver for SQL Server will validate the SQL Server TLS certificate. Validating the server
certificate is a part of the TLS handshake and ensures that the server is the correct server to connect to. To
validate the server certificate, the trust material must be supplied at connection time either by using trustStore
and trustStorePassword connection properties explicitly, or by using the underlying Java Virtual Machine
(JVM)'s default trust store implicitly.
The trustStore property specifies the path (including filename) to the certificate trustStore file, which contains
the list of certificates that the client trusts. The trustStorePassword property specifies the password used to
check the integrity of the trustStore data. For more information on using the JVM's default trust store, see the
Configuring the client for encryption.
The following code example demonstrates how to set the trustStore and trustStorePassword properties in a
connection string:
String connectionUrl =
"jdbc:sqlserver://localhost:1433;" +
"databaseName=AdventureWorks;integratedSecurity=true;" +
"encrypt=true; trustServerCertificate=false;" +
"trustStore=storeName;trustStorePassword=storePassword";
The JDBC Driver provides another property, hostNameInCer tificate , which specifies the host name of the
server. The value of this property must match the subject property of the certificate.
The following code example demonstrates how to use the hostNameInCer tificate property in a connection
string:
String connectionUrl =
"jdbc:sqlserver://localhost:1433;" +
"databaseName=AdventureWorks;integratedSecurity=true;" +
"encrypt=true; trustServerCertificate=false;" +
"trustStore=storeName;trustStorePassword=storePassword;" +
"hostNameInCertificate=hostName";
NOTE
Alternatively, you can set the value of connection properties by using the appropriate setter methods provided by the
SQLServerDataSource class.
If the encr ypt property is true and the trustSer verCer tificate property is false and if the server name in the
connection string doesn't match the server name in the TLS certificate, the following error will be issued:
The driver couldn't establish a secure connection to SQL Server by using Secure Sockets Layer (SSL)
encryption. Error: "java.security.cert.CertificateException: Failed to validate the server name in a
certificate during Secure Sockets Layer (SSL) initialization."
. With version 7.2 and up, the driver supports wildcard pattern matching in the left-most label of the server
name in the TLS certificate.
See also
Using encryption
Securing JDBC driver applications
Configuring the client for encryption
4/27/2022 • 3 minutes to read • Edit Online
java -Djavax.net.ssl.trustStore=C:\MyCertificates\storeName
java -Djavax.net.ssl.trustStorePassword=storePassword
In this case, any application running on this JVM will use these settings as default. To override the default
settings in your application, you should set the trustStore and trustStorePassword connection properties
either in the connection string or in the appropriate setter method of the SQLServerDataSource class.
Also, you can configure and manage the default trust store files such as "<java-home>/lib/security/jssecacerts"
and "<java-home>/lib/security/cacerts". To do that, use the JAVA "keytool" utility that is installed with the JRE
(Java Runtime Environment). For more information about the "keytool" utility, see keytool documentation on the
Oracle Web site.
Importing the server certificate to trust store
During the TLS handshake, the server sends its public key certificate to the client. The issuer of a public key
certificate is known as a Certificate Authority (CA). The client has to ensure the certificate authority is one the
client trusts. This assurance is achieved by knowing the public key of trusted CAs in advance. Normally, the JVM
ships with a predefined set of trusted certificate authorities.
If the instance of SQL Server's TLS certificate is issued by a private certificate authority, you must add the
certificate authority's certificate to the list of trusted certificates in the client computer's trust store.
To do that, use the JAVA "keytool" utility that is installed with the JRE (Java Runtime Environment). The following
command prompt demonstrates how to use the "keytool" utility to import a certificate from a file:
The example uses a file named "caCert.cer" as a certificate file. You must obtain this certificate file from the
server. The following steps explain how to export the server certificate to a file:
1. Select Start and then Run, and type MMC. (MMC is an acronym for the Microsoft Management Console.)
2. In MMC, open the Certificates.
3. Expand Personal and then Certificates.
4. Right-click the server certificate, and then select All Tasks\Export.
5. Select Next to move past the welcome dialog box of the Certificate Export Wizard.
6. Confirm that No, do not export the private key is selected, and then select Next.
7. Make sure to select either DER encoded binary X.509 (.CER) or Base-64 encoded X.509 (.CER), and then select
Next.
8. Enter an export file name.
9. Select Next, and then select Finish to export the certificate.
See also
Using encryption
Securing JDBC driver applications
FIPS mode
4/27/2022 • 2 minutes to read • Edit Online
Prerequisites
FIPS configured JVM
Appropriate TLS/SSL Certificate
Appropriate policy files
Appropriate Configuration parameters
The following example is importing an Azure TLS/SSL Certificate in PKCS12 format with the BouncyCastle
Provider. The certificate is imported in the working directory named MyTrustStore_PKCS12 by using the
following snippet:
saveGenericKeyStore(BCFIPS, PKCS12, "SQLAzure SSL Certificate Name", "SQLAzure.cer");
In this section
A RT IC L E DESC RIP T IO N
Closing objects when not in use Describes the importance of closing JDBC driver objects
when they're no longer needed.
Working with statements and result sets Describes techniques for improving performance when using
the Statement or ResultSet objects.
Sparse columns Discusses the JDBC driver's support for SQL Server sparse
columns.
Prepared statement metadata caching for the JDBC driver Discusses the techniques for improving performance with
prepared statement queries.
Using bulk copy API for batch insert operation Describes how to enable Bulk Copy API for batch insert
operations and its benefits.
Not sending String parameters as Unicode When working with CHAR, VARCHAR, and
LONGVARCHAR data, users can set the connection
property sendStringParametersAsUnicode to false
for optimal performance gain.
See also
Overview of the JDBC driver
Closing objects when not in use
4/27/2022 • 2 minutes to read • Edit Online
See also
Improving performance and reliability with the JDBC driver
Managing transaction size
4/27/2022 • 2 minutes to read • Edit Online
See also
Improving performance and reliability with the JDBC driver
Working with statements and result sets
4/27/2022 • 2 minutes to read • Edit Online
NOTE
With adaptive buffering, the JDBC driver buffers only the amount of data that it has to. The driver does not provide any
public method to control or limit the size of the buffer.
NOTE
A call to ResultSet.close() in the middle of processing a ResultSet would require the Microsoft JDBC Driver for SQL Server
to read and discard all remaining packets. This may take substantial time if the query returned a large data set and
especially if the network connection is slow.
See also
Improving performance and reliability with the JDBC driver
Sparse columns
4/27/2022 • 3 minutes to read • Edit Online
\<installation directory>\sqljdbc_<version>\<language>\samples\sparse
Column sets are computed columns that return all sparse columns in untyped XML form. Consider using
column sets when the number of columns in a table is large or greater than 1024 or operating on individual
sparse columns is cumbersome. A column set can contain up to 30,000 columns.
Example
Description
This sample demonstrates how to detect column sets. It also shows how to parse a column set's XML output to
get the data from the sparse columns.
The code listing is the Java source code. Before you compile the application, change the connection string.
Code
import java.io.StringReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
createColdCallingTable(stmt);
is.setCharacterStream(new StringReader(xml));
Document doc = db.parse(is);
// Extract the NodeList from the artificial root node that was added
NodeList list = doc.getChildNodes();
Node root = list.item(0); // This is the <sparse> node
NodeList sparseColumnList = root.getChildNodes(); // These are the xml
column nodes
String sql = "CREATE TABLE ColdCalling ( ID int IDENTITY(1,1) PRIMARY KEY, [Date] date, [Time]
time, PositiveFirstName nvarchar(50) SPARSE, PositiveLastName nvarchar(50) SPARSE, SpecialPurposeColumns
XML COLUMN_SET FOR ALL_SPARSE_COLUMNS );";
stmt.execute(sql);
See also
Improving performance and reliability with the JDBC driver
Prepared statement metadata caching for the JDBC
driver
4/27/2022 • 5 minutes to read • Edit Online
NOTE
Users can change the default value with the following method: setServerPreparedStatementDiscardThreshold(int value)
One more change introduced from 6.1.6-preview is that before this version, the driver would always call
sp_prepexec . Now, for the first execution of a prepared statement, driver calls sp_executesql and for the rest it
executes sp_prepexec and assigns a handle to it. More details can be found here.
NOTE
Users can change the default behavior to the previous versions of always calling sp_prepexec by setting
enablePrepareOnFirstPreparedStatementCall to true using the following method:
setEnablePrepareOnFirstPreparedStatementCall(boolean value)
List of the new APIs introduced with this change, for batching of unprepare for prepared statements
SQLServerConnection
N EW M ET H O D DESC RIP T IO N
int getServerPreparedStatementDiscardThreshold() Returns the behavior for a specific connection instance. This
setting controls how many outstanding discard actions (
sp_unprepare ) there can be per connection before a call to
clean up the outstanding handles on the server is executed.
If the setting is <= 1, unprepare actions are executed
immediately on prepared statement close. If it's set to
{@literal >} 1, these calls are batched together to avoid the
overhead of calling sp_unprepare too often. The default for
this option can be changed by calling
getDefaultServerPreparedStatementDiscardThreshold().
void setServerPreparedStatementDiscardThreshold(int value) Specifies the behavior for a specific connection instance. This
setting controls how many outstanding discard actions (
sp_unprepare ) there can be per connection before a call to
clean up the outstanding handles on the server is executed.
If the setting is <= 1, unprepare actions are executed
immediately on prepared statement close. If it is set to > 1,
these calls are batched together to avoid overhead of calling
sp_unprepare too often.
SQLServerDataSource
N EW M ET H O D DESC RIP T IO N
void setServerPreparedStatementDiscardThreshold(int This setting controls how many outstanding discard actions (
serverPreparedStatementDiscardThreshold) sp_unprepare ) there can be per connection before a call to
clean up the outstanding handles on the server is executed.
If the setting is <= 1, unprepare actions are executed
immediately on prepared statement close. If it's set to
{@literal >} 1, these calls are batched together to avoid the
overhead of calling sp_unprepare too often
int getServerPreparedStatementDiscardThreshold() This setting controls how many outstanding discard actions (
sp_unprepare ) there can be per connection before a call to
clean up the outstanding handles on the server is executed.
If the setting is <= 1, unprepare actions are executed
immediately on prepared statement close. If it's set to
{@literal >} 1, these calls are batched together to avoid the
overhead of calling sp_unprepare too often.
List of the new APIs introduced with this change, for prepared statement metadata caching
SQLServerConnection
N EW M ET H O D DESC RIP T IO N
void setStatementPoolingCacheSize(int value) Specifies the size of the prepared statement cache for this
connection. A value less than 1 means no cache.
int getStatementPoolingCacheSize() Returns the size of the prepared statement cache for this
connection. A value less than 1 means no cache.
SQLServerDataSource
N EW M ET H O D DESC RIP T IO N
void setStatementPoolingCacheSize(int Specifies the size of the prepared statement cache for this
statementPoolingCacheSize) connection. A value less than 1 means no cache.
int getStatementPoolingCacheSize() Returns the size of the prepared statement cache for this
connection. A value less than 1 means no cache.
See also
Improving performance and reliability with the JDBC driver
Diagnosing problems with the JDBC driver
4/27/2022 • 2 minutes to read • Edit Online
In this section
A RT IC L E DESC RIP T IO N
Handling errors Describes how to handle errors that are returned from SQL
Server.
Getting the driver version Describes how to determine which version of the JDBC
driver is installed.
Tracing driver operation Describes how to enable tracing when using the JDBC driver.
Accessing diagnostic information in the extended events log Describes how to use information in the server's extended
events log to understand connection failures.
See also
Overview of the JDBC driver
Handling errors
4/27/2022 • 2 minutes to read • Edit Online
while (rs.next()) {
System.out.println(rs.getString("FirstName") + " " + rs.getString("LastName"));
}
}
catch (SQLException se) {
do {
System.out.println("SQL STATE: " + se.getSQLState());
System.out.println("ERROR CODE: " + se.getErrorCode());
System.out.println("MESSAGE: " + se.getMessage());
System.out.println();
se = se.getNextException();
}
while (se != null);
}
}
See also
Diagnosing problems with the JDBC driver
Getting the driver version
4/27/2022 • 2 minutes to read • Edit Online
See also
Diagnosing problems with the JDBC driver
Tracing driver operation
4/27/2022 • 8 minutes to read • Edit Online
NOTE
For the native component (sqljdbc_xa.dll) that is included with the JDBC driver, tracing is enabled by the Built-In
Diagnostics (BID) framework. For information about BID, see Data Access Tracing in SQL Server.
When you develop your application, you can make calls to Logger objects, which in turn create LogRecord
objects, which are then passed to Handler objects for processing. Logger and Handler objects both use logging
levels, and optionally logging filters, to regulate which LogRecords are processed. When the logging operations
are complete, the Handler objects can optionally use Formatter objects to publish the log information.
By default, the java.util.logging framework writes its output to a file. This output log file must have write
permissions for the context under which the JDBC driver is running.
NOTE
For more information about using the various logging objects for program tracing, see the Java Logging APIs
documentation on the Sun Microsystems Web site.
The following sections describe the logging levels and the categories that can be logged, and provide
information about how to enable tracing in your application.
Logging levels
Every log message that is created has an associated logging level. The logging level determines the importance
of the log message, which is defined by the Level class in java.util.logging. Enabling logging at one level also
enables logging at all higher levels. This section describes the logging levels for both public logging categories
and internal logging categories. For more information about the logging categories, see the Logging Categories
section in this article.
The following table describes each of the available logging levels for public logging categories.
The following table describes each of the available logging levels for the internal logging categories.
Logging Categories
When you create a Logger object, you must tell the object, which named entity or category that you're interested
in getting log information from. The JDBC driver supports the following public logging categories, which are all
defined in the com.microsoft.sqlserver.jdbc driver package.
Starting with the Microsoft JDBC Driver version 2.0, the driver also provides the
com.microsoft.sqlserver.jdbc.internals package, which includes the logging support for the following internal
logging categories.
TDS.Writer This category traces writes to the TDS channel. Only the
length of the writes is traced, not the contents. This category
also traces issues when an attention signal is sent to the
server to cancel a statement's execution.
TDS.Reader This category traces certain read operations from the TDS
channel at the FINEST level. At the FINEST level, tracing can
be verbose. At WARNING and SEVERE levels, this category
traces when the driver receives an invalid TDS protocol from
SQL Server before the driver closes the connection.
TDS.TOKEN This category logs only the tokens within the TDS packets,
and is less verbose than the TDS.DATA category. It can only
be enabled by setting the logging level to FINEST.
logger.setLevel(Level.OFF);
To disable a specific category from being logged, use the following code:
NOTE
You can set the properties in the logging.properties file by using the LogManager object that is part of
java.util.logging.
See also
Diagnosing problems with the JDBC driver
Troubleshooting connectivity
4/27/2022 • 2 minutes to read • Edit Online
See also
Diagnosing problems with the JDBC driver
Connecting to SQL Server with the JDBC driver
Accessing diagnostic information in the extended
events log
4/27/2022 • 3 minutes to read • Edit Online
Details
For connection operations, the Microsoft JDBC Driver for SQL Server will send a client connection ID. If the
connection fails, you can access the connectivity ring buffer and find the ClientConnectionID field to get
diagnostic information about the failure. For more information about the ring buffer, see Connectivity
troubleshooting in SQL Server 2008 with the Connectivity Ring Buffer. Client connection IDs are logged in the
ring buffer only if an error occurs. If a connection fails before sending the prelogin packet, a client connection ID
won't be generated.
The client connection ID is a 16-byte GUID. If the client_connection_id action is added to events in an
extended events session, the client connection ID will be in the extended events target output. For more client
driver diagnostics, you can enable tracing and rerun the connection command to see the ClientConnectionID
field in the trace.
You can get the client connection ID programmatically by using ISQLServerConnection Interface. The connection
ID will also be present in any connection-related exceptions.
When there's a connection error, the client connection ID in the server's Built In Diagnostics (BID) trace
information and in the connectivity ring buffer can help correlate the client connections to connections on the
server. For more information about BID traces on the server, see Data Access Tracing. Note, the data access
tracing article also contains information about data access trace, which doesn't apply to the Microsoft JDBC
Driver for SQL Server; see Tracing driver operation for information on doing a data access trace using the
Microsoft JDBC Driver for SQL Server.
The JDBC Driver also sends a thread-specific activity ID. If the session is started with the TRACK_CAUSAILITY
option enabled, the activity ID is captured in the extended events session. For performance issues with an active
connection, you can get the activity ID from the client's trace (ActivityID field) and then locate the activity ID in
the extended events output.
The activity ID in extended events is a 16-byte GUID (not the same as the GUID for the client connection ID)
appended with a 4-byte sequence number. The sequence number represents the order of a request within a
thread. The ActivityId is sent for SQL batch statements and RPC requests. To enable sending ActivityId to the
server, specify the following key-value pair in the Logging.Properties file:
com.microsoft.sqlserver.jdbc.traceactivity = on
Any value other than on (case sensitive) will disable sending the ActivityId.
For more information, see Tracing driver operation. This trace flag is used with corresponding JDBC object
loggers to decide whether to trace and send the ActivityId in the JDBC driver. In addition to updating the
Logging.Properties file, enable the logger com.microsoft.sqlserver.jdbc at FINER or higher. To send ActivityId to
the server for requests that are made by a particular class, enable the corresponding class logger at FINER or
FINEST. For example, if the class is, SQLServerStatement, enable the logger
com.microsoft.sqlserver.jdbc.SQLServerStatement.
The following sample uses Transact-SQL to start an extended events session that is stored in a ring buffer and
records the activity ID sent from a client on RPC and batch operations:
See also
Diagnosing problems with the JDBC driver
Sample JDBC driver applications
4/27/2022 • 2 minutes to read • Edit Online
\<installation directory>\sqljdbc_<version>\<language>\samples
The articles in this section describe how to configure and run the sample applications, and include a discussion
of what the sample applications demonstrate.
In this section
A RT IC L E DESC RIP T IO N
Connecting and Retrieving Data These sample applications demonstrate how to connect to a
SQL Server database. They also demonstrate different ways
in which to retrieve data from a SQL Server database.
Working with Data Types (JDBC) These sample applications demonstrate how to use the JDBC
driver data type methods to work with data in a SQL Server
database.
Working with Result Sets These sample applications demonstrate how to use result
sets to process data contained in a SQL Server database.
Working with Large Data These sample applications demonstrate how to use adaptive
buffering to retrieve large-value data from a SQL Server
database without the overhead of server cursors.
SQL Data Discovery and Classification This sample application demonstrates how to retrieve Data
Discovery and Classification information contained in a SQL
Server database from a ResultSet object using JDBC Driver.
See also
Overview of the JDBC driver
Connecting and retrieving data
4/27/2022 • 2 minutes to read • Edit Online
NOTE
For a list of the connection properties supported by the JDBC driver, see Setting the connection properties.
The second method involves setting the connection properties by using setter methods of the
SQLServerDataSource class, and then calling the getConnection method to return a SQLServerConnection
object.
The topics in this section describe the different ways in which you can connect to a SQL Server database, and
they also demonstrate different techniques for retrieving data.
In this section
TO P IC DESC RIP T IO N
Connection URL Sample Describes how to use a connection URL to connect to SQL
Server and then use an SQL statement to retrieve data.
Data Source Sample Describes how to use a data source to connect to SQL
Server and then use a stored procedure to retrieve data.
See also
Sample JDBC driver applications
Connection URL sample
4/27/2022 • 2 minutes to read • Edit Online
\<installation directory>\sqljdbc_<version>\<language>\samples\connections
Requirements
To run this sample application, you must set the classpath to include the mssql-jdbc jar file. You'll also need
access to the sample database. For more information about how to set the classpath, see Using the JDBC Driver.
NOTE
The Microsoft JDBC Driver for SQL Server provides mssql-jdbc class library files to be used depending on your preferred
Java Runtime Environment (JRE) settings. For more information about which JAR file to choose, see System Requirements
for the JDBC Driver.
Example
In the following example, the sample code sets various connection properties in the connection URL, and then
calls the getConnection method of the DriverManager class to return a SQLServerConnection object.
Next, the sample code uses the createStatement method of the SQLServerConnection object to create a
SQLServerStatement object, and then the executeQuery method is called to execute the SQL statement.
Finally, the sample uses the SQLServerResultSet object returned from the executeQuery method to iterate
through the results returned by the SQL statement.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
// Iterate through the data in the result set and display it.
while (rs.next()) {
System.out.println(rs.getString("FirstName") + " " + rs.getString("LastName"));
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
}
}
See also
Connecting and retrieving data
Data source sample
4/27/2022 • 2 minutes to read • Edit Online
\<installation directory>\sqljdbc_<version>\<language>\samples\connections
Requirements
To run this sample application, you must set the classpath to include the mssql-jdbc jar file. You'll also need
access to the sample database. For more information about how to set the classpath, see Using the JDBC Driver.
NOTE
The Microsoft JDBC Driver for SQL Server provides mssql-jdbc class library files to be used depending on your preferred
Java Runtime Environment (JRE) settings. For more information about which JAR file to choose, see System Requirements
for the JDBC Driver.
Example
In the following example, the sample code sets various connection properties by using setter methods of the
SQLServerDataSource object, and then calls the getConnection method of the SQLServerDataSource object to
return a SQLServerConnection object.
Next, the sample code uses the prepareCall method of the SQLServerConnection object to create a
SQLServerCallableStatement object, and then the executeQuery method is called to execute the stored
procedure.
Finally, the sample uses the SQLServerResultSet object returned from the executeQuery method to iterate
through the results returned by the stored procedure.
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
// Create datasource.
SQLServerDataSource ds = new SQLServerDataSource();
ds.setUser("<user>");
ds.setPassword("<password>");
ds.setServerName("<server>");
ds.setPortNumber(<port>);
ds.setDatabaseName("AdventureWorks");
// Iterate through the data in the result set and display it.
while (rs.next()) {
System.out.println("EMPLOYEE: " + rs.getString("LastName") + ", " +
rs.getString("FirstName"));
System.out.println("MANAGER: " + rs.getString("ManagerLastName") + ", " +
rs.getString("ManagerFirstName"));
System.out.println();
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
}
}
See also
Connecting and retrieving data
Working with data types (JDBC)
4/27/2022 • 2 minutes to read • Edit Online
NOTE
For a detailed discussion of the SQL Server and JDBC driver data types, including their differences and how they are
converted to Java language data types, see Understanding the JDBC driver data types.
In order to work with SQL Server data types, the JDBC driver provides get<Type> and set<Type> methods for
the SQLServerPreparedStatement and SQLServerCallableStatement classes, and it provides get<Type> and
update<Type> methods for the SQLServerResultSet class. Which method you use depends on the type of data
that you are working with, and whether you are using result sets or queries.
The topics in this section describe how to use the JDBC driver data types to access SQL Server data in your Java
applications.
In this section
TO P IC DESC RIP T IO N
Basic data types sample Describes how to use result set getter methods to retrieve
basic SQL Server data type values, and how to use result set
update methods to update those values.
SQLXML data type sample Describes how to store an XML data in a relational database,
how to retrieve an XML data from a database, and how to
parse an XML data with the SQLXML Java data type.
Spatial data types sample Describes how to store and retrieve data with Spatial
Datatypes 'Geometry' and 'Geography' of SQL Server
database with Geometr y and Geography Java types
defined by Microsoft JDBC Driver.
See also
Sample JDBC driver applications
Basic data types sample
4/27/2022 • 3 minutes to read • Edit Online
\<installation directory>\sqljdbc_<version>\<language>\samples\datatypes
Requirements
To run this sample application, you must set the classpath to include the mssql-jdbc jar file. You'll also need
access to the sample database. For more information about how to set the classpath, see Using the JDBC Driver.
The sample will create the required table and insert sample data in the sample database:
NOTE
The Microsoft JDBC Driver for SQL Server provides mssql-jdbc class library files to be used depending on your preferred
Java Runtime Environment (JRE) settings. For more information about which JAR file to choose, see System Requirements
for the JDBC Driver.
Example
In the following example, the sample code makes a connection to the database, and then retrieves a single row
of data from the DataTypesTable test table. The custom displayRow method is then called to display all the data
in the result set using various get<Type> methods of the SQLServerResultSet class.
Next, the sample uses various update<Type> methods of the SQLServerResultSet class to update the data in the
result set, and then calls the updateRow method to persist that data back to the database.
Finally, the sample refreshes the data in the result set and then calls the custom displayRow method again to
display the data in the result set.
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import com.microsoft.sqlserver.jdbc.SQLServerResultSet;
import microsoft.sql.DateTimeOffset;
dropAndCreateTable(stmt);
insertOriginalData(con);
rs.updateRow();
// Get the updated data from the database and display it.
rs = stmt.executeQuery(SQL);
rs.next();
displayRow("UPDATED DATA", rs);
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
}
String sql = "create table " + tableName + " (" + "c1 int, " + "c2 char(20), " + "c3 varchar(20), "
+ "c4 bit, "
+ "c5 decimal(10,5), " + "c6 money, " + "c7 datetime, " + "c8 date, " + "c9 time(7), "
+ "c10 datetime2(7), " + "c11 datetimeoffset(7), " + "c12 sql_variant" + ");";
stmt.execute(sql);
}
See also
Working with data types (JDBC)
SQLXML data type sample
4/27/2022 • 7 minutes to read • Edit Online
IMPORTANT
In order to use the SAX parser API, you must import the standard SAX implementation from the javax.xml package.
The code file for this sample is named SqlXmlDataType.java, and it can be found in the following location:
\<installation directory>\sqljdbc_<version>\<language>\samples\datatypes
Requirements
To run this sample application, you must set the classpath to include the sqljdbc4.jar file. If the classpath is
missing an entry for sqljdbc4.jar, the sample application throws the "Class not found" exception. For more
information about how to set the classpath, see Using the JDBC Driver.
You also need access to the sample database to run this sample application.
Example
In the following example, the sample code makes a connection to the database and then calls the
createSampleTables method.
The createSampleTables method drops the test tables, TestTable1, and TestTable2, if they exist. Then, it inserts two
rows into TestTable1.
Also, the code sample includes the following three methods and one other class, which is named
ExampleContentHandler.
The ExampleContentHandler class implements a custom content handler, which defines methods for parser
events.
The showGetters method demonstrates how to parse the data in the SQLXML object by using the SAX,
ContentHandler, and XMLReader. First, the code sample creates an instance of a custom content handler, which is
ExampleContentHandler. Next, it creates and executes an SQL statement that returns a set of data from
TestTable1. Then, the code example gets a SAX parser and parses the XML data.
The showSetters method demonstrates how to set the xml column by using the SAX, ContentHandler, and
ResultSet. First, it creates an empty SQLXML object by using the createSQLXML method of the Connection class.
Then, it gets an instance of a content handler to write the data into the SQLXML object. Next, the code example
writes the data to TestTable1. Finally, the sample code iterates through the rows of data that are in the result set,
and uses the getSQLXML method to read the XML data.
The showTransformer method demonstrates how to get XML data from one table and insert that XML data into
another table by using the SAX and the Transformer. First, it retrieves the source SQLXML object from the
TestTable1. Then, it creates an empty destination SQLXML object by using the createSQLXML method of the
Connection class. Next, it updates the destination SQLXML object and writes the XML data to TestTable2. Finally,
the sample code iterates through the rows of data that are in the result set, and uses the getSQLXML method to
read the XML data in TestTable2.
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLXML;
import java.sql.Statement;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
rs.next();
rs.next();
// Get the value of the source SQLXML object from the database.
SQLXML xmlSource = rs.getSQLXML("Col3");
stmt.executeUpdate("if exists (select * from sys.objects where name = 'TestTable2')" + "drop table
TestTable2");
stmt.executeUpdate("insert into TestTable1" + " (Col2, Col3) values('A', '" + row1 + "')");
stmt.executeUpdate("insert into TestTable1" + " (Col2, Col3) values('B', '" + row2 + "')");
}
}
/**
* Handles output for XML elements for the test.
*/
class ExampleContentHandler implements ContentHandler {
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws
SAXException {
System.out.println("startElement method: localName => " + localName);
}
public void characters(char[] text, int start, int length) throws SAXException {
System.out.println("characters method");
}
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
System.out.println("endElement method: localName => " + localName);
}
public void ignorableWhitespace(char[] text, int start, int length) throws SAXException {
System.out.println("ignorableWhiteSpace method");
}
See also
Working with data types (JDBC)
Spatial data types sample
4/27/2022 • 2 minutes to read • Edit Online
\<installation directory>\sqljdbc_<version>\<language>\samples\datatypes
Requirements
To run this sample application, you must set the classpath to include the mssql-jdbc jar file. For more
information about how to set the classpath, see Using the JDBC Driver.
NOTE
The Microsoft JDBC Driver for SQL Server provides mssql-jdbc class library files to be used depending on your preferred
Java Runtime Environment (JRE) settings. For more information about which JAR file to choose, see System Requirements
for the JDBC Driver.
Example
In the following example, the sample code creates a table called SpatialDataTypesTable_JDBC_Sample that
contains 'Geometry' and 'Geography' columns.
The sample first creates 'Geometry' and 'Geography' objects from a Well-Known-Text (WKT) representing a
POINT. It uses a SQLServerPreparedStatement with a parameterized query to map the data to each column.
Finally, the sample inserts the data into the table, and retrieves it. The data is displayed in the form of WKT.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.Geography;
import com.microsoft.sqlserver.jdbc.Geometry;
import com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement;
import com.microsoft.sqlserver.jdbc.SQLServerResultSet;
See also
Working with JDBC data types
Working with result sets
4/27/2022 • 2 minutes to read • Edit Online
NOTE
For more information about managing result sets, including their sensitivity to changes, see Managing result sets with the
JDBC driver.
The topics in this section describe different ways that you can use a result set to manipulate the data contained
in a SQL Server database.
In this section
TO P IC DESC RIP T IO N
Retrieving result set data sample Describes how to use a result set to retrieve data from a SQL
Server database and display it.
Modifying result set data sample Describes how to use a result set to insert, retrieve, and
modify data in a SQL Server database.
Caching result set data sample Describes how to use a result set to retrieve large amounts
of data from a SQL Server database, and to control how that
data is cached on the client.
See also
Sample JDBC driver applications
Retrieving result set data sample
4/27/2022 • 2 minutes to read • Edit Online
\<installation directory>\sqljdbc_<version>\<language>\samples\resultsets
Requirements
To run this sample application, you must set the classpath to include the mssql-jdbc jar file. You'll also need
access to the sample database. For more information about how to set the classpath, see Using the JDBC Driver.
NOTE
The Microsoft JDBC Driver for SQL Server provides mssql-jdbc class library files to be used depending on your preferred
Java Runtime Environment (JRE) settings. For more information about which JAR file to choose, see System Requirements
for the JDBC Driver.
Example
In the following example, the sample code makes a connection to the sample database. Then, using an SQL
statement with the SQLServerStatement object, it runs the SQL statement and places the data that it returns into
a SQLServerResultSet object.
Next, the sample code calls the custom displayRow method to iterate through the rows of data that are in the
result set, and uses the getString method to display some of the data.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
String sql = "CREATE TABLE [Product_JDBC_Sample](" + "[ProductID] [int] IDENTITY(1,1) NOT NULL,"
+ "[Name] [varchar](30) NOT NULL," + "[ProductNumber] [nvarchar](25) NOT NULL,"
+ "[MakeFlag] [bit] NOT NULL," + "[FinishedGoodsFlag] [bit] NOT NULL," + "[Color] [nvarchar]
(15) NULL,"
+ "[SafetyStockLevel] [smallint] NOT NULL," + "[ReorderPoint] [smallint] NOT NULL,"
+ "[StandardCost] [money] NOT NULL," + "[ListPrice] [money] NOT NULL," + "[Size] [nvarchar]
(5) NULL,"
+ "[SizeUnitMeasureCode] [nchar](3) NULL," + "[WeightUnitMeasureCode] [nchar](3) NULL,"
+ "[Weight] [decimal](8, 2) NULL," + "[DaysToManufacture] [int] NOT NULL,"
+ "[ProductLine] [nchar](2) NULL," + "[Class] [nchar](2) NULL," + "[Style] [nchar](2) NULL,"
+ "[ProductSubcategoryID] [int] NULL," + "[ProductModelID] [int] NULL,"
+ "[SellStartDate] [datetime] NOT NULL," + "[SellEndDate] [datetime] NULL,"
+ "[DiscontinuedDate] [datetime] NULL," + "[rowguid] [uniqueidentifier] ROWGUIDCOL NOT
NULL,"
+ "[ModifiedDate] [datetime] NOT NULL,)";
stmt.execute(sql);
See also
Working with result sets
Modifying result set data sample
4/27/2022 • 2 minutes to read • Edit Online
\<installation directory>\sqljdbc_<version>\<language>\samples\resultsets
Requirements
To run this sample application, you must set the classpath to include the mssql-jdbc jar file. You'll also need
access to the sample database. For more information about how to set the classpath, see Using the JDBC Driver.
NOTE
The Microsoft JDBC Driver for SQL Server provides mssql-jdbc class library files to be used depending on your preferred
Java Runtime Environment (JRE) settings. For more information about which JAR file to choose, see System Requirements
for the JDBC Driver.
Example
The sample code makes a connection to the sample database. Then, using an SQL statement with the
SQLServerStatement object, it runs the SQL statement and places the data that it returns into an updatable
SQLServerResultSet object.
Next, the sample code uses the moveToInsertRow method to move the result set cursor to the insert row. It then
uses a series of updateString methods to insert data into the new row. After that, it calls the insertRow method
to persist the new row of data back to the database.
After inserting the new row of data, the sample code uses an SQL statement to retrieve the previously inserted
row. From there, it uses the combination of updateString and updateRow methods to update the row of data
and again persist it back to the database.
Finally, the sample code retrieves the previously updated row of data and then deletes it from the database
using the deleteRow method.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
See also
Working with result sets
Caching result set data sample
4/27/2022 • 3 minutes to read • Edit Online
NOTE
Limiting the number of rows cached on the client is different from limiting the total number of rows that a result set can
contain. To control the total number of rows that are contained in a result set, use the setMaxRows method of the
SQLServerStatement object, which is inherited by both the SQLServerPreparedStatement and SQLServerCallableStatement
objects.
To set a limit on the number of rows cached on the client, specify a cursor type that uses a server-side cursor
when creating Statement objects. For example, the JDBC driver provides the
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY cursor type, which is a fast forward-only, read-only server-side
cursor for use with SQL Server databases.
NOTE
An alternative to using the SQL Server specific cursor type is to use the selectMethod connection string property, setting
its value to "cursor". For more information about the cursor types supported by the JDBC driver, see Understanding
cursor types.
After you have run the query in the Statement object and the data is returned to the client as a result set, call
setFetchSize to control how much data is retrieved from the database at one time. For example, if you have a
table with 100 rows of data, and the fetch size is 10, only 10 rows of data are cached on the client at a time.
Although this setting can slow down the speed at which the data is processed, it uses less memory on the client.
This scenario is useful when you need to process large amounts of data without using too much memory.
The code file for this sample is named CacheResultSet.java, and it can be found in the following location:
\<installation directory>\sqljdbc_<version>\<language>\samples\resultsets
Requirements
To run this sample application, set the classpath to include the mssql-jdbc jar file. You also need access to the
sample database. For more information about how to set the classpath, see Using the JDBC Driver.
NOTE
The Microsoft JDBC Driver for SQL Server provides mssql-jdbc class library files to be used depending on your preferred
Java Runtime Environment (JRE) settings. For more information about which JAR file to choose, see System Requirements
for the JDBC Driver.
Example
In the following example, the sample code makes a connection to the sample database. Then it uses an SQL
statement with the SQLServerStatement object, specifies the server-side cursor type, and runs the SQL
statement. The data is returned in a SQLServerResultSet object.
Next, the sample code calls the custom timerTest method, passing as arguments the fetch size to use and the
result set. The timerTest method then sets the fetch size of the result set by using the setFetchSize method, sets
the start time of the test, and then iterates through the result set with a While loop. As soon as the While loop
is exited, the code sets the stop time of the test, and then displays the result of the test including the fetch size,
the number of rows processed, and the time it took to execute the test.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import com.microsoft.sqlserver.jdbc.SQLServerResultSet;
@SuppressWarnings("serial")
public static void main(String[] args) {
// Declare the variables for tracking the row count and elapsed time.
int rowCount = 0;
long startTime = 0;
long stopTime = 0;
long runTime = 0;
// Set the fetch size then iterate through the result set to
// cache the data locally.
rs.setFetchSize(fetchSize);
startTime = System.currentTimeMillis();
while (rs.next()) {
rowCount++;
}
stopTime = System.currentTimeMillis();
runTime = stopTime - startTime;
See also
Working with result sets
Working with large data
4/27/2022 • 2 minutes to read • Edit Online
In This Section
TO P IC DESC RIP T IO N
Reading large data sample Describes how to use a SQL statement to retrieve large-
value data.
Reading large data with stored procedures sample Describes how to retrieve a large CallableStatement OUT
parameter value.
Updating large data sample Describes how to update a large-value data in a database.
See also
Sample JDBC driver applications
Reading large data sample
4/27/2022 • 2 minutes to read • Edit Online
\<installation directory>\sqljdbc_<version>\<language>\samples\adaptive
Requirements
To run this sample application, you'll need access to the sample database. You must also set the classpath to
include the mssql-jdbc jar file. For more information about how to set the classpath, see Using the JDBC Driver.
NOTE
The Microsoft JDBC Driver for SQL Server provides mssql-jdbc class library files to be used depending on your preferred
Java Runtime Environment (JRE) settings. For more information about which JAR file to choose, see System Requirements
for the JDBC Driver.
Example
In the following example, the sample code makes a connection to the database. Next, the sample code creates
sample data and updates the Production.Document table by using a parameterized query.
In addition, the sample code demonstrates how to get the adaptive buffering mode by using the
getResponseBuffering method of the SQLServerStatement class. Note that starting with the JDBC driver version
2.0 release, the responseBuffering connection property is set to "adaptive" by default.
Then, using an SQL statement with the SQLServerStatement object, the sample code runs the SQL statement
and places the data that it returns into a SQLServerResultSet object.
Finally, the sample code iterates through the rows of data that are in the result set, and uses the
getCharacterStream method to access some of the data.
import java.io.IOException;
import java.io.Reader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerStatement;
pstmt.setString(1, buffer.toString());
pstmt.executeUpdate();
// In adaptive mode, the application does not have to use a server cursor
// to avoid OutOfMemoryError when the SELECT statement produces very large
// results.
// Get the updated data from the database and display it.
ResultSet rs = stmt.executeQuery(SQL);
while (rs.next()) {
Reader reader = rs.getCharacterStream(2);
if (reader != null) {
char output[] = new char[40];
while (reader.read(output) != -1) {
// Do something with the chunk of the data that was
// read.
}
See also
Working with large data
Reading large data with stored procedures sample
4/27/2022 • 3 minutes to read • Edit Online
\<installation directory>\sqljdbc_<version>\<language>\samples\adaptive
Requirements
To run this sample application, you'll need access to the sample database. Set the classpath to include the mssql-
jdbc jar file. For more information about how to set the classpath, see Using the JDBC Driver.
NOTE
The Microsoft JDBC Driver for SQL Server provides mssql-jdbc class library files to be used depending on your preferred
Java Runtime Environment (JRE) settings. For more information about which JAR file to choose, see System Requirements
for the JDBC Driver.
The sample would create the required stored procedure in the sample database:
Example
This sample code:
1. Makes a connection to the database.
2. Creates sample data and updates the Production.Document table by using a parameterized query. Finally, the
sample code gets the adaptive buffering mode by using the getResponseBuffering method of the
SQLServerStatement class and executes the GetLargeDataValue stored procedure. Starting with the JDBC
driver version 2.0 release, the responseBuffering connection property is set to "adaptive" by default.
Finally, the sample code displays the data returned with the OUT parameters and also demonstrates how to use
the mark and reset methods on the stream to re-read any portion of the data.
import java.io.Reader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerCallableStatement;
createTable(stmt);
createStoredProcedure(stmt);
pstmt.setString(1, buffer.toString());
pstmt.executeUpdate();
}
cstmt.setInt(1, 1);
cstmt.registerOutParameter(2, java.sql.Types.INTEGER);
cstmt.registerOutParameter(3, java.sql.Types.CHAR);
cstmt.registerOutParameter(4, java.sql.Types.LONGVARCHAR);
cstmt.execute();
System.out.println("DocumentID: " + cstmt.getInt(2));
System.out.println("Document_Title: " + cstmt.getString(3));
String sql = " IF EXISTS (select * from sysobjects where id = object_id(N'" + outputProcedure
+ "') and OBJECTPROPERTY(id, N'IsProcedure') = 1)" + " DROP PROCEDURE " + outputProcedure;
stmt.execute(sql);
sql = "CREATE PROCEDURE " + outputProcedure + " @p0 int, @p1 int OUTPUT, @p2 char(50) OUTPUT, "
+ "@p3 varchar(max) OUTPUT " + " AS" + " SELECT top 1 @p1=DocumentID, @p2=Title,"
+ " @p3=DocumentSummary FROM Document_JDBC_Sample where DocumentID = @p0";
stmt.execute(sql);
}
String sql = "CREATE TABLE Document_JDBC_Sample(" + "[DocumentID] [int] NOT NULL identity,"
+ "[Title] [char](50) NOT NULL," + "[DocumentSummary] [varchar](max) NULL)";
stmt.execute(sql);
See also
Working with large data
Updating Large Data Sample
4/27/2022 • 3 minutes to read • Edit Online
\<installation directory>\sqljdbc_<version>\<language>\samples\adaptive
Requirements
To run this sample application, you'll need access to the sample database. You must also set the classpath to
include the sqljdbc4.jar file. If the classpath is missing an entry for sqljdbc4.jar, the sample application will throw
the common "Class not found" exception. For more information about how to set the classpath, see Using the
JDBC Driver.
NOTE
The Microsoft JDBC Driver for SQL Server provides sqljdbc.jar, sqljdbc4.jar, sqljdbc41.jar, or sqljdbc42.jar class library files
to be used depending on your preferred Java Runtime Environment (JRE) settings. This sample uses the isWrapperFor and
unwrap methods, which are introduced in the JDBC 4.0 API, to access the driver-specific response buffering methods. In
order to compile and run this sample, you will need sqljdbc4.jar class library, which provides support for JDBC 4.0. For
more information about which JAR file to choose, see System Requirements for the JDBC Driver.
Example
In the following example, the sample code makes a connection to the database. Then, the sample code creates a
Statement object and uses the isWrapperFor method to check whether the Statement object is a wrapper for the
specified SQLServerStatement class. The unwrap method is used to access the driver-specific response buffering
methods.
Next, the sample code sets the response buffering mode as "adaptive " by using the setResponseBuffering
method of the SQLServerStatement class and also demonstrates how to get the adaptive buffering mode.
Then, it runs the SQL statement, and places the data that it returns into an updateable SQLServerResultSet
object.
Finally, the sample code iterates through the rows of data that are in the result set. If it finds an empty document
summary, it uses the combination of updateString and updateRow methods to update the row of data and again
persist it to the database. If there's already data, it uses the getString method to display some of the data.
The default behavior of the driver is "adaptive." However, for the forward-only updatable result sets and when
the data in the result set is larger than the application memory, the application has to set the adaptive buffering
mode explicitly by using the setResponseBuffering method of the SQLServerStatement class.
import java.io.Reader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerStatement;
createTable(stmt);
// The recommended way to access the Microsoft JDBC Driver for SQL Server
// specific methods is to use the JDBC 4.0 Wrapper functionality.
// The following code statement demonstrates how to use the
// Statement.isWrapperFor and Statement.unwrap methods
// to access the driver specific response buffering methods.
if (stmt.isWrapperFor(com.microsoft.sqlserver.jdbc.SQLServerStatement.class)) {
SQLServerStatement SQLstmt =
stmt.unwrap(com.microsoft.sqlserver.jdbc.SQLServerStatement.class);
SQLstmt.setResponseBuffering("adaptive");
System.out.println("Response buffering mode has been set to " +
SQLstmt.getResponseBuffering());
}
if (reader == null) {
// Update the document summary.
System.out.println("Updating " + rs.getString("Title"));
rs.updateString("DocumentSummary", "Work in progress");
rs.updateRow();
}
}
}
}
}
// Handle any errors that may have occurred.
catch (Exception e) {
e.printStackTrace();
}
}
String sql = "CREATE TABLE Document_JDBC_Sample (" + "[DocumentID] [int] NOT NULL identity,"
+ "[Title] [char](50) NOT NULL," + "[DocumentSummary] [varchar](max) NULL)";
stmt.execute(sql);
See also
Working with Large Data
SQL Data Discovery and Classification JDBC
Sample
4/27/2022 • 3 minutes to read • Edit Online
\<installation directory>\sqljdbc_<version>\<language>\samples\dataclassification
Requirements
To run this sample application, you must set the classpath to include the mssql-jdbc jar file. You'll also need
access to the sample database. For more information about how to set the classpath, see Using the JDBC Driver.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerResultSet;
import com.microsoft.sqlserver.jdbc.dataclassification.SensitivityProperty;
/**
/**
* Verifies if SQL Discovery and Classification feature is applicable on target server.
*
* @param stmt
* Statement object to work with
*/
private static void verifySupportability(Statement stmt) {
try {
stmt.execute("SELECT * FROM SYS.SENSITIVITY_CLASSIFICATIONS");
featureSupported = true;
} catch (SQLException e) {
// Error Code 208 : Object Not Found
if (e.getErrorCode() == 208) {
featureSupported = false;
System.err.println("This feature is not supported on the target SQL Server.");
}
}
}
/**
* Creates table for the test and sets tags for Sensitivity Classification
*
* @param stmt
* Statement to work with
* @param tableName
* Table to be created
* @throws SQLException
* If an exception occurs
*/
private static void createTable(Statement stmt, String tableName) throws SQLException {
// Creates table for storing Supplier data
stmt.execute("CREATE TABLE " + tableName + " (" + "[Id] [int] IDENTITY(1,1) NOT NULL,"
+ "[CompanyName] [nvarchar](40) NOT NULL," + "[ContactName] [nvarchar](50) NULL,"
+ "[ContactTitle] [nvarchar](40) NULL," + "[City] [nvarchar](40) NULL,"
+ "[Country] [nvarchar](40) NULL," + "[Phone] [nvarchar](30) MASKED WITH (FUNCTION =
'default()') NULL,"
+ "[Fax] [nvarchar](30) MASKED WITH (FUNCTION = 'default()') NULL," + "CONSTRAINT [PK_" +
tableName
+ "] PRIMARY KEY CLUSTERED" + "([Id] ASC "
+ ")WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]" + ") ON
[PRIMARY]");
/**
* Runs query to fetch ResultSet from target table
*
* @param stmt
* Statement to work with
* @param tableName
* Name of table to fetch results from
* @throws SQLException
* If an exception occurs
*/
private static void runTests(Statement stmt, String tableName) throws SQLException {
String query = "SELECT * FROM " + tableName;
try (SQLServerResultSet rs = (SQLServerResultSet) stmt.executeQuery(query)) {
try (SQLServerResultSet rs = (SQLServerResultSet) stmt.executeQuery(query)) {
printSensitivityClassification(rs);
}
}
/**
* Prints Sensitivity Classification data as received in ResultSet
*
* @param rs
* Active ResultSet to read data from
* @throws SQLException
* If an exception occurs
*/
private static void printSensitivityClassification(SQLServerResultSet rs) throws SQLException {
if (null != rs.getSensitivityClassification()) {
for (int columnPos = 0; columnPos <
rs.getSensitivityClassification().getColumnSensitivities().size();
columnPos++) {
for (SensitivityProperty sp :
rs.getSensitivityClassification().getColumnSensitivities().get(columnPos)
.getSensitivityProperties()) {
if (sp.getLabel() != null) {
System.out.println("Labels received for Column : " + columnPos);
System.out.println("Label ID: " + sp.getLabel().getId());
System.out.println("Label Name: " + sp.getLabel().getName());
System.out.println();
}
if (sp.getInformationType() != null) {
System.out.println("Information Types received for Column : " + columnPos);
System.out.println("Information Type ID: " + sp.getInformationType().getId());
System.out.println("Information Type Name: " + sp.getInformationType().getName());
System.out.println();
}
/**
* Drops the table created for test
*
* @param stmt
* Statement to work with
* @param tableName
* Table Name to be used
* @throws SQLException
* If an exception occurs
*/
private static void drop_table(Statement stmt, String tableName) throws SQLException {
stmt.execute("DROP TABLE " + tableName);
}
}
See also
Sample JDBC driver applications
JDBC specification compliance
4/27/2022 • 2 minutes to read • Edit Online
NOTE
Versions prior to Microsoft JDBC Driver 4.2 for SQL Server are compliant for Java Database Connectivity API 4.0
specifications. This section does not apply for versions prior to the 4.2 release.
The Java Database Connectivity API 4.1 specification is supported by the Microsoft JDBC Driver 4.2 for SQL
Server, with the following API methods.
SQLServerConnection class
N EW M ET H O D DESC RIP T IO N JDB C DRIVER IM P L EM EN TAT IO N
void abort(Executor executor) Terminates an open connection to SQL Implemented as described in the
Server. java.sql.Connection interface. For more
information, see java.sql.Connection.
void setSchema(String schema) Sets schema for the current SQL Server doesn't support setting
connection. schema for the current session. The
driver silently logs a warning message
if this method is called. For more
information, see java.sql.Connection.
String getSchema() Returns the schema name for the Since SQL Server doesn't support
current connection. setting schema for the current
connection, the driver instead returns
the default schema of the user. For
more information, see
java.sql.Connection.
SQLServerDatabaseMetaData class
N EW M ET H O D DESC RIP T IO N JDB C DRIVER IM P L EM EN TAT IO N
ResultSet getPseudoColumns(String Retrieves a description of the Return an empty result set as SQL
catalog, String schemaPattern, String pseudo/hidden columns Server doesn't have a formal notion of
tableNamePattern, String pseudo-columns. For more
columnNamePattern) information, see
java.sql.DatabaseMetaData.
SQLServerStatement class
N EW M ET H O D DESC RIP T IO N JDB C DRIVER IM P L EM EN TAT IO N
void closeOnCompletion() Specifies that this Statement will be Implemented as described in the
closed when all its dependent result java.sql.Statement interface. For more
sets are closed. information, see java.sql.Statement.
boolean isCloseOnCompletion() Returns a value indicating whether this Implemented as described in the
Statement will be closed when all its java.sql.Statement interface. For more
dependent result sets are closed. information, see java.sql.Statement.
The Java Database Connectivity API 4.1 specification is supported by the Microsoft JDBC Driver 4.2 for SQL
Server, with the following features.
Limited Return Rows Escape Escape syntax: LIMIT <rows> OFFSET <row_offset>.
The Java Database Connectivity API 4.1 specification is supported by the Microsoft JDBC Driver 4.2 for SQL
Server, with the following Data Type Mappings.
New data type mappings are now supported in 1. New Java to JDBC type mapping
PreparedStatement.setObject() and
PreparedStatement.setNull() methods. (a) java.math.BigInteger to JDBC BIGINT
NOTE
Versions prior to Microsoft JDBC Driver 4.2 for SQL Server are compliant for Java Database Connectivity API 4.0
specifications. This section does not apply for versions prior to the 4.2 release.
The Java Database Connectivity API 4.2 specification is supported by the Microsoft JDBC Driver 4.2 for SQL
Server, with the following API methods.
SQLServerStatement class
N EW M ET H O DS DESC RIP T IO N N OT EW O RT H Y IM P L EM EN TAT IO N
long[] executeLargeBatch() Executes batch where returned update Implemented as described in the
counts can be long. java.sql.Statement interface. For more
information, see java.sql.Statement.
long executeLargeUpdate(String sql) Executes a DML/DDL statement where Implemented as described in the
returned update counts can be long. java.sql.Statement interface. For more
long executeLargeUpdate(String sql, There are 4 new (overloaded) methods information, see java.sql.Statement.
int autoGeneratedKeys) to support long update count.
long getLargeMaxRows() Retrieves the maximum number of SQL Server only supports integer
rows as a long value that the ResultSet limits for max rows. For more
can contain. information, see java.sql.Statement.
long getLargeUpdateCount() Retrieves the current result as a long SQL Server only supports integer
update count. limits for max rows. For more
information, see java.sql.Statement.
void setLargeMaxRows(long max) Sets the maximum number of rows as SQL Server only supports integer
a long value that the ResultSet can limits for max rows. This method
contain. throws a not supported exception if
greater than max integer size is passed
as the parameter. For more
information, see java.sql.Statement.
SQLServerCallableStatement class
N EW M ET H O DS DESC RIP T IO N N OT EW O RT H Y IM P L EM EN TAT IO N
void registerOutParameter(int Registers the OUT parameter. There are Implemented as described in the
parameterIndex, SQLType sqlType) 6 new (overloaded) methods to java.sql.CallableStatement interface. For
support the new SQLType interface. more information, see
void registerOutParameter(int java.sql.CallableStatement.
parameterIndex, SQLType sqlType, int
scale)
void registerOutParameter(int
parameterIndex, SQLType sqlType,
String typeName)
void registerOutParameter(String
parameterName, SQLType sqlType)
void registerOutParameter(String
parameterName, SQLType sqlType, int
scale)
registerOutParameter(String
parameterName, SQLType sqlType,
String typeName)
void setObject(String parameterName, Sets the value of the parameter with Implemented as described in the
Object x, SQLType targetSqlType) the given object. There are 2 new java.sql.CallableStatement interface. For
(overloaded) methods to support the more information, see
void setObject(String parameterName, new SQLType interface java.sql.CallableStatement.
Object x, SQLType targetSqlType, int
scaleOrLength)
SQLServerPreparedStatement class
N EW M ET H O DS DESC RIP T IO N N OT EW O RT H Y IM P L EM EN TAT IO N
void setObject(int parameterIndex, Sets the value of the parameter with Implemented as described in the
Object x, SQLType targetSqlType) the given object. There are 2 new java.sql.PreparedStatement interface.
(overloaded) methods to support the For more information, see
void setObject(int parameterIndex, new SQLType interface. java.sql.PreparedStatement.
Object x, SQLType targetSqlType, int
scaleOrLength)
SQLServerDatabaseMetaData class
N EW M ET H O DS DESC RIP T IO N N OT EW O RT H Y IM P L EM EN TAT IO N
long getMaxLogicalLobSize() Retrieves the maximum number of For SQL Server, this value is 2^31-1.
bytes this database allows for the For more information, see
logical size for a LOB. java.sql.DatabaseMetaData.
N EW M ET H O DS DESC RIP T IO N N OT EW O RT H Y IM P L EM EN TAT IO N
boolean supportsRefCursors() Retrieves whether this database Returns false as SQL Server doesn't
supports REF CURSOR. support REF CURSOR. For more
information, see
java.sql.DatabaseMetaData.
SQLServerResultSet class
N EW M ET H O DS DESC RIP T IO N N OT EW O RT H Y IM P L EM EN TAT IO N
The Java Database Connectivity API 4.2 specification is supported by the Microsoft JDBC Driver 4.2 for SQL
Server, with the following Data Type Mappings.
New Java classes in Java 8: REF_CURSOR isn't supported in SQL Server. Driver throws a
SQLFeatureNotSupportedException exception if this type is
LocalDate/LocalTime/LocalDateTime used. The driver supports all other new Java and JDBC type
mappings as specified in the JDBC 4.2 specification.
OffsetTime/OffsetDateTime
TIME_WITH_TIMEZONE
TIMESTAMP_WITH_TIMEZONE
REF_CURSOR
JDBC 4.3 compliance for the JDBC driver
4/27/2022 • 2 minutes to read • Edit Online
NOTE
Versions prior to Microsoft JDBC Driver 6.4 for SQL Server are only compliant for Java Database Connectivity (JDBC) API
4.2 specifications. This section does not apply for versions including and prior to the 6.4 release.
As of version 6.4, Microsoft JDBC Driver for SQL Server is JAVA 9 compatible and throws
SQLFeatureNotSupportedException for new JDBC 4.3 APIs that have unimplemented methods.
With Microsoft JDBC Driver 7.0 for SQL Server release, the driver is now JAVA 10 compatible, and supports
below mentioned APIs. The driver throws SQLFeatureNotSupportedException for other unimplemented methods
from JDBC 4.3 Specifications.
void java.sql.connection.beginRequest() Hints to the driver that a request, an Saves the values of the connection
independent unit of work, is beginning fields that are modifiable through
on this connection. For more details, public API methods:
see java.sql.Connection. databaseAutoCommitMode ,
transactionIsolationLevel ,
networkTimeout , holdability ,
sendTimeAsDatetime ,
statementPoolingCacheSize ,
disableStatementPooling ,
serverPreparedStatementDiscardThreshold
,
enablePrepareOnFirstPreparedStatementCall
, catalogName , sqlWarnings ,
useBulkCopyForBatchInsert .
void java.sql.connection.endRequest() Hints to the driver that a request, an Closes the statements that are created
independent unit of work, has during the work unit and rolls back
completed. For more details, see any open transactions. The method
java.sql.Connection. also reverts the changes to the
connection fields that are listed above.
Programming guide for JDBC SQL driver
4/27/2022 • 2 minutes to read • Edit Online
System.setProperty("java.net.preferIPv6Addresses", "true");
The articles in this section describe how to make and work with a connection to a SQL Server database.
In this section
A RT IC L E DESC RIP T IO N
Building the connection URL Describes how to form a connection URL for connecting to a
SQL Server database. Also describes connecting to named
instances of a SQL Server database.
Setting the connection properties Describes the various connection properties and how they
can be used when you connect to a SQL Server database.
Setting the data source Properties Describes how to use data sources in a Java Platform,
Enterprise Edition (Java EE) environment.
Working with a connection Describes the various ways in which to create an instance of
a connection to a SQL Server database.
Using connection pooling Describes how the JDBC driver supports the use of
connection pooling.
Using database mirroring (JDBC) Describes how the JDBC driver supports the use of database
mirroring.
JDBC driver support for High Availability, disaster recovery Describes how to develop an application that will connect to
an AlwaysOn availability group.
Using Kerberos Integrated Authentication to Connect to Discusses a Java implementation for applications to connect
SQL Server to a SQL Server database using Kerberos integrated
authentication.
Connecting to an Azure SQL database Discusses connectivity issues for databases on Azure SQL.
See also
Overview of the JDBC driver
Understanding the JDBC driver data types
4/27/2022 • 2 minutes to read • Edit Online
In this section
TO P IC DESC RIP T IO N
Using basic data types Describes the JDBC basic data types. Includes examples of
how to work with the data types by using result sets,
parameterized queries, and stored procedures.
Configuring how java.sql.Time values are sent to the server Describes how the JDBC Driver generates dates.
Using advanced data types Describes the JDBC advanced data types.
Understanding data type differences Describes differences between the various JDBC driver data
types.
Understanding data type conversions Describes how data type conversion is handled when using
getter and setter methods.
National character set support Describes the support for the national character set types.
Supporting XML data Describes the SQLXML interface. Also describes how to read
and write an XML data from and to the relational database
with the SQLXML Java data type.
Wrappers and interfaces Discusses the interfaces that have the Microsoft JDBC Driver
for SQL Server specific methods and constants that allow an
application server to create a proxy of the class, Also
discusses supports for the java.sql.Wrapper interface.
See also
Overview of the JDBC driver
Using statements with the JDBC driver
4/27/2022 • 2 minutes to read • Edit Online
In this section
TO P IC DESC RIP T IO N
Using statements with SQL Describes how to use SQL statements with the JDBC driver
to work with data in a SQL Server database.
Using statements with stored procedures Describes how to use stored procedures with the JDBC
driver to work with data in a SQL Server database.
Using multiple result sets Describes how to use the JDBC driver to retrieve data from
multiple result sets.
Using SQL escape sequences Describes how to use SQL escape sequences, such as date
and time literals and functions.
Using auto generated keys Describes how to use automatically generated keys.
Performing batch operations Describes how to use the JDBC driver to perform batch
operations.
Handling complex statements Describes how to use the JDBC driver to run complex
statements that perform a variety of tasks and might return
different types of data.
See also
Overview of the JDBC driver
Managing result sets with the JDBC driver
4/27/2022 • 2 minutes to read • Edit Online
while (rs.next()) {
System.out.println(rs.getString("FirstName") + " " + rs.getString("LastName"));
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
}
The articles in this section describe various aspects of result set usage, including cursor types, concurrency, and
row locking.
In this section
A RT IC L E DESC RIP T IO N
Understanding cursor types Describes the different cursor types that the Microsoft JDBC
Driver for SQL Server supports.
Understanding concurrency control Describes how the JDBC driver supports concurrency
control.
Understanding row locking Describes how the JDBC driver supports row locking.
See also
Overview of the JDBC driver
Performing transactions with the JDBC driver
4/27/2022 • 2 minutes to read • Edit Online
In this section
A RT IC L E DESC RIP T IO N
Understanding transactions Provides an overview of how transactions are used with the
JDBC driver.
Understanding isolation levels Describes the various isolation levels that are supported by
the JDBC driver.
Using savepoints Describes how to use the JDBC driver with transaction
savepoints.
Using holdability Describes how to use the JDBC driver with result set
holdability.
See also
Overview of the JDBC driver
Handling metadata with the JDBC driver
4/27/2022 • 2 minutes to read • Edit Online
NOTE
The metadata methods discussed in this section are generally expensive in terms of application performance, so care
should be taken with their usage.
In this section
A RT IC L E DESC RIP T IO N
Using database metadata Describes how to retrieve metadata information about the
currently connected database.
Using result set metadata Describes how to retrieve metadata information about the
current result set.
Using parameter metadata Describes how to retrieve metadata information about the
parameters of prepared and callable statements.
See also
Overview of the JDBC driver
Use Always Encrypted with the JDBC driver
4/27/2022 • 40 minutes to read • Edit Online
Prerequisites
Make sure Microsoft JDBC Driver 6.0 (or higher) for SQL Server is installed on your development machine.
Download and install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. Be
sure to read the Readme included in the zip file for installation instructions, and relevant details on possible
export or import issues.
For mssql-jdbc-X.X.X.jre7.jar or sqljdbc41.jar, the policy files can be downloaded from Java
Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7 Download
For mssql-jdbc-X.X.X.jre8.jar or sqljdbc42.jar, the policy files can be downloaded from Java
Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 Download
For mssql-jdbc-X.X.X.jre9.jar, no policy file needs to be downloaded. The jurisdiction policy in Java 9
defaults to unlimited strength encryption.
P RO VIDER ( LO O K UP )
C L A SS DESC RIP T IO N NAME IS P RE- REGIST ERED? P L AT F O RM
For the pre-registered keystore providers, you don't need any application code changes to use these providers
but note the following items:
You must make sure the provider name that's configured in the column master key metadata is correct and
the column master key path follows the key path format that is valid for a given provider. It's recommended
that you configure the keys with tools such as SQL Server Management Studio, which automatically
generates the valid provider names and key paths to issue the CREATE COLUMN MASTER KEY (Transact-SQL)
statement.
Ensure your application can access the key in the keystore. This task might involve granting your application
access to the key and/or the keystore. Depending on the keystore, this might involve other keystore-specific
configuration steps. For example, to use the SQLServerColumnEncryptionJavaKeyStoreProvider , you must
provide the location and the password of the keystore in the connection properties.
All of these keystore providers are described in more detail in the sections that follow. You only need to
implement one keystore provider to use Always Encrypted.
Use Azure Key Vault provider
Azure Key Vault is a convenient option to store and manage column master keys for Always Encrypted
(especially if your application is hosted in Azure). The Microsoft JDBC Driver for SQL Server includes a built-in
provider, SQLServerColumnEncryptionAzureKeyVaultProvider , for applications that have keys stored in Azure Key
Vault. The name of this provider is AZURE_KEY_VAULT.
NOTE
The Azure Key Vault provider built in to the JDBC driver supports both Vaults and Managed HSMs in Azure Key Vault.
To use the Azure Key Vault store provider, an application developer must create the vault and the keys in Azure
Key Vault and create an App registration in Azure Active Directory. The registered application must be granted
Get, Decrypt, Encrypt, Unwrap Key, Wrap Key, and Verify permissions in the Access policies defined for the key
vault created for use with Always Encrypted. For more information on how to set up the key vault and create a
column master key, see Azure Key Vault—Step by Step and Creating Column Master Keys in Azure Key Vault.
For Azure Key Vault provider, the JDBC driver validates the column master key path against the list of trusted
endpoints. As of version 8.2.2, this list is configurable: create a mssql-jdbc.properties file in the working
directory of the application, set the AKVTrustedEndpoints property to a semicolon-delimited list. If the value
begins with a semicolon, it extends the default list. Otherwise, it replaces the default list.
The default, trusted endpoints are:
*vault.azure.net
*vault.azure.cn
*vault.usgovcloudapi.net
*vault.microsoftazure.de
*managedhsm.azure.net (v9.2+)
*managedhsm.azure.cn (v9.2+)
*managedhsm.usgovcloudapi.net (v9.2+)
*managedhsm.microsoftazure.de (v9.2+)
For the examples on this page, if you've created an Azure Key Vault based column master key and column
encryption key with SQL Server Management Studio, the T-SQL script to re-create them might look similar to
this example with its own specific KEY_PATH and ENCRYPTED_VALUE :
An application that uses the JDBC driver can use the Azure Key Vault. The syntax or statements for this use of
Azure Key Vault changed as of with JDBC driver version 7.4.1.
JDBC driver 7.4.1 or later
This section involves JDBC driver version 7.4.1 or later.
A client application that uses the JDBC driver can configure to use Azure Key Vault by mentioning
keyVaultProviderClientId=<ClientId>;keyVaultProviderClientKey=<ClientKey> in JDBC connection string.
Here's an example that provides this configuration information in a JDBC connection string.
IMPORTANT
The connection properties keyVaultProviderClientId and keyVaultProviderClientKey have been deprecated as of
v8.4.1. Users are encouraged to use keyStoreAuthentication , KeyStorePrincipalId , and KeyStoreSecret instead.
clientID is the Application ID of an App registration in an Azure Active Directory instance. clientKey is a Key
Password registered under that Application, which provides API access to the Azure Key Vault.
After the application creates an instance of SQLServerColumnEncryptionAzureKeyVaultProvider , the application
must register the instance with the driver with the
SQLServerConnection.registerColumnEncryptionKeyStoreProviders() method. It's highly recommended that the
instance is registered using the default lookup name, AZURE_KEY_VAULT, which can be obtained by the
SQLServerColumnEncryptionAzureKeyVaultProvider.getName() API. The default name allows you to use tools such as
SQL Server Management Studio or PowerShell to provision and manage Always Encrypted keys (the tools use
the default name to generate the metadata object to column master key). The following example shows
registering the Azure Key Vault provider. For more information on the
SQLServerConnection.registerColumnEncryptionKeyStoreProviders() method, see Always Encrypted API Reference
for the JDBC Driver.
IMPORTANT
If you use the Azure Key Vault keystore provider, the Azure Key Vault implementation of the JDBC driver has
dependencies on these libraries (from GitHub) which must be included with your application:
azure-sdk-for-java
microsoft-authentication-library-for-java libraries
For an example of how to include these dependencies in a Maven project, see Download MSAL4J And AKV Dependencies
with Apache Maven
"jdbc:sqlserver://<server>:
<port>;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultManagedIdentity;"
"jdbc:sqlserver://<server>:
<port>;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultManagedIdentity;keyStorePrincipal=
<principalId>"
"jdbc:sqlserver://<server>:
<port>;columnEncryptionSetting=Enabled;keyStoreAuthentication=KeyVaultClientSecret;keyStorePrincipalId=
<clientId>;keyStoreSecret=<clientSecret>"
Users are encouraged to use these connection properties to specify the type of authentication used for the Key
Stores instead of the SQLServerColumnEncryptionAzureKeyVaultProvider API.
Previously added connection properties keyVaultProviderClientId and keyVaultProviderClientKey are
deprecated and replaced by the connection properties described above.
For information on how to configure Managed Identities, see Configure managed identities for Azure resources
on a VM using the Azure portal.
Use Windows Certificate Store provider
The SQLServerColumnEncryptionCertificateStoreProvider can be used to store column master keys in the
Windows Certificate Store. Use the SQL Server Management Studio (SSMS) Always Encrypted wizard or other
supported tools to create the column master key and column encryption key definitions in the database. The
same wizard can be used to generate a self-signed certificate in the Windows Certificate Store that can be used
as a column master key for the Always Encrypted data. For more information on column master key and column
encryption key T-SQL syntax, see CREATE COLUMN MASTER KEY and CREATE COLUMN ENCRYPTION KEY
respectively.
The name of the SQLServerColumnEncryptionCertificateStoreProvider is MSSQL_CERTIFICATE_STORE and can be
queried by the getName() API of the provider object. It's automatically registered by the driver and can be used
seamlessly without any application change.
For the examples on this page, if you've created a Windows Certificate Store based column master key and
column encryption key with SQL Server Management Studio, the T-SQL script to re-create them might look
similar to this example with its own specific KEY_PATH and ENCRYPTED_VALUE :
CREATE COLUMN MASTER KEY [MyCMK]
WITH
(
KEY_STORE_PROVIDER_NAME = N'MSSQL_CERTIFICATE_STORE',
KEY_PATH = N'CurrentUser/My/A2A91F59C461B559E4D962DA9D2BC6131B32CB91'
);
IMPORTANT
While the other keystore providers in this article are available on all platforms supported by the driver, the
SQLServerColumnEncryptionCertificateStoreProvider implementation of the JDBC driver is available on Windows
operating systems only. It has a dependency on the mssql-jdbc_auth-<version>-<arch>.dll that is available in the
driver package. To use this provider, copy the mssql-jdbc_auth-<version>-<arch>.dll file to a directory on the
Windows system path on the computer where the JDBC driver is installed. Alternatively you can set the java.library.path
system property to specify the directory of the mssql-jdbc_auth-<version>-<arch>.dll . If you are running a 32-bit
Java Virtual Machine (JVM), use the mssql-jdbc_auth-<version>-x86.dll file in the x86 folder, even if the operating
system is the x64 version. If you are running a 64-bit JVM on a x64 processor, use the
mssql-jdbc_auth-<version>-x64.dll file in the x64 folder. For example, if you use the 32-bit JVM and the JDBC driver
is installed in the default directory, you can specify the location of the DLL with the following virtual machine (VM)
argument when the Java application is started:
-Djava.library.path=C:\Microsoft JDBC Driver <version> for SQL Server\sqljdbc_<version>\enu\auth\x86
There are three connection string properties that allow a client application to specify the credentials the driver
needs to authenticate to the Java Key Store. The driver initializes the provider based on the values of these three
properties in the connection string.
keyStoreAuthentication : Identifies the Java Key Store to use. With Microsoft JDBC Driver 6.0 and higher for SQL
Server, you can authenticate to the Java Key Store only through this property. For the Java Key Store, the value
for this property must be JavaKeyStorePassword .
keyStoreLocation : The path to the Java Key Store file that stores the column master key. The path includes the
keystore filename.
keyStoreSecret : The secret/password to use for the keystore and the key. To use the Java Key Store, the keystore
and the key password must be the same.
Here's an example of providing these credentials in the connection string:
String connectionUrl = "jdbc:sqlserver://<server>:<port>;user=<user>;password=
<password>;columnEncryptionSetting=Enabled;keyStoreAuthentication=JavaKeyStorePassword;keyStoreLocation=
<path_to_the_keystore_file>;keyStoreSecret=<keystore_key_password>";
You can also get or set these settings with the SQLServerDataSource object. For more information, see Always
Encrypted API Reference for the JDBC Driver.
The JDBC driver automatically instantiates the SQLServerColumnEncryptionJavaKeyStoreProvider when these
credentials are present in connection properties.
Creating a column master key for the Java Key Store
The SQLServerColumnEncryptionJavaKeyStoreProvider can be used with JKS or PKCS12 keystore types. To create or
import a key to use with this provider use the Java keytool utility. The key must have the same password as the
keystore itself. Here's an example of how to create a public key and its associated private key with the keytool
utility:
keytool -genkeypair -keyalg RSA -alias AlwaysEncryptedKey -keystore keystore.jks -storepass mypassword -
validity 360 -keysize 2048 -storetype jks
This command creates a public key and wraps it in an X.509 self-signed certificate, which is stored in the
keystore keystore.jks along with its associated private key. This entry in the keystore is identified by the alias
AlwaysEncryptedKey .
keytool -genkeypair -keyalg RSA -alias AlwaysEncryptedKey -keystore keystore.pfx -storepass mypassword -
validity 360 -keysize 2048 -storetype pkcs12 -keypass mypassword
If the keystore is of type PKCS12, the keytool utility doesn't prompt for a key password and the key password
needs to be provided with -keypass option as the SQLServerColumnEncryptionJavaKeyStoreProvider requires that
the keystore and the key have the same password.
You can also export a certificate from the Windows Certificate store in .pfx format and use that with the
SQLServerColumnEncryptionJavaKeyStoreProvider . The exported certificate can also be imported to the Java Key
Store as a JKS keystore type.
After you create the keytool entry, create the column master key metadata in the database, which needs the
keystore provider name and the key path. For more information on how to create column master key meta data,
see CREATE COLUMN MASTER KEY. For SQLServerColumnEncryptionJavaKeyStoreProvider , the key path is just the
alias of the key and the name of the SQLServerColumnEncryptionJavaKeyStoreProvider is MSSQL_JAVA_KEYSTORE . You
can also query this name with the getName() public API of the SQLServerColumnEncryptionJavaKeyStoreProvider
class.
The T-SQL syntax to create the column master key is:
For the 'AlwaysEncryptedKey' created above, the column master key definition would be:
CREATE COLUMN MASTER KEY [MyCMK]
WITH
(
KEY_STORE_PROVIDER_NAME = N'MSSQL_JAVA_KEYSTORE',
KEY_PATH = N'AlwaysEncryptedKey'
);
NOTE
The built-in SQL Server management Studio functionality cannot create column master key definitions for the Java Key
Store. T-SQL commands must be used programmatically.
NOTE
CEK caching implemented by custom key store providers will be disabled by the driver if the key store provider instance is
registered in the driver globally with the SQLServerConnection.registerColumnEncryptionKeyStoreProviders method.
Any CEK caching implementation should reference the value of time-to-live duration before caching a CEK and not cache
it if the value is zero. This will avoid duplicate caching and possible user confusion when they are trying to configure key
caching. The time-to-live value for the cache can be set with the
SQLServerColumnEncryptionKeyStoreProvider.setColumnEncryptionCacheTtl method.
The following example shows the precedence of custom column master key store providers registered on a
statement instance:
Map<String, SQLServerColumnEncryptionKeyStoreProvider> customKeyStoreProviders = new HashMap<>();
MyCustomKeyStore firstProvider = new MyCustomKeyStore();
customKeyStoreProviders.put("FIRST_CUSTOM_STORE", firstProvider);
// Registers the provider globally
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(customKeyStoreProviders);
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionJavaKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerException;
/**
* This program demonstrates how to create a column encryption key programmatically for the Java Key Store.
*/
public class AlwaysEncrypted {
// Alias of the key stored in the keystore.
private static String keyAlias = "<provide key alias>";
// Name by which the column master key will be known in the database.
private static String columnMasterKeyName = "MyCMK";
// Name by which the column encryption key will be known in the database.
// Name by which the column encryption key will be known in the database.
private static String columnEncryptionKey = "MyCEK";
/**
* Name of the encryption algorithm used to encrypt the value of the column encryption key. The
algorithm for the system providers must be
* RSA_OAEP.
*/
private static String algorithm = "RSA_OAEP";
/**
* Create column encryption key For more details on the syntax, see:
* https://docs.microsoft.com/sql/t-sql/statements/create-column-encryption-key-transact-sql
Encrypted column encryption key first needs
* to be converted into varbinary_literal from bytes, for which byteArrayToHex() is used.
*/
String createCEKSQL = "CREATE COLUMN ENCRYPTION KEY "
+ columnEncryptionKey
+ " WITH VALUES ( "
+ " COLUMN_MASTER_KEY = "
+ columnMasterKeyName
+ " , ALGORITHM = '"
+ algorithm
+ "' , ENCRYPTED_VALUE = 0x"
+ byteArrayToHex(encryptedCEK)
+ " ) ";
statement.executeUpdate(createCEKSQL);
System.out.println("Column encryption key created with name : " + columnEncryptionKey);
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
}
return encryptedCEK;
}
Always Encrypted can also be enabled for individual queries. For more information, see Controlling the
performance impact of Always Encrypted. Enabling Always Encrypted isn't sufficient for encryption or
decryption to succeed. You also need to make sure:
The application has the VIEW ANY COLUMN MASTER KEY DEFINITION and
VIEW ANY COLUMN ENCRYPTION KEY DEFINITION database permissions, required to access the metadata about
Always Encrypted keys in the database. For details, see Permissions in Always Encrypted (Database Engine).
The application can access the column master key that protects the column encryption keys, which encrypt
the queried database columns. To use the Java Key Store provider, you need to provide extra credentials in
the connection string. For more information, see Use Java Key Store provider.
Configuring how java.sql.Time values are sent to the server
The sendTimeAsDatetime connection property is used to configure how the java.sql.Time value is sent to the
server. When set to false, the time value is sent as a SQL Server time type. When set to true, the time value is
sent as a datetime type. If a time column is encrypted, the sendTimeAsDatetime property must be false, as
encrypted columns don't support the conversion from time to datetime. Also note that this property is by
default true, so to use encrypted time columns set it to false. Otherwise, the driver will throw an exception.
Starting with version 6.0 of the driver, the SQLServerConnection class has two methods to configure the value of
this property programmatically:
public void setSendTimeAsDatetime(boolean sendTimeAsDateTimeValue)
public boolean getSendTimeAsDatetime()
For more information on this property, see Configuring How java.sql.Time Values are Sent to the Server.
Configuring how String values are sent to the server
The sendStringParametersAsUnicode connection property is used to configure how String values are sent to SQL
Server. If set to true, String parameters are sent to the server in Unicode format. If set to false, String parameters
are sent in non-Unicode format, such as ASCII or MBCS, instead of Unicode. The default value for this property is
true. When Always Encrypted is enabled and a char / varchar / varchar(max) column is encrypted, the value of
sendStringParametersAsUnicode must be set to false. If this property is set to true, the driver will throw an
exception when decrypting data from an encrypted char / varchar / varchar(max) column that has Unicode
characters. For more information on this property, see Setting the Connection Properties.
IMPORTANT
If sendStringParametersAsUnicode is set to true and unicode data is inserted into a char / varchar column
encrypted with Always Encrypted, data loss may occur without an error being reported. The data loss may only be
detected when trying to decrypt the data after reading it back from the server. An error like
Decryption failed. The last 10 bytes of the encrypted column encryption key are: 'C3-D9-10-4E-C1-45-8B-
94-A2-43'. The first 10 bytes of ciphertext are: '01-9B-9D-A6-3E-40-22-53-15-9B'.
might be the result.
It is important to use correct column data types and specify the correct data type for parameters when inserting
encrypted data. If unicode data is expected, use nchar / nvarchar columns and setNString() methods. The server
can't perform implicit data conversions and has limited ability to detect data errors when Always Encrypted is enabled.
A L WAY S EN C RY P T ED IS A L WAY S EN C RY P T ED IS
EN A B L ED A N D EN A B L ED A N D
A P P L IC AT IO N C A N A C C ESS A P P L IC AT IO N C A N 'T
T H E K EY S A N D K EY A C C ESS T H E K EY S O R K EY A L WAY S EN C RY P T ED IS
Q UERY C H A RA C T ERIST IC M ETA DATA M ETA DATA DISA B L ED
Queries retrieving data Results from encrypted Error Results from encrypted
from encrypted columns columns are transparently columns aren't decrypted.
without parameters decrypted. The application The application receives
targeting encrypted receives plaintext values of encrypted values as byte
columns. the JDBC datatypes arrays (byte[]).
corresponding to the SQL
Server types configured for
the encrypted columns.
For each Java code example, you'll need to insert keystore-specific code in the location noted.
To use an Azure Key Vault keystore provider:
NOTE
if columns are encrypted with deterministic encryption, queries can perform equality comparisons on them. For more
information, see Selecting Deterministic or Randomized encryption in Always Encrypted (Database Engine).
// <Insert keystore-specific code here>
try (Connection connection = DriverManager.getConnection(connectionUrl);
PreparedStatement selectStatement = connection
.prepareStatement("\"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].
[Patients] WHERE SSN = ?;\"");) {
selectStatement.setString(1, "795-73-9838");
ResultSet rs = selectStatement.executeQuery();
while (rs.next()) {
System.out.println("SSN: " + rs.getString("SSN") + ", FirstName: " + rs.getString("FirstName") + ",
LastName:"
+ rs.getString("LastName") + ", Date of Birth: " + rs.getString("BirthDate"));
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
selectStatement.setString(1, "Abel");
ResultSet rs = selectStatement.executeQuery();
while (rs.next()) {
System.out.println("SSN: " + rs.getString("SSN") + ", FirstName: " + rs.getString("FirstName") + ",
LastName:"
+ rs.getString("LastName") + ", Date of Birth: " + rs.getString("BirthDate"));
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
String filterRecord = "SELECT FirstName, LastName, SSN, BirthDate FROM " + tableName + " WHERE LastName =
?";
selectStatement.setString(1, "Abel");
ResultSet rs = selectStatement.executeQuery();
while (rs.next()) {
System.out.println("First name: " + rs.getString("FirstName"));
System.out.println("Last name: " + rs.getString("LastName"));
System.out.println("SSN: " + rs.getString("SSN"));
System.out.println("Date of Birth: " + rs.getDate("BirthDate"));
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
Only DAYS, HOURS, MINUTES, or SECONDS are supported as the time unit.
NOTE
Use caution when specifying AllowEncryptedValueModifications as this option may lead to corrupting the database
because the Microsoft JDBC Driver for SQL Server does not check if the data is indeed encrypted or if it is correctly
encrypted with the same encryption type, algorithm, and key as the target column.
See also
Always Encrypted (Database Engine)
Using Always Encrypted with secure enclaves with
the JDBC driver
4/27/2022 • 3 minutes to read • Edit Online
Prerequisites
Make sure Microsoft JDBC Driver 8.2 (or higher) for SQL Server is installed on your development machine.
Verify environment dependencies such as DLLs, KeyStores, and so on, are in the correct paths. Always
Encrypted with secure enclaves is an add-on to the existing Always Encrypted feature and share similar
prerequisites.
NOTE
If you are using an older version of JDK 8, you may need to download and install the Java Cryptography Extension (JCE)
Unlimited Strength Jurisdiction Policy Files. Be sure to read the Readme included in the zip file for installation instructions
and relevant details on possible export/import issues.
The policy files can be downloaded from Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8
Download
Java 8 users
This feature requires the RSASSA-PSA signature algorithm. This algorithm was added in JDK 11, but not back-
ported to JDK 8. Users who wish to use this feature with the JDK 8 version of the Microsoft JDBC Driver for SQL
Server must either load their own provider, which supports the RSASSA-PSA signature algorithm, or include the
BouncyCastleProvider optional dependency. The dependency will be removed at a later date if JDK 8 back ports
the signature algorithm or if the support lifecycle of JDK 8 ends.
See also
Using Always Encrypted with the JDBC driver
Setting the data source properties
4/27/2022 • 2 minutes to read • Edit Online
See also
Connecting to SQL Server with the JDBC driver
Setting the connection properties
4/27/2022 • 25 minutes to read • Edit Online
datasource.setServerName(value)
datasource.setDatabaseName(value)
Remarks
Property names are case-insensitive, and duplicate property names are resolved in the following order:
1. API arguments (such as user and password)
2. Property collection
3. Last instance in the connection string
Unknown values are allowed for the property names, and aren't validated by the JDBC driver for case sensitivity.
Synonyms are allowed and are resolved in order, just as duplicate property names.
Properties
The following table lists all the currently available connection string properties for the JDBC driver.
P RO P ERT Y
TYPE
DEFA ULT DESC RIP T IO N
null
clientKey (Version 8.4+) Specifies the location of the private key for
PEM, DER, and CER certificates specified by the
String clientCertificate attribute.
10
null
delayLoadingLobs Flag to indicate whether to stream or not stream all the LOB
objects being retrieved from the ResultSet. Setting this
boolean property to "false" loads the entire LOB object into memory
["true" | "false"] without streaming.
true
String
null
P RO P ERT Y
TYPE
DEFA ULT DESC RIP T IO N
boolean
["true" | "false"]
true
encrypt Set to "true" to specify that the SQL Server uses TLS
encryption for all the data sent between the client and the
boolean server if the server has a certificate installed. The default
["true" | "false"] value is "true" in version 10.2 and up and "false" in 9.4 and
below.
true
In version 6.0 and up, there is a new connection setting
'authentication' that uses TLS encryption by default.
fips For FIPS enabled Java Virtual Machine (JVM) this property
should be true .
boolean
["true" | "false"]
"false"
null
jaasConfigurationName (Version 6.2+) Each connection to SQL Server can have its
own JAAS Login Configuration file to establish a Kerberos
String connection. The name of the JAAS Login Configuration file
can be passed through this property.
SQLJDBCDriver By default, the driver sets useDefaultCcache = true for
IBM JVMs, and useTicketCache = true for other JVMs.
keyStoreAuthentication (Version 6.0+) This property identifies which key store to use
with Always Encrypted and determines an authentication
String mechanism used to authenticate to the key store. The driver
supports setting up of the Java Key Store seamlessly when
null you set
"keyStoreAuthentication=JavaKeyStorePassword ". To
use this property, you also must set the keyStoreLocation
and keyStoreSecret properties for the Java Key Store.
lastUpdateCount A "true" value only returns the last update count from an
SQL statement passed to the server, and it can be used on
boolean single SELECT, INSERT, or DELETE statements to ignore other
["true" | "false"] update count caused by server triggers. Setting this
property to "false" causes all update counts to be returned,
true including this update counts returned by server triggers.
Note: This property only applies when it's used with the
executeUpdate methods. All other execute methods return
all results and update counts. This property only affects
update counts returned by server triggers. It doesn't affect
result sets or errors that result as part of trigger execution.
loginTimeout The number of seconds the driver should wait before timing
out a failed connection. A zero value indicates that the
int timeout is the default system timeout, which is specified as
[0..65535] 15 seconds by default. A non-zero value is the number of
seconds the driver should wait before timing out a failed
15 connection.
null
portNumber, The port where the server is listening. If the port number is
port specified in the connection string, no request to SQLbrowser
is made. When the port and instanceName are both
int specified, the connection is made to the specified port.
[0..65535] However, the instanceName is validated and an error is
thrown if it doesn't match the port.
1433
Impor tant: It is recommended that the port number is
always specified, as it's more secure than using SQLbrowser.
null
replication (Version 9.4+) This setting tells the server if the connection
is used for replication. When enabled, triggers with the
boolean NOT FOR REPLICATION option won't fire on the connection.
["true" | "false"]
false
P RO P ERT Y
TYPE
DEFA ULT DESC RIP T IO N
Note: After upgrading the JDBC driver from version 1.2, the
default buffering behavior will be "adaptive." If you want to
keep the version 1.2 default behavior in your application,
you must set the responseBufferring property to "full" either
in the connection properties, or use the
setResponseBuffering method of the SQLServerStatement
object.
The default behavior is that all result set rows are kept in
client memory. This behavior provides the fastest
performance when the application is processing all rows.
P RO P ERT Y
TYPE
DEFA ULT DESC RIP T IO N
DATE: YYYY-MM-DD
DATETIME: YYYY-MM-DD hh:mm:ss[.nnn]
DATETIME2: YYYY-MM-DD hh:mm:ss[.nnnnnnn]
DATETIMEOFFSET:
YYYY-MM-DD hh:mm:ss[.nnnnnnn] [{+/-}hh:mm]
SMALLDATETIME: YYYY-MM-DD hh:mm:ss
TIME: hh:mm:ss[.nnnnnnn]
sendTimeAsDatetime This property was added in SQL Server JDBC Driver 3.0.
String You can also specify the Virtual Network Name of an Always
On Availability Groups availability group. For more
null information about disaster recovery, see JDBC driver
support for High Availability, disaster recovery.
serverNameAsACE (Version 6.0+) Set to "true" to indicate that the driver should
translate the Unicode server name to ASCII compatible
boolean encoding (Punycode) for the connection. If this setting is
["true" | "false"] false, the driver uses the server name as provided to
connect.
false
For more information about international features, see
International features of the JDBC driver.
P RO P ERT Y
TYPE
DEFA ULT DESC RIP T IO N
socketFactoryClass (Version 8.4+) Specifies the class name for a custom socket
factory to be used instead of the default socket factory.
String
null
int This property defines the size of the cache for statement
pooling.
0
This property can only be used with the
disableStatementPooling connection property, which
should be set to "false". Setting disableStatementPooling
to "true" or statementPoolingCacheSize to 0 disables
prepared statement handle caching.
P RO P ERT Y
TYPE
DEFA ULT DESC RIP T IO N
sslProtocol (Version 6.4+) This property can be used to specify the TLS
protocol to be considered during secure connection.
String Possible values are: TLS, TLSv1 , TLSv1.1 , and TLSv1.2 .
null
trustServerCertificate Set to "true" to specify that the driver doesn't validate the
server TLS/SSL certificate.
boolean
["true" | "false"] If "true", the server TLS/SSL certificate is automatically
trusted when the communication layer is encrypted using
false TLS.
"<java-home>/lib/security/jssecacerts" file.
"<java-home>/lib/security/cacerts" file.
trustStoreType Set this property to specify trust store type to be used for
FIPS mode.
String
Possible values are either PKCS12 or type defined by FIPS
JKS provider.
<empty string>
false
NOTE
The Microsoft JDBC Driver for SQL Server takes the server default values for connection properties except for
ANSI_DEFAULTS and IMPLICIT_TRANSACTIONS. The Microsoft JDBC Driver for SQL Server automatically sets
ANSI_DEFAULTS to ON and IMPLICIT_TRANSACTIONS to OFF.
IMPORTANT
If authentication is set to ActiveDirectoryPassword, the following library needs to be included in the classpath: microsoft-
authentication-library-for-java. It can be found on Maven Repository. The simplest way to download the library and its
dependencies is by using Maven:
1. Install Maven on your system
2. Go to the GitHub page of the driver
3. Download the pom.xml file
4. Run the following Maven command to download the library and its dependencies:
mvn dependency:copy-dependencies
See also
Connecting to SQL Server with the JDBC driver
FIPS mode
Working with a connection
4/27/2022 • 2 minutes to read • Edit Online
NOTE
If you have problems connecting to SQL Server using the JDBC driver, see Troubleshooting Connectivity for suggestions
on how to correct it.
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String connectionUrl = "jdbc:sqlserver://localhost;database=AdventureWorks;integratedSecurity=true;"
Connection con = DriverManager.getConnection(connectionUrl);
This technique will create a database connection using the first available driver in the list of drivers that can
successfully connect with the given URL.
NOTE
When using the sqljdbc4.jar class library, applications do not need to explicitly register or load the driver by using the
Class.forName method. When the getConnection method of the DriverManager class is called, an appropriate driver is
located from the set of registered JDBC drivers. For more information, see Using the JDBC Driver.
For more connection URL examples, see Building the connection URL.
Closing a connection
You can explicitly close a database connection by calling the close method of the SQLServerConnection class, as
in the following:
con.close();
This will release the database resources that the SQLServerConnection object is using, or return the connection
to the connection pool in pooled scenarios.
NOTE
Calling the close method will also roll back any pending transactions.
See also
Connecting to SQL Server with the JDBC driver
Connect to an Azure SQL database
4/27/2022 • 3 minutes to read • Edit Online
Details
To connect to an Azure SQL Database, you should connect to the master database to call
SQLSer verDatabaseMetaData.getCatalogs .
Azure SQL Database doesn't support returning the entire set of catalogs from a user database.
SQLSer verDatabaseMetaData.getCatalogs use the sys.databases view to get the catalogs. Refer to the
discussion of permissions in sys.databases (Transact-SQL) to understand
SQLSer verDatabaseMetaData.getCatalogs behavior on an Azure SQL Database.
Connections dropped
When you connect to an Azure SQL Database, idle connections may be terminated by a network component
(such as a firewall) after a period of inactivity. There are two types of idle connections, in this context:
Idle at the TCP layer, where connections can be dropped by any number of network devices.
Idle by the Azure SQL Gateway, where TCP keepalive messages might be occurring (which makes the
connection not idle from a TCP perspective), but not had an active query in 30 minutes. In this scenario,
the Gateway will determine that the TDS connection is idle at 30 minutes and terminates the connection.
To address the second point and avoid the Gateway terminating idle connections, you can:
Use the Redirect connection policy to configure your Azure SQL data source.
Keep connections active via lightweight activity. This method isn’t recommended and should only be used
if there are no other possible options.
To address the first point and avoid dropping idle connections by a network component, set the following
registry settings or their non-Windows equivalents on the operating system where the driver is loaded:
NOTE
TcpMaxDataRetransmissions isn't controllable on Windows Vista or Windows 2008 and higher.
To configure this in an Azure VM, create a startup task to add the registry keys. For example, add the following
Startup task to the service definition file:
<Startup>
<Task commandLine="AddKeepAlive.cmd" executionContext="elevated" taskType="simple">
</Task>
</Startup>
Then add a AddKeepAlive.cmd file to your project. Set the "Copy to Output Directory" setting to Copy always.
The following script is a sample AddKeepAlive.cmd file:
jdbc:sqlserver://abcd.int.mscds.com;databaseName=myDatabase;user=myName;password=myPassword;encrypt=true;hos
tNameInCertificate=*.int.mscds.com;
See also
Connecting to SQL Server with the JDBC driver
Connection resiliency (JDBC)
4/27/2022 • 2 minutes to read • Edit Online
If the product of connectRetryCount multiplied by connectRetryInterval is larger than loginTimeout , then the
driver will stop attempting to connect once loginTimeout is reached. Otherwise, it will continue to try to
reconnect until connectRetryCount is reached.
To detect broken idle connections, the driver relies on TCP keepalive packets at the socket level. On Linux and
Java 11+, the driver automatically enables keepalive packets at a 30-second interval ( KeepAliveTime ) with a 1-
second delay between retries when a failure occurs ( KeepAliveInterval ).
IMPORTANT
On Windows and macOS or on Java 8, keepalives must be manually configured in the operating system in order to take
advantage of restoring broken idle connections. For information on how to configure keepalives, see Connection to Azure
SQL database.
Limitations
Broken idle connections can't be restored when:
There's an open result set that hasn't been completely parsed or buffered
Switching databases against Azure SQL
There's an open transaction
See also
Connecting to an Azure SQL database
Technical Article - Idle Connection Resiliency
Overview of the JDBC driver
Building the connection URL
4/27/2022 • 4 minutes to read • Edit Online
where:
jdbc:sqlser ver :// (Required) is known as the subprotocol and is constant.
ser verName (Optional) is the address of the server to connect to. This address can be a DNS or IP
address, or it can be localhost or 127.0.0.1 for the local computer. If not specified in the connection URL,
the server name must be specified in the properties collection.
instanceName (Optional) is the instance to connect to on serverName. If not specified, a connection to
the default instance is made.
por tNumber (Optional) is the port to connect to on serverName. The default is 1433. If you're using the
default, you don't have to specify the port, nor its preceding ':', in the URL.
NOTE
For optimal connection performance, you should set the portNumber when you connect to a named instance.
This will avoid a round trip to the server to determine the port number. If both a portNumber and instanceName
are used, the portNumber will take precedence and the instanceName will be ignored.
proper ty (Optional) is one or more option connection properties. For more information, see Setting the
connection properties. Any property from the list can be specified. Properties can only be delimited by
using the semicolon (';'), and they can't be duplicated.
Cau t i on
For security purposes, you should avoid building the connection URLs based on user input. You should only
specify the server name and driver in the URL. For user name and password values, use the connection property
collections. For more information about security in your JDBC applications, see Securing JDBC driver
applications.
Connection properties
For a detailed list of properties that can be set in the connection string, see Setting the connection properties.
Connection examples
Connect to the default database on the local computer by using a user name and password:
jdbc:sqlserver://localhost;user=MyUserName;password=*****;
NOTE
Although the previous example uses a username and password in the connection string, you should use integrated
security as it is more secure. For more information, see the Connecting with Integrated Authentication section later in this
topic.
The following connection string shows an example of how to connect to a SQL Server database using integrated
authentication and Kerberos from an application running on any operating system supported by the Microsoft
JDBC Driver for SQL Server:
jdbc:sqlserver://;servername=server_name;integratedSecurity=true;authenticationScheme=JavaKerberos
Connect to the default database on the local computer by using integrated authentication:
jdbc:sqlserver://localhost;integratedSecurity=true;
NOTE
White space inside the braces is literal and not trimmed.
NOTE
If you are running a 32-bit Java Virtual Machine (JVM), use the mssql-jdbc_auth-<version>-<arch>.dll file in the x86
folder, even if the operating system is the x64 version. If you are running a 64-bit JVM on a x64 processor, use the mssql-
jdbc_auth-<version>-<arch>.dll file in the x64 folder.
Alternatively you can set the java.library.path system property to specify the directory of the mssql-jdbc_auth-
<version>-<arch>.dll. For example, if the JDBC driver is installed in the default directory, you can specify the
location of the DLL by using the following virtual machine (VM) argument when the Java application is started:
-Djava.library.path=C:\Microsoft JDBC Driver 6.4 for SQL Server\sqljdbc_<version>\enu\auth\x86
pro.setProperty("serverName", "serverName=3ffe:8311:eeee:f70f:0:5eae:10.203.31.9\\instance1");
See also
Connecting to SQL Server with the JDBC driver
Using connection pooling
4/27/2022 • 2 minutes to read • Edit Online
NOTE
Although the JDBC driver supports Java EE connection pooling, it does not provide its own pooling implementation. The
driver relies on third-party Java Application Servers to manage the connections.
Remarks
The classes for the connection pooling implementation are as follows.
C L A SS IM P L EM EN T S DESC RIP T IO N
JDBC application code should always close connections explicitly to derive the most benefit from pooling. When
the application explicitly closes a connection, the pooling implementation can reuse the connection immediately.
If the connection is not closed, other applications cannot reuse it. Applications can use the finally construct to
make sure that pooled connections are closed even if an exception occurs.
NOTE
The JDBC driver does not currently call the sp_reset_connection stored procedure when it returns the connection to the
pool. Instead, the driver relies on third-party Java Application Servers to return the connections back to their original
states.
See also
Connecting to SQL Server with the JDBC driver
Using Kerberos integrated authentication to connect
to SQL Server
4/27/2022 • 7 minutes to read • Edit Online
Remarks
Prior to Microsoft JDBC Driver 4.0 for SQL Server, applications could specify integrated authentication (using
Kerberos or NTLM, depending on which is available) by using the integratedSecurity connection property and
by referencing mssql-jdbc_auth-<version>-<arch>.dll , as described in Building the connection URL.
Beginning in Microsoft JDBC Driver 4.0 for SQL Server, an application can use the authenticationScheme
connection property to indicate that it wants to connect to a database using Kerberos integrated authentication
using the pure Java Kerberos implementation:
If you want integrated authentication using Krb5LoginModule , you must still specify the
integratedSecurity=true connection property. You would then also specify the
authenticationScheme=JavaKerberos connection property.
To continue using integrated authentication with mssql-jdbc_auth-<version>-<arch>.dll , just specify
integratedSecurity=true connection property (and optionally
authenticationScheme=NativeAuthentication ).
If you specify authenticationScheme=JavaKerberos but do not also specify
integratedSecurity=true , the driver will ignore the authenticationScheme connection property and
it will expect to find user name and password credentials in the connection string.
When using a datasource to create connections, you can programmatically set the authentication scheme using
setAuthenticationScheme and (optionally) set the SPN for Kerberos connections using setSer verSpn .
A new logger has been added to support Kerberos authentication:
com.microsoft.sqlserver.jdbc.internals.KerbAuthentication. For more information, see Tracing driver operation.
The following guidelines will help you to configure Kerberos:
1. Set AllowTgtSessionKey to 1 in the registry for Windows. For more information, see Kerberos protocol
registry entries and KDC configuration keys in Windows Server 2003.
2. Make sure that the Kerberos configuration (krb5.conf in UNIX environments), points to the correct realm and
KDC for your environment.
3. Initialize the TGT cache by using kinit or logging into the domain.
4. When an application that uses authenticationScheme=JavaKerberos runs on the Windows Vista or
Windows 7 operating systems, you should use a standard user account. However if you run the application
under an administrator's account, the application must run with administrator privileges.
NOTE
The serverSpn connection attribute is only supported by Microsoft JDBC Drivers 4.2 and higher.
NOTE
Before 6.2 release of JDBC driver, for proper use of Cross Realm Kerberos, you would need to explicitly set the ser verSpn .
As of the 6.2 release, the driver will be able to build the ser verSpn by default, even when using Cross Realm Kerberos.
Although one can use ser verSpn explicitly too.
A login configuration file consists of one or more entries, each specifying which underlying authentication
technology should be used for a particular application or applications. For example,
SQLJDBCDriver {
com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true;
};
So, each login module configuration file entry consists of a name followed by one or more LoginModule-
specific entries, where each LoginModule-specific entry is terminated by a semicolon and the entire group of
LoginModule-specific entries is enclosed in braces. Each configuration file entry is terminated by a semicolon.
In addition to allowing the driver to acquire Kerberos credentials using the settings specified in the login module
configuration file, the driver can use existing credentials. This can be useful when your application needs to
create connections using more than one user's credentials.
The driver will attempt to use existing credentials if they are available, before attempting to login using the
specified login module. Thus, when using the Subject.doAs method for executing code under a specific context,
a connection will be created with the credentials passed to the Subject.doAs call.
For more information, see JAAS Login Configuration File and Class Krb5LoginModule.
Beginning in Microsoft JDBC Driver 6.2, name of login module configuration file can optionally be passed using
connection property jaasConfigurationName , this allows each connection to have its own login configuration.
[libdefaults]
default_realm = YYYY.CORP.CONTOSO.COM
dns_lookup_realm = false
dns_lookup_kdc = true
ticket_lifetime = 24h
forwardable = yes
[domain_realm]
.yyyy.corp.contoso.com = YYYY.CORP.CONTOSO.COM
.zzzz.corp.contoso.com = ZZZZ.CORP.CONTOSO.COM
[realms]
YYYY.CORP.CONTOSO.COM = {
kdc = krbtgt/YYYY.CORP. CONTOSO.COM @ YYYY.CORP. CONTOSO.COM
default_domain = YYYY.CORP. CONTOSO.COM
}
ZZZZ.CORP. CONTOSO.COM = {
kdc = krbtgt/ZZZZ.CORP. CONTOSO.COM @ ZZZZ.CORP. CONTOSO.COM
default_domain = ZZZZ.CORP. CONTOSO.COM
}
Enabling the domain configuration file and the login module
configuration file
You can enable a domain configuration file with -Djava.security.krb5.conf. You can enable a login module
configuration file with -Djava.security.auth.login.config .
For example, the following command can be used to start the application:
Make sure that you have the necessary permission to run this query.
Constrained delegation
Beginning in Microsoft JDBC Driver 6.2, the driver supports Kerberos Constrained Delegation. The delegated
credential can be passed in as org.ietf.jgss.GSSCredential object, these credentials are used by driver to establish
connection.
jdbc:sqlserver://servername=server_name;integratedSecurity=true;authenticationScheme=JavaKerberos;userName=u
ser@REALM;password=****
The username property does not require a REALM if the user belongs to the default_realm set in krb5.conf file.
When userName and password are set along with integratedSecurity=true; and the
authenticationScheme=JavaKerberos; property, the connection is established with a value of userName as the
Kerberos Principal along with the password supplied.
Beginning in Microsoft JDBC Driver 9.4, the user can specify the realm for Kerberos authentication in the
connection string.
jdbc:sqlserver://servername=server_name;integratedSecurity=true;authenticationScheme=JavaKerberos;userName=u
ser;password=****;realm=REALM
Using Kerberos authentication from Unix Machines on the same
domain
This guide assumes a working Kerberos setup already exists. Run the following code on a Windows machine
with working Kerberos authentication to verify if the aforementioned is true. The code will print "Authentication
Scheme: KERBEROS" to the console if successful. No additional run-time flags, dependencies, or driver settings
are required outside of the ones provided. The same block of code can be run on Linux to verify successful
connections.
1. Domain join the client machine to the same domain as the server.
2. (Optional) Set the default Kerberos ticket location. This is most conveniently done by setting the KRB5CCNAME
environment variable.
3. Get the Kerberos ticket, either by generating a new one or placing an existing one in the default Kerberos
ticket location. To generate a ticket, simply use a terminal and initialize the ticket via kinit [email protected]
where "USER" and "DOMAIN.AD" is the principal and domain respectively. E.g:
kinit [email protected] . The ticket will be generated in the default ticket location or in the
KRB5CCNAME path if set.
4. The terminal will prompt for a password, enter the password.
5. Verify the credentials in the ticket via klist and confirm the credentials are the ones you intend to use for
authentication.
6. Run the above sample code and confirm that Kerberos Authentication was successful.
See also
Connecting to SQL Server with the JDBC driver
Connect using Azure Active Directory
authentication
4/27/2022 • 18 minutes to read • Edit Online
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
This example on an Azure Virtual Machine fetches an access token from System Assigned Managed Identity or
User Assigned Managed Identity (if msiClientId is specified) and establishes a connection using the fetched
access token. If a connection is established, you should see the following message:
The following example shows how to use authentication=ActiveDirectoryIntegrated mode. Run this example on
a domain joined machine that is federated with Azure Active Directory. A contained database user that
represents your Azure AD user, or one of the groups you belong to, must exist in the database, and must have
the CONNECT permission.
To build and run the example, on the client machine where you run the example, download the Microsoft
Authentication Library (MSAL) for Java and its dependencies for JDBC Driver 9.1 and above, or Microsoft Azure
Active Directory Authentication Library (ADAL) for Java and its dependencies for driver versions before JDBC
Driver 9.1, and include them in the Java build path.
Replace the server/database name with your server/database name in the following lines before executing the
example:
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
Running this example on a client machine automatically uses your Kerberos ticket and no password is required.
If a connection is established, you should see the following message:
NOTE
On Windows, mssql-jdbc_auth-<version>-<arch>.dll from the downloaded package can be used instead of these
Kerberos configuration steps. These steps are only required if you can't use the DLL.
JDK comes with kinit , which you can use to get a TGT from Key Distribution Center (KDC) on a domain joined
machine that is federated with Azure Active Directory.
St e p 1 : T i c k e t g r a n t i n g t i c k e t r e t r i e v a l
Run on : Windows
Action :
Use the command kinit [email protected] to get a TGT from KDC, then it prompts you for
your domain password.
Use klist to see the available tickets. If the kinit was successful, you should see a ticket from
krbtgt/DOMAIN.COMPANY.COM@ DOMAIN.COMPANY.COM.
NOTE
You might have to specify a .ini file with -Djava.security.krb5.conf for your application to locate KDC.
DC: \\co1-red-dc-33.domain.company.com
Address: \\2111:4444:2111:33:1111:ecff:ffff:3333
...
The command completed successfully
St e p 2 : C o n fi g u r i n g K D C i n k r b 5 .c o n f
Run on : Linux/macOS
Action : Edit the /etc/krb5.conf in an editor of your choice. Configure the following keys
[libdefaults]
default_realm = DOMAIN.COMPANY.COM
[realms]
DOMAIN.COMPANY.COM = {
kdc = co1-red-dc-28.domain.company.com
}
St e p 3 : Te st t h e t i c k e t g r a n t i n g t i c k e t r e t r i e v a l
Run on : Linux/macOS
Action :
Use the command kinit [email protected] to get a TGT from KDC, then it prompts you for
your domain password.
Use klist to see the available tickets. If the kinit was successful, you should see a ticket from
krbtgt/DOMAIN.COMPANY.COM@ DOMAIN.COMPANY.COM.
3. Locate the following lines of code. Replace user name with the name of the Azure AD user that you want
to connect as.
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
NOTE
A contained user database must exist and a contained database user that represents the specified Azure AD user or one
of the groups, the specified Azure AD user belongs to, must exist in the database, and must have the CONNECT
permission (except for Azure Active Directory server admin or group)
3. Locate the following lines of code. Replace user name with the name of the Azure AD user that you want
to connect as.
ds.setUser("[email protected]"); // replace with your user name
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
When you run the program, a browser is displayed to authenticate the user. Exactly what you see depends on
how your Azure AD has been configured. It might or might not include multi-factor authentication prompts for
username, password, PIN, or second device authentication via a phone. If multiple interactive authentication
requests are done in the same program, later requests might not even prompt you if the authentication library
can reuse a previously cached authentication token.
For information about how to configure Azure AD to require Multi-Factor Authentication, see Getting started
with Azure AD Multi-Factor Authentication in the cloud.
For screenshots of these dialog boxes, see Configure multi-factor authentication for SQL Server Management
Studio and Azure AD.
If user authentication is completed successfully, you should see the following message in the browser:
Authentication complete. You can close the browser and return to the application.
This message only indicates that user authentication was successful but not necessarily a successful connection
to the server. Upon return to the application, if a connection is established to the server, you should see the
following message as output:
3. Locate the following lines of code. Replace the value of principalId with the Application ID / Client ID of
the Azure AD service principal that you want to connect as. Replace the value of principalSecret with the
secret.
4. Set the principalId and principal Secret using setUser and setPassword in version 10.2 and up, and
setAADSecurePrincipalId and setAADSecurePrincipalSecret in version 9.4 and below.
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
NOTE
A contained user database must exist and a contained database user that represents the specified Azure AD principal or
one of the groups the specified Azure AD principal belongs to, must exist in the database and must have the CONNECT
permission (except for an Azure Active Directory server admin or group)
NOTE
accessToken can only be set using the Properties parameter of the getConnection() method in the DriverManager class.
It can't be used in the connection string.
The following example contains a simple Java application that connects to Azure SQL Database/Synapse
Analytics using access token-based authentication.
To build and run the example:
1. Create an application account in Azure Active Directory for your service.
a. Sign in to the Azure portal.
b. Select Azure Active Directory in the left-hand navigation.
c. Select the "App registrations" tab.
d. In the drawer, select "New application registration".
e. Enter mytokentest as a friendly name for the application, select "Web App/API".
f. Don't need SIGN-ON URL, provide anything: "https://mytokentest".
g. Select "Create" at the bottom.
h. While still in the Azure portal, select the "Settings" tab of your application, and open the "Properties"
tab.
i. Find the "Application ID" (also known as Client ID) value and copy it. You need this value later to
configure your application (for example, 1846943b-ad04-4808-aa13-4702d908b5c1).
j. Under section "Keys", create a key to fill in the name field, select the duration of the key, and save the
configuration (leave the value field empty). After you save, the value field should be filled
automatically. Copy the generated value. This value is the client Secret.
k. Select Azure Active Directory on the left side panel. Under "App Registrations", find the "End points"
tab. Copy the URL under "OATH 2.0 TOKEN ENDPOINT", this URL is your STS URL.
2. Sign in to your Azure SQL Server user database as an Azure Active Directory admin and use a T-SQL
command, provision a contained database user for your application principal. For more information on
how to create an Azure Active Directory admin and a contained database user, see the Connecting to SQL
Database or Azure Synapse Analytics By Using Azure Active Directory authentication.
3. On the client machine where you run the example, download the Microsoft Authentication Library
(MSAL) for Java library and its dependencies for JDBC Driver 9.1 and above, or Microsoft Azure Active
Directory Authentication Library (ADAL) for Java and its dependencies for driver versions before JDBC
Driver 9.1, and include them in the Java build path. The microsoft-authentication-library-for-java is only
required to run this specific example. The example uses the APIs from this library to retrieve the access
token from Azure AD. If you already have an access token, you can skip this step and remove the section
in the example that retrieves an access token.
In the following example, replace the STS URL, Client ID, Client Secret, server and database name with your
values.
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
// The azure-activedirectory-library-for-java is needed to retrieve the access token from the AD.
import com.microsoft.aad.msal4j.ClientCredentialFactory;
import com.microsoft.aad.msal4j.ClientCredentialParameters;
import com.microsoft.aad.msal4j.ConfidentialClientApplication;
import com.microsoft.aad.msal4j.IAuthenticationResult;
import com.microsoft.aad.msal4j.IClientCredential;
If the connection is successful, you should see the following message as output:
Remarks
See Network security: LAN Manager authentication level for description of the SQL server settings, which
control the behavior of NTLM authentication.
Logging
A new logger has been added to support NTLM authentication:
com.microsoft.sqlserver.jdbc.internals.NTLMAuthentication. For more information, see Tracing Driver Operation.
DataSource
When using a datasource to create connections, the NTLM properties can be programmatically set using
setAuthenticationScheme , setDomain , and (optionally) setSer verSpn .
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("<server>");
ds.setPortNumber(1433); // change if necessary
ds.setIntegratedSecurity(true);
ds.setAuthenticationScheme("NTLM");
ds.setDomain("<domainName>");
ds.setUser("<userName>");
ds.setPassword("<password>");
ds.setDatabaseName("<database>");
ds.setServerSpn("<serverSpn");
NOTE
The serverSpn connection attribute is only supported by Microsoft JDBC Drivers 4.2 and higher.
Before 6.2 release of JDBC driver, you would need to explicitly set the ser verSpn . As of the 6.2 release, the
driver will be able to build the ser verSpn by default, although one can use ser verSpn explicitly too.
Security risks
The NTLM protocol is an old authentication protocol with various vulnerabilities, which pose a security risk. It's
based on a weak cryptographic scheme and is vulnerable to attacks. NTLM has been replaced by Kerberos,
which much more secure and recommended. NTLM authentication should only be used in a secure trusted
environment, or when Kerberos can't be used.
The Microsoft JDBC Driver for SQL Server only supports NTLM v2, which has some security improvements over
the original v1 protocol. It's also recommended to enable Extended Protection, or use TLS Encryption for
increased security.
For more information on how to enable Extended Protection and, see:
Connect to the Database Engine Using Extended Protection
For more information on connecting with encryption, see:
Connecting with encryption
NOTE
For the 7.4 release, enabling both Extended Protection and Encryption is not supported.
See also
Connecting to SQL Server with the JDBC driver
Client Certificate Authentication for Loopback
Scenarios
4/27/2022 • 2 minutes to read • Edit Online
clientCertificate=<file_location>
The driver uses a certificate file. For certificates in PEM, DER, and CER formats clientKey attribute is required. File
location can be either relative or absolute.
clientKey – specifies a file location of the private key for PEM, DER, and CER certificates specified by the
clientCertificate attribute.
Format
clientKey=<file_location>
Specifies location of the private key file. In case if private key file is password protected then password keyword
is required. File location can be either relative or absolute.
clientKeyPassword – optional password string provided to access the clientKey file's private key.
This feature is only officially supported for loopback authentication scenarios against Linux SQL Server
2019 and up.
See also
Connecting to SQL Server with the JDBC driver
sp_execute_external_script (Transact-SQL)
Using basic data types
4/27/2022 • 5 minutes to read • Edit Online
1 To use java.sql.Time with the time SQL Server type, you must set the sendTimeAsDatetime connection
property to false.
2 You can programmatically access values of datetimeoffset with DateTimeOffset Class.
3
3 Note that java.sql.Timestamp values can no longer be used to compare values from a datetime column starting
from SQL Server 2016. This limitation is due to a server-side change that converts datetime to datetime2
differently, resulting in non-equitable values. The workaround to this issue is to either change datetime columns
to datetime2(3), use String instead of java.sql.Timestamp, or change database compatibility level to 120 or
below.
The following sections provide examples of how you can use the JDBC Driver and the basic data types. For a
more detailed example of how to use the basic data types in a Java application, see Basic Data Types Sample.
NOTE
The getUnicodeStream and getBigDecimal with scale methods are deprecated and are not supported by the JDBC driver.
For more information about parameterized queries, see Using an SQL statement with parameters.
NOTE
In this example, a result set is returned with the results of running the stored procedure.
For more information about using the JDBC driver with stored procedures and input parameters, see Using a
stored procedure with input parameters.
NOTE
In addition to the returned out parameter, a result set might also be returned with the results of running the stored
procedure.
For more information about how to use the JDBC driver with stored procedures and output parameters, see
Using a stored procedure with output parameters.
See also
Understanding the JDBC driver data types
Understanding data type differences
4/27/2022 • 3 minutes to read • Edit Online
Character types
The JDBC character string data types are CHAR , VARCHAR , and LONGVARCHAR . The JDBC driver provides
support for the JDBC 4.0 API. In the JDBC 4.0, the JDBC character string data types can also be NCHAR ,
NVARCHAR , and LONGNVARCHAR . These new character string types maintain Java native character types in
Unicode format and remove the need to perform any ANSI-to-Unicode or Unicode-to-ANSI conversion.
Fixed-length The SQL Server char and nchar data types map directly to
the JDBC CHAR and NCHAR types. These are fixed-length
types with padding provided by the server in the case where
the column has SET ANSI_PADDING ON . Padding is always
turned on for nchar , but for char , in the case where the
server char columns are not padded, the JDBC driver adds
the padding.
Variable-length The SQL Server varchar and nvarchar types map directly
to the JDBC VARCHAR and NVARCHAR types, respectively.
Long The SQL Server text and ntext types map to the JDBC
LONGVARCHAR and LONGNVARCHAR type, respectively.
These are deprecated types beginning in SQL Server 2005
(9.x), so you should use large value types, varchar(max) or
nvarchar(max) , instead.
Fixed-length The SQL Server binar y type maps directly to the JDBC
BINARY type. This is a fixed-length type with padding
provided by the server in the case where the column has SET
ANSI_PADDING ON. When the server char columns are not
padded, the JDBC driver adds the padding.
BIT The JDBC BIT type represents a single bit that can be 0 or 1.
This maps to a SQL Server bit type.
TINYINT The JDBC TINYINT type represents a single byte. This maps
to a SQL Server tinyint type.
REAL The JDBC REAL type has seven digits of precision (single
precision) and maps directly to the SQL Server real type.
Datetime Types
The JDBC TIMESTAMP type maps to the SQL Server datetime and smalldatetime types. The datetime type
is stored in two 4-byte integers. The smalldatetime type holds the same information (date and time), but with
less accuracy, in two 2-byte small integers.
NOTE
The SQL Server timestamp type is a fixed-length binary-string type. It does not map to any of the JDBC time types:
DATE , TIME , or TIMESTAMP .
See also
Understanding the JDBC driver data types
Understanding data type conversions
4/27/2022 • 7 minutes to read • Edit Online
There are three categories of conversions that are supported by the JDBC driver's getter methods:
Non-Lossy (x) : Conversions for cases where the getter type is the same or smaller than the underlying
server type. For example, when calling getBigDecimal on an underlying server decimal column, no
conversion is necessary.
Conver ted (y) : Conversions from numeric server types to Java language types where the conversion is
regular and follows Java language conversion rules. For these conversions, precision is always truncated-
never rounded-and overflow is handled as modulo of the destination type, which is smaller. For example,
calling getInt on an underlying decimal column that contains "1.9999" will return "1", or if the
underlying decimal value is "3000000000" then the int value overflows to "-1294967296".
Data Dependent (z) : Conversions from underlying character types to numeric types require that the
character types contain values that can be converted into that type. No other conversions are performed.
If the value is too large for the getter type, the value isn't valid. For example, if getInt is called on a
varchar(50) column that contains "53", the value is returned as an int ; but if the underlying value is "xyz"
or "3000000000", an error is thrown.
If getString is called on a binar y , varbinar y , varbinar y(max) , or image column data type, the value is
returned as a hexadecimal string value.
There are three categories of conversions supported by the JDBC driver's updater methods:
Non-Lossy (x) : Conversions for cases where the updater type is the same or smaller than the underlying
server type. For example, when calling updateBigDecimal on an underlying server decimal column, no
conversion is necessary.
Conver ted (y) : Conversions from numeric server types to Java language types where the conversion is
regular and follows Java language conversion rules. For these conversions, precision is always truncated
(never rounded) and overflow is handled as modulo of the destination (the smaller) type. For example,
calling updateDecimal on an underlying int column that contains "1.9999" will return "1", or if the
underlying decimal value is "3000000000" then the int value overflows to "-1294967296".
Data Dependent (z) : Conversions from underlying source data types to destination data types require
that the contained values can be converted into the destination types. No other conversions are
performed. If the value is too large for the getter type, the value isn't valid. For example, if updateString is
called on an int column that contains "53", the update succeeds; but if the underlying String value is "foo"
or "3000000000", an error is thrown.
When updateString is called on a binar y , varbinar y , varbinar y(max) , or image column data type, it handles
the String value as a hexadecimal string value.
When the SQL Server column data type is XML , the data value must be a valid XML . When calling updateBytes,
updateBinaryStream, or updateBlob methods, the data value should be the hexadecimal string representation of
the XML characters. For example:
<hello>world</hello> = 0x3C68656C6C6F3E776F726C643C2F68656C6C6F3E
Note that a byte-order mark (BOM) is required if the XML characters are in specific character encodings.
<hello>world</hello> = 0x3C68656C6C6F3E776F726C643C2F68656C6C6F3E
Note that a byte-order mark (BOM) is required if the XML characters are in specific character encodings.
Conversions on setObject
NOTE
Microsoft JDBC Drivers 4.2 (and higher) for SQL Server supports JDBC 4.1 and 4.2. For more detail on 4.1 and 4.2
datatype mappings and conversions see JDBC 4.1 compliance for the JDBC Driver and JDBC 4.2 compliance for the JDBC
Driver, in addition to the information below.
For the Java typed data passed to the setObject(<Type>) methods of the SQLServerPreparedStatement class,
the following conversions apply.
The setObject method with no specified target type uses the default mapping. In the case of the String data
type, if the value exceeds the length of VARCHAR , it maps to LONGVARCHAR . Similarly, NVARCHAR maps to
LONGNVARCHAR if the value exceeds the supported length of NVARCHAR . The same is true for byte[] .
Values longer than VARBINARY become LONGVARBINARY .
There are three categories of conversions that are supported by the JDBC driver's setObject methods:
Non-Lossy (x) : Conversions for numeric cases where the setter type is the same or smaller than the
underlying server type. For example, when calling setBigDecimal on an underlying server decimal
column, no conversion is necessary. For numeric to character cases, the Java numeric data type is
converted to a String . For example, calling setDouble with a value of "53" on a varchar(50) column will
produce a character value "53" in that destination column.
Conver ted (y) : Conversions from a Java numeric type to an underlying server numeric type that is
smaller. This conversion is regular and follows SQL Server conversion conventions. Precision is always
truncated-never rounded-and overflow throws an unsupported conversion error. For example, using
updateDecimal with a value of "1.9999" on an underlying integer column results in a "1" in the
destination column; but if "3000000000" is passed, the driver throws an error.
Data Dependent (z) : Conversions from a Java String type to the underlying SQL Server data type
depends on the following conditions: The driver sends the String value to SQL Server and SQL Server
performs conversions, if necessary. If the sendStringParametersAsUnicode connection property is set to
true and the underlying SQL Server data type is image , SQL Server doesn't allow converting nvarchar
to image and throws an SQLServerException. If the sendStringParametersAsUnicode is set to false and
the underlying SQL Server data type is image , SQL Server allows converting varchar to image and
doesn't throw an exception.
SQL Server performs the bulk of the set conversions and passes errors back to the JDBC driver when there are
problems. Client-side conversions are the exception and are performed only in the case of date , time ,
timestamp , Boolean , and String values.
When the SQL Server column data type is XML , the data value must be a valid XML . When calling
setObject(byte[], SQLXML), setObject(inputStream, SQLXML), or setObject(Blob, SQLXML) methods, the data
value should be the hexadecimal string representation of the XML characters. For example:
<hello>world</hello> = 0x3C68656C6C6F3E776F726C643C2F68656C6C6F3E
Note that a byte-order mark (BOM) is required if the XML characters are in specific character encodings.
See also
Understanding the JDBC driver data types
Using advanced data types
4/27/2022 • 6 minutes to read • Edit Online
Remarks
The following table lists the default mappings between the advanced SQL Server, JDBC, and Java programming
language data types.
varchar(max)
geography
1 The Microsoft JDBC Driverfor SQL Server supports sending and retrieving CLR UDTs as binary data but
doesn't support manipulation of the CLR metadata.
The following sections provide examples of how you can use the JDBC driver and the advanced data types.
NOTE
This same approach can also be used for the text , ntext , and nvarchar(max) data types.
When you retrieve a binary large-value data type-such as the varbinar y(max) data type-from a database, there
are several approaches that you can take. The most efficient approach is to read the data as a binary stream, as
in the following:
You can also use the getBytes method to read the data as a byte array, as in the following:
NOTE
You can also read the data as a BLOB. However, this is less efficient than the two methods shown previously.
PreparedStatement pstmt = con.prepareStatement("INSERT INTO test1 (c1_id, c2_vcmax) VALUES (?, ?)");
pstmt.setInt(1, 1);
pstmt.setString(2, htmlStr);
pstmt.executeUpdate();
NOTE
This approach can also be used for values that are stored in text , ntext , and nvarchar(max) columns.
If you have an image library on the server and must upload entire binary image files to a varbinar y(max)
column, the most efficient method with the JDBC driver is to use streams directly, as in the following:
NOTE
Using either the CLOB or BLOB method is not an efficient way to upload large data.
Additionally, you could do all the work on the server and just pass parameters to a prepared UPDATE statement.
For more information about large-value types, see "Using Large-Value Types" in SQL Server Books Online.
XML data type
SQL Server provides an xml data type that lets you store XML documents and fragments in a SQL Server
database. The xml data type is a built-in data type in SQL Server, and is in some ways similar to other built-in
types, such as int and varchar . As with other built-in types, you can use the xml data type as a column type
when you create a table; as a variable type, a parameter type, or a function-return type; or in Transact-SQL CAST
and CONVERT functions.
In the JDBC driver, the xml data type can be mapped as a String, byte array, stream, CLOB, BLOB, or SQLXML
object. String is the default. Starting with the JDBC Driver version 2.0, the JDBC driver provides support for the
JDBC 4.0 API, which introduces the SQLXML interface. The SQLXML interface defines methods to interact and
manipulate XML data. The SQLXML data type maps to the SQL Serverxml data type. For more information
about how to read and write XML data from and to the relational database with the SQLXML Java data type, see
Supporting XML data.
The implementation of the xml data type in the JDBC driver provides support for the following:
Access to the XML as a standard Java UTF-16 string for most common programming scenarios
Input of UTF-8 and other 8-bit encoded XML
Access to the XML as a byte array with a leading BOM when encoded in UTF-16 for interchange with
other XML processors and disk files
SQL Server requires a leading BOM for UTF-16-encoded XML. The application must provide this when XML
parameter values are supplied as byte arrays. SQL Server always outputs XML values as UTF-16 strings with no
BOM or embedded encoding declaration. When XML values are retrieved as byte[], BinaryStream or Blob, a UTF-
16 BOM is pre-pended to the value.
For more information about the xml data type, see "xml Data Type" in SQL Server Books Online.
See also
Understanding the JDBC driver data types
Using Sql_variant data type
4/27/2022 • 2 minutes to read • Edit Online
If the underlying type of the data being passed is known, the respective setter can be used. For instance,
preparedStatement.setInt() can be used when inserting an integer value.
For reading values from the table, the respective getters can be used. For example, getInt() or getString()
methods can be used if the values coming from the server are known:
try (CallableStatement callableStatement = con.prepareCall(" {call " + inputProc + " (?) }")) {
callableStatement.registerOutParameter(1, microsoft.sql.Types.SQL_VARIANT);
callableStatement.execute();
}
Limitations of sql_variant
When using TVP to populate a table with a datetime / smalldatetime / date value stored in a sql_variant,
calling getDateTime() / getSmallDateTime() / getDate() on a ResultSet doesn't work and throws the
following exception:
Java.lang.String cannot be cast to java.sql.Timestamp
See also
Understanding the JDBC driver data types
Using spatial data types
4/27/2022 • 6 minutes to read • Edit Online
This code will create a LINESTRING Geometry object with Spatial Reference System Identifier (SRID) 0, and a
Geography object with SRID 4326.
Creating from CLR
byte[] geomCLR =
Hex.decodeHex("00000000010403000000000000000000F03F00000000000000000000000000000000000000000000F03F000000000
000F0BF000000000000000001000000010000000001000000FFFFFFFF0000000002".toCharArray());
byte[] geogCLR =
Hex.decodeHex("E61000000104030000000000000000000000000000000000F03F000000000000F03F0000000000000000000000000
0000000000000000000F0BF01000000010000000001000000FFFFFFFF0000000002".toCharArray());
This code will create a Geometry and Geography object that is equivalent to the ones created from the WKT
previously.
The same can be done for the Geography counterpart, using a Geography column and setGeography()
method.
To read a Geometry / Geography column:
The same can be done for the Geography counterpart, using a Geography column and getGeography()
method.
SQLServerResultSet
M ET H O D DESC RIP T IO N
Geometry getGeometry(int colunIndex) Returns the value of the designated column in the current
row of this ResultSet object as a
com.microsoft.sqlserver.jdbc.Geometry object in the Java
programming language.
Geometry getGeometry(String columnName) Returns the value of the designated column in the current
row of this ResultSet object as a
com.microsoft.sqlserver.jdbc.Geometry object in the Java
programming language.
Geography getGeography(int colunIndex) Returns the value of the designated column in the current
row of this ResultSet object as a
com.microsoft.sqlserver.jdbc.Geography object in the Java
programming language.
M ET H O D DESC RIP T IO N
Geography getGeography(String columnName) Returns the value of the designated column in the current
row of this ResultSet object as a
com.microsoft.sqlserver.jdbc.Geography object in the Java
programming language.
Geometry
M ET H O D DESC RIP T IO N
Geometry STGeomFromText(String wkt , int SRID ) Constructor for a Geometry instance from an Open
Geospatial Consortium (OGC) Well-Known Text (WKT)
representation augmented with any Z (elevation) and M
(measure) values carried by the instance.
Geometries deserialize(byte[] clr) Constructor for a Geometry instance from an internal SQL
Server format for spatial data.
Geometry point(double x, double y, int SRID) Constructor for a Geometry instance that represents a Point
instance from its X and Y values and a Spatial Reference
Identifier.
byte[] STAsBinary() Returns the internal SQL Server format (CLR) representation
of a Geometry instance. This value won't contain any Z or M
values carried by the instance.
byte[] serialize() Returns the bytes that represent an internal SQL Server
format of Geometry type.
String STGeometryType() Returns the Open Geospatial Consortium (OGC) type name
represented by a geometry instance.
Geography
M ET H O D DESC RIP T IO N
Geography STGeomFromText(String wkt, int SRID) Constructor for a Geography instance from an Open
Geospatial Consortium (OGC) Well-Known Text (WKT)
representation augmented with any Z (elevation) and M
(measure) values carried by the instance.
Geography deserialize(byte[] clr) Constructor for a Geography instance from an internal SQL
Server format for spatial data.
Geography point(double lon, double lat, int SRID) Constructor for a Geography instance that represents a
Point instance from its longitude and latitude and a Spatial
Reference Identifier.
byte[] STAsBinary()) Returns the internal SQL Server format (CLR) representation
of a Geography instance. This value won't contain any Z or
M values carried by the instance.
M ET H O D DESC RIP T IO N
byte[] serialize() Returns the bytes that represent an internal SQL Server
format of Geography type.
String STGeographyType() Returns the Open Geospatial Consortium (OGC) type name
represented by a geography instance.
See also
Spatial data types sample (JDBC)
User defined types
4/27/2022 • 2 minutes to read • Edit Online
See also
Understanding the JDBC driver data types
Configuring how java.sql.Time values are sent
4/27/2022 • 2 minutes to read • Edit Online
SendTimeAsDatetime
You can configure how the java.sql.Time value is sent by using the sendTimeAsDatetime connection property.
For more information, see Setting the Connection Properties.
You can programmatically modify the value of the sendTimeAsDatetime connection property with
SQLServerDataSource.setSendTimeAsDatetime.
Versions of SQL Server earlier than SQL Server 2008 don't support the time data type, so applications using
java.sql.Time typically store java.sql.Time values either as datetime or smalldatetime SQL Server data types.
If you want to use the datetime and smalldatetime SQL Server data types when working with java.sql.Time
values, you should set the sendTimeAsDatetime connection property to true . If you want to use the time SQL
Server data type when working with java.sql.Time values, you should set the sendTimeAsDatetime connection
property to false .
Sending java.sql.Time values into a parameter whose data type can also store the date, that default dates are
different depending on whether the java.sql.Time value is sent as a datetime (1/1/1970) or time (1/1/1900)
value. For more information about data conversions when sending data to a SQL Server, see Using Date and
Time Data.
In SQL Server JDBC Driver 3.0, sendTimeAsDatetime is true by default. In a future release, the
sendTimeAsDatetime connection property may be set to false by default.
To ensure that your application continues to work as expected regardless of the default value of the
sendTimeAsDatetime connection property, you can:
Use java.sql.Time when working with the time SQL Server data type.
Use java.sql.Timestamp when working with the datetime , smalldatetime , and datetime2 SQL Server data
types.
SendTimeAsDatetime must be false for encrypted columns as encrypted columns don't support the conversion
from time to datetime. Beginning with Microsoft JDBC Driver 6.0 for SQL Server, the SQLServerConnection class
has the following two methods to set/get the value of the sendTimeAsDatetime property.
public boolean getSendTimeAsDatetime()
public void setSendTimeAsDatetime(boolean sendTimeAsDateTimeValue)
See also
Understanding the JDBC driver data types
Programming with SQLXML
4/27/2022 • 5 minutes to read • Edit Online
M ET H O D N A M E ( REA DA B L E) ( W RITA B L E)
As shown in the table above, the setter SQLXML methods will not work with the readable SQLXML objects;
similarly, the getter methods will not work with the writable SQLXML objects.
If the application invokes the setObject method by specifying a scale or a length parameter with a SQLXML
object, the scale or length parameter is ignored.
See also
Supporting XML data
Supporting XML data
4/27/2022 • 2 minutes to read • Edit Online
IMPORTANT
SQL Server always validates the XML data before storing it in the database column. Applications can use SQLXML data
type, because the JDBC driver maps it to the xml data type automatically. The SQLXML support is available in
sqljdbc4.jar. See System Requirements for the JDBC driver for the list of JRE versions supported by the Microsoft JDBC
Driver for SQL Server.
The articles in this section describe the SQLXML interface and how to program against the SQLXML data type
by using the JDBC API methods.
In this section
A RT IC L E DESC RIP T IO N
Programming with SQLXML Describes how to use the Microsoft JDBC Driver for SQL
Server API methods to store and retrieve an XML data in
and from a relational database with the SQLXML Java data
type. Also contains information about the types of SQLXML
objects and provides a list of important guidelines and
limitations when using SQLXML objects.
See also
Understanding the JDBC driver data types
SQLXML interface
4/27/2022 • 2 minutes to read • Edit Online
Remarks
The following table describes the methods defined in the SQLXML interface:
M ET H O D SY N TA X M ET H O D DESC RIP T IO N
void free() This method frees the SQLXML object and releases the
resources that it holds.
InputStream getBinaryStream() Returns an input stream to read data from the SQLXML.
T extends Source T getSource(Class<T> sourceClass) Returns a Source for reading the XML value specified by
this SQLXML object.
OutputStream setBinaryStream() Retrieves a stream that can be used to write the XML value
that this SQLXML object represents.
Writer setCharacterStream() Returns a stream to be used to write the XML value that
this SQLXML object represents.
T extends Result T setResult(Class<T> resultClass) Returns a Result for setting the XML value specified by this
SQLXML object.
void setString(String value) Sets the XML value designated by this SQLXML object to the
specified String representation.
The applications can read and write XML values to or from an SQLXML object only once.
When the free() method is called, a SQLXML object becomes invalid and is neither readable nor writeable. If the
application tries to invoke a method on that SQLXML object other than the free() method, an exception is
thrown.
The SQLXML object becomes neither readable nor writable when the application calls any of the following getter
methods: getSource, getCharacterStream, getBinaryStream, and getString.
The SQLXML object becomes neither writeable nor readable when the application calls any of the following
setter methods: setResult, setCharacterStream, setBinaryStream, and setString.
See also
Supporting XML data
Using statements with SQL
4/27/2022 • 2 minutes to read • Edit Online
NOTE
If you need to use SQL statements that contain both IN and OUT parameters, you must implement them as stored
procedures and call them by using the SQLServerCallableStatement class. For more information about using stored
procedures, see Using statements with stored procedures.
The following sections describe the different scenarios for working with data in a SQL Server database by using
SQL statements.
In This Section
TO P IC DESC RIP T IO N
Using an SQL statement with no parameters Describes how to use SQL statements that contain no
parameters.
Using an SQL statement with parameters Describes how to use SQL statements that contain
parameters.
Using an SQL statement to modify database objects Describes how to use SQL statements to modify database
objects.
Using an SQL statement to modify data Describes how to use SQL statements to modify data in a
database.
See also
Using Statements with the JDBC driver
Using an SQL statement with no parameters
4/27/2022 • 2 minutes to read • Edit Online
while (rs.next()) {
System.out.println(rs.getString("LastName") + ", " + rs.getString("FirstName"));
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
}
For more information about using result sets, see Managing result sets with the JDBC driver.
See also
Using statements with SQL
Using an SQL statement with parameters
4/27/2022 • 2 minutes to read • Edit Online
while (rs.next()) {
System.out.println(rs.getString("LastName") + ", " + rs.getString("FirstName"));
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
}
See also
Using statements with SQL
Using an SQL statement to modify database objects
4/27/2022 • 2 minutes to read • Edit Online
NOTE
SQL statements that modify objects within a database are called Data Definition Language (DDL) statements. These
include statements such as CREATE TABLE , DROP TABLE , CREATE INDEX , and DROP INDEX . For more information
about the types of DDL statements that are supported by SQL Server, see SQL Server Books Online.
In the following example, an open connection to the sample database is passed in to the function, an SQL
statement is constructed that will create the simple TestTable in the database, and then the statement is run and
the return value is displayed.
See also
Using statements with SQL
Using an SQL statement to modify data
4/27/2022 • 2 minutes to read • Edit Online
NOTE
If you must use an SQL statement that contains parameters to modify the data in a SQL Server database, you should use
the executeUpdate method of the SQLServerPreparedStatement class.
If the column that you are trying to insert data into contains special characters such as spaces, you must provide the
values to be inserted, even if they are default values. If you do not, the insert operation will fail.
If you want the JDBC driver to return all update counts, including update counts returned by any triggers that may have
fired, set the lastUpdateCount connection string property to "false". For more information about the lastUpdateCount
property, see Setting the connection properties.
See also
Using statements with SQL
Using statements with stored procedures
4/27/2022 • 2 minutes to read • Edit Online
NOTE
For more information about SQL Server stored procedures, see "Understanding Stored Procedures" in SQL Server Books
Online.
To work with data in a SQL Server database by using a stored procedure, the Microsoft JDBC Driver for SQL
Server provides the SQLServerStatement, SQLServerPreparedStatement, and SQLServerCallableStatement
classes. Which class you use depends on whether IN (input) or OUT (output) parameters are required by the
stored procedure. If the stored procedure requires no IN or OUT parameters, you can use the
SQLServerStatement class; if the stored procedure will be called multiple times, or requires only IN parameters,
you can use the SQLServerPreparedStatement class. If the stored procedure requires both IN and OUT
parameters, you should use the SQLServerCallableStatement class. It is only when the stored procedure requires
OUT parameters that you will need the overhead of using the SQLServerCallableStatement class.
NOTE
Stored procedures can also return update counts and multiple result sets. For more information, see Using a stored
procedure with an update count and Using multiple result sets.
When you use the JDBC driver to call a stored procedure with parameters, you must use the call SQL escape
sequence together with the prepareCall method of the SQLServerConnection class. The complete syntax for the
call escape sequence is as follows:
{[?=]call procedure-name[([parameter][,[parameter]]...)]}
NOTE
For more information about the call and other SQL escape sequences, see Using SQL escape sequences.
The topics in this section describe the ways that you can call SQL Server stored procedures by using the JDBC
driver and the call SQL escape sequence.
In this section
TO P IC DESC RIP T IO N
Using a stored procedure with no parameters Describes how to use the JDBC driver to run stored
procedures that contain no input or output parameters.
Using a stored procedure with input parameters Describes how to use the JDBC driver to run stored
procedures that contain input parameters.
Using a stored procedure with output parameters Describes how to use the JDBC driver to run stored
procedures that contain output parameters.
Using a stored procedure with a return status Describes how to use the JDBC driver to run stored
procedures that contain return status values.
Using a stored procedure with an update count Describes how to use the JDBC driver to run stored
procedures that return update counts.
See also
Using statements with the JDBC driver
Using a stored procedure with no parameters
4/27/2022 • 2 minutes to read • Edit Online
NOTE
For more information about the SQL escape sequences, see Using SQL escape sequences.
This stored procedure returns a single result set that contains one column of data, which is a combination of the
title, first name, and last name of the top 10 contacts that are in the Person.Contact table.
In the following example, an open connection to the sample database is passed in to the function, and the
executeQuery method is used to call the GetContactFormalNames stored procedure.
See also
Using statements with stored procedures
Using a stored procedure with input parameters
4/27/2022 • 2 minutes to read • Edit Online
{call procedure-name[([parameter][,[parameter]]...)]}
NOTE
For more information about the SQL escape sequences, see Using SQL escape sequences.
When you construct the call escape sequence, specify the IN parameters by using the ? (question mark)
character. This character acts as a placeholder for the parameter values that will be passed into the stored
procedure. To specify a value for a parameter, you can use one of the setter methods of the
SQLServerPreparedStatement class. The setter method that you can use is determined by the data type of the IN
parameter.
When you pass a value to the setter method, you must specify not only the actual value that will be used in the
parameter, but also the ordinal placement of the parameter in the stored procedure. For example, if your stored
procedure contains a single IN parameter, its ordinal value will be 1. If the stored procedure contains two
parameters, the first ordinal value will be 1, and the second ordinal value will be 2.
As an example of how to call a stored procedure that contains an IN parameter, use the
uspGetEmployeeManagers stored procedure in the sample database. This stored procedure accepts a single
input parameter named EmployeeID, which is an integer value, and it returns a recursive list of employees and
their managers based on the specified EmployeeID. The Java code for calling this stored procedure is as follows:
pstmt.setInt(1, 50);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
System.out.println("EMPLOYEE:");
System.out.println(rs.getString("LastName") + ", " + rs.getString("FirstName"));
System.out.println("MANAGER:");
System.out.println(rs.getString("ManagerLastName") + ", " + rs.getString("ManagerFirstName"));
System.out.println();
}
}
}
See also
Using statements with stored procedures
Using a stored procedure with output parameters
4/27/2022 • 3 minutes to read • Edit Online
NOTE
For more information about the SQL escape sequences, see Using SQL escape sequences.
When you construct the call escape sequence, specify the OUT parameters by using the ? (question mark)
character. This character acts as a placeholder for the parameter values that will be returned from the stored
procedure. To specify a value for an OUT parameter, you must specify the data type of each parameter by using
the registerOutParameter method of the SQLServerCallableStatement class before you run the stored
procedure.
The value that you specify for the OUT parameter in the registerOutParameter method must be one of the JDBC
data types contained in java.sql.Types, which in turn maps to one of the native SQL Server data types. For more
information about the JDBC and SQL Server data types, see Understanding the JDBC Driver data types.
When you pass a value to the registerOutParameter method for an OUT parameter, you must specify not only
the data type to be used for the parameter, but also the parameter's ordinal placement or the parameter's name
in the stored procedure. For example, if your stored procedure contains a single OUT parameter, its ordinal value
will be 1; if the stored procedure contains two parameters, the first ordinal value will be 1, and the second
ordinal value will be 2.
NOTE
The JDBC driver does not support the use of CURSOR, SQLVARIANT, TABLE, and TIMESTAMP SQL Server data types as
OUT parameters.
This stored procedure returns a single OUT parameter (managerID), which is an integer, based on the specified
IN parameter (employeeID), which is also an integer. The value that is returned in the OUT parameter is the
ManagerID based on the EmployeeID that is contained in the HumanResources.Employee table.
In the following example, an open connection to the sample database is passed in to the function, and the
execute method is used to call the GetImmediateManager stored procedure:
This example uses the ordinal positions to identify the parameters. Alternatively, you can identify a parameter by
using its name instead of its ordinal position. The following code example modifies the previous example to
demonstrate how to use named parameters in a Java application. Note that parameter names correspond to the
parameter names in the stored procedure's definition:
NOTE
These examples use the execute method of the SQLServerCallableStatement class to run the stored procedure. This is
used because the stored procedure did not also return a result set. If it did, the executeQuery method would be used.
Stored procedures can return update counts and multiple result sets. The Microsoft JDBC Driver for SQL Server
follows the JDBC 3.0 specification, which states that multiple result sets and update counts should be retrieved
before the OUT parameters are retrieved. That is, the application should retrieve all of the ResultSet objects and
update counts before retrieving the OUT parameters by using the CallableStatement.getter methods. Otherwise,
the ResultSet objects and update counts that haven't already been retrieved will be lost when the OUT
parameters are retrieved. For more information about update counts and multiple result sets, see Using a stored
procedure with an update count and Using Multiple Result Sets.
See also
Using statements with stored procedures
Using a stored procedure with a return status
4/27/2022 • 2 minutes to read • Edit Online
{[?=]call procedure-name[([parameter][,[parameter]]...)]}
NOTE
For more information about the SQL escape sequences, see Using SQL escape sequences.
When you construct the call escape sequence, specify the return status parameter by using the ? (question
mark) character. This character acts as a placeholder for the parameter value that will be returned from the
stored procedure. To specify a value for a return status parameter, you must specify the data type of the
parameter by using the registerOutParameter method of the SQLServerCallableStatement class, before
executing the stored procedure.
NOTE
When using the JDBC driver with a SQL Server database, the value that you specify for the return status parameter in the
registerOutParameter method will always be an integer, which you can specify by using the java.sql.Types.INTEGER data
type.
In addition, when you pass a value to the registerOutParameter method for a return status parameter, you must
specify not only the data type to be used for the parameter, but also the parameter's ordinal placement in the
stored procedure call. In the case of the return status parameter, its ordinal position will always be 1 because it is
always the first parameter in the call to the stored procedure. Although the SQLServerCallableStatement class
provides support for using the parameter's name to indicate the specific parameter, you can use only a
parameter's ordinal position number for return status parameters.
As an example, create the following stored procedure in the sample database:
CREATE PROCEDURE CheckContactCity
(@cityName CHAR(50))
AS
BEGIN
IF ((SELECT COUNT(*)
FROM Person.Address
WHERE City = @cityName) > 1)
RETURN 1
ELSE
RETURN 0
END
This stored procedure returns a status value of 1 or 0, depending on whether the city that is specified in the
cityName parameter is found in the Person.Address table.
In the following example, an open connection to the sample database is passed in to the function, and the
execute method is used to call the CheckContactCity stored procedure:
See also
Using statements with stored procedures
Using a stored procedure with an update count
4/27/2022 • 2 minutes to read • Edit Online
NOTE
If you want the JDBC driver to return all update counts, including update counts returned by any triggers that may have
fired, set the lastUpdateCount connection string property to "false". For more information about the lastUpdateCount
property, see Setting the connection properties.
As an example, create the following table and stored procedure, and also insert sample data in the sample
database:
In the following example, an open connection to the sample database is passed in to the function, the execute
method is used to call the UpdateTestTable stored procedure, and then the getUpdateCount method is used to
return a count of the rows that are affected by the stored procedure.
public static void executeUpdateStoredProcedure(Connection con) {
try(CallableStatement cstmt = con.prepareCall("{call dbo.UpdateTestTable(?, ?)}");) {
cstmt.setString(1, "A");
cstmt.setInt(2, 100);
cstmt.execute();
int count = cstmt.getUpdateCount();
System.out.println("ROWS AFFECTED: " + count);
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
}
See also
Using statements with stored procedures
Using table-valued parameters
4/27/2022 • 13 minutes to read • Edit Online
NOTE
Support for Table-Valued Parameters is available starting with Microsoft JDBC Driver 6.0 for SQL Server.
You can't return data in a table-valued parameter. Table-valued parameters are input-only; the OUTPUT keyword is not
supported.
For more information about table-valued parameters, see the following resources.
Table-Valued Parameters (Database Engine) in SQL Server Describes how to create and use table-valued parameters
Books Online
User-Defined Table Types in SQL Server Books Online Describes user-defined table types that are used to declare
table-valued parameters
After creating a table type, you can declare table-valued parameters based on that type. The following Transact-
SQL fragment demonstrates how to declare a table-valued parameter in a stored procedure definition. The
READONLY keyword is required for declaring a table-valued parameter.
UPDATE dbo.Categories
SET Categories.CategoryName = ec.CategoryName
FROM dbo.Categories INNER JOIN @tvpEditedCategories AS ec
ON dbo.Categories.CategoryID = ec.CategoryID;
This Transact-SQL example demonstrates how to select rows from a table-valued parameter to perform an
INSERT in a single set-based operation.
NOTE
See Section Table-Valued Parameter API for the JDBC Driver below for a complete list of APIs available for setting
the table-valued parameter.
This example is similar to the previous one. The only difference is that it sets the TVP Name on the
SQLServerDataTable instead of relying on casting PreparedStatement to a SQLServerPreparedStatement to use the
setStructured method.
NOTE
See Section Table-Valued Parameter API for the JDBC Driver below for a complete list of APIs available for setting
the table-valued parameter.
// Create the source ResultSet object. Here SourceCategories is a table defined with the same schema as
Categories table.
ResultSet sourceResultSet = connection.createStatement().executeQuery("SELECT * FROM SourceCategories");
// Pass the source result set as a table-valued parameter using a prepared statement.
SQLServerPreparedStatement pStmt =
(SQLServerPreparedStatement) connection.prepareStatement(
"INSERT INTO dbo.Categories SELECT * FROM ?;");
pStmt.setStructured(1, "dbo.CategoryTableType", sourceResultSet);
pStmt.execute();
NOTE
See Section Table-Valued Parameter API for the JDBC Driver below for a complete list of APIs available for setting
the table-valued parameter.
MyRecords(){
// Constructor. This implementation has just one row.
row[0] = new Integer(1);
row[1] = "categoryName1";
}
NOTE
See Section Table-valued parameter API for the JDBC driver below for a complete list of APIs available for setting
the table-valued parameter.
public SQLServerMetaData(String columnName, int sqlType, Initializes a new instance of SQLServerMetaData with the
int precision, int scale, boolean useServerDefault, boolean specified column name, sql type, precision, scale and server
isUniqueKey, SQLServerSortOrder sortOrder, int sortOrdinal) default. This form of the constructor supports table-valued
parameters by allowing you to specify if the column is
unique in the table-valued parameter, the sort order for the
column, and the ordinal of the sort column.
public SQLServerMetaData(String columnName, int sqlType) Initializes a new instance of SQLServerMetaData using the
column name and the sql type.
public SQLServerMetaData(String columnName, int sqlType, Initializes a new instance of SQLServerMetaData using the
int length) column name, the sql type and the length (for String data).
The length is used to differentiate large strings from strings
with length less than 4000 characters. Introduced in the
version 7.2 of the JDBC driver.
public SQLServerMetaData(String columnName, int sqlType, Initializes a new instance of SQLServerMetaData using the
int precision, int scale) column name, sql type, precision and scale.
public int getPrecision() Retrieves the precision of the type passed to the column.
public int getScale() Retrieves the scale of the type passed to the column.
public boolean useServerDefault() Returns whether the column uses the default server value.
SQLServerSortOrder
An Enum that defines the sort order. Possible values are Ascending, Descending and Unspecified.
SQLServerDataTable
This class represents an in-memory data table to be used with table-valued parameters. The methods in this
class are:
NAME DESC RIP T IO N
public Iterator<Entry<Integer, Object[]>> getIterator() Retrieves an iterator on the rows of the data table.
public void addColumnMetadata(String columnName, int Adds metadata for the specified column.
sqlType)
public void addRow(Object... values) Adds one row of data to the data table.
public Map<Integer, SQLServerDataColumn> Retrieves column meta data of this data table.
getColumnMetadata()
SQLServerDataColumn
This class represents a column of the in-memory data table represented by SQLServerDataTable. The methods
in this class are:
public SQLServerDataColumn(String columnName, int Initializes a new instance of SQLServerDataColumn with the
sqlType) column name and type.
ISQLServerDataRecord
This class represents an interface that users can implement to stream data to a table-valued parameter. The
methods in this interface are:
public SQLServerMetaData getColumnMetaData(int Retrieves the column meta data of the given column index.
column);
public Object[] getRowData(); Retrieves the data for the current row as an array of Objects.
public boolean next(); Moves to the next row. Returns True if the move is successful
and there's a next row, false otherwise.
SQLServerPreparedStatement
The following methods have been added to this class to support passing of table-valued parameters.
NAME DESC RIP T IO N
public final void setStructured(int parameterIndex, String Populates a table-valued parameter with a data table.
tvpName, SQLServerDataTable tvpDataTable) parameterIndex is the parameter index, tvpName is the
name of the table-valued parameter, and tvpDataTable is the
source data table object.
public final void setStructured(int parameterIndex, String Populates a table-valued parameter with a ResultSet
tvpName, ResultSet tvpResultSet) retrieved from another table. parameterIndex is the
parameter index, tvpName is the name of the table-valued
parameter, and tvpResultSet is the source result set object.
public final void setStructured(int parameterIndex, String Populates a table-valued parameter with an
tvpName, ISQLServerDataRecord tvpDataRecord) ISQLServerDataRecord object. ISQLServerDataRecord is used
for streaming data and the user decides how to use it.
parameterIndex is the parameter index, tvpName is the
name of the table-valued parameter, and tvpDataRecord is
an ISQLServerDataRecord object.
SQLServerCallableStatement
The following methods have been added to this class to support passing of table-valued parameters.
public final void setStructured(String paratemeterName, Populates a table-valued parameter passed to a stored
String tvpName, SQLServerDataTable tvpDataTable) procedure with a data table. paratemeterName is the name
of the parameter, tvpName is the name of the type TVP, and
tvpDataTable is the data table object.
public final void setStructured(String paratemeterName, Populates a table-valued parameter passed to a stored
String tvpName, ResultSet tvpResultSet) procedure with a ResultSet retrieved from another table.
paratemeterName is the name of the parameter, tvpName is
the name of the type TVP, and tvpResultSet is the source
result set object.
public final void setStructured(String paratemeterName, Populates a table-valued parameter passed to a stored
String tvpName, ISQLServerDataRecord tvpDataRecord) procedure with an ISQLServerDataRecord object.
ISQLServerDataRecord is used for streaming data and the
user decides how to use it. paratemeterName is the name of
the parameter, tvpName is the name of the type TVP, and
tvpDataRecord is an ISQLServerDataRecord object.
See also
Overview of the JDBC driver
Handling complex statements
4/27/2022 • 2 minutes to read • Edit Online
NOTE
For more information about update counts, see Using a stored procedure with an update count.
In the following example, an open connection to the sample database is passed in to the function, and an SQL
statement is constructed that, when run, returns two result sets:
public static void executeStatement(Connection con) {
try (Statement stmt = con.createStatement();) {
String SQL = "SELECT TOP 10 * FROM Person.Contact; SELECT TOP 20 * FROM Person.Contact";
In this case, the number of result sets returned is known to be two. However, the code is written so that if an
unknown number of result sets were returned, such as when calling a stored procedure, they would all be
processed. To see an example of calling a stored procedure that returns multiple result sets along with update
values, see Handling complex statements.
NOTE
When you make the call to the getMoreResults method of the SQLServerStatement class, the previously returned result
set is implicitly closed.
See also
Using statements with the JDBC driver
Using parameter metadata
4/27/2022 • 2 minutes to read • Edit Online
NOTE
There are some limitations when using the SQLServerParameterMetaData class with prepared statements.
With Microsoft JDBC Driver 6.0 (or higher) for SQL Ser ver : When using SQL Server 2008 or 2008 R2, the JDBC
driver supports SELECT, DELETE, INSERT, and UPDATE statements as long as these statements does not contain
subqueries and/or joins.
MERGE queries are also not supported for SQLServerParameterMetaData class when using SQL Server 2008 or
2008 R2. For SQL Server 2012 and higher versions parameter metadata with complex queries are supported.
Retrieval of parameter metadata for encrypted columns are not supported. With Microsoft JDBC Driver 4.1
or 4.2 for SQL Ser ver : The JDBC driver supports SELECT, DELETE, INSERT, and UPDATE statements as long as
these statements does not contain subqueries and/or joins. MERGE queries are also not supported for
SQLServerParameterMetaData class.
Using result set metadata
4/27/2022 • 2 minutes to read • Edit Online
ResultSet rs = stmt.executeQuery(SQL);
ResultSetMetaData rsmd = rs.getMetaData();
See also
Handling metadata with the JDBC driver
Understanding transactions
4/27/2022 • 2 minutes to read • Edit Online
See also
Performing transactions with the JDBC driver
Understanding XA transactions
4/27/2022 • 11 minutes to read • Edit Online
WARNING
Microsoft JDBC Driver 4.2 (and higher) for SQL includes new timeout options for the existing feature for automatic
rollback of unprepared transactions. See Configuring server-side timeout settings for automatic rollback of unprepared
transactions later in this topic for more detail.
Remarks
The classes for the distributed transaction implementation are as follows:
C L A SS IM P L EM EN T S DESC RIP T IO N
NOTE
XA distributed transaction connections default to the Read Committed isolation level.
xaRes.start(xid, SQLServerXAResource.SSTRANSTIGHTLYCPLD);
Configuration instructions
The following steps are required if you want to use XA data sources together with Microsoft Distributed
Transaction Coordinator (MS DTC) for handling distributed transactions.
NOTE
The JDBC distributed transaction components are included in the xa directory of the JDBC driver installation. These
components include the xa_install.sql and sqljdbc_xa.dll files. If you have different versions of the JDBC driver on different
clients, it is recommended to use the newest sqljdbc_xa.dll on the server.
NOTE
The JDBC XA distributed transaction components are included in the SQL Server engine in SQL Server 2017 starting with
cumulative update 16 and in SQL Server 2019, and can be enabled or disabled with a system stored procedure. The
sqjdbc_xa.dll from the driver is not required and it is recommended to enable the server components instead for these
server versions. To enable the required components to perform XA distributed transactions using the JDBC driver, execute
the following stored procedure.
EXEC sp_sqljdbc_xa_install
To disable the previously installed components, execute the following stored procedure.
EXEC sp_sqljdbc_xa_uninstall
NOTE
If you are using XA transactions with a 32-bit SQL Server, use the sqljdbc_xa.dll file in the x86 folder, even if the
SQL Server is installed on a x64 processor. If you are using XA transactions with a 64-bit SQL Server on the x64
processor, use the sqljdbc_xa.dll file in the x64 folder.
2. Execute the database script xa_install.sql on every SQL Server instance that will participate in distributed
transactions. This script installs the extended stored procedures that are called by sqljdbc_xa.dll. These
extended stored procedures implement distributed transaction and XA support for the Microsoft JDBC
Driver for SQL Server. You'll need to run this script as an administrator of the SQL Server instance.
3. To grant permissions to a specific user to participate in distributed transactions with the JDBC driver, add
the user to the SqlJDBCXAUser role.
You can configure only one version of the sqljdbc_xa.dll assembly on each SQL Server instance at a time.
Applications may need to use different versions of the JDBC driver to connect to the same SQL Server instance
by using the XA connection. In that case, sqljdbc_xa.dll, which comes with the newest JDBC driver, must be
installed on the SQL Server instance.
There are three ways to verify the version of sqljdbc_xa.dll currently installed on the SQL Server instance:
1. Open the LOG directory of SQL Server computer that will participate in distributed transactions. Select
and open the SQL Server "ERRORLOG" file. Search for "Using 'SQLJDBC_XA.dll' version ..." phrase in the
"ERRORLOG" file.
2. Open the Binn directory of SQL Server computer that will participate in distributed transactions. Select
the sqljdbc_xa.dll assembly.
On Windows Vista or later: Right-click sqljdbc_xa.dll and then select Properties. Then click the Details
tab. The File Version field shows the version of sqljdbc_xa.dll that is currently installed on the SQL
Server instance.
3. Set the logging functionality as shown in the code example in the next section. Search for "Server XA DLL
version:..." phrase in the output log file.
Configuring server-side timeout settings for automatic rollback of unprepared transactions
WARNING
This server-side option is new with Microsoft JDBC Driver 4.2 (and higher) for SQL Server. To get the updated behavior,
make sure the sqljdbc_xa.dll on the server is updated. For more information on setting client side timeouts, see
XAResource.setTransactionTimeout().
There are two registry settings (DWORD values) to control the timeout behavior of distributed transactions:
XADefaultTimeout (in seconds): The default timeout value to be used when the user does not specify
any timeout. The default is 0.
XAMaxTimeout (in seconds): The maximum value of the timeout that a user can set. The default is 0.
These settings are SQL Server instance specific and should be created under the following registry key:
A timeout value is set for each transaction when it's started and the transaction is rolled back by the SQL Server
if the timeout expires. The timeout is determined depending on these registry settings and depending on what
the user has specified through XAResource.setTransactionTimeout(). A few examples on how these timeout
values are interpreted as follows:
XADefaultTimeout = 0 , XAMaxTimeout = 0
Means no default timeout will be used, and no maximum timeout will be enforced on clients. In this case,
the transactions will have a timeout only if the client sets a timeout using
XAResource.setTransactionTimeout.
XADefaultTimeout = 60 , XAMaxTimeout = 0
Means all transactions will have a 60-second timeout if the client doesn't specify any timeout. If the client
specifies a timeout, then that timeout value will be used. No maximum value for timeout is enforced.
XADefaultTimeout = 30 , XAMaxTimeout = 60
Means all transactions will have a 30-second timeout if the client doesn't specify any timeout. If client
specifies any timeout, then the client's timeout will be used as long as it is less than 60 seconds (the max
value).
XADefaultTimeout = 0 , XAMaxTimeout = 30
Means all transactions will have a 30-second timeout (the max value) if the client does not specify any
timeout. If the client specifies any timeout, then the client's timeout will be used as long as it is less than
30 seconds (the max value).
Upgrading sqljdbc_xa.dll
When you install a new version of the JDBC driver, you should also use sqljdbc_xa.dll from the new version to
upgrade sqljdbc_xa.dll on the server.
IMPORTANT
You should upgrade sqljdbc_xa.dll during a maintenance window or when there are no MS DTC transactions in progress.
SQL user-defined roles are defined per database. To create your own role for security purposes, you'll have to
define the role in each database, and add users in a per database manner. The SqlJDBCXAUser role is strictly
defined in the master database because it's used to grant access to the SQL JDBC extended stored procedures
that reside in master. You'll have to first grant individual users access to master, and then grant them access to
the SqlJDBCXAUser role while you're logged into the master database.
Example
import java.net.Inet4Address;
import java.sql.*;
import java.util.Random;
import javax.sql.XAConnection;
import javax.transaction.xa.*;
import com.microsoft.sqlserver.jdbc.*;
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
}
// Create the XA data source and XA ready connection.
SQLServerXADataSource ds = new SQLServerXADataSource();
ds.setUser(user);
ds.setPassword(password);
ds.setServerName(serverName);
ds.setPortNumber(portNumber);
ds.setDatabaseName(databaseName);
// Open a new connection and read back the record to verify that it worked.
try (Connection con = DriverManager.getConnection(connectionUrl); Statement stmt =
con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM XAMin")) {
rs.next();
System.out.println("Read -> xid = " + rs.getString(2));
stmt.executeUpdate("DROP TABLE XAMin");
}
}
}
See also
Performing transactions with the JDBC driver
Using holdability
4/27/2022 • 2 minutes to read • Edit Online
The JDBC driver also supports setting holdability when creating one of the Statement objects. When creating the
Statement objects that have overloads with result set holdability parameters, the holdability of statement object
must match the connection's holdability. When they don't match, an exception is thrown. It's because SQL Server
supports the holdability only at the connection level.
The holdability of a result set is the holdability of the SQLServerConnection object that is associated with the
result set at the time when the result set is created for server-side cursors only. It does not apply to client-side
cursors. All result sets with client-side cursors will always have the holdability value of
ResultSet.HOLD_CURSORS_OVER_COMMIT .
For server cursors, when connected to SQL Server 2005 or later, setting the holdability affects only the
holdability of new result sets that are yet to be created on that connection. It means that setting holdability has
no impact on the holdability of any result sets that were previously created and are already open on that
connection.
In the following example, the result set holdability is set while performing a local transaction consisting of two
separate statements in the try block. The statements are run against the Production.ScrapReason table in the
sample database. First, the example switches to manual transaction mode by setting the auto-commit to false .
Once auto-commit mode is disabled, no SQL Statements will be committed until the application calls the
commit method explicitly. The code in the catch block rolls back the transaction if an exception is thrown.
public static void executeTransaction(Connection con) {
try (Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);) {
con.setAutoCommit(false);
con.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
// Display results.
while (rs.next()) {
System.out.println(rs.getString(2));
}
}
catch (SQLException ex) {
ex.printStackTrace();
try {
System.out.println("Transaction failed.");
con.rollback();
}
catch (SQLException se) {
se.printStackTrace();
}
}
}
See also
Performing transactions with the JDBC driver
Using savepoints
4/27/2022 • 2 minutes to read • Edit Online
See also
Performing transactions with the JDBC driver
Understanding row locking
4/27/2022 • 2 minutes to read • Edit Online
NOTE
If row locking is used, all rows in the fetch buffer are locked, so a very large setting for the fetch size can affect
concurrency.
Locking is used to assure transactional integrity and database consistency. Locking prevents users from reading
data that is being changed by other users, and prevents multiple users from changing the same data at the same
time. If locking is not used, data within the database might become logically incorrect, and queries run against
that data might produce unexpected results.
NOTE
For more information about row locking in SQL Server, see Locking in the Database Engine.
See also
Managing result sets with the JDBC driver
Understanding concurrency control
4/27/2022 • 2 minutes to read • Edit Online
NOTE
For more information about SQL Server concurrency, see "Managing Concurrent Data Access".
Remarks
The JDBC driver supports the following concurrency types:
Statement is not created by using JDBC 2.0 introduced new methods to Specify result set type and concurrency
JDBC 2.0 (or later) syntax create statements. If JDBC 1.0 syntax is when creating the statement.
used, the result set defaults to read-
only.
Statement is created by using SQL Server creates a static snapshot Use TYPE_SCROLL_SENSITIVE,
TYPE_SCROLL_INSENSITIVE cursor. This is disconnected from the TYPE_SS_SCROLL_KEYSET,
underlying table rows to help protect TYPE_SS_SCROLL_DYNAMIC, or
the cursor from row updates by other TYPE_FORWARD_ONLY with
users. CONCUR_UPDATABLE to avoid
creating a static cursor.
Table design precludes a KEYSET or The underlying table does not have Add unique keys to the table to
DYNAMIC cursor unique keys to enable SQL Server to provide unique identification of each
uniquely identify a row. row.
See also
Managing result sets with the JDBC driver
International features of the JDBC driver
4/27/2022 • 3 minutes to read • Edit Online
Non-unicode parameters
For optimal performance with CHAR , VARCHAR or LONGVARCHAR type of non-Unicode parameters, set the
sendStringParametersAsUnicode connection string property to "false" and use the non-national character
methods.
Formatting issues
For date, time, and currencies, all formatting with localized data is done at the Java language level using the
Locale object; and the various formatting methods for Date , Calendar , and Number data types. In the rare
case where the JDBC driver must pass along locale sensitive data in a localized format, the proper formatter is
used with the default JVM locale.
Collation support
The JDBC Driver 3.0 supports all the collations supported by SQL Server 2000 (8.x), SQL Server 2005 (9.x), and
the new collations or new versions of Windows collation names introduced in SQL Server 2008.
For more information on the collations, see Collation and Unicode Support and Windows Collation Name
(Transact-SQL).
NOTE
Most resolver software written for non-Windows platforms is based on the Internet DSN standards and is therefore most
likely to use the Punycode format for IDNs, while a Windows-based DNS Server on a private network can be configured
to allow the use of UTF-8 characters on a per-server basis. For more information, see Unicode character support.
See also
Overview of the JDBC driver
National character set support
4/27/2022 • 2 minutes to read • Edit Online
NOTE
You must set the classpath to include the sqljdbc4.jar file to use these methods in your application.
To send String parameters to the server in Unicode format, the applications should either use the new JDBC 4.0
national character methods; or set the sendStringParametersAsUnicode connection property to "true " when
using the non-national character methods. The recommended way is to use the new JDBC 4.0 national character
methods where possible. For more information about the sendStringParametersAsUnicode connection
property, see Setting the Connection Properties.
See also
Understanding the JDBC driver data types
Using database metadata
4/27/2022 • 2 minutes to read • Edit Online
See also
Handling metadata with the JDBC driver
Always Encrypted API reference for the JDBC driver
4/27/2022 • 16 minutes to read • Edit Online
NOTE
Always Encrypted is supported only by Microsoft JDBC Driver 6.0 or higher for SQL Server with Azure SQL Database and
SQL Server 2016 and higher.
New method: Returns a list of trusted key paths for a database server.
New method: Allows you to register custom key store providers. It's a
dictionary that maps key store provider names to key store
public static void provider implementations.
registerColumnEncryptionKeyStoreProviders (Map\
<String, SQLServerColumnEncryptionKeyStoreProvider>
clientKeyStoreProviders) To use the JVM key store, you need to instantiate a
SQLServerColumnEncryptionJVMKeyStoreProvider object
with JVM keystore credentials and register it with the driver.
The name for this provider must be
'MSSQL_JVM_KEYSTORE'.
New method: Allows you to unregister all the custom key store providers
by clearing the dictionary that maps key store provider
public static void names to key store provider implementations.
unregisterColumnEncryptionKeyStoreProviders (Map\
<String, SQLServerColumnEncryptionKeyStoreProvider>
clientKeyStoreProviders)
public final boolean getSendTimeAsDatetime() Returns the setting of the sendTimeAsDatetime connection
property.
SQLServerConnectionPoolProxy class
NAME DESC RIP T IO N
public final boolean getSendTimeAsDatetime() Returns the setting of the sendTimeAsDatetime connection
property.
SQLServerDataSource class
NAME DESC RIP T IO N
public void setColumnEncryptionSetting(String Enables/disables Always Encrypted functionality for the data
columnEncryptionSetting) source object.
public String getColumnEncryptionSetting() Retrieves the Always Encrypted functionality setting for the
data source object.
NAME DESC RIP T IO N
public void setKeyStoreAuthentication(String Sets the name that identifies a key store. Only value
keyStoreAuthentication) supported is the JavaKeyStorePassword for identifying
the Java Key Store.
public String getKeyStoreAuthentication() Gets the value of the keyStoreAuthentication setting for the
data source object.
public void setKeyStoreSecret(String Sets the password for the Java keystore. The password for
keyStoreSecret) the keystore and the key must be the same.
keyStoreAuthentication must be set with
JavaKeyStorePassword .
public void setKeyStoreLocation(String Sets the location including the file name for the Java
keyStoreLocation) keystore. keyStoreAuthentication must be set with
JavaKeyStorePassword .
public String getKeyStoreLocation() Retrieves the keyStoreLocation for the Java Key Store.
SQLServerColumnEncryptionJavaKeyStoreProvider class
The implementation of the key store provider for Java Key Store. This class enables using certificates stored in
the Java keystore as column master keys.
Constructors:
Methods:
public byte[] decryptColumnEncryptionKey (String Decrypts the specified encrypted value of a column
masterKeyPath, String encryptionAlgorithm, byte[] encryption key. The encrypted value is expected to be
encryptedColumnEncryptionKey)
encrypted using the certificate with the specified key path
and using the specified algorithm.
Thumbprint:<certificate_thumbprint>
Alias:<certificate_alias>
(Overrides SQLServerColumnEncryptionKeyStoreProvider .
decryptColumnEncryptionKey(String, String, Byte[]).)
NAME DESC RIP T IO N
public byte[] encryptColumnEncryptionKey (String Encrypts a column encryption key using the certificate with
masterKeyPath, String encryptionAlgorithm, byte[] the specified key path and using the specified algorithm.
plainTextColumnEncryptionKey)
Thumbprint:<certificate_thumbprint>
Alias:<certificate_alias>
(Overrides SQLServerColumnEncryptionKeyStoreProvider .
encryptColumnEncryptionKey(String, String, Byte[]).)
public boolean verifyColumnEncryptionKey (String Verifies the signature of the column encryption key using
masterKeyPath, boolean allowEnclaveComputations, the certificate.
byte[] signature)
Thumbprint:<certificate_thumbprint>
Alias:<certificate_alias>
(Overrides SQLServerColumnEncryptionKeyStoreProvider .
verifyColumnEncryptionKey(String, boolean, Byte[]).)
public void setName (String name) Sets the name of this key store provider.
public String getName () Gets the name of this key store provider.
SQLServerColumnEncryptionAzureKeyVaultProvider class
The implementation of the key store provider for Azure Key Vault. This class enables using keys stored in the
Azure Key Vault as column master keys.
Constructors:
public Constructs a
SQLServerColumnEncryptionAzureKeyVaultProvider () SQLServerColumnEncryptionAzureKeyVaultProvider to
authenticate to Azure Key Vault.
public Constructs a
SQLServerColumnEncryptionAzureKeyVaultProvider SQLServerColumnEncryptionAzureKeyVaultProvider to
(String clientId)
authenticate to Azure Key Vault using the identifier of the
client requesting the token.
public Constructs a
SQLServerColumnEncryptionAzureKeyVaultProvider SQLServerColumnEncryptionAzureKeyVaultProvider to
(String clientId, String clientKey)
authenticate to Azure Key Vault using the identifier and the
key of the client requesting the token.
public Constructs a
SQLServerColumnEncryptionAzureKeyVaultProvider SQLServerColumnEncryptionAzureKeyVaultProvider to
(TokenCredential tokenCredential)
authenticate to Azure Key Vault using provided
TokenCredential.
Methods:
public byte[] decryptColumnEncryptionKey (String Decrypts an encrypted column encryption key (CEK). This
masterKeyPath, String encryptionAlgorithm, byte[] decryption is accomplished with an RSA encryption
encryptedColumnEncryptionKey)
algorithm that uses the asymmetric key specified by the
master key path.
(Overrides SQLServerColumnEncryptionKeyStoreProvider .
decryptColumnEncryptionKey(String, String, Byte[]).)
public byte[] encryptColumnEncryptionKey (String Encrypts a column encryption key, by giving the specified
masterKeyPath, String encryptionAlgorithm, byte[] column master key to the specified algorithm.
columnEncryptionKey)
(Overrides SQLServerColumnEncryptionKeyStoreProvider .
encryptColumnEncryptionKey(String, String, Byte[]).)
public void setName (String name) Sets the name of this key store provider.
public String getName () Gets the name of this key store provider.
SQLServerKeyVaultAuthenticationCallback interface
This interface contains one method for Azure Key Vault authentication, which is to be implemented by user.
Methods:
public String getAccessToken(String authority, The method must be overridden. The method is used to get
String resource, String scope); an access token to Azure Key Vault.
SQLServerColumnEncryptionKeyStoreProvider class
Extend this class to implement a custom key store provider.
SQLServerColumnEncryptionKeyStoreProvider Base class for all key store providers. A custom provider
must derive from this class and override its member
functions and then register it using SQLServerConnection.
registerColumnEncryptionKeyStoreProviders().
Methods:
public abstract byte[] decryptColumnEncryptionKey Base class method for decrypting the specified encrypted
(String masterKeyPath, String encryptionAlgorithm, value of a column encryption key. The encrypted value is
byte [] encryptedColumnEncryptionKey)
expected to be encrypted using the column master key with
the specified key path and the specified algorithm.
public abstract byte[] encryptColumnEncryptionKey Base class method for encrypting a column encryption key
(String masterKeyPath, String encryptionAlgorithm, using the column master key with the specified key path and
byte[] columnEncryptionKey)
using the specified algorithm.
public abstract void setName(String name) Sets the name of this key store provider.
NAME DESC RIP T IO N
public abstract String getName() Gets the name of this key store provider.
public void setBigDecimal(int parameterIndex, These methods are overloaded with a precision or a scale
BigDecimal x, int precision, int scale) argument or both to support Always Encrypted for specific
data types that require precision and scale information.
public void setObject(int parameterIndex, Object x,
int targetSqlType, Integer precision, int scale)
public void setMoney(int parameterIndex, BigDecimal These methods add support for Always Encrypted for the
x) data types money, smallmoney, uniqueidentifier, datetime
and smalldatetime.
public void setSmallMoney(int parameterIndex,
BigDecimal x)
The existing setTimestamp() method is used for sending
parameter values to the encrypted datetime2 column. For
public void setUniqueIdentifier(int parameterIndex,
String guid) encrypted datetime and smalldatetime columns, use the new
methods setDateTime() and setSmallDateTime()
public void setDateTime(int parameterIndex, respectively.
java.sql.Timestamp x)
public final void setBigDecimal(int parameterIndex, Sets the named parameter to the given java value.
BigDecimal x, int precision, int scale, boolean
forceEncrypt)
If the boolean forceEncrypt is set to true, the query
parameter will only be set if the designated column is
public final void setMoney(int parameterIndex,
BigDecimal x, boolean forceEncrypt) encrypted and Always Encrypted is enabled on the
connection or on the statement.
public final void setSmallMoney(int parameterIndex,
BigDecimal x, boolean forceEncrypt) If the boolean forceEncrypt is set to false, the driver won't
force encryption on parameters.
public final void setBoolean(int parameterIndex,
boolean x, boolean forceEncrypt)
public void registerOutParameter(int These methods are overloaded with a precision or a scale
parameterIndex, int sqlType, int precision, int argument or both to support Always Encrypted for specific
scale)
data types that require precision and scale information.
public void registerOutParameter(int
parameterIndex, SQLType sqlType, int precision, int
scale)
public void setDateTime(String parameterName, These methods add support for Always Encrypted for the
java.sql.Timestamp x) data types money, smallmoney, uniqueidentifier, datetime
and smalldatetime.
public void setSmallDateTime(String parameterName,
java.sql.Timestamp x)
The existing setTimestamp() method is used for sending
parameter values to the encrypted datetime2 column. For
public void setUniqueIdentifier(String
parameterName, String guid) encrypted datetime and smalldatetime columns, use the new
methods setDateTime() and setSmallDateTime()
public void setMoney(String parameterName,
respectively.
BigDecimal bd)
public void setObject(String parameterName, Object Sets the named parameter to the given java value.
o, int n, int m, boolean forceEncrypt)
If the boolean forceEncrypt is set to true, the query
public void setObject(String parameterName, Object parameter will only be set if the designated column is
obj, SQLType jdbcType, int scale, boolean
forceEncrypt) encrypted and Always Encrypted is enabled on the
connection or on the statement.
public void setDate(String parameterName,
java.sql.Date x, Calendar c, boolean forceEncrypt) If the boolean forceEncrypt is set to false, the driver won't
force encryption on parameters.
public void setTime(String parameterName,
java.sql.Time t, int scale, boolean forceEncrypt)
public String getUniqueIdentifier(int columnIndex) These methods add support for Always Encrypted for the
data types money, smallmoney, uniqueidentifier, datetime,
public String getUniqueIdentifier(String and smalldatetime.
columnLabel)
The existing updateTimestamp() method is used for
public java.sql.Timestamp getDateTime(int updating encrypted datetime2 columns. For encrypted
columnIndex)
datetime and smalldatetime columns, use the new methods
updateDateTime() and updateSmallDateTime()
public java.sql.Timestamp getDateTime(String
columnName) respectively.
public void updateBoolean(int index, boolean x, Updates the named column to the given java value.
boolean forceEncrypt)
If the boolean forceEncrypt is set to true, the column will
public void updateByte(int index, byte x, boolean only be set if it's encrypted and Always Encrypted is enabled
forceEncrypt)
on the connection or on the statement.
public void updateShort(int index, short x, boolean
forceEncrypt) If the boolean forceEncrypt is set to false, the driver won't
force encryption on parameters.
public void updateInt(int index, int x, boolean
forceEncrypt)
DATETIME, SMALLDATETIME, MONEY, SMALLMONEY, GUID Use these types as the target SQL types when sending
parameter values to encr ypted datetime, smalldatetime,
money, smallmoney, uniqueidentifier columns using
setObject()/updateObject() API methods.
SQLServerStatementColumnEncryptionSetting Enum
Specifies how data will be sent and received when reading and writing encrypted columns. Depending on your
specific query, performance impact may be reduced by bypassing the Always Encrypted driver's processing
when non-encrypted columns are being used. These settings can't be used to bypass encryption and gain access
to plaintext data.
Syntax:
Members:
The statement level setting for AE is added to the SQLServerConnection class and to the
SQLServerConnectionPoolProxy class. The following methods in these classes are overloaded with the new
setting.
public Statement createStatement(int nType, int Creates a Statement object that will generate ResultSet
nConcur, int statementHoldability, objects with the given type, concurrency, holdability, and
SQLServerStatementColumnEncryptionSetting
stmtColEncSetting) column encryption setting.
public CallableStatement prepareCall(String sql, Creates a CallableStatement object with the given column
int nType, int nConcur, int statementHoldability, encryption setting that will generate ResultSet objects with
SQLServerStatementColumnEncryptionSetting
stmtColEncSetiing) the given type, concurrency, and holdability.
public PreparedStatement prepareStatement(String Creates a PreparedStatement object with the given column
sql, int autogeneratedKeys, encryption setting that has the capability to retrieve
SQLServerStatementColumnEncryptionSetting
stmtColEncSetting) autogenerated keys.
public PreparedStatement prepareStatement(String Creates a PreparedStatement object with the given column
sql, String[] columnNames, encryption setting that will generate ResultSet objects with
SQLServerStatementColumnEncryptionSetting
stmtColEncSetting) the given column names.
public PreparedStatement prepareStatement(String Creates a PreparedStatement object with the given column
sql, int[] columnIndexes, encryption setting that will generate ResultSet objects with
SQLServerStatementColumnEncryptionSetting
stmtColEncSetting the given column indexes.
NAME DESC RIP T IO N
public PreparedStatement prepareStatement(String Creates a PreparedStatement object with the given column
sql, int nType, int nConcur, int nHold, encryption setting that will generate ResultSet objects with
SQLServerStatementColumnEncryptionSetting
stmtColEncSetting) the given type, concurrency, and holdability.
NOTE
If Always Encrypted is disabled for a query and the query has parameters that need to be encrypted (parameters that
correspond to encrypted columns), the query will fail.
If Always Encrypted is disabled for a query and the query returns results from encrypted columns, the query will return
encrypted values. The encrypted values will have the varbinary datatype.
See also
Using Always Encrypted with the JDBC driver
JDBC driver support for High Availability, disaster
recovery
4/27/2022 • 8 minutes to read • Edit Online
NOTE
multiSubnetFailover is false by default. Use applicationIntent to declare the application workload type. For more
details, see the sections below.
Beginning in version 6.0 of the Microsoft JDBC Driver for SQL Server, a new connection property
transparentNetworkIPResolution (TNIR) is added for transparent connection to Always On availability
groups or to a server that has multiple IP addresses associated. When transparentNetworkIPResolution is
true, the driver attempts to connect to the first IP address available. If the first attempt fails, the driver tries to
connect to all IP addresses in parallel until the timeout expires, discarding any pending connection attempts
when one of them succeeds.
Note:
transparentNetworkIPResolution is true by default
transparentNetworkIPResolution is ignored if multiSubnetFailover is true
transparentNetworkIPResolution is ignored if database mirroring is used
transparentNetworkIPResolution is ignored if there are more than 64 IP addresses
When transparentNetworkIPResolution is true, the first connection attempt uses a timeout value of 500 ms.
Rest of the connection attempts follow the same logic as in the multiSubnetFailover feature.
NOTE
If you are using Microsoft JDBC Driver 4.2 (or lower) for SQL Server and if multiSubnetFailover is false, the Microsoft
JDBC Driver for SQL Server attempts to connect to the first IP address. If the Microsoft JDBC Driver for SQL Server
cannot establish a connection with first IP address, the connection fails. The Microsoft JDBC Driver for SQL Server will not
attempt to connect to any subsequent IP address associated with the server.
NOTE
Increasing connection timeout and implementing connection retry logic will increase the probability that an application
will connect to an availability group. Also, because a connection can fail because of an availability group failover, you
should implement connection retry logic, retrying a failed connection until it reconnects.
Read-only routing
Read-only routing is a feature that can ensure the availability of a read-only replica of a database. To enable
read-only routing, all of the following apply:
You must connect to an Always On availability group listener.
The ApplicationIntent connection string keyword must be set to ReadOnly .
The database administrator must configure the availability group to enable read-only routing.
Multiple connections that each use read-only routing might not all connect to the same read-only replica.
Changes in database synchronization or changes in the server's routing configuration can result in client
connections to different read-only replicas.
You can ensure that all read-only requests connect to the same read-only replica by not passing an availability
group listener to the Server connection string keyword. Instead, specify the name of the read-only instance.
Read-only routing might take longer than connecting to the primary. This is because read-only routing first
connects to the primary, and then looks for the best available readable secondary. Due to these multiple steps,
you should increase your login timeout to at least 30 seconds.
Connection pooling
When using the Microsoft JDBC Driver for SQL Server in combination with a connection pooling library, you
should consider the following points:
If you have read-only routing configured and a pool of read-only servers that you want to distribute load
over, connection pooling will reduce the number of opportunities for new connections to spread over the
target servers.
To avoid a higher load on any single server in a pool, choose pool options that encourage an even
distribution of connections across the pool.
Make sure your connection pool is configured with a connection lifetime. In the event a read-only replica is
unavailable when a read-only connection is made, the configuration should ensure that connection is
eventually closed and re-established to a read-only replica when one becomes available again.
See also
Connecting to SQL Server with the JDBC driver
Setting the connection properties
Using auto-generated keys
4/27/2022 • 2 minutes to read • Edit Online
In the following example, an open connection to the sample database is passed in to the function, an SQL
statement is constructed that will add data to the table, and then the statement is run and the IDENTITY column
value is displayed.
Programming considerations
When the principal database server fails, the client application receives errors in response to API calls, which
indicate that the connection to the database has been lost. When these errors occur, any uncommitted changes
to the database are lost and the current transaction is rolled back. In this scenario, the application should close
the connection (or release the data source object) and try to reopen it. On connection, the new connection is
transparently redirected to the mirror database, which now acts as the principal server, without the client having
to modify the connection string or data source object.
When a connection is initially established, the principal server sends the identity of its failover partner to the
client that will be used when failover occurs. When an application tries to establish an initial connection with a
failed principal server, the client doesn't know the identity of the failover partner. To allow clients the opportunity
to cope with this scenario, the failoverPartner connection string property, and optionally the setFailoverPartner
data source method, allows the client to specify the identity of the failover partner on its own. The client
property is used only in this scenario; if the principal server is available, it isn't used.
NOTE
When a failoverPartner is specified in either the connection string or with a data source object, the databaseName
property must also be set or else an exception will be thrown. If the failoverPartner and databaseName are not specified
explicitly, the application will not attempt to failover when the principal database server fails. In other words, the
transparent redirection only works for connections that explicitly specify the failoverPartner and databaseName. For more
information about failoverPartner and other connection string properties, see Setting the connection properties.
If the failover partner server supplied by the client doesn't refer to a server acting as a failover partner for the
specified database, and if the server/database referred to is in a mirrored arrangement, the connection is
refused by the server. Although the SQLServerDataSource class provides the getFailoverPartner method, this
method only returns the name of the failover partner specified in the connection string or the setFailoverPartner
method. To retrieve the name of the actual failover partner that is currently being used, use the following
Transact-SQL statement:
NOTE
You will need to change this statement to use the name of your mirroring database.
Consider caching the partner information to update the connection string or devise a retry strategy in case the
first attempt at making a connection fails.
Example
In the following example, an attempt is first made to connect to the principle server. If that fails and an exception
is thrown, an attempt is made to connect to the mirror server, which may have been promoted to the new
principle server. Note the use of the failoverPartner property in the connection string.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
See also
Connecting to SQL Server with the JDBC driver
Understanding cursor types
4/27/2022 • 12 minutes to read • Edit Online
NOTE
For a full description of the SQL Server cursor types, see Type of Cursors.
The JDBC specification provides support for forward-only and scrollable cursors that are sensitive or insensitive
to changes made by other jobs, and can be read-only or updatable. This functionality is provided by the
Microsoft JDBC Driver for SQL ServerSQLServerResultSet class.
Remarks
The JDBC driver supports the following result set and cursor types along with the specified behavior options.
The application has to make a single (forward) pass through the result set. This pass is the default behavior and
behaves the same as a TYPE_SS_DIRECT_FORWARD_ONLY cursor. The driver reads the entire result set from the
server into a memory during the statement execution time.
The application has to make a single (forward) pass through the result set. This pass is the default behavior and
behaves the same as a TYPE_SS_DIRECT_FORWARD_ONLY cursor. The driver reads the entire result set from the
server into a memory during the statement execution time.
The application has to make a single (forward) pass through the result set. It behaves the same as a
TYPE_SS_DIRECT_FORWARD_ONLY cursor. The driver reads rows from the server as the application requests
them and minimizes client-side memory usage.
The application has to make a single (forward) pass through the result set by using a server cursor. It behaves
the same as a TYPE_SS_SERVER_CURSOR_FORWARD_ONLY cursor.
Rows are retrieved from the server in blocks that are specified by the fetch size.
The application has to make a single (forward) pass through the result set to update one or more rows.
Rows are retrieved from the server in blocks that are specified by the fetch size.
By default, the fetch size is fixed when the application calls the setFetchSize method of the SQLServerResultSet
object.
NOTE
The JDBC driver provides an adaptive buffering feature that allows you to retrieve statement execution results from the
SQL Server as the application needs them, rather than all at once. For example, if the application should retrieve a large
data that is too large to fit entirely in application memory, adaptive buffering allows the client application to retrieve such
a value as a stream. The default behavior of the driver is "adaptive ". However, in order to get the adaptive buffering for
the forward-only updatable result sets, the application has to explicitly call the setResponseBuffering method of the
SQLServerStatement object by providing a String value "adaptive". For an example code, see Updating large data
sample.
RESULT SET SQ L SERVER C URSO R RESP O N SE
( C URSO R) T Y P E TYPE C H A RA C T ERIST IC S SEL EC T M ET H O D B UF F ERIN G
The application requires a database snapshot. The result set isn't updatable. Only CONCUR_READ_ONLY is
supported. All other concurrency types will cause an exception when used with this cursor type.
Rows are retrieved from the server in blocks that are specified by the fetch size.
The application has to see changed data for existing rows only.
Rows are retrieved from the server in blocks that are specified by the fetch size.
The application may change data in the existing rows by using the ResultSet object. The application must also be
able to see the changes to rows made by others from outside the ResultSet object.
Rows are retrieved from the server in blocks that are specified by the fetch size.
Integer value = 2003. Provides a read-only client-side cursor that is fully buffered. No server cursor is created.
Only CONCUR_READ_ONLY concurrency type is supported. All other concurrency types cause an exception
when used with this cursor type.
RESULT SET SQ L SERVER C URSO R RESP O N SE
( C URSO R) T Y P E TYPE C H A RA C T ERIST IC S SEL EC T M ET H O D B UF F ERIN G
Integer value = 2004. Fast and accesses all data using a server cursor. It's updatable when used with
CONCUR_UPDATABLE concurrency type.
Rows are retrieved from the server in blocks that are specified by the fetch size.
To get adaptive buffering for this case, the application has to explicitly call the setResponseBuffering method of
the SQLServerStatement object by providing a String value "adaptive" . For an example code, see Updating
large data sample.
Integer value = 1004. Application requires a database snapshot. This option is the SQL Server-specific synonym
for the JDBC TYPE_SCROLL_INSENSITIVE and has the same concurrency setting behavior.
Rows are retrieved from the server in blocks that are specified by the fetch size.
Integer value = 1005. Application has to see changed data for existing rows only. This option is the SQL Server-
specific synonym for the JDBC TYPE_SCROLL_SENSITIVE and has the same concurrency setting behavior.
Rows are retrieved from the server in blocks that are specified by the fetch size.
Integer value = 1005. Application has to change data or see changed data for existing rows. This option is the
SQL Server-specific synonym for the JDBC TYPE_SCROLL_SENSITIVE and has the same concurrency setting
behavior.
Rows are retrieved from the server in blocks that are specified by the fetch size.
Integer value = 1006. Application must see changed data for existing rows, and see inserted and deleted rows
during the lifetime of the cursor.
Rows are retrieved from the server in blocks that are specified by the fetch size.
Integer value = 1006. The application may change data for existing rows, or insert or delete rows by using the
ResultSet object. The application must also be able to see changes, inserts, and deletes made by others from
outside the ResultSet object.
Rows are retrieved from the server in blocks that are specified by the fetch size.
Cursor positioning
The TYPE_FORWARD_ONLY, TYPE_SS_DIRECT_FORWARD_ONLY, and
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY cursors support only the next positioning method.
The TYPE_SS_SCROLL_DYNAMIC cursor doesn't support the absolute and getRow methods. The absolute
method can be approximated by a combination of calls to the first and relative methods for dynamic cursors.
The getRow method is supported by TYPE_FORWARD_ONLY, TYPE_SS_DIRECT_FORWARD_ONLY,
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY, TYPE_SS_SCROLL_KEYSET, and TYPE_SS_SCROLL_STATIC cursors
only. The getRow method with all forward-only cursor types returns the number of rows read so far through the
cursor.
NOTE
When an application makes an unsupported cursor positioning call, or an unsupported call to the getRow method, an
exception is thrown with the message, "The requested operation is not supported with this cursor type."
Only the TYPE_SS_SCROLL_KEYSET and the equivalent TYPE_SCROLL_SENSITIVE cursors expose deleted rows. If
the cursor is positioned on a deleted row, column values are unavailable, and the rowDeleted method returns
"true". Calls to get<Type> methods throw an exception with the message, "Cannot get value from a deleted
row". Deleted rows cannot be updated. If you try to call an update<Type> method on a deleted row, an
exception is thrown with the message, "A deleted row cannot be updated". The TYPE_SS_SCROLL_DYNAMIC
cursor has the same behavior until the cursor is moved out of the current fetch buffer.
Forward and dynamic cursors expose deleted rows in a similar way, but only while the cursors remain accessible
in the fetch buffer. For forward cursors, this behavior is fairly straightforward. For dynamic cursors, it more
complex when the fetch size is greater than 1. An application can move the cursor forward and backward within
the window that is defined by the fetch buffer, but the deleted row will disappear when the original fetch buffer
in which it was updated is left. If an application doesn't want to see transient deleted rows by using dynamic
cursors, a fetch relative (0) should be used.
If the key values of a TYPE_SS_SCROLL_KEYSET or TYPE_SCROLL_SENSITIVE cursor row are updated with the
cursor, the row keeps its original position in the result set, regardless of whether the updated row meets the
cursor's selection criteria. If the row was updated outside the cursor, a deleted row will appear at the row's
original position, but the row will appear in the cursor only if another row with the new key values was present
in the cursor, but has since been deleted.
For dynamic cursors, updated rows will keep their position within the fetch buffer until the window that is
defined by the fetch buffer is left. Updated rows might later reappear at different positions within the result set,
or might disappear completely. Applications that have to avoid transient inconsistencies in the result set should
use a fetch size of 1 (the default is 8 rows with CONCUR_SS_SCROLL_LOCKS concurrency and 128 rows with
other concurrencies).
Cursor conversion
SQL Server can sometimes choose to implement a cursor type other than the one requested, which is referred
to as an implicit cursor conversion (or cursor degradation).
With SQL Server 2000 (8.x), when you update the data through the ResultSet.TYPE_SCROLL_SENSITIVE and
ResultSet.CONCUR_UPDATABLE result set, an exception is thrown with a message "The cursor is READ ONLY".
This exception occurs because the SQL Server 2000 (8.x) has done an implicit cursor conversion for that result
set and didn't return the updatable cursor that has been requested.
To work around this problem, you can do one of the following solutions:
Ensure that the underlying table has a primary key
Use SQLServerResultSet.TYPE_SS_SCROLL_DYNAMIC instead of ResultSet.TYPE_SCROLL_SENSITIVE while
creating a statement.
Cursor updating
In-place updates are supported for cursors where the cursor type and concurrency support updates. If the
cursor isn't positioned on an updatable row in the result set (no get<Type> method call succeeded), a call to an
update<Type> method will throw an exception with the message, "The result set has no current row." The JDBC
specification states that an exception arises when an update method is called for a column of a cursor that is
CONCUR_READ_ONLY. In situations where the row is not updatable, such as because of an optimistic
concurrency conflict such as a competing update or deletion, the exception might not arise until insertRow,
updateRow, or deleteRow is called.
After a call to update<Type>, the affected column cannot be accessed by get<Type> until updateRow or
cancelRowUpdates has been called. This behavior avoids problems where a column is updated by using a
different type from the type returned by the server, and subsequent getter calls could invoke client-side type
conversions that give inaccurate results. Calls to get<Type> will throw an exception with the message, "Updated
columns cannot be accessed until updateRow() or cancelRowUpdates() has been called."
NOTE
If the updateRow method is called when no columns have been updated, the JDBC driver will throw an exception with the
message, "updateRow() called when no columns have been updated."
After moveToInsertRow has been called, an exception will be thrown if any method other than get<Type>,
update<Type>, insertRow, and cursor positioning methods (including moveToCurrentRow) are called on the
result set. The moveToInsertRow method effectively places the result set into insert mode, and cursor
positioning methods terminate insert mode. Relative cursor positioning calls move the cursor relative to the
position it was at before moveToInsertRow was called. After cursor positioning calls, the eventual destination
cursor position becomes the new cursor position.
If the cursor positioning call made while in insert mode doesn't succeed, the cursor position after the failed call
is the original cursor position before moveToInsetRow was called. If insertRow fails, the cursor remains on the
insert row and the cursor remains in insert mode.
Columns in the insert row are initially in an uninitialized state. Calls to the update<Type> method set the
column state to initialized. A call to the get<Type> method for an uninitialized column throws an exception. A
call to the insertRow method returns all the columns in the insert row to an uninitialized state.
If any columns are uninitialized when the insertRow method is called, the default value for the column is
inserted. If there's no default value but the column is nullable, then NULL is inserted. If there's no default value
and the column is not nullable, the server will return an error and an exception will be thrown.
NOTE
Calls to the getRow method returns 0 when in insert mode.
The JDBC driver does not support positioned updates or deletes. According to the JDBC specification, the setCursorName
method has no effect and the getCursorName method will throw an exception if called.
Read-only and static cursors are never updatable.
SQL Server restricts server cursors to a single result set. If a batch or stored procedure contains multiple statements, then
a forward-only read-only client cursor must be used.
See also
Managing result sets with the JDBC driver
Understanding isolation levels
4/27/2022 • 2 minutes to read • Edit Online
Remarks
The following table shows the concurrency side effects allowed by the different isolation levels.
Snapshot No No No
Serializable No No No
Transactions must be run at an isolation level of at least repeatable read to prevent lost updates that can occur
when two transactions each retrieve the same row. The transaction then later updates the row based on the
originally retrieved values. If the two transactions update rows using a single UPDATE statement and don't base
the update on the previously retrieved values, lost updates can't occur at the default isolation level of read
committed.
To set the isolation level for a transaction, you can use the setTransactionIsolation method of the
SQLServerConnection class. This method accepts an int value as its argument, which is based on one of the
connection constants as in the following:
con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
To use the new snapshot isolation level of SQL Server, you can use one of the SQLServerConnection constants:
con.setTransactionIsolation(SQLServerConnection.TRANSACTION_SNAPSHOT);
con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED + 4094);
For more information about SQL Server isolation levels, see "Isolation Levels in the Database Engine" in SQL
Server Books Online.
See also
Performing transactions with the JDBC driver
SET TRANSACTION ISOLATION LEVEL (Transact-SQL)
Wrappers and interfaces
4/27/2022 • 2 minutes to read • Edit Online
Wrappers
The Microsoft JDBC Driver for SQL Server supports the java.sql.Wrapper interface. This interface provides a
mechanism to access extensions to the JDBC API that are specific to the Microsoft JDBC Driver for SQL Server
through a proxy interface.
The java.sql.Wrapper interface defines two methods: isWrapperFor and unwrap . The isWrapperFor method
checks whether the specified input object implements this interface. The unwrap method returns an object that
implements this interface to allow access to the Microsoft JDBC Driver for SQL Server specific methods.
isWrapperFor and unwrap methods are exposed as follows:
isWrapperFor Method (SQLServerCallableStatement)
unwrap Method (SQLServerCallableStatement)
isWrapperFor Method (SQLServerConnectionPoolDataSource)
unwrap Method (SQLServerConnectionPoolDataSource)
isWrapperFor Method (SQLServerDataSource)
unwrap Method (SQLServerDataSource)
isWrapperFor Method (SQLServerPreparedStatement)
unwrap Method (SQLServerPreparedStatement)
isWrapperFor Method (SQLServerStatement)
unwrap Method (SQLServerStatement)
isWrapperFor Method (SQLServerXADataSource)
unwrap Method (SQLServerXADataSource)
Interfaces
Beginning in SQL Server JDBC Driver 3.0, interfaces are available for an application server to access a driver-
specific method from the associated class. The application server can wrap the class by creating a proxy,
exposing the Microsoft JDBC Driver for SQL Server-specific functionality from an interface. The Microsoft JDBC
Driver for SQL Server supports interfaces that have the Microsoft JDBC Driver for SQL Server specific methods
and constants so an application server can create a proxy of the class.
The interfaces derive from standard Java interfaces so you can use the same object once it is unwrapped to
access driver-specific functionality or generic Microsoft JDBC Driver for SQL Server functionality.
The following interfaces are added:
ISQLServerCallableStatement
ISQLServerConnection
ISQLServerDataSource
ISQLServerPreparedStatement
ISQLServerResultSet
ISQLServerStatement
Example
Description
This sample demonstrates how to access to a Microsoft JDBC Driver for SQL Server-specific function from a
DataSource object. This DataSource class may have been wrapped by an application server. To access the JDBC
driver-specific function or constant, you can unwrap the datasource to an ISQLServerDataSource interface and
use the functions declared in this interface.
Code
import javax.sql.*;
import java.sql.*;
import com.microsoft.sqlserver.jdbc.*;
See also
Understanding the JDBC driver data types
Using bulk copy with the JDBC driver
4/27/2022 • 31 minutes to read • Edit Online
NOTE
When using the Microsoft JDBC Driver 4.1 for SQL Server or earlier (which does not support the SQLServerBulkCopy
class), you can execute the SQL Server Transact-SQL BULK INSERT statement instead.
A few of the code samples demonstrate how to use one SQLServerBulkCopy class to write to multiple tables. For
these samples, the BulkCopyDemoOrderHeader and BulkCopyDemoOrderDetail tables are used as the destination
tables. These tables are based on the Sales.SalesOrderHeader and Sales.SalesOrderDetail tables in
AdventureWorks.
NOTE
The SQLServerBulkCopy code samples are provided to demonstrate the syntax for using SQLServerBulkCopy only. If
the source and destination tables are located in the same SQL Server instance, it is easier and faster to use a Transact-SQL
INSERT ... SELECT statement to copy the data.
Table setup
To create the tables necessary for the code samples to run correctly, you must run the following Transact-SQL
statements in a SQL Server database.
USE AdventureWorks
NOTE
If you need to roll back all or part of the bulk copy when an error occurs, you can either use a SQLServerBulkCopy -
managed transaction, or perform the bulk copy operation within an existing transaction.
For more information, see Transaction and bulk copy operations
We recommend that the source and target column data types match. If the data types do not match,
SQLServerBulkCopy attempts to convert each source value to the target data type. Conversions can affect
performance, and also can result in unexpected errors. For example, a double data type can be converted to a
decimal data type most of the time, but not always.
Example
The following application demonstrates how to load data using the SQLServerBulkCopy class. In this example, a
ResultSet is used to copy data from the Production.Product table in the SQL Server AdventureWorks database
to a similar table in the same database.
IMPORTANT
This sample will not run unless you have created the work tables as described in Table setup. This code is provided to
demonstrate the syntax for using SQLServerBulkCopy only. If the source and destination tables are located in the same
SQL Server instance, it is easier and faster to use a Transact-SQL INSERT ... SELECT statement to copy the data.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerBulkCopy;
NOTE
The file path for the data source is relative to the server. The server process must have access to that path in order for the
bulk copy operation to succeed.
NOTE
Performing multiple bulk copy operations using the same instance of SQLServerBulkCopy is usually more efficient than
using a separate instance for each operation.
If you perform several bulk copy operations using the same SQLServerBulkCopy object, there are no restrictions
on whether source or target information is equal or different in each operation. However, you must ensure that
column association information is properly set each time you write to the server.
IMPORTANT
This sample will not run unless you have created the work tables as described in Table setup. This code is provided to
demonstrate the syntax for using SQLServerBulkCopy only. If the source and destination tables are located in the same
SQL Server instance, it is easier and faster to use a Transact-SQL INSERT ... SELECT statement to copy the data.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerBulkCopy;
import com.microsoft.sqlserver.jdbc.SQLServerBulkCopyOptions;
SMALLDATETIME:YYYY-MM-DD hh:mm:ss
TIME: hh:mm:ss[.nnnnnnn]
2. With this connection property set to false , the column type specified for bulk copy has to respect the
data type mapping chart from here. For example, previously users could specify
java.sql.Types.TIMESTAMP to bulk copy data into a DATE column, but with this feature enabled, they must
specify java.sql.Types.DATE to perform the same.
Performing a non-transacted bulk copy operation
The following application shows what happens when a non-transacted bulk copy operation encounters an error
partway through the operation.
In the example, the source table and destination table each include an Identity column named ProductID . The
code first prepares the destination table by deleting all rows and then inserting a single row whose ProductID is
known to exist in the source table. By default, a new value for the Identity column is generated in the destination
table for each row added. In this example, an option is set when the connection is opened that forces the bulk-
load process to use the Identity values from the source table instead.
The bulk copy operation is executed with the BatchSize property set to 10. When the operation encounters the
invalid row, an exception is thrown. In this first example, the bulk copy operation is non-transacted. All batches
copied up to the point of the error are committed; the batch containing the duplicate key is rolled back, and the
bulk copy operation is halted before processing any other batches.
NOTE
This sample will not run unless you have created the work tables as described in Table setup. This code is provided to
demonstrate the syntax for using SQLServerBulkCopy only. If the source and destination tables are located in the same
SQL Server instance, it is easier and faster to use a Transact-SQL INSERT ... SELECT statement to copy the data.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerBulkCopy;
import com.microsoft.sqlserver.jdbc.SQLServerBulkCopyOptions;
// Set up the bulk copy object using the KeepIdentity option and BatchSize = 10.
SQLServerBulkCopyOptions copyOptions = new SQLServerBulkCopyOptions();
copyOptions.setKeepIdentity(true);
copyOptions.setBatchSize(10);
bulkCopy.setBulkCopyOptions(copyOptions);
bulkCopy.setDestinationTableName(destinationTable);
NOTE
This sample will not run unless you have created the work tables as described in Table setup. This code is provided to
demonstrate the syntax for using SQLServerBulkCopy only. If the source and destination tables are located in the same
SQL Server instance, it is easier and faster to use a Transact-SQL INSERT ... SELECT statement to copy the data.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerBulkCopy;
import com.microsoft.sqlserver.jdbc.SQLServerBulkCopyOptions;
bulkCopy.setBulkCopyOptions(copyOptions);
bulkCopy.setDestinationTableName(destinationTable);
IMPORTANT
This sample will not run unless you have created the work tables as described in Table setup to get it.
1. Open SQL Ser ver Management Studio and connect to the SQL Server with the AdventureWorks
database.
2. Expand the databases, right-click the AdventureWorks database, select Tasks and Expor t Data ...
3. For the Data Source, select the Data source that allows you to connect to your SQL Server (for example,
SQL Server Native Client 11.0), check the configuration and then Next
4. For the Destination, Select the Flat File Destination and enter a File Name with a destination such as
C:\Test\TestBulkCSVExample.csv . Check that the Format is Delimited, the Text qualifier is none, and
enable Column names in the first data row , and then select Next
5. Select Write a quer y to specify the data to transfer and Next . Enter your SQL Statement
SELECT ProductID, Name, ProductNumber FROM Production.Product , and Next
6. Check the configuration: You can leave the Row delimiter as {CR}{LF} and Column Delimiter as Comma
{,} . Select Edit Mappings ... and check that the data Type is correct for each column (for example,
integer for ProductID and Unicode string for the others).
7. Skip ahead to Finish and run the export.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.microsoft.sqlserver.jdbc.SQLServerBulkCSVFileRecord;
import com.microsoft.sqlserver.jdbc.SQLServerBulkCopy;
// Get data from the source file by loading it into a class that implements ISQLServerBulkRecord.
// Here we are using the SQLServerBulkCSVFileRecord implementation to import the example CSV file.
try (Connection destinationConnection = DriverManager.getConnection(connectionUrl);
Statement stmt = destinationConnection.createStatement();
SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(destinationConnection);
SQLServerBulkCSVFileRecord fileRecord = new
SQLServerBulkCSVFileRecord("C:\\Test\\TestBulkCSVExample.csv", true);) {
NOTE
When setting a custom delimiter, escape it if it's a regex character such as '|'.
IMPORTANT
Limitation of the Microsoft JDBC Driver 6.0 for SQL Server, when bulk copying data from a CSV file to encrypted columns:
Only the Transact-SQL default string literal format is supported for the date and time types
DATETIME and SMALLDATETIME data types are not supported
M ET H O D DESC RIP T IO N
void addColumnMapping(int sourceColumn, int Adds a new column-mapping, using ordinals to specify both
destinationColumn) source and destination columns.
void addColumnMapping (int sourceColumn, String Adds a new column-mapping, using an ordinal for the
destinationColumn) source column and a column name for the destination
column.
M ET H O D DESC RIP T IO N
void addColumnMapping (String sourceColumn, int Adds a new column-mapping, using a column name to
destinationColumn) describe the source column and an ordinal to specify the
destination column.
void addColumnMapping (String sourceColumn, String Adds a new column-mapping, using column names to
destinationColumn) specify both source and destination columns.
void writeToServer(ResultSet sourceData) Copies all rows in the supplied ResultSet to a destination
table specified by the DestinationTableName property of
the SQLServerBulkCopy object.
void writeToServer(RowSet sourceData) Copies all rows in the supplied RowSet to a destination
table specified by the DestinationTableName property of
the SQLServerBulkCopy object.
SQLServerBulkCopyOptions
A collection of settings that control how the writeToServer methods behave in an instance of
SQLServerBulkCopy .
boolean CheckConstraints Check constraints while data is being False - constraints aren't checked
inserted.
O P T IO N DESC RIP T IO N DEFA ULT
boolean FireTriggers Cause the server to fire the insert False - no triggers are fired
triggers for the rows being inserted
into the database.
boolean KeepIdentity Preserve source identity values. False - identity values are assigned by
the destination
boolean KeepNulls Preserve null values in the destination False - null values are replaced by
table regardless of the settings for default values where applicable.
default values.
boolean TableLock Obtain a bulk update lock for the False - row locks are used.
duration of the bulk copy operation.
boolean UseInternalTransaction When set to true , each batch of the False - no transaction
bulk-copy operation will occur within a
transaction. If SQLServerBulkCopy is
using an existing connection (as
specified by the constructor), a
SQLServerException will occur. If
SQLServerBulkCopy created a
dedicated connection, a transaction will
be created and committed for each
batch.
int BatchSize Number of rows in each batch. At the 0 - indicates that each
end of each batch, the rows in the writeToServer operation is a single
batch are sent to the server. batch
M ET H O DS DESC RIP T IO N
void setCheckConstraints(boolean checkConstraints) Sets whether constraints are to be checked while data is
being inserted or not.
boolean isFireTriggers() Indicates if the server should fire the insert triggers for the
rows being inserted into the database.
void setFireTriggers(boolean fireTriggers) Sets whether the server should be set to fire triggers for the
rows being inserted into the database.
void setKeepNulls(boolean keepNulls) Sets whether to preserve null values in the destination table
regardless of the settings for default values, or if they should
be replaced by the default values (where applicable).
boolean isUseInternalTransaction() Indicates whether each batch of the bulk-copy operation will
occur within a transaction.
void setUseInternalTranscation(boolean Sets whether each batch of the bulk-copy operations will
useInternalTransaction) occur within a transaction or not.
int getBatchSize() Gets the number of rows in each batch. At the end of each
batch, the rows in the batch are sent to the server.
void setBatchSize(int batchSize) Sets the number of rows in each batch. At the end of each
batch, the rows in the batch are sent to the server.
int getBulkCopyTimeout() Gets the number of seconds for the operation to complete
before it times out.
void setBulkCopyTimeout(int timeout) Sets the number of seconds for the operation to complete
before it times out.
ISQLServerBulkRecord
The ISQLServerBulkRecord interface can be used to create classes that read in data from any source (such as a
file) and allow a SQLServerBulkCopy instance to bulk load a SQL Server table with that data.
set<Integer> getColumnOrdinals() Get the ordinals for each of the columns represented in this
data record.
int getColumnType(int column) Get the JDBC data type of the given column.
int getPrecision(int column) Get the precision for the given column.
IN T ERFA C E M ET H O DS DESC RIP T IO N
object[] getRowData() Gets the data for the current row as an array of Objects.
Each Object must match the Java language Type that is used
to represent the indicated JDBC data type for the given
column. For more information, see Understanding the JDBC
Driver Data Types for the appropriate mappings.
int getScale(int column) Get the scale for the given column.
boolean isAutoIncrement(int column) Indicates whether the column represents an identity column.
SQLServerBulkCSVFileRecord
A simple implementation of the ISQLServerBulkRecord interface that can be used to read in the basic Java data
types from a delimited file where each line represents a row of data.
Implementation Notes and Limitations:
1. The maximum amount of data allowed in any given row is limited by the available memory because the
data is read one line at a time.
2. Streaming of large data types such as varchar(max) , varbinary(max) , nvarchar(max) , sqlxml , and
ntext isn't supported.
3. The delimiter specified for the CSV file shouldn't appear anywhere in the data and should be escaped
properly if it is a restricted character in Java regular expressions.
4. In the CSV file implementation, double quotes are treated as part of the data. For example, the line
hello,"world","hello,world" would be treated as having four columns with the values hello , "world" ,
"hello and world" if the delimiter is a comma.
5. New line characters are used as row terminators and aren't allowed anywhere in the data.
M ET H O D DESC RIP T IO N
void addColumnMetadata(int positionInFile, String Adds metadata for the given column in the file.
columnName, int jdbcType, int precision, int scale)
void close() Releases any resources associated with the file reader.
void Sets the format for parsing Timestamp data from the file as
setTimestampWithTimezoneFormat(DateTimeFormatter java.sql.Types.TIMESTAMP_WITH_TIMEZONE .
dateTimeFormatter)
void setTimestampWithTimezoneFormat(String Sets the format for parsing Time data from the file as
dateTimeFormat) java.sql.Types.TIME_WITH_TIMEZONE .
void setTimeWithTimezoneFormat(DateTimeFormatter Sets the format for parsing Time data from the file as
dateTimeFormatter) java.sql.Types.TIME_WITH_TIMEZONE .
void setTimeWithTimezoneFormat(String timeFormat) Sets the format for parsing Time data from the file as
java.sql.Types.TIME_WITH_TIMEZONE .
See also
Overview of the JDBC driver
Using bulk copy API for batch insert operation
4/27/2022 • 3 minutes to read • Edit Online
Prerequisites
Prerequisite to enable Bulk Copy API for batch insert.
The query must be an insert query (the query may contain comments, but the query must start with the
INSERT keyword for this feature to come into effect).
Known limitations
There are currently these limitations that apply to this feature.
Insert queries that contain non-parameterized values (for example, INSERT INTO TABLE VALUES (?, 2 )), isn't
supported. Wildcards (?) are the only supported parameters for this function.
Insert queries that contain INSERT-SELECT expressions (for example, INSERT INTO TABLE SELECT * FROM TABLE2
), isn't supported.
Insert queries that contain multiple VALUE expressions (for example, INSERT INTO TABLE VALUES (1, 2) (3, 4)
), isn't supported.
Insert queries that are followed by the OPTION clause, joined with multiple tables, or followed by another
query, isn't supported.
Because of the limitations of Bulk Copy API, MONEY , SMALLMONEY , DATE , DATETIME , DATETIMEOFFSET ,
SMALLDATETIME , TIME , GEOMETRY , and GEOGRAPHY data types, are currently not supported for this feature.
If the query fails because of non "SQL server" related errors, the driver will log the error message and fallback to
the original logic for batch insert.
Example
This is an example that demonstrates the use case for a batch insert operation of a thousand rows, for both
regular vs Bulk Copy API scenarios.
public static void main(String[] args) throws Exception
{
String tableName = "batchTest";
String tableNameBulkCopyAPI = "batchTestBulk";
String createSql = "create table " + tableName + " (c1 int, c2 varchar(20))";
stmt.execute(createSql);
String createSql = "create table " + tableNameBulkCopyAPI + " (c1 int, c2 varchar(20))";
stmt.execute(createSql);
Result:
Starting batch operation using regular batch insert operation.
Finished. Time taken : 104132 milliseconds.
Starting batch operation using Bulk Copy API.
Finished. Time taken : 1058 milliseconds.
See also
Improving performance and reliability with the JDBC driver
Performing batch operations
4/27/2022 • 2 minutes to read • Edit Online
NOTE
If you do not have to use update counts, you can first issue a SET NOCOUNT ON statement to SQL Server. This will
reduce network traffic and additionally enhance the performance of your application.
In the following example, an open connection to the sample database is passed in to the function, the addBatch
method is used to create the statements to be executed, and the executeBatch method is called to submit the
batch to the database.
NOTE
SQL escape processing is always turned on for the JDBC driver.
The following sections describe the five types of escape sequences and how they are supported by the JDBC
driver.
NOTE
The escape sequence must be at the end of the SQL statement. For multiple SQL statements in a command string, the
escape sequence needs to be at the end of each relevant SQL statement.
Function handling
The JDBC driver supports function escape sequences in SQL statements with the following syntax:
{fn functionName}
The following table lists the various functions that are supported by the JDBC driver when using a function
escape sequence:
SOUNDEX PI TIMESTAMPADD
ROUND
SIGN
SIN
SQRT
TAN
TRUNCATE
NOTE
If you try to use a function that the database does not support, an error will occur.
{literal-type 'value'}
d Date yyyy-mm-dd
For example:
{[?=]call procedure-name[([parameter][,[parameter]]...)]}
where procedure-name specifies the name of a stored procedure and parameter specifies a stored procedure
parameter.
For more information about using the call escape sequence with stored procedures, see Using Statements
with Stored Procedures.
Outer joins
The JDBC driver supports the SQL92 left, right, and full outer join syntax. The escape sequence for outer joins is
the following:
{oj outer-join}
where table-reference is a table name and search-condition is the join condition you want to use for the
tables.
For example:
The following outer join escape sequences are supported by the JDBC driver:
Left outer joins
Right outer joins
Full outer joins
Nested outer joins
The escape syntax has two parts: <rows> is mandatory and specifies the number of rows to return. OFFSET and
<row offset> are optional and specify the number of rows to skip before beginning to return rows. The JDBC
driver supports only the mandatory part by transforming the query to use TOP instead of LIMIT. SQL Server
does not support the LIMIT clause. The JDBC driver does not suppor t the optional <row offset> and
the driver will throw an exception if it is used .
See also
Using statements with the JDBC driver
Azure Key Vault sample version 9.2
4/27/2022 • 4 minutes to read • Edit Online
import java.net.URISyntaxException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import com.microsoft.aad.msal4j.IAuthenticationResult;
import com.microsoft.aad.msal4j.PublicClientApplication;
import com.microsoft.aad.msal4j.UserNamePasswordParameters;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionAzureKeyVaultProvider;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerConnection;
import com.microsoft.sqlserver.jdbc.SQLServerException;
import com.microsoft.sqlserver.jdbc.SQLServerKeyVaultAuthenticationCallback;
statement.execute("DBCC FREEPROCCACHE");
System.out.println("Create SQLServerColumnEncryptionAzureKeyVaultProvider with
'authenticationCallback'");
/* Constructor added in 7.0.0 driver version [Supports SQLServerKeyVaultAuthenticationCallback
in 7.0 for backwards compatibility]
* This constructor is recommended to replace the above deprecated constructor */
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider2 = new
SQLServerColumnEncryptionAzureKeyVaultProvider(
tryAuthenticationCallback());
setupKeyStoreProviders(akvProvider2.getName(), akvProvider2);
testAKV(akvProvider2.getName(), akvProvider2, connection, statement);
statement.execute("DBCC FREEPROCCACHE");
System.out.println("Create SQLServerColumnEncryptionAzureKeyVaultProvider with 'clientId' and
'clientKey'");
/* Constructor added in 6.2.2 driver version [Continued Support] */
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider3 = new
SQLServerColumnEncryptionAzureKeyVaultProvider(
applicationClientID, applicationKey);
setupKeyStoreProviders(akvProvider3.getName(), akvProvider3);
testAKV(akvProvider3.getName(), akvProvider3, connection, statement);
statement.execute("DBCC FREEPROCCACHE");
System.out.println("Create SQLServerColumnEncryptionAzureKeyVaultProvider with 'token
credential'");
/* see Azure Identity client library for Java
* https://docs.microsoft.com/java/api/overview/azure/identity-readme?view=azure-java-stable */
ClientSecretCredential tokenCredential = new ClientSecretCredentialBuilder().tenantId(tenantID)
.clientId(applicationClientID).clientSecret(applicationKey).build();
/* Constructor added in 9.2.0 driver version */
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider4 = new
SQLServerColumnEncryptionAzureKeyVaultProvider(
tokenCredential);
setupKeyStoreProviders(akvProvider4.getName(), akvProvider4);
testAKV(akvProvider4.getName(), akvProvider4, connection, statement);
System.exit(0);
}
}
@Override
public String getAccessToken(String authority, String resource, String scope) {
try {
IClientCredential credential = ClientCredentialFactory.createFromSecret(applicationKey);
ConfidentialClientApplication confidentialClientApplication =
ConfidentialClientApplication
.builder(applicationClientID, credential).authority(authority).build();
Set<String> scopes = new HashSet<>();
scopes.add(scope);
return
confidentialClientApplication.acquireToken(ClientCredentialParameters.builder(scopes).build()).get().accessT
oken();
} catch (Exception e) {
fail(TestResource.getResource("R_unexpectedException") + e.getMessage());
}
return null;
}
};
return authenticationCallback;
}
}
dropTable(statement);
dropKeys(statement);
System.out.println("createCMK");
createCMK(CUSTOM_AKV_PROVIDER_NAME, statement);
System.out.println("createCEK");
createCEK(akvProvider, statement);
System.out.println("create Table");
statement.execute(createTableSQL);
System.out.println("populate");
populateCharNormalCase(connection);
final static char[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'A', 'B', 'C', 'D', 'E', 'F'};
/**
* Rerieves the table
*
* @throws SQLException
*/
private static void testChar(Statement statement) throws SQLException {
try (ResultSet rs = statement
.executeQuery("select * from " + akvTable);) {
int numberOfColumns = rs.getMetaData().getColumnCount();
while (rs.next()) {
for (int i = 1; i <= numberOfColumns; i++) {
System.out.println(rs.getString(i));
}
}
}
}
}
See also
Azure Key vault sample version 7.0
Azure Key vault sample version 6.2.2
Azure Key vault sample version 6.0.0
Azure Key Vault sample versions 7.0, 8.0
4/27/2022 • 4 minutes to read • Edit Online
import java.net.URISyntaxException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import com.microsoft.aad.adal4j.AuthenticationContext;
import com.microsoft.aad.adal4j.AuthenticationResult;
import com.microsoft.aad.adal4j.ClientCredential;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionAzureKeyVaultProvider;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerConnection;
import com.microsoft.sqlserver.jdbc.SQLServerException;
import com.microsoft.sqlserver.jdbc.SQLServerKeyVaultAuthenticationCallback;
statement.execute("DBCC FREEPROCCACHE");
System.out.println("Create SQLServerColumnEncryptionAzureKeyVaultProvider with
'authenticationCallback'");
/* Constructor added in 7.0.0 driver version [Supports SQLServerKeyVaultAuthenticationCallback
in 7.0 for backwards compatibility]
* This constructor is recommended to replace the above deprecated constructor */
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider2 = new
SQLServerColumnEncryptionAzureKeyVaultProvider(
tryAuthenticationCallback());
testAKV(akvProvider2.getName(), akvProvider2, connection, statement);
statement.execute("DBCC FREEPROCCACHE");
System.out.println("Create SQLServerColumnEncryptionAzureKeyVaultProvider with 'clientId' and
'clientKey'");
/* Constructor added in 6.2.2 driver version [Continued Support] */
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider3 = new
SQLServerColumnEncryptionAzureKeyVaultProvider(
applicationClientID, applicationKey);
testAKV(akvProvider3.getName(), akvProvider3, connection, statement);
System.exit(0);
}
}
@Override
public String getAccessToken(String authority, String resource,
String scope) {
AuthenticationResult result = null;
try {
ExecutorService service = Executors.newFixedThreadPool(1);
AuthenticationContext context = new AuthenticationContext(
authority, false, service);
ClientCredential cred = new ClientCredential(
applicationClientID, applicationKey);
Future<AuthenticationResult> future = context
.acquireToken(resource, cred, null);
result = future.get();
service.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
return result.getAccessToken();
}
};
return authenticationCallback;
dropTable(statement);
dropKeys(statement);
System.out.println("createCMK");
createCMK(CUSTOM_AKV_PROVIDER_NAME, statement);
System.out.println("createCEK");
createCEK(akvProvider, statement);
System.out.println("create Table");
statement.execute(createTableSQL);
System.out.println("populate");
populateCharNormalCase(connection);
final static char[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'A', 'B', 'C', 'D', 'E', 'F'};
/**
* Rerieves the table
*
* @throws SQLException
*/
private static void testChar(Statement statement) throws SQLException {
try (ResultSet rs = statement
.executeQuery("select * from " + akvTable);) {
int numberOfColumns = rs.getMetaData().getColumnCount();
while (rs.next()) {
for (int i = 1; i <= numberOfColumns; i++) {
System.out.println(rs.getString(i));
}
}
}
}
}
See also
Azure Key vault sample version 9.2
Azure Key vault sample version 6.2.2
Azure Key vault sample version 6.0.0
Azure Key Vault sample version 6.2.2
4/27/2022 • 3 minutes to read • Edit Online
import java.net.URISyntaxException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionAzureKeyVaultProvider;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerConnection;
import com.microsoft.sqlserver.jdbc.SQLServerException;
dropTable(statement);
dropKeys(statement);
System.out.println("createCMK");
createCMK(CUSTOM_AKV_PROVIDER_NAME, statement);
System.out.println("createCEK");
createCEK(akvProvider, statement);
System.out.println("create Table");
statement.execute(createTableSQL);
System.out.println("populate");
populateCharNormalCase(connection);
See also
Azure Key vault sample version 9.2
Azure Key Vault sample version 7.0.0
Azure Key Vault sample version 6.0.0
Azure Key Vault sample version 6.0.0
4/27/2022 • 3 minutes to read • Edit Online
import java.net.URISyntaxException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import com.microsoft.aad.adal4j.AuthenticationContext;
import com.microsoft.aad.adal4j.AuthenticationResult;
import com.microsoft.aad.adal4j.ClientCredential;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionAzureKeyVaultProvider;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerConnection;
import com.microsoft.sqlserver.jdbc.SQLServerException;
import com.microsoft.sqlserver.jdbc.SQLServerKeyVaultAuthenticationCallback;
@Override
public String getAccessToken(String authority, String resource,
String scope) {
AuthenticationResult result = null;
try {
AuthenticationContext context = new AuthenticationContext(
authority, false, service);
ClientCredential cred = new ClientCredential(
applicationClientID, applicationKey);
Future<AuthenticationResult> future = context
.acquireToken(resource, cred, null);
result = future.get();
} catch (Exception e) {
e.printStackTrace();
}
return result.getAccessToken();
}
};
dropTable(statement);
dropKeys(statement);
System.out.println("createCMK");
createCMK(CUSTOM_AKV_PROVIDER_NAME, statement);
System.out.println("createCEK");
createCEK(akvProvider, statement);
System.out.println("create Table");
statement.execute(createTableSQL);
System.out.println("populate");
populateCharNormalCase(connection);
final static char[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'A', 'B', 'C', 'D', 'E', 'F'};
See also
Azure Key vault sample version 9.2
Azure Key Vault sample version 7.0
Azure Key Vault sample version 6.2.2
Node.js Driver for SQL Server
4/27/2022 • 2 minutes to read • Edit Online
Get started
Step 1: Configure development environment for Node.js development
Step 2: Create a SQL database for Node.js development
Step 3: Proof of concept connecting to SQL using Node.js
Documentation
Tedious module documentation on GitHub
Support
Tedious for Node.js is community-supported software. Microsoft contributes to the tedious open-source
community and is an active participant in the repository at https://github.com/tediousjs/tedious. However, this
software doesn't come with Microsoft support.
To get help, file an issue in the tedious GitHub repository or visit other Node.js community resources.
Community resources
Azure Node.js Developer Center
Get Involved at nodejs.org
Code examples
Getting Started with Node.js on Windows
Getting Started with Node.js on macOS
Getting Started with Node.js on Ubuntu
Getting Started with Node.js on Red Hat Enterprise Linux (RHEL)
Getting Started with Node.js on SUSE Linux Enterprise Server (SLES)
Step 1: Configure development environment for
Node.js development
4/27/2022 • 2 minutes to read • Edit Online
You will need to configure your development environment with the prerequisites in order to develop an
application using the Node.js Driver for SQL Server. The most common method is to use the node package
manager (npm) to install the tedious module, but you can download the tedious module directly at GitHub if
you prefer.
The Node.js Driver uses the TDS protocol, which is enabled by default in SQL Server and Azure SQL Database.
No additional configuration is required.
Windows
1. Install Node.js runtime and npm package manager.
a. Go to Node.js
b. Click on the appropriate Windows installer msi link.
c. Once downloaded, run the msi to install Node.js
2. Open cmd.exe
3. Create a project director y and navigate to it.
4. Create a Node project. To retain the defaults during your project creation, press enter until the project is
created. At the end of this step, you should see a package.json file in your project directory.
5. Install tedious module in your project. Tedious is the implementation of the TDS protocol, which is used
to communicate to SQL Server.
Ubuntu Linux
1. Open terminal
2. Install Node.js runtime.
5. Create a Node project. To retain the defaults during your project creation, press enter until the project is
created. At the end of this step, you should see a package.json file in your project directory.
6. Install tedious module in your project. Tedious is the implementation of the TDS protocol, which is used
to communicate to SQL Server.
macOS
1. Install Node.js runtime and npm package manager.
a. Go to Node.js
b. Click on the appropriate macOS installer link.
c. Once downloaded, run 'dmg' to install Node.js
2. Open terminal
3. Create a project director y and navigate to it.
4. Create a Node project. To retain the defaults during your project creation, press enter until the project is
created. At the end of this step, you should see a package.json file in your project directory.
5. Install tedious module in your project. This is the implementation of the TDS protocol which the driver
uses to communicate to SQL Server.
The samples in this section only work with the AdventureWorks schema, on either Microsoft SQL Server or
Azure SQL Database.
Step 1: Connect
The new Connection function is used to connect to SQL Database.
connection.connect();
connection.connect();
function executeStatement() {
request = new Request("SELECT c.CustomerID, c.CompanyName,COUNT(soh.SalesOrderID) AS OrderCount FROM
SalesLT.Customer AS c LEFT OUTER JOIN SalesLT.SalesOrderHeader AS soh ON c.CustomerID = soh.CustomerID GROUP
BY c.CustomerID, c.CompanyName ORDER BY OrderCount DESC;", function(err) {
if (err) {
console.log(err);}
});
var result = "";
request.on('row', function(columns) {
columns.forEach(function(column) {
if (column.value === null) {
console.log('NULL');
} else {
result+= column.value + " ";
}
});
console.log(result);
result ="";
});
// Close the connection after the final event emitted by the request, after the callback passes
request.on("requestCompleted", function (rowCount, more) {
connection.close();
});
connection.execSql(request);
}
connection.connect();
function executeStatement1() {
request = new Request("INSERT SalesLT.Product (Name, ProductNumber, StandardCost, ListPrice,
SellStartDate) OUTPUT INSERTED.ProductID VALUES (@Name, @Number, @Cost, @Price, CURRENT_TIMESTAMP);",
function(err) {
if (err) {
console.log(err);}
});
request.addParameter('Name', TYPES.NVarChar,'SQL Server Express 2014');
request.addParameter('Number', TYPES.NVarChar , 'SQLEXPRESS2014');
request.addParameter('Cost', TYPES.Int, 11);
request.addParameter('Price', TYPES.Int,11);
request.on('row', function(columns) {
columns.forEach(function(column) {
if (column.value === null) {
console.log('NULL');
} else {
console.log("Product id of inserted item is " + column.value);
}
});
});
// Close the connection after the final event emitted by the request, after the callback passes
request.on("requestCompleted", function (rowCount, more) {
connection.close();
});
connection.execSql(request);
}
Microsoft ODBC Driver for SQL Server
4/27/2022 • 2 minutes to read • Edit Online
Version: 18.0.1.1
Date: February 15th 2022
Download
To download ODBC driver
Documentation
Features
Connection Resiliency
Custom Keystore Providers
Data Classification
DSN and Connection String Keywords and Attributes
SQL Server Native Client (the features available also apply, without OLEDB, to the ODBC Driver for SQL
Server)
Using Always Encrypted
Using Azure Active Directory
Using Transparent Network IP Resolution
Using XA Transactions
Linux and macOS
Installing the driver on Linux
Installing the driver on macOS
Connecting to SQL Server
Connecting with bcp
Connecting with sqlcmd
Data Access Tracing
Frequently Asked Questions
Installing the Driver Manager
Known Issues
Programming Guidelines
Release Notes
Release Notes (mssql-tools)
Support for High Availability and Disaster Recovery
Using Integrated Authentication (Kerberos)
Windows
Asynchronous Execution (Notification Method) Sample
Driver-Aware Connection Pooling
Features and Behavior Changes
Release Notes for ODBC to SQL Server on Windows
System Requirements, Installation, and Driver Files
Community
SQL Server Drivers blog
SQL Server Data Access Forum
Download ODBC Driver for SQL Server
4/27/2022 • 3 minutes to read • Edit Online
Applies to: SQL Server (all supported versions) Azure SQL Database Azure SQL Managed Instance
Azure Synapse Analytics Analytics Platform System (PDW)
Microsoft ODBC Driver for SQL Server is a single dynamic-link library (DLL) containing run-time support for
applications using native-code APIs to connect to SQL Server. Use Microsoft ODBC Driver 18 for SQL Server to
create new applications or enhance existing applications that need to take advantage of newer SQL Server
features.
NOTE
If you are accessing this page from a non-English language version, and want to see the most up-to-date content, please
select Read in English at the top of this page. You can download different languages from the US-English version site by
selecting available languages.
Available languages
This release of Microsoft ODBC Driver for SQL Server can be installed in the following languages:
Microsoft ODBC Driver 18.0.1.1 for SQL Server (x64):
Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian | Japanese |
Korean | Portuguese (Brazil) | Russian | Spanish
Microsoft ODBC Driver 18.0.1.1 for SQL Server (x86):
Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian | Japanese |
Korean | Portuguese (Brazil) | Russian | Spanish
Version 17.9.1 is the latest general availability (GA) version of the 17.x driver. If you have a previous version of
Microsoft ODBC Driver 17 for SQL Server installed, installing 17.9.1 upgrades it to 17.9.1.
NOTE
Packages named msodbcsql18-* are the latest version. Packages named msodbcsql-* are version 13 of the driver.
Alpine
18.0.1.1 Alpine package (PGP Signature)
17.9.1.1 Alpine package (PGP Signature)
17.8.1.1 Alpine package (PGP Signature)
17.7.2.1 Alpine package (PGP Signature)
17.7.1.1 Alpine package (PGP Signature)
17.6.1.1 Alpine package (PGP Signature)
17.5.2.2 Alpine package (PGP Signature)
17.5.2.1 Alpine package (PGP Signature)
17.5.1.1 Alpine package (PGP Signature)
Debian
Debian 11 .deb packages: v17 v18
Debian 10 .deb packages: v17 v18
Debian 9 .deb packages: v17 v18
Debian 8 .deb packages: v13 v17
Red Hat
Red Hat 8 .rpm packages
Red Hat 7 .rpm packages
Red Hat 6 .rpm packages
Suse
SuSE 15 .rpm packages
SuSE 12 .rpm packages
SuSE 11 .rpm packages
Ubuntu
Ubuntu 21.10 .deb packages: v17 v18
Ubuntu 20.04 .deb packages: v17 v18
Ubuntu 18.04 .deb packages: v17 v18
Ubuntu 16.04 .deb packages: v13 v17
Ubuntu 14.04 .deb packages: v13 v17
See also Installing the Linux driver.
macOS
See the Homebrew formulae for details.
See also Installing the macOS driver.
Older Linux releases
Red Hat Enterprise Linux 5 and 6 (64-bit) - Download Microsoft ODBC Driver 11 for SQL Server - Red
Hat Linux
SUSE Linux Enterprise 11 Ser vice Pack 2 (64-bit) - Download Microsoft ODBC Driver 11 Preview for
SQL Server - SUSE Linux
Release notes for Linux and macOS
For details about releases for Linux and macOS, see the Linux and macOS release notes.
System Requirements (Linux and macOS)
4/27/2022 • 3 minutes to read • Edit Online
DRIV
ER
VER
SIO
N→
↓
OPE
RAT I
NG
SY S
T EM 18. 0 17. 9 17. 8 17. 7 17. 6 17. 5 17. 4 17. 3 17. 2 17. 1 17. 0 13. 1 13
Appl Yes Yes Yes Yes Yes Yes Yes Yes Yes
e
mac
OS
10.1
3
(Hig
h
Sierr
a)
DRIV
ER
VER
SIO
N→
↓
OPE
RAT I
NG
SY S
T EM 18. 0 17. 9 17. 8 17. 7 17. 6 17. 5 17. 4 17. 3 17. 2 17. 1 17. 0 13. 1 13
Debi Yes Yes Yes Yes Yes Yes Yes Yes Yes
an
Linu
x8
Debi Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes
an
Linu
x9
Red Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes
Hat
Ente
rpris
e
Linu
x6
Red Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes
Hat
Ente
rpris
e
Linu
x7
SUS Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes
E
Linu
x
Ente
rpris
e
Serv
er
111
SUS Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes
E
Linu
x
Ente
rpris
e
Serv
er
12
DRIV
ER
VER
SIO
N→
↓
OPE
RAT I
NG
SY S
T EM 18. 0 17. 9 17. 8 17. 7 17. 6 17. 5 17. 4 17. 3 17. 2 17. 1 17. 0 13. 1 13
Ubu Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes
ntu
Linu
x
16.0
4
Ubu Yes Yes Yes Yes Yes Yes Yes Yes Yes
ntu
Linu
x
18.0
4
See Also
Installing the Driver Manager
Known Issues in this Version of the Driver
Release Notes
Installing the Driver Manager
4/27/2022 • 3 minutes to read • Edit Online
IMPORTANT
Delete any driver manager packages installed on your computer before you install the unixODBC Driver Manager.
Installing the unixODBC Driver Manager could cause a failure of an existing Driver Manager.
Installing the Driver Manager for Microsoft ODBC Driver 13, 13.1, 17,
and 18
The driver manager dependency is resolved automatically by the package management system when you install
the Microsoft ODBC Driver 13, 13.1, 17, or 18 for SQL Server on Linux or macOS by following the instructions in
the following articles:
Installing the Microsoft ODBC Driver for SQL Server on Linux
Installing the Microsoft ODBC Driver for SQL Server on macOS
Installing the Driver Manager for Microsoft ODBC Driver 11 for SQL
Server
(SUSE and Red Hat Linux only.)
Using the Installation Script
IMPORTANT
These instructions refer to msodbcsql-11.0.2270.0.tar.gz , which is the installation file for Red Hat Linux. If you are
installing the Preview for SUSE Linux, the file name is msodbcsql-11.0.2260.0.tar.gz .
See Also
Installing the Microsoft ODBC Driver for SQL Server on Linux
Installing the Microsoft ODBC Driver for SQL Server on macOS
Release Notes
Install the Microsoft ODBC driver for SQL Server
(Linux)
4/27/2022 • 14 minutes to read • Edit Online
This article explains how to install the Microsoft ODBC Driver for SQL Server on Linux. It also includes
instructions for the optional command-line tools for SQL Server ( bcp and sqlcmd ) and the unixODBC
development headers.
This article provides commands for installing the ODBC driver from the bash shell. If you want to download the
packages directly, see Download ODBC Driver for SQL Server.
Microsoft ODBC 18
The following sections explain how to install the Microsoft ODBC driver 18 from the bash shell for different
Linux distributions.
Alpine Linux
Debian
Red Hat Enterprise Linux and Oracle
SUSE Linux Enterprise Server
Ubuntu
Alpine Linux
#(Optional) Verify signature, if 'gpg' is missing install it using 'apk add gnupg':
curl -O https://download.microsoft.com/download/b/9/f/b9f3cce4-3925-46d4-9f46-
da08869c6486/msodbcsql18_18.0.1.1-1_amd64.sig
curl -O https://download.microsoft.com/download/b/9/f/b9f3cce4-3925-46d4-9f46-da08869c6486/mssql-
tools18_18.0.1.1-1_amd64.sig
NOTE
Driver version 17.5 or higher is required for Alpine support.
Debian
sudo su
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
#Debian 9
curl https://packages.microsoft.com/config/debian/9/prod.list > /etc/apt/sources.list.d/mssql-release.list
#Debian 10
curl https://packages.microsoft.com/config/debian/10/prod.list > /etc/apt/sources.list.d/mssql-release.list
#Debian 11
curl https://packages.microsoft.com/config/debian/11/prod.list > /etc/apt/sources.list.d/mssql-release.list
exit
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y apt-get install -y mssql-tools18
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo apt-get install -y unixodbc-dev
# optional: kerberos library for debian-slim distributions
sudo apt-get install -y libgssapi-krb5-2
NOTE
You can substitute setting the environment variable 'ACCEPT_EULA' with setting the debconf variable
'msodbcsql/ACCEPT_EULA' instead:
echo msodbcsql18 msodbcsql/ACCEPT_EULA boolean true | sudo debconf-set-selections
sudo su
exit
sudo yum remove unixODBC-utf16 unixODBC-utf16-devel #to avoid conflicts
sudo ACCEPT_EULA=Y yum install -y msodbcsql18
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y yum install -y mssql-tools18
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo yum install -y unixODBC-devel
exit
sudo ACCEPT_EULA=Y zypper install -y msodbcsql18
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y zypper install -y mssql-tools18
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo zypper install -y unixODBC-devel
Ubuntu
sudo su
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
exit
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y apt-get install -y mssql-tools18
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo apt-get install -y unixodbc-dev
NOTE
You can substitute setting the environment variable 'ACCEPT_EULA' with setting the debconf variable
'msodbcsql/ACCEPT_EULA' instead:
echo msodbcsql18 msodbcsql/ACCEPT_EULA boolean true | sudo debconf-set-selections
Previous versions
The following sections provide instructions for installing previous versions of the Microsoft ODBC driver on
Linux. The following driver versions are covered:
Microsoft ODBC driver 17 for SQL Server
Microsoft ODBC driver 13.1 for SQL Server
Microsoft ODBC driver 13 for SQL Server
Microsoft ODBC driver 11 for SQL Server
Microsoft ODBC 17
The following sections explain how to install the Microsoft ODBC driver 17 from the bash shell for different
Linux distributions.
Alpine Linux
Debian
Red Hat Enterprise Linux and Oracle
SUSE Linux Enterprise Server
Ubuntu
IMPORTANT
If you installed the v17 msodbcsql package that was briefly available, you should remove it before installing the
msodbcsql17 package. This will avoid conflicts. The msodbcsql17 package can be installed side by side with the
msodbcsql v13 package.
Alpine Linux
#(Optional) Verify signature, if 'gpg' is missing install it using 'apk add gnupg':
curl -O https://download.microsoft.com/download/e/4/e/e4e67866-dffd-428c-aac7-
8d28ddafb39b/msodbcsql17_17.9.1.1-1_amd64.sig
curl -O https://download.microsoft.com/download/e/4/e/e4e67866-dffd-428c-aac7-8d28ddafb39b/mssql-
tools_17.9.1.1-1_amd64.sig
NOTE
Driver version 17.5 or higher is required for Alpine support.
Debian
sudo su
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
#Debian 9
curl https://packages.microsoft.com/config/debian/9/prod.list > /etc/apt/sources.list.d/mssql-release.list
#Debian 10
curl https://packages.microsoft.com/config/debian/10/prod.list > /etc/apt/sources.list.d/mssql-release.list
#Debian 11
curl https://packages.microsoft.com/config/debian/11/prod.list > /etc/apt/sources.list.d/mssql-release.list
exit
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql17
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y apt-get install -y mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo apt-get install -y unixodbc-dev
# optional: kerberos library for debian-slim distributions
sudo apt-get install -y libgssapi-krb5-2
NOTE
You can substitute setting the environment variable 'ACCEPT_EULA' with setting the debconf variable
'msodbcsql/ACCEPT_EULA' instead:
echo msodbcsql17 msodbcsql/ACCEPT_EULA boolean true | sudo debconf-set-selections
sudo su
exit
sudo yum remove unixODBC-utf16 unixODBC-utf16-devel #to avoid conflicts
sudo ACCEPT_EULA=Y yum install -y msodbcsql17
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y yum install -y mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo yum install -y unixODBC-devel
SUSE Linux Enterprise Server
sudo su
curl -O https://packages.microsoft.com/keys/microsoft.asc
rpm --import microsoft.asc
exit
sudo ACCEPT_EULA=Y zypper install -y msodbcsql17
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y zypper install -y mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo zypper install -y unixODBC-devel
Ubuntu
sudo su
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
exit
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql17
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y apt-get install -y mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo apt-get install -y unixodbc-dev
NOTE
You can substitute setting the environment variable 'ACCEPT_EULA' with setting the debconf variable
'msodbcsql/ACCEPT_EULA' instead:
echo msodbcsql17 msodbcsql/ACCEPT_EULA boolean true | sudo debconf-set-selections
ODBC 13.1
The following sections explain how to install the Microsoft ODBC driver 13.1 from the bash shell for different
Linux distributions.
Debian 8
sudo su
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
curl https://packages.microsoft.com/config/debian/8/prod.list > /etc/apt/sources.list.d/mssql-release.list
exit
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install msodbcsql
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y apt-get install mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo apt-get install unixodbc-dev
sudo su
curl https://packages.microsoft.com/config/rhel/6/prod.repo > /etc/yum.repos.d/mssql-release.repo
exit
sudo yum remove unixODBC-utf16 unixODBC-utf16-devel #to avoid conflicts
sudo ACCEPT_EULA=Y yum install msodbcsql
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y yum install mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo yum install unixODBC-devel
sudo su
curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/mssql-release.repo
exit
sudo yum remove unixODBC-utf16 unixODBC-utf16-devel #to avoid conflicts
sudo ACCEPT_EULA=Y yum install msodbcsql
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y yum install mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo yum install unixODBC-devel
sudo su
zypper ar https://packages.microsoft.com/config/sles/11/prod.repo
exit
sudo ACCEPT_EULA=Y zypper install msodbcsql
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y zypper install mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo zypper install unixODBC-devel
Ubuntu 15.10
sudo su
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
curl https://packages.microsoft.com/config/ubuntu/15.10/prod.list > /etc/apt/sources.list.d/mssql-
release.list
exit
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install msodbcsql
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y apt-get install mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo apt-get install unixodbc-dev
Ubuntu 16.04
sudo su
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list > /etc/apt/sources.list.d/mssql-
release.list
exit
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install msodbcsql
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y apt-get install mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo apt-get install unixodbc-dev
Ubuntu 16.10
sudo su
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
curl https://packages.microsoft.com/config/ubuntu/16.10/prod.list > /etc/apt/sources.list.d/mssql-
release.list
exit
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install msodbcsql
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y apt-get install mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo apt-get install unixodbc-dev
ODBC 13
The following sections explain how to install the Microsoft ODBC driver 13 from the bash shell for different
Linux distributions.
Red Hat Enterprise Server 6 (ODBC 13)
sudo su
curl https://packages.microsoft.com/config/rhel/6/prod.repo > /etc/yum.repos.d/mssql-release.repo
exit
sudo yum update
sudo yum remove unixODBC #to avoid conflicts
sudo ACCEPT_EULA=Y yum install msodbcsql-13.0.1.0-1 mssql-tools-14.0.2.0-1
sudo yum install unixODBC-utf16-devel #this step is optional but recommended*
#Create symlinks for tools
ln -sfn /opt/mssql-tools/bin/sqlcmd-13.0.1.0 /usr/bin/sqlcmd
ln -sfn /opt/mssql-tools/bin/bcp-13.0.1.0 /usr/bin/bcp
sudo su
curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/mssql-release.repo
exit
sudo yum update
sudo yum remove unixODBC #to avoid conflicts
sudo ACCEPT_EULA=Y yum install msodbcsql-13.0.1.0-1 mssql-tools-14.0.2.0-1
sudo yum install unixODBC-utf16-devel #this step is optional but recommended*
#Create symlinks for tools
ln -sfn /opt/mssql-tools/bin/sqlcmd-13.0.1.0 /usr/bin/sqlcmd
ln -sfn /opt/mssql-tools/bin/bcp-13.0.1.0 /usr/bin/bcp
sudo su
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
curl https://packages.microsoft.com/config/ubuntu/15.10/prod.list > /etc/apt/sources.list.d/mssql-
release.list
exit
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install msodbcsql=13.0.1.0-1 mssql-tools=14.0.2.0-1
sudo apt-get install unixodbc-dev-utf16 #this step is optional but recommended*
#Create symlinks for tools
ln -sfn /opt/mssql-tools/bin/sqlcmd-13.0.1.0 /usr/bin/sqlcmd
ln -sfn /opt/mssql-tools/bin/bcp-13.0.1.0 /usr/bin/bcp
sudo su
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list > /etc/apt/sources.list.d/mssql-
release.list
exit
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install msodbcsql=13.0.1.0-1 mssql-tools=14.0.2.0-1
sudo apt-get install unixodbc-dev-utf16 #this step is optional but recommended*
#Create symlinks for tools
ln -sfn /opt/mssql-tools/bin/sqlcmd-13.0.1.0 /usr/bin/sqlcmd
ln -sfn /opt/mssql-tools/bin/bcp-13.0.1.0 /usr/bin/bcp
Offline installation
If you prefer/require the Microsoft ODBC Driver 13 to be installed on a computer with no internet connection,
you'll need to resolve package dependencies manually. The Microsoft ODBC Driver 13 has the following direct
dependencies:
Ubuntu: libc6 (>= 2.21), libstdc++6 (>= 4.9), libkrb5-3, libcurl3, openssl, debconf (>= 0.5), unixodbc (>=
2.3.1-1)
Red Hat: glibc, e2fsprogs, krb5-libs, openssl, unixODBC
SUSE: glibc, libuuid1, krb5, openssl, unixODBC
Each of these packages in turn has their own dependencies, which may or may not be present on the system.
For a general solution to this issue, refer to your distribution's package manager documentation: Red Hat,
Ubuntu, and SUSE
It's also common to manually download all the dependent packages and place them together on the installation
computer, then manually install each package in turn, finishing with the Microsoft ODBC Driver 13 package.
Red Hat Linux Enterprise Server 7
Download the latest msodbcsql .rpm from https://packages.microsoft.com/rhel/7/prod/.
Install dependencies and the driver.
yum install glibc e2fsprogs krb5-libs openssl unixODBC unixODBC-devel #install dependencies
sudo rpm -i msodbcsql-13.1.X.X-X.x86_64.rpm #install the Driver
sudo apt-get install libc6 libstdc++6 libkrb5-3 libcurl3 openssl debconf unixodbc unixodbc-dev #install
dependencies
sudo dpkg -i msodbcsql_13.1.X.X-X_amd64.deb #install the Driver
zypper install glibc, libuuid1, krb5, openssl, unixODBC unixODBC-devel #install dependencies
sudo rpm -i msodbcsql-13.1.X.X-X.x86_64.rpm #install the Driver
After you've completed the package installation, you can verify that the Microsoft ODBC Driver 13 can find all its
dependencies by running ldd and inspecting its output for missing libraries:
ldd /opt/microsoft/msodbcsql/lib64/libmsodbcsql-*
ODBC 11
The following sections explain how to install the Microsoft ODBC driver 11 on Linux. Before you can use the
driver, install the unixODBC driver manager. For more information, see Installing the Driver Manager.
Installation Steps
IMPORTANT
These instructions refer to msodbcsql-11.0.2270.0.tar.gz , which is installation file for Red Hat Linux. If you are
installing the Preview for SUSE Linux, the file name is msodbcsql-11.0.2260.0.tar.gz .
Uninstall
You can uninstall the ODBC driver 11 on Linux by executing the following commands:
1. rm -f /usr/bin/sqlcmd
2. rm -f /usr/bin/bcp
3. rm -rf /opt/microsoft/msodbcsql
C O M P O N EN T DESC RIP T IO N
libmsodbcsql-17.X.so.X.X or libmsodbcsql-13.X.so.X.X The shared object ( so ) dynamic library file that contains all
of the driver's functionality. This file is installed in
/opt/microsoft/msodbcsql17/lib64/ for the Driver 17
and in /opt/microsoft/msodbcsql/lib64/ for Driver 13.
msodbcsqlr17.rll or msodbcsqlr13.rll The accompanying resource file for the driver library. This file
is installed in
[driver .so directory]../share/resources/en_US/
msodbcsql.h The header file that contains all of the new definitions
needed to use the driver.
msodbcsql.h is installed in
/opt/microsoft/msodbcsql17/include/ for Driver 17 and
in /opt/microsoft/msodbcsql/include/ for Driver 13.
LICENSE.txt The text file that contains the terms of the End-User License
Agreement. This file is placed in
/usr/share/doc/msodbcsql17/ for Driver 17 and in
/usr/share/doc/msodbcsql/ for Driver 13.
RELEASE_NOTES The text file that contains release notes. This file is placed in
/usr/share/doc/msodbcsql17/ for Driver 17 and in
/usr/share/doc/msodbcsql/ for Driver 13.
Troubleshooting
If you're unable to make a connection to SQL Server using the ODBC driver, see the known issues article on
troubleshooting connection problems.
Next steps
After installing the driver, you can try the C++ ODBC example application. For more information about
developing ODBC applications, see Developing Applications.
For more information, see the ODBC driver release notes and system requirements.
Install the Microsoft ODBC driver for SQL Server
(macOS)
4/27/2022 • 3 minutes to read • Edit Online
This article explains how to install the Microsoft ODBC Driver for SQL Server on macOS. It also includes
instructions for the optional command-line tools for SQL Server ( bcp and sqlcmd ) and the unixODBC
development headers.
This article provides commands for installing the ODBC driver from the bash shell. If you want to download the
packages directly, see Download ODBC Driver for SQL Server.
NOTE
The Microsoft ODBC driver for SQL Server on macOS is only supported on the x64 architecture through version 17.7.
Apple M1 (ARM64) support was added starting with version 17.8. The architecture will be detected and the correct
package will be automatically installed by the Homebrew formula. If your command prompt is running in x64 emulation
mode on the M1, the x64 package will be installed. If you're not running in emulation mode in your command prompt,
the ARM64 package will be installed.
Microsoft ODBC 18
To install Microsoft ODBC driver 18 for SQL Server on macOS, run the following commands:
Previous versions
The following sections provide instructions for installing previous versions of the Microsoft ODBC driver on
macOS.
Microsoft ODBC 17
To install Microsoft ODBC driver 17 for SQL Server on macOS, run the following commands:
IMPORTANT
If you installed the v17 msodbcsql package that was briefly available, you should remove it before installing the
msodbcsql17 package. This will avoid conflicts. The msodbcsql17 package can be installed side by side with the
msodbcsql v13 package.
ODBC 13.1
Use the following commands to install the Microsoft ODBC driver 13.1 for SQL Server on OS X 10.11 (El
Capitan) and macOS 10.12 (Sierra):
Driver files
The ODBC driver on macOS consists of the following components:
C O M P O N EN T DESC RIP T IO N
libmsodbcsql.17.dylib or libmsodbcsql.13.dylib The dynamic library ( dylib ) file that contains all of the
driver's functionality. This file is installed in
/usr/local/lib/ .
msodbcsqlr17.rll or msodbcsqlr13.rll The accompanying resource file for the driver library. This file
is installed in
[driver .dylib
directory]../share/msodbcsql17/resources/en_US/
for Driver 17 and in
[driver .dylib
directory]../share/msodbcsql/resources/en_US/
for Driver 13.
msodbcsql.h The header file that contains all of the new definitions
needed to use the driver.
msodbcsql.h is installed in
/usr/local/include/msodbcsql17/ for Driver 17 and in
/usr/local/include/msodbcsql/ for Driver 13.
LICENSE.txt The text file that contains the terms of the End-User License
Agreement. This file is placed in
/usr/local/share/doc/msodbcsql17/ for Driver 17 and in
/usr/local/share/doc/msodbcsql/ for Driver 13.
RELEASE_NOTES The text file that contains release notes. This file is placed in
/usr/local/share/doc/msodbcsql17/ for Driver 17 and in
/usr/local/share/doc/msodbcsql/ for Driver 13.
For additional cases where you're unable to make a connection to SQL Server using the ODBC driver, see the
known issues article on troubleshooting connection problems.
If brew is having trouble finding the formulas, make sure you didn't skip the install step:
brew tap microsoft/mssql-release https://github.com/Microsoft/homebrew-mssql-release
Next steps
After installing the driver, you can try the C++ ODBC example application. For more information about
developing ODBC applications, see Developing Applications.
For more information, see the ODBC driver release notes and system requirements.
Connecting from Linux or macOS
4/27/2022 • 6 minutes to read • Edit Online
Connection Properties
See DSN and Connection String Keywords and Attributes for all the connection string keywords and attributes
supported on Linux and macOS.
IMPORTANT
When connecting to a database that uses database mirroring (has a failover partner), do not specify the database name in
the connection string. Instead, send a use database_name command to connect to the database before executing your
queries.
The value passed to the Driver keyword can be one of the following:
The name you used when you installed the driver.
The path to the driver library, which was specified in the template .ini file used to install the driver.
DSNs are optional. You can use a DSN to define connection string keywords under a DSN name that you can
then reference in the connection string. To create a DSN, create (if necessary) and edit the file ~/.odbc.ini (
.odbc.ini in your home directory) for a User DSN only accessible to the current user, or /etc/odbc.ini for a
System DSN (administrative privileges required.) The following odbc.ini is a sample that shows the minimal
required entries for a DSN:
# [DSN name]
[MSSQLTest]
Driver = ODBC Driver 17 for SQL Server
# Server = [protocol:]server[,port]
Server = tcp:localhost,1433
#
# Note:
# Port isn't a valid keyword in the odbc.ini file
# for the Microsoft ODBC driver on Linux or macOS
#
To connect using the above DSN in a connection string, you would specify the DSN keyword like:
DSN=MSSQLTest;UID=my_username;PWD=my_password
The above connection string would be the equivalent of specifying a connection string without the DSN
keyword like: Driver=ODBC Driver 17 for SQL Server;Server=tcp:localhost,1433;UID=my_username;PWD=my_password
You can optionally specify the protocol and port to connect to the server. For example,
Ser ver=tcp:servername,12345 . The only protocol supported by the Linux and macOS drivers is tcp .
To connect to a named instance on a static port, use Ser ver= servername,por t_number . Connecting to a
dynamic port isn't supported before version 17.4.
Alternatively, you can add the DSN information to a template file, and execute the following command to add it
to ~/.odbc.ini :
odbcinst -i -s -f <template_file>
For complete documentation on ini files and odbcinst , see the unixODBC documentation. For entries in the
odbc.ini file specific to the ODBC Driver for SQL Server, see DSN and Connection String Keywords and
Attributes for ones supported on Linux and macOS.
You can verify that your driver is working by using isql to test the connection, or you can use this command:
Using TLS/SSL
You can use Transport Layer Security (TLS), previously known as Secure Sockets Layer (SSL), to encrypt
connections to SQL Server. TLS protects SQL Server user names and passwords over the network. TLS also
verifies the identity of the server to protect against man-in-the-middle (MITM) attacks.
Enabling encryption increases security at the expense of performance.
For more information, see Encrypting Connections to SQL Server and Using Encryption Without Validation.
Regardless of the settings for Encr ypt and TrustSer verCer tificate , the server login credentials (user name
and password) are always encrypted. The following tables show the effect of the Encr ypt and
TrustSer verCer tificate settings.
ODBC Driver 18 and newer
SERVER F O RC E
EN C RY P T SET T IN G T RUST SERVER C ERT IF IC AT E EN C RY P T IO N RESULT
Strict - - TrustServerCertificate is
ignored. Server certificate is
checked.
Data sent between client
and server is encrypted.
NOTE
Strict is only available against servers that support TDS 8.0 connections.
When using connection encryption, the name (or IP address) in a Subject Common Name (CN) or Subject
Alternative Name (SAN) in a SQL Server TLS/SSL certificate should exactly match the server name (or IP
address) specified in the connection string.
By default, encrypted connections always verify the server's certificate. However, if you connect to a server that
has a self-signed certificate, and aren't using strict encryption mode, you can add the TrustServerCertificate
option to bypass checking the certificate against the list of trusted certificate authorities:
TLS on Linux and macOS uses the OpenSSL library. The following table shows the minimum supported versions
of OpenSSL and the default Certificate Trust Store locations for each platform:
You can also specify encryption in the connection string using the Encrypt option when using
SQLDriverConnect to connect.
See Also
Installing the Microsoft ODBC Driver for SQL Server on Linux
Installing the Microsoft ODBC Driver for SQL Server on macOS
Programming Guidelines
Data access tracing on Linux and macOS
4/27/2022 • 2 minutes to read • Edit Online
[ODBC]
Trace=Yes
TraceFile=/home/myappuser/odbctrace.log
You can also use /dev/stdout or any other device name to send trace output there, instead of to a persistent file.
With the preceding settings, every time an application loads the unixODBC Driver Manager, it records all ODBC
API calls made, into the output file.
After you finish tracing your application, remove Trace=Yes from the odbcinst.ini file to avoid the
performance penalty of tracing, and ensure that any unnecessary trace files are removed.
Tracing applies to all applications that use the driver in odbcinst.ini . To not trace all applications (for example,
to avoid disclosing sensitive per-user information), you can trace an individual application instance. Provide the
instance the location of a private odbcinst.ini , by using the ODBCSYSINI environment variable. For example:
$ ODBCSYSINI=/home/myappuser myapp
In this case, you can add Trace=Yes to the [ODBC Driver 17 for SQL Server] section of
/home/myappuser/odbcinst.ini .
For example, the following command prints the location of system and user odbc.ini files that contain,
respectively, system and user data source names (DSNs):
$ odbcinst -j
unixODBC 2.3.1
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /home/odbcuser/.odbc.ini`
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
User DSNs are only available to a specific user. User DSNs are stored in a file in the user's home directory, or a
subdirectory. System DSNs are available for every user on the system, but can only be added, modified, and
removed by a system administrator. If a user has a user DSN with the same name as a system DSN, the user
DSN will be used upon connections by that user. For more information, see the unixODBC documentation.
See also
Programming guidelines
High availability and disaster recovery on Linux and
macOS
4/27/2022 • 5 minutes to read • Edit Online
NOTE
Because a connection can fail due to an availability group failover, you should implement connection retry logic. Retry a
failed connection until it reconnects. Increasing the connection timeout and implementing connection retry logic increases
the chance of connecting to an availability group.
ODBC syntax
Two ODBC connection string keywords support Always On availability groups:
ApplicationIntent
MultiSubnetFailover
For more information about ODBC connection string keywords, see Using connection string keywords with SQL
Server Native Client.
The equivalent connection attributes are:
SQL_COPT_SS_APPLICATION_INTENT
SQL_COPT_SS_MULTISUBNET_FAILOVER
F UN C T IO N DESC RIP T IO N
See also
Connection string keywords and data source names (DSNs)
Programming guidelines
Release notes
Programming Guidelines
4/27/2022 • 7 minutes to read • Edit Online
Available Features
The following sections from the SQL Server Native Client documentation for ODBC (SQL Server Native Client
(ODBC)) are valid when using the ODBC driver on macOS and Linux:
Communicating with SQL Server (ODBC)
Connection and query timeout support
Cursors
Date/Time Improvements (ODBC)
Executing Queries (ODBC)
Handling Errors and Messages
Kerberos authentication
Large CLR User-Defined Types (ODBC)
Performing Transactions (ODBC) (except distributed transactions)
Processing Results (ODBC)
Running Stored Procedures
Sparse Columns Support (ODBC)
Using Encryption Without Validation
Table Valued Parameters
UTF-8 and UTF-16 for command and data API
Using Catalog Functions
Unsupported Features
The following features haven't been verified to work correctly in the ODBC driver on macOS and Linux:
Failover Cluster Connection
Transparent Network IP Resolution (before ODBC Driver 17)
Linux and macOS ODBC Driver BID Tracing (before ODBC Driver 17.3)
The following features aren't available in the ODBC driver on macOS and Linux:
Distributed Transactions (SQL_ATTR_ENLIST_IN_DTC attribute isn't supported)
Database Mirroring
FILESTREAM
Profiling ODBC driver performance, discussed in SQLSetConnectAttr, and the following performance-related
connection attributes:
SQL_COPT_SS_PERF_DATA
SQL_COPT_SS_PERF_DATA_LOG
SQL_COPT_SS_PERF_DATA_LOG_NOW
SQL_COPT_SS_PERF_QUERY
SQL_COPT_SS_PERF_QUERY_INTERVAL
SQL_COPT_SS_PERF_QUERY_LOG
SQLBrowseConnect (before version 17.2)
C interval types such as SQL_C_INTERVAL_YEAR_TO_MONTH (documented in Data Type Identifiers and
Descriptors)
The SQL_CUR_USE_ODBC value of the SQL_ATTR_ODBC_CURSORS attribute of the SQLSetConnectAttr
function.
NOTE
Due to iconv differences in musl and glibc many of these locales are not supported on Alpine Linux.
For more information, see Functional differences from glibc
UTF-8 Unicode
CP874 Latin/Thai
CP1251 Cyrillic
CP1253 Greek
CP1256 Arabic
CP1257 Baltic
NAME DESC RIP T IO N
CP1258 Vietnamese
ISO-8859-3 Latin-3
ISO-8859-4 Latin-4
ISO-8859-5 Latin/Cyrillic
ISO-8859-6 Latin/Arabic
ISO-8859-7 Latin/Greek
ISO-8859-13 Latin-7
ISO-8859-15 Latin-9
Upon connection, the driver detects the current locale of the process it's loaded in. If it uses one of the encodings
above, the driver uses that encoding for SQLCHAR (narrow-character) data; otherwise, it defaults to UTF-8. Since
all processes start in the "C" locale by default (and cause the driver to default to UTF-8), if an application needs
to use one of the encodings above, it should use the setlocale function to set the locale appropriately before
connecting; either by specifying the locale explicitly, or using an empty string for example
setlocale(LC_ALL, "") to use the locale settings of the environment.
Therefore, in a typical Linux or macOS environment where the encoding is UTF-8, users of ODBC Driver 17
upgrading from 13 or 13.1 won't observe any differences. However, applications that use a non-UTF-8 encoding
in the above list via setlocale() need to use that encoding for data to/from the driver instead of UTF-8.
SQLWCHAR data must be UTF-16LE (Little Endian).
When binding input parameters with SQLBindParameter, if a narrow character SQL type such as SQL_VARCHAR
is specified, the driver converts the supplied data from the client encoding to the default (typically codepage
1252) SQL Server encoding. For output parameters, the driver converts from the encoding specified in the
collation information associated with the data to the client encoding. However, data loss is possible ---
characters in the source encoding not representable in the target encoding will convert to a question mark ('?').
To avoid this data loss when binding input parameters, specify a Unicode SQL character type such as
SQL_NVARCHAR. In this case, the driver converts from the client encoding to UTF-16, which can represent all
Unicode characters. Furthermore, the target column or parameter on the server must also be either a Unicode
type (nchar , nvarchar , ntext ) or one with a collation/encoding, which can represent all the characters of the
original source data. For avoiding data loss with output parameters, specify a Unicode SQL type, and either a
Unicode C type (SQL_C_WCHAR), causing the driver to return data as UTF-16, or a narrow C type, and ensure
that the client encoding can represent all the characters of the source data (this representation is always possible
with UTF-8.)
For more information about collations and encodings, see Collation and Unicode Support.
There are some encoding conversion differences between Windows and several versions of the iconv library on
Linux and macOS. Text data in codepage 1255 (Hebrew) has one code point (0xCA) that behaves differently
upon conversion to Unicode. On Windows, this character converts to the UTF-16 code point of 0x05BA. On
macOS and Linux with libiconv versions earlier than 1.15, it converts to 0x00CA. On Linux with iconv libraries
that don't support the 2003 revision of Big5/CP950 (named BIG5-2003 ), characters added with that revision
won't convert correctly. In codepage 932 (Japanese, Shift-JIS), the result of decoding of characters not originally
defined in the encoding standard also differs. For example, the byte 0x80 converts to U+0080 on Windows but
may become U+30FB on Linux and macOS, depending on iconv version.
In ODBC Driver 13 and 13.1, when UTF-8 multibyte characters or UTF-16 surrogates are split across SQLPutData
buffers, it results in data corruption. Use buffers for streaming SQLPutData that don't end in partial character
encodings. This limitation has been removed with ODBC Driver 17.
OpenSSL
Starting with version 17.4, the driver loads OpenSSL dynamically, which allows it to run on systems that have
either version 1.0 or 1.1 without a need for separate driver files. Starting with version 17.9, the driver supports
OpenSSL 3.0 in addition to the previous versions. When multiple versions of OpenSSL are present, the driver
will attempt to load the latest one.
NOTE
A potential conflict may occur if the application that uses the driver (or one of its components) is linked with or
dynamically loads a different version of OpenSSL. If several versions of OpenSSL are present on the system and the
application uses it, it is highly recommended that one be extra careful in making sure that the version loaded by the
application and the driver do not mismatch, as the errors could corrupt memory and thus will not necessarily manifest in
obvious or consistent ways.
Alpine Linux
At the time of this writing the default stack size in MUSL is 128K, which is enough for basic ODBC driver
functionality, however depending on what the application does it isn't difficult to exceed this limit, especially
when calling the driver from multiple threads. It's recommended that an ODBC application on Alpine Linux is
compiled with -Wl,-z,stack-size=<VALUE IN BYTES> to increase the stack size. For reference, the default stack size
on most GLIBC systems is 2MB.
Additional Notes
You can make a dedicated administrator connection (DAC) using SQL Server authentication and
host,por t . A member of the Sysadmin role first needs to discover the DAC port. See Diagnostic
Connection for Database Administrators to discover how. For example, if the DAC port were 33000, you
could connect to it with sqlcmd as follows:
The UnixODBC driver manager returns "invalid attribute/option identifier" for all statement attributes
when they're passed through SQLSetConnectAttr. On Windows, when SQLSetConnectAttr receives a
statement attribute value, it causes the driver to set that value on all active statements, which are children
of the connection handle.
When using the driver with highly multithreaded applications, unixODBC's handle validation may become
a performance bottleneck. In such scenarios, higher performance may be obtained by compiling
unixODBC with the --enable-fastvalidate option. However, beware that this option may cause
applications that pass invalid handles to ODBC APIs to crash instead of returning SQL_INVALID_HANDLE
errors.
See Also
Frequently Asked Questions
Known Issues in this Version of the Driver
Release Notes
Connecting with bcp
4/27/2022 • 5 minutes to read • Edit Online
NOTE
A backslash '\' on a command-line argument must either be quoted or escaped. For example, to specify a newline as a
custom row terminator, you must use one of the following mechanisms:
-r\\n
-r"\n"
-r'\n'
The following example is a command invocation of bcp to copy table rows to a text file:
Available options
In the current release, the following syntax and options are available:
[database.]schema.table in data_file | out data_file
-a packet_size
Specifies the number of bytes, per network packet, sent to and from the server.
-b batch_size
Specifies the number of rows per batch of imported data.
-c
Uses a character data type.
-d database_name
Specifies the database to connect to.
-D
Causes the value passed to the bcp -S option to be interpreted as a data source name (DSN). For more
information, see "DSN Support in sqlcmd and bcp" in Connecting with sqlcmd.
-e error_file
Specifies the full path of an error file used to store any rows that the bcp utility can't transfer from the file to
the database.
-E
Uses an identity value or values in the imported data file for the identity column.
-f format_file
Specifies the full path of a format file.
-F first_row
Specifies the number of the first row to export from a table or import from a data file.
-G
This switch is used by the client when connecting to Azure SQL Database or Azure Synapse Analytics to specify
that the user be authenticated using Azure Active Directory authentication. It can be combined with just the -P
option to use access token authentication (v17.8+). The -G switch requires at least bcp version 17.6. To
determine your version, execute bcp -v.
IMPORTANT
The -G option only applies to Azure SQL Database and Azure Synapse Analytics. AAD Interactive Authentication is not
currently supported on Linux or macOS. AAD Integrated Authentication requires Microsoft ODBC Driver 17 for SQL
Server version 17.6.1 or higher and a properly configured Kerberos environment.
-k
Specifies that empty columns should keep a null value during the operation, rather than have any default values
for the columns inserted.
-l
Specifies a login timeout. The -l option specifies the number of seconds before a login to SQL Server times out
when you try to connect to a server. The default login timeout is 15 seconds. The login timeout must be a
number between 0 and 65534. If the value supplied isn't numeric or doesn't fall into that range, bcp generates
an error message. A value of 0 specifies an infinite timeout.
-L last_row
Specifies the number of the last row to export from a table or import from a data file.
-m max_errors
Specifies the maximum number of syntax errors that can occur before the bcp operation is canceled.
-n
Uses the native (database) data types of the data to do the bulk-copy operation.
-P password
Specifies the password for the login ID. When used with the -G option without -U, specifies a file that contains an
access token (v17.8+). The token file should be in UTF-16LE (no BOM) format.
Access tokens can be obtained via various methods. It's important to ensure the access token is correct byte-for-
byte, as it will be sent as-is. Below is an example command that obtains an access token. The command uses the
Azure CLI and Linux commands and saves it to a file in the proper format. If your system or terminal's default
encoding isn't ASCII or UTF-8, you may need to adjust the iconv options. Be sure to carefully secure the
resulting file and delete it when it's no longer required.
-q
Executes the SET QUOTED_IDENTIFIERS ON statement in the connection between the bcp utility and an
instance of SQL Server.
-r row_terminator
Specifies the row terminator.
-R
Specifies that currency, date, and time data is bulk copied into SQL Server using the regional format defined for
the locale setting of the client computer.
-S server
Specifies the name of the SQL Server instance to connect to, or if -D is used, a DSN.
-t field_terminator
Specifies the field terminator.
-T
Specifies that the bcp utility connect to SQL Server with a trusted connection (integrated security).
-u
Trust server certificate. (available since bcp version 18)
-U login_id
Specifies the login ID used to connect to SQL Server.
-v
Reports the bcp utility version number and copyright.
-w
Uses Unicode characters to do the bulk copy operation.
In this release, Latin-1 and UTF-16 characters are supported.
-Y [s|m|o]
Specifies the connection encryption mode. The options are Strict, Mandatory, and Optional. Using -Y without any
parameters uses the Mandatory encryption mode, and is equivalent to -Ym. (available since bcp version 18)
Unavailable options
In the current release, the following syntax and options aren't available:
-C
Specifies the code page of the data in the data file.
-h hint
Specifies the hint or hints used during a bulk import of data into a table or view.
-i input_file
Specifies the name of a response file.
-N
Uses the native (database) data types of the data for noncharacter data, and Unicode characters for character
data.
-o output_file
Specifies the name of a file that receives output redirected from the command prompt.
-V (80 | 90 | 100)
Uses data types from an earlier version of SQL Server.
-x
Used with the format and -f format_file options, generates an XML-based format file instead of the default non-
XML format file.
See also
Connecting with sqlcmd
Release notes
Connecting with sqlcmd
4/27/2022 • 7 minutes to read • Edit Online
sqlcmd -E -Sxxx.xxx.xxx.xxx
sqlcmd -Sxxx.xxx.xxx.xxx -Uxxx -Pxxx
Available options
The following options are available in sqlcmd on Linux and macOS:
-?
Display sqlcmd usage.
-a
Request a packet size.
-b
Terminate batch job if there's an error.
-c batch_terminator
Specify the batch terminator.
-C
Trust server certificate.
-d database_name
Issue a USE database_name statement when you start sqlcmd .
-D
Causes the value passed to the sqlcmd -S option to be interpreted as a data source name (DSN). For more
information, see "DSN Support in sqlcmd and bcp " at the end of this article.
-e
Write input scripts to the standard output device (stdout).
-E
Use trusted connection (integrated authentication.) For more information about making trusted connections that
use integrated authentication from a Linux or macOS client, see Using Integrated Authentication.
-f codepage | i:codepage[,o:codepage] | o:codepage[,i:codepage]
Specifies the input and output code pages. The codepage number is a numeric value that specifies an installed
Linux code page. (available since 17.5.1.1)
-G
This switch is used by the client when connecting to SQL Database or Azure Synapse Analytics to specify that the
user be authenticated using Azure Active Directory authentication. It can be combined with just the -P option to
use access token authentication (v17.8+). This option sets the sqlcmd scripting variable SQLCMDUSEAAD = true.
The -G switch requires at least sqlcmd version 17.6. To determine your version, execute sqlcmd -? .
IMPORTANT
The -G option only applies to Azure SQL Database and Azure Synapse Analytics. AAD Interactive Authentication isn't
currently supported on Linux or macOS. AAD Integrated Authentication requires Microsoft ODBC Driver 17 for SQL
Server version 17.6.1 or higher and a properly configured Kerberos environment.
-h number_of_rows
Specify the number of rows to print between the column headings.
-H
Specify a workstation name.
-i input_file[,input_file[,...]]
Identify the file that contains a batch of SQL statements or stored procedures.
-I
Set the SET QUOTED_IDENTIFIER connection option to ON.
-k
Remove or replace control characters.
-K application_intent
Declares the application workload type when connecting to a server. The only currently supported value is
ReadOnly . If -K isn't specified, sqlcmd doesn't support connectivity to a secondary replica in an AlwaysOn
availability group. For more information, see ODBC Driver on Linux and macOS - High Availability and Disaster
Recovery.
NOTE
-K isn't supported in the CTP for SUSE Linux. You can, however, specify the ApplicationIntent=ReadOnly keyword in a
DSN file passed to sqlcmd . For more information, see "DSN Support in sqlcmd and bcp " at the end of this article.
-l timeout
Specify the number of seconds before a sqlcmd login times out when you try to connect to a server.
-m error_level
Control which error messages are sent to stdout.
-M multisubnet_failover
Always specify -M when connecting to the availability group listener of a SQL Server 2012 (11.x) availability
group or a SQL Server 2012 (11.x) Failover Cluster Instance. -M provides for faster detection of failovers and
connection to the (currently) active server. If -M isn't specified, -M is off. For more information about Always On
Availability Groups, see ODBC Driver on Linux and macOS - High Availability and Disaster Recovery.
NOTE
-M isn't supported in the CTP for SUSE Linux. You can, however, specify the MultiSubnetFailover=Yes keyword in a
DSN file passed to sqlcmd . For more information, see "DSN Support in sqlcmd and bcp " at the end of this article.
-N [s|m|o]
Set the connection encryption mode to be Strict, Mandatory, or Optional respectively. Defaults to mandatory if
not specified. ( [s|m|o] added in ODBC 18.0)
-o output_file
Identify the file that receives output from sqlcmd .
-p
Print performance statistics for every result set.
-P
Specify a user password. When used with the -G option without -U, specifies a file that contains an access token
(v17.8+). The token file should be in UTF-16LE (no BOM) format.
Access tokens can be obtained via various methods. It's important to ensure the access token is correct byte-for-
byte, as it will be sent as-is. Below is an example command that obtains an access token. The command uses the
Azure CLI and Linux commands and saves it to a file in the proper format. If your system or terminal's default
encoding isn't ASCII or UTF-8, you may need to adjust the iconv options. Be sure to carefully secure the
resulting file and delete it when it's no longer required.
-q commandline_query
Execute a query when sqlcmd starts, but doesn't exit when the query has finished running.
-Q commandline_query
Execute a query when sqlcmd starts. sqlcmd will exit when the query finishes.
-r
Redirects error messages to stderr.
-R
Causes the driver to use client regional settings to convert currency and date and time data to character data.
Currently only uses en_US (US English) formatting.
-s column_separator_char
Specify the column-separator character.
-S [protocol:] server[,port]
Specify the instance of SQL Server to connect to, or if -D is used, a DSN. The ODBC driver on Linux and macOS
requires -S. The only valid protocol value is tcp .
-t query_timeout
Specify the number of seconds before a command (or SQL statement) times out.
-u
Specify that output_file is stored in Unicode format, whatever the format of input_file.
-U
login_id Specify a user login ID.
-V error_severity_level
Control the severity level that is used to set the ERRORLEVEL variable.
-w column_width
Specify the screen width for output.
-W
Remove trailing spaces from a column.
-x
Disable variable substitution.
-X
Disable commands, startup script, and environment variables.
-y variable_length_type_display_width
Set the sqlcmd scripting variable SQLCMDMAXFIXEDTYPEWIDTH .
-Y fixed_length_type_display_width
Set the sqlcmd scripting variable SQLCMDMAXVARTYPEWIDTH .
-z password
Change password.
-Z password
Change password and exit.
Available commands
In the current release, the following commands are available:
[:]!!
:Connect
:Error
[:]EXIT
GO [ count ]
:Help
:List
:Listvar
:On Error
:Out
:Perftrace
[:]QUIT
:r
:RESET
:setvar
Unavailable options
In the current release, the following options aren't available:
-A
Log in to SQL Server with a Dedicated Administrator Connection (DAC). For information on how to make a
dedicated administrator connection (DAC), see Programming Guidelines.
-L
List the locally configured server computers, and the names of the server computers that are broadcasting on
the network.
-v
Create a sqlcmd scripting variable that can be used in a sqlcmd script.
You can use the following alternative method: Put the parameters inside one file, which you can then append to
another file. This method will help you use a parameter file to replace the values. For example, create a file called
a.sql (the parameter file) with the following content:
Then create a file called b.sql , with the parameters for replacement:
At the command line, combine a.sql and b.sql into c.sql using the following commands:
Unavailable commands
In the current release, the following commands aren't available:
:ED
:Ser verList
:XML
See also
Connecting with bcp
Release notes
Using Integrated Authentication
4/27/2022 • 5 minutes to read • Edit Online
When connecting with a DSN, you can also add Trusted_Connection=yes to the DSN entry in odbc.ini .
The -E option of sqlcmd and the -T option of bcp can also be used to specify integrated authentication; see
Connecting with sqlcmd and Connecting with bcp for more information.
Ensure that the client principal which is going to connect to SQL Server is already authenticated with the
Kerberos KDC.
Ser verSPN and FailoverPar tnerSPN are not supported.
SY N TA X DESC RIP T IO N
[libdefaults]
default_realm = YYYY.CORP.CONTOSO.COM
dns_lookup_realm = false
dns_lookup_kdc = true
ticket_lifetime = 24h
forwardable = yes
[domain_realm]
.yyyy.corp.contoso.com = YYYY.CORP.CONTOSO.COM
.zzzz.corp.contoso.com = ZZZZ.CORP.CONTOSO.COM
If your Linux or macOS computer is configured to use the Dynamic Host Configuration Protocol (DHCP) with a
Windows DHCP server providing the DNS servers to use, you can use dns_lookup_kdc=true . Now, you can
use Kerberos to sign in to your domain by issuing the command kinit [email protected] . Parameters
passed to kinit are case-sensitive and the SQL Server computer configured to be in the domain must have
that user [email protected] added for login. Now, you can use trusted connections
(Trusted_Connection=YES in a connection string, bcp -T , or sqlcmd -E ).
The time on the Linux or macOS computer and the time on the Kerberos Key Distribution Center (KDC) must be
close. Ensure that your system time is set correctly, e.g. by using the Network Time Protocol (NTP).
If Kerberos authentication fails, the ODBC driver on Linux or macOS does not use NTLM authentication.
For more information about authenticating Linux or macOS computers with Active Directory, see Authenticate
Linux Clients with Active Directory. For more information about configuring Kerberos, see the MIT Kerberos
Documentation.
See Also
Programming Guidelines
Release Notes
Using Azure Active Directory
Release Notes for the Microsoft ODBC Driver for
SQL Server on Linux and macOS
4/27/2022 • 7 minutes to read • Edit Online
Added compatibility with OpenSSL 3.0 See Connection String Keywords and Data Source Names.
Ability to send long types as max types See DSN and Connection String Attributes and Keywords.
Support for TDS 8.0 See Features of the Microsoft ODBC Driver for SQL Server
on Windows.
Compatibility extensions for SQLGetData See Features of the Microsoft ODBC Driver for SQL Server
on Windows.
Added compatibility with OpenSSL 3.0 See Connection String Keywords and Data Source Names.
Package update Updated RPM packages for Red Hat 7, Red Hat 8, SUSE 12,
and SUSE 15 to use SHA256 RPM signing.
N EW IT EM DETA IL S
Support for Apple M1 ARM64 hardware See Install the ODBC driver (macOS).
Replication option added to the connection string See DSN and Connection String Attributes and Keywords.
KeepAlive and KeepAliveInterval options added to the See DSN and Connection String Attributes and Keywords.
connection string
New distributions supported. Ubuntu 20.10, macOS Big Sur (11.0), Oracle Linux 7
Service Principal Authentication See DSN and Connection String Attributes and Keywords.
Ability to insert into encrypted money and smallmoney See Using Always Encrypted.
columns
SQL_COPT_SS_AUTOBEGINTXN connection attribute to See DSN and Connection String Attributes and Keywords.
control whether automatic BEGIN TRANSACTION happens
after ROLLBACK or COMMIT
Support authentication with Managed Identity for Azure Key See Using Always Encrypted with the ODBC Driver.
Vault
Support for more Azure Key Vault endpoints See Using Always Encrypted with the ODBC Driver.
SQL_COPT_SS_SPID connection attribute to retrieve SPID See DSN and Connection String Attributes and Keywords.
without round trip to server
Support for indicating EULA acceptance via debconf on See Installing the Driver.
Debian and Ubuntu
Support for more Azure Key Vault endpoints See Using Always Encrypted with the ODBC Driver.
Known Issue:
When using Always Encrypted with secure enclaves and Azure Key Vault, odd key path lengths may result in
CMK signature verification errors. If you encounter this issue, try changing the length of the key path by one
character by renaming the AKV key.
Always Encrypted with secure enclaves. See Using Always Encrypted with the ODBC Driver.
Azure Active Directory Managed Identity (system and user- See Using Azure Active Directory with the ODBC Driver.
assigned) authentication mode.
Ability to stream input parameters against Always Encrypted For more information, see Limitations of the ODBC driver
columns. when using Always Encrypted.
N EW IT EM DETA IL S
Data Classification for Azure SQL Database and SQL Server. See Data Classification.
SQLBrowseConnect
Dynamic dependency on libcurl . Starting with this version, the libcurl package isn't an
explicit dependency.
The libcurl package for OpenSSL or NSS is required when
using Azure Key Vault or Azure Active Directory
authentication.
If you encounter an error regarding libcurl , ensure it's
installed.
Idle Connection Resiliency with ConnectRetryCount and • Use SQL_COPT_SS_CONNECT_RETRY_COUNT (read only) to
ConnectRetryInterval keywords in connection string. retrieve the number of connection retry attempts.
See Using Always Encrypted with the ODBC Driver for SQL
Server).
Support for loading the .rll from default location. See 'Resource File Loading' section in the Installation
document.
17
New distributions suppor ted : macOS High Sierra and Ubuntu 17.10
Performance Improvements : Greater than 10 times performance improvement when driver converts to/from
UTF-8/16.
Features Added :
Always Encrypted support for BCP API
New connection string attribute UseFMTOnly causes driver to use legacy metadata in special cases requiring
temp tables.
Support for Azure SQL Managed Instance.
NOTE
There are a number of differences when using Managed Instance:
FILESTREAM is not supported
Local filesystem access is not supported, but required for things like tracefiles
Create UDT from local path is not supported
Windows Integrated Authentication is not supported
DTC is not supported
'sa' account is not present (default account is called 'cloudSA')
TDS token ERROR (0xAA) returns incorrect server name
Special characters in database name are not supported
ALTER DATABASE [dbname1] MODIFY NAME = [dbname2] is not supported
The error messages are always shown in English, regardless of language settings (same as Azure)
Package update Updated RPM packages for Red Hat 7, Red Hat 8, SUSE 12,
and SUSE 15 to use SHA256 RPM signing.
Sqlcmd Bugfix Fixed input redirection bug and empty lines leading to
repeated execution.
Sqlcmd Command Line Parser Updated Fixed bugs where unexpected behavior occurred when using
certain options in different orders.
Sqlcmd Error Messages Updated Fixed various inconsistencies in how errors in sqlcmd were
returned.
Sqlcmd Column Name Truncation Fixed Fixed issue where column names would be truncated
incorrectly
Sqlcmd Linux Exit Codes Fixed issue where process exit code was missing on Linux
Next steps
Learn more about connecting with BCP and SQLCMD!
Known issues for the ODBC driver on Linux and
macOS
4/27/2022 • 4 minutes to read • Edit Online
Known issues
Additional issues will be posted on the SQL Server Drivers blog.
Due to system library limitations, Alpine Linux supports fewer character encodings and locales. For
example, en_US.UTF-8 isn't available. For more information, see musl libc - functional differences from
glibc .
Windows, Linux, and macOS convert characters from the Private Use Area (PUA) or End User-Defined
Characters (EUDC) differently. Conversions performed on the server within Transact-SQL use the
Windows conversion library. Conversions in the driver use the Windows, Linux, or macOS conversion
libraries. Each library may produce different results when performing these conversions. For more
information, see End-User-Defined and Private Use Area Characters.
If the client encoding is UTF-8, the driver manager doesn't always correctly convert from UTF-8 to UTF-
16. Currently, data corruption occurs when one or more characters in the string aren't valid UTF-8
characters. ASCII characters are mapped correctly. The driver manager attempts this conversion when
calling the SQLCHAR versions of the ODBC API (for example, SQLDriverConnectA). The driver manager
won't attempt this conversion when calling the SQLWCHAR versions of the ODBC API (for example,
SQLDriverConnectW).
The ColumnSize parameter of SQLBindParameter refers to the number of characters in the SQL type,
while BufferLength is the number of bytes in the application's buffer. However, if the SQL data type is
varchar(n) or char(n) , the application binds the parameter as SQL_C_CHAR for the C type, and
SQL_CHAR or SQL_VARCHAR for the SQL type, and the character encoding of the client is UTF-8, you
may get a "String data, right truncation" error from the driver even if the value of ColumnSize is aligned
with the size of the data type on the server. This error occurs since conversions between character
encodings may change the length of the data. For example, a right apostrophe character (U+2019) is
encoded in CP-1252 as the single-byte 0x92, but in UTF-8 as the 3-byte sequence 0xe2 0x80 0x99.
For example, if your encoding is UTF-8 and you specify 1 for both BufferLength and ColumnSize in
SQLBindParameter for an out-parameter, and then attempt to retrieve the preceding character stored in a
char(1) column on the server (using CP-1252), the driver attempts to convert it to the 3-byte UTF-8 encoding,
but can't fit the result into a 1-byte buffer. In the other direction, it compares ColumnSize with the BufferLength
in SQLBindParameter before doing the conversion between the different code pages on the client and server.
Because a ColumnSize of 1 is less than a BufferLength of (for example) 3, the driver generates an error. To avoid
this error, ensure that the length of the data after conversion fits into the specified buffer or column. Note that
ColumnSize can't be greater than 8000 for the varchar(n) type.
[ODBC]
Trace = Yes
TraceFile = (path to log file, or /dev/stdout to output directly to the terminal)
If you get another connection failure and don't see a log file, there (possibly) are two copies of the driver
manager on your computer. Otherwise, the log output should be similar to:
[ODBC][28783][1321576347.077780][SQLDriverConnectW.c][290]
Entry:
Connection = 0x17c858e0
Window Hdl = (nil)
Str In = [DRIVER={ODBC Driver 17 for SQL Server};SERVER={contoso.com};Trusted_Connection=
{YES};WSID={mydb.contoso.com};AP...][length = 139 (SQL_NTS)]
Str Out = (nil)
Str Out Max = 0
Str Out Ptr = (nil)
Completion = 0
UNICODE Using encoding ASCII 'UTF8' and UNICODE 'UTF16LE'
There's more than one driver manager installed and your application is using the wrong one, or the driver
manager wasn't built correctly.
Some macOS users encounter the following error with driver version 17.8 or older:
(This error has been resolved in driver version 17.9+)
[08001][Microsoft][ODBC Driver 17 for SQL Server]SSL Provider: [OpenSSL library could not be loaded, make
sure OpenSSL 1.0 or 1.1 is installed]
[08001][Microsoft][ODBC Driver 17 for SQL Server]Client unable to establish connection (0)
(SQLDriverConnect)
The error can happen when OpenSSL 3.0 is installed. OpenSSL typically is installed through Brew, and it contains
the openssl, [email protected], and openssl@3 binaries.
To resolve this error, change the symlink of the openssl binary to [email protected]:
Next steps
For ODBC driver installation instructions, see the following articles:
Installing the Microsoft ODBC Driver for SQL Server on Linux
Installing the Microsoft ODBC Driver for SQL Server on macOS
For more information, see the Programming guidelines and the Release notes.
Microsoft ODBC Driver for SQL Server on Windows
4/27/2022 • 2 minutes to read • Edit Online
Summary
VERSIO N F EAT URES SUP P O RT ED
Microsoft ODBC Driver 18 for SQL Server Support for TDS 8.0
Extensions to SQLGetData
Option to send SQL_LONG_* types as (max) -types
Microsoft ODBC Driver 17 for SQL Server Always Encrypted support for BCP API
New connection string attribute UseFMTONLY causes
driver to use legacy metadata in special cases
requiring temp tables
Microsoft ODBC Driver 13 for SQL Server Internationalized Domain Name (IDN)
Documentation
This documentation for the Microsoft ODBC Driver for SQL Server includes:
Release Notes for ODBC to SQL Server on Windows
Features of the Microsoft ODBC Driver for SQL Server on Windows
System Requirements, Installation, and Driver Files
Driver-Aware Connection Pooling in the ODBC Driver for SQL Server
Asynchronous Execution (Notification Method) Sample
Connection Resiliency in the Windows ODBC Driver
Using Always Encrypted with the ODBC Driver
Using Azure Active Directory with the ODBC Driver
Using Transparent Network IP Resolution
Community
SQL Server Drivers blog
SQL Server Data Access Forum
See Also
Building Applications with SQL Server Native Client
SQL Server Native Client FAQ
ODBC Programmer's Reference
SQL Server Native Client (ODBC)
Features of the Microsoft ODBC Driver for SQL
Server on Windows
4/27/2022 • 4 minutes to read • Edit Online
Behavior changes
In SQL Server Native Client, the -y0 option for sqlcmd.exe caused output to be truncated at 1 MB if the display
width was 0.
Beginning in the ODBC Driver 11 for SQL Server, there's no limit on the amount of data that can be retrieved in a
single column when -y0 is specified. sqlcmd.exe now streams columns as large as 2 GB (SQL Server data type
maximum).
Another difference is that specifying both -h and -y0 now produces an error reporting that the options are
incompatible. -h , which specifies the number of rows to print between the column headings and has never
been compatible with -y0 , was ignored although no headers were printed.
-y0 can cause performance issues on both the server and the network, depending on the size of the data
returned.
See also
Microsoft ODBC Driver for SQL Server on Windows
Release Notes for Microsoft ODBC Driver for SQL
Server on Windows
4/27/2022 • 13 minutes to read • Edit Online
This release notes article describes what's new for the Microsoft ODBC driver for SQL Server on Windows.
18.0
Download x64 installer
Download x86 installer
Version number: 18.0.1.1
Released: February 15, 2022
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Added compatibility with OpenSSL 3.0 See Connection String Keywords and Data Source Names.
Ability to send long types as max types See DSN and Connection String Attributes and Keywords.
Support for TDS 8.0 See Features of the Microsoft ODBC Driver for SQL Server
on Windows.
Compatibility extensions for SQLGetData See Features of the Microsoft ODBC Driver for SQL Server
on Windows.
17.9
Download x64 installer
Download x86 installer
Version number: 17.9.1.1
Released: February 17, 2022
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Added compatibility with OpenSSL 3.0 See Connection String Keywords and Data Source Names.
Previous Releases
17.8
Download x64 installer
Download x86 installer
Version number: 17.8.1.1
Released: July 30, 2021
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Replication option added to the connection string See DSN and Connection String Attributes and Keywords.
KeepAlive and KeepAliveInterval options added to the See DSN and Connection String Attributes and Keywords.
connection string
17.7.2
Download x64 installer
Download x86 installer
Version number: 17.7.2.1
Released: March 10, 2021
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
17.7
Download x64 installer
Download x86 installer
Version number: 17.7.1.1
Released: January 29, 2021
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Service Principal Authentication See DSN and Connection String Attributes and Keywords.
Ability to insert into encrypted money and smallmoney See Using Always Encrypted.
columns
17.6
Download x64 installer
Download x86 installer
Version number: 17.6.1.1
Released: July 31, 2020
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
SQL_COPT_SS_AUTOBEGINTXN connection attribute to See DSN and Connection String Attributes and Keywords.
control whether automatic BEGIN TRANSACTION happens
after ROLLBACK or COMMIT
17.5.2
Download x64 installer
Download x86 installer
Version number: 17.5.2.1
Released: March 6, 2020
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Features added in 17.5.2
F EAT URE A DDED DETA IL S
Support authentication with Managed Identity for Azure Key See Using Always Encrypted with the ODBC Driver.
Vault
Support for more Azure Key Vault endpoints See Using Always Encrypted with the ODBC Driver.
Download previous ODBC Driver versions by clicking the download links in the following sections:
17.5
Download x64 installer
Download x86 installer
Version number: 17.5.1.1
Released: January 31, 2020
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Features added in 17.5
F EAT URE A DDED DETA IL S
SQL_COPT_SS_SPID connection attribute to retrieve SPID See DSN and Connection String Attributes and Keywords.
without round trip to server
17.4.2
Download x64 installer
Download x86 installer
Version number: 17.4.2.1
Released: October 2019
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Features added in 17.4.2
F EAT URE A DDED DETA IL S
Support for more Azure Key Vault endpoints See Using Always Encrypted with the ODBC Driver.
Include Azure Active Directory Authentication Library Now included in the base driver installation, the ODBC
(adal.dll) in the installer installer will upgrade existing installations of the Microsoft
Active Directory Authentication Library for SQL Server,
removing it from the list of installed applications in Windows.
17.4
Download x64 installer
Download x86 installer
Version number: 17.4.1.1
Released: July 2019
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Features added in 17.4
F EAT URE A DDED DETA IL S
Always Encrypted with secure enclaves. See Using Always Encrypted with the ODBC Driver.
17.3
Download x64 installer
Download x86 installer
Version number: 17.3.1.1
Released: February 2019
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Features added in 17.3
F EAT URE A DDED DETA IL S
Azure Active Directory Managed Identity (system and user- See Using Azure Active Directory with the ODBC Driver.
assigned) authentication mode.
Ability to stream input parameters against Always Encrypted See Limitations of the ODBC driver when using Always
columns. Encrypted.
Updated Visual C++ Redistributable Upgraded the runtime dependency to the Visual C++ 2017
Redistributable (x64 Download, x86 Download)
Data Classification for Azure SQL Database and SQL Server. See Data Classification.
17.1
Download x64 installer
Download x86 installer
Version number: 17.1.0.1
Released: March 2018
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Features added in 17.1
F EAT URE A DDED DETA IL S
• SQL_COPT_SS_TRUSTEDCMKPATHS
Allows the application to restrict AE operations to only use
the specified list of Column Master Keys.
17.0
Download x64 installer
Download x86 installer
Version number: 17.0.1.1
Released: February 2018
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Features added in 17.0
F EAT URE A DDED DETA IL S
New connection string attribute UseFMTOnly . Causes the driver to use legacy metadata in special cases
that require temporary tables.
Support for Azure SQL Managed Instance. See the following list of Differences when using Managed
Instance (ODBC version 17).
Removed Microsoft online service sign-in assistant The dependency has been removed.
13.1
Download x64 installer
Download x86 installer
Version number: 13.1
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Download the Microsoft Command Line Utilities 13.1 for SQL Server
Features added in 13.1
F EAT URE A DDED DETA IL S
ODBC Driver 13.1 for SQL Server adds support for Always These added supports are available when connecting to
Encrypted and Azure Active Directory. Microsoft SQL Server 2016, or to a later version.
There are connection pooling keywords and attributes, that These keywords and attributes are described in Driver Aware
correspond to the supports for Always Encrypted and Azure Connection Pooling in the ODBC Driver for SQL Server.
Active Directory.
13
Download x64 installer
Download x86 installer
Version number: 13
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Download the Microsoft Command Line Utilities 13 for SQL Server
Features added in 13
F EAT URE A DDED DETA IL S
Adds support for Microsoft SQL Server 2016. Retains the functionality of ODBC driver version 11.
11
Download x64 installer
Download x86 installer
Version number: 11
If you need to download the installer in a language other than the one detected for you, you can use these direct
links.
For the x64 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
For the x86 driver: Chinese (Simplified) | Chinese (Traditional) | English (United States) | French | German | Italian
| Japanese | Korean | Portuguese (Brazil) | Russian | Spanish
Download the Microsoft Command Line Utilities 11 for SQL Server
Features added in 11
F EAT URE A DDED DETA IL S
Contains new features. See Features of the Microsoft ODBC Driver for SQL Server
on Windows.
DATA
B A SE
VERSI
ON → A Z UR A Z UR
↓ E E SQ L SQ L
DRIVE A Z UR SY N A MAN SQ L SQ L SQ L SQ L SQ L SERVE SQ L SQ L
R E SQ L P SE A GED SERVE SERVE SERVE SERVE SERVE R SERVE SERVE
VERSI DATA ANAL IN STA R R R R R 2008 R R
ON B A SE Y T IC S NCE 2019 2017 2016 2014 2012 R2 2008 2005
17.3 Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes
17.2 Yes Yes Yes Yes Yes Yes Yes Yes Yes
17.1 Yes Yes Yes Yes Yes Yes Yes Yes Yes
17.0 Yes Yes Yes Yes Yes Yes Yes Yes Yes
O P ER
AT IN
G
SY ST E
M→ W IN D W IN D
↓ W IN D W IN D W IN D OWS W IN D OWS
DRIVE OWS OWS OWS SERVE OWS SERVE W IN D
R SERVE SERVE SERVE R SERVE R W IN D W IN D W IN D W IN D OWS
VERSI R R R 2012 R 2008 OWS OWS OWS OWS VISTA
ON 2022 2019 2016 R2 2012 R2 11 10 8. 1 7 SP 2
End-user license
Specify IACCEPTMSODBCSQLLICENSETERMS=YES to accept the terms of the end-user license if you use the /passive ,
/qn , /qb , or /qr option to install. This option must be specified in all uppercase letters. Here is an example.
Silent uninstall
The following example shows how to perform a silent uninstall.
Indicate dependency
When an application uses the driver, the application should indicate that it depends on the driver through the
install option APPGUID . this indication enables the driver installer to report dependent applications before
uninstalling. To specify a dependency on the driver, set the APPGUID command-line parameter to your product
code when silently installing the driver. A product code must be created when using Microsoft Installer to bundle
your application setup program. Here is an example.
C O M P O N EN T DESC RIP T IO N
msodbcsql18.dll or The dynamic-link library (DLL) file that contains all of the
msodbcsql17.dll or driver's functionality. This file is installed in
msodbcsql13.dll or %SYSTEMROOT%\System32.
msodbcsql11.dll
msodbcdiag18.dll or The dynamic-link library (DLL) file that contains the driver's
msodbcdiag17.dll or diagnostics (tracing) interface. This file is installed in
msodbcdiag13.dll or %SYSTEMROOT%\System32.
msodbcdiag11.dll
msodbcsqlr18.rll or The accompanying resource file for the driver library. This file
msodbcsqlr17.rll or is installed in %SYSTEMROOT%\System32\1033.
msodbcsqlr13.rll or
msodbcsqlr11.rll
s13ch_msodbcsql.chm or The Data Source Wizard help file that documents how to
s11ch_msodbcsql.chm create a data source for the driver. This file is installed in
%SYSTEMROOT%\System32\1033
msodbcsql.h The header file that contains all of the new definitions
needed to use the driver.
msodbcsql18.lib or The library file needed to call the bcp utility functions that
msodbcsql17.lib or are part of the driver.
msodbcsql13.lib or
msodbcsql11.lib Note: If you do reference this library file in your program,
make sure that it is in your system path and in the system
path of those that use the application.
See also
Microsoft ODBC Driver for SQL Server on Windows
Driver-Aware Connection Pooling in the ODBC
Driver for SQL Server
4/27/2022 • 3 minutes to read • Edit Online
Authentication Yes No
ColumnEncryption Yes No
If there's a difference in any of the following connection attributes between your connection string and a
pooled connection string, a pooled connection isn't used.
SQL_COPT_SS_ACCESS_TOKEN Yes No
AT T RIB UT E O DB C DRIVER 13+ O DB C DRIVER 11
SQL_COPT_SS_AUTHENTICATION Yes No
SQL_COPT_SS_COLUMN_ENCRYPTION Yes No
SQL_COPT_SS_TRUST_SERVER_CERTIFICATEYes Yes
SQL_COPT_SS_TNIR Yes No
The driver can reset and adjust the following connection keywords and attributes without making an
extra network call. The driver resets these parameters to ensure that the connection doesn't contain
incorrect information.
These connection keywords aren't considered when the Driver Manager tries to match your connection
with a connection in the pool. (Even if you change one of these parameters, an existing connection can be
reused. The driver will reset the options, as needed.) These attributes can be reset in the client side
without making an extra network call.
If you change one of the following connection attributes, an existing connection can be reused. The driver
will reset the value, as needed. The driver can reset these attributes in the client without making an extra
network call.
#define NUMBER_OPERATIONS 5
int AsyncNotificationSample(void)
{
RETCODE rc;
rc = SQLSetEnvAttr(hEnv,
SQL_ATTR_ODBC_VERSION,
(SQLPOINTER) SQL_OV_ODBC3_80,
SQL_IS_INTEGER);
if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;
goto Cleanup;
}
// Now, call SQLCompleteAsync to complete the operation and get return code
for (int i=0; i<NUMBER_OPERATIONS; i++)
{
SQLCompleteAsync(SQL_HANDLE_STMT, arhStmt[i], &arrcSTMT[i]);
}
Cleanup:
if (hEnv)
{
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
hEnv = NULL;
}
return 0;
}
This function shows a pattern to start multiple operations simultaneously and wait for them when asynchronous
notification is used:
// Global variables
struct
{
{
char szOutConnectionString[500];
SQLSMALLINT iLen;
} g_connOut[g_nConnection];
PTP_WAIT waits[g_nConnection];
for(int i = 0; i < g_nConnection; i++)
{
waits[i] = CreateThreadpoolWait(&WaitCallBack, reinterpret_cast<PVOID>((UINT_PTR)i), NULL);
SetThreadpoolWait(waits[i], g_hevents[i], NULL);
}
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE,&g_hEnv);
SQLSetEnvAttr(g_hEnv,SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3_80, SQL_IS_UINTEGER);
for(int i = 0; i < g_nConnection; i++)
{
SQLAllocHandle( SQL_HANDLE_DBC, g_hEnv , &g_hDbcs[i]);
SQLSetConnectAttr(
g_hDbcs[i],
SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE,
(SQLPOINTER)SQL_ASYNC_ENABLE_ON,
SQL_IS_INTEGER);
SQLSetConnectAttr(g_hDbcs[i], SQL_ATTR_ASYNC_DBC_EVENT, g_hevents[i], SQL_IS_POINTER);
}
// make connections
g_JobDoneNumber = 0;
for(int i = 0; i < g_nConnection; i++)
{
SQLDriverConnect(g_hDbcs[i],NULL,
(SQLCHAR*)"DRIVER={ODBC Driver 17 for SQL
Server};Server=your_server;database=your_database;uid=usr;pwd=your_password",
SQL_NTS, (SQLCHAR*)g_connOut[i].szOutConnectionString, 500, &g_connOut[i].iLen,
SQL_DRIVER_NOPROMPT);
}
printf("connect wait..\n");
while(g_JobDoneNumber < g_nConnection)
SleepEx(50, false);
// disconnect
for(int i = 0; i < g_nConnection; i++)
SetThreadpoolWait(waits[i], g_hevents[i], NULL);
printf("disconnect wait..\n");
g_JobDoneNumber = 0;
for(int i = 0; i < g_nConnection; i++)
SQLDisconnect(g_hDbcs[i]);
See Also
Microsoft ODBC Driver for SQL Server on Windows
Data Source Wizard Screen 1
4/27/2022 • 2 minutes to read • Edit Online
Specify the name and description of the data source, and the name of the server running SQL Server to which
the data source will connect.
Options
Name
The data source name used by an ODBC application when it requests a connection to the data source. For
example, "Personnel." The data source name is displayed in the ODBC Data Source Administrator dialog box.
Description
(Optional) A description of the data source. For example, "Hire date, salary history, and current review of all
employees."
Select or enter a server name
The name of an instance of SQL Server on your network. You will need to specify a server in the next edit box.
In most cases, the ODBC driver can connect by using the default protocol order and the server name supplied in
this box. Use SQL Server Configuration Manager if you want to create an alias for the server or configure client
network libraries.
You can enter "(local)" in the server box when you are using the same computer as SQL Server. The user can
then connect to the local instance of SQL Server, even when running a non-networked version of SQL Server.
Multiple instances of SQL Server can run on the same computer. To specify a named instance of SQL Server, the
server name is specified as ServerName\InstanceName.
For more information about server names for different types of networks, see Logging In to SQL Server.
Finish
If the information specified on this screen is all that is needed to connect to SQL Server, you can select Finish .
Defaults are used for all attributes specified on other screens of the wizard.
Next
To proceed to the next screen of the wizard, select Next .
Next steps
Data Source Wizard Screen 2
Data Source Wizard Screen 2
4/27/2022 • 2 minutes to read • Edit Online
Specify the method of authentication, and set up Microsoft SQL Server advanced-client entries and the login
and password the ODBC driver for SQL Server will use to connect to SQL Server while configuring the data
source.
Options
With Integrated Windows Authentication
Specifies that the driver request a secure (or trusted) connection to a SQL Server. When selected, SQL Server
uses integrated login security to establish connections using this data source, regardless of the current login
security mode at the server. Any login ID or password supplied is ignored. The SQL Server system administrator
must have associated your Windows login with a SQL Server login ID (for example, by using SQL Server
Management Studio).
Optionally, you can specify a service principal name (SPN) for the server.
With Active Directory Integrated Authentication
Specifies that the driver authenticate to SQL Server using Azure Active Directory. When selected, SQL Server
uses Azure Active Directory integrated login security to establish a connection using this data source, regardless
of the current login security mode at the server.
With SQL Server authentication
Specifies that the driver authenticate to SQL Server using a login ID and password.
With Active Directory Password authentication
Specifies that the driver authenticate to SQL Server using an Azure Active Directory login ID and password.
With Active Directory Interactive authentication
Specifies that the driver authenticate to SQL Server using Azure Active Directory Interactive mode by providing
login ID. This option will trigger the Azure Authentication prompt dialog.
With Managed Identity authentication
Specifies that the driver authenticate to SQL Server using a Managed Identity.
With Active Directory Service Principal authentication
Specifies that the driver authenticate to SQL Server using an Azure Active Directory Service Principal.
Login ID
Specifies the login ID the driver uses when connecting to SQL Server if With SQL Ser ver Authentication
using a login ID and password entered by the user or With Active Director y Password
authentication using a login ID and password entered by the user or With Active Director y
Interactive authentication using a login ID entered by the user is selected. If With Managed Identity
authentication is selected, specify the object ID of the managed identity or leave blank to use the default
identity. This field only applies to the connection made to determine the server default settings; it does not apply
to subsequent connections made using the data source after it has been created except if using Managed
Identity authentication.
Password
Specifies the password the driver uses when connecting to SQL Server if With SQL Ser ver Authentication
using a login ID and password entered by the user or With Active Director y Password
authentication using a login ID and password entered by the user is selected. This field only applies to
the connection made to determine the server default settings; it does not apply to subsequent connections
made using the new data source.
Both the Login ID and Password boxes are disabled if With Integrated Windows authentication or With
Active Director y Integrated authentication is selected.
Next
Proceeds to the next screen of the wizard.
Back
Returns to the previous screen of the wizard.
Next steps
Data Source Wizard Screen 1
Data Source Wizard Screen 3
Data Source Wizard Screen 3
4/27/2022 • 3 minutes to read • Edit Online
Specify the default database, various ANSI options to be used by the driver, and the name of a mirror server.
Options
Change the default database to
Specifies the name of the default database for any connection made using this data source. When this box is
cleared, connections use the default database defined for the login ID on the server. When this box is selected,
the database named in the box overrides the default database defined for the login ID. If the Attach database
filename box has the name of a primary file, the database described by the primary file is attached as a
database using the database name specified in the Change the default database to box.
Using the default database for the login ID is more efficient than specifying a default database in the ODBC data
source.
Mirror server
Specifies the name of the failover partner of the database to be mirrored. If a database name is not shown in the
Change the default database to box, or the name shown is the default database, Mirror Ser ver is grayed
out.
Optionally, you can specify a server principal name (SPN) for the mirror server. The SPN for the mirror server is
used for mutual authentication between client and server.
Attach database filename
Specifies the name of the primary file for an attachable database. This database is attached and used as the
default database for the data source. Specify the full path and file name for the primary file. The database name
specified in the Change the default database to box is used as the name for the attached database.
Use ANSI quoted identifiers
Specifies that QUOTED_IDENTIFIERS is set to on when the ODBC driver for SQL Server connects. When this check
box is selected, SQL Server enforces ANSI rules regarding quote marks. Double quotes can only be used for
identifiers, such as column and table names. Character strings must be enclosed in single quotes:
SELECT "LastName"
FROM "Person.Contact"
WHERE "LastName" = 'O''Brien'
When this check box is cleared, applications that use quoted identifiers, such as the Microsoft Query utility that
comes with Microsoft Excel, encounter errors when they generate SQL statements with quoted identifiers.
Use ANSI nulls, paddings, and warnings
Specifies that the ANSI_NULLS, ANSI_WARNINGS, and ANSI_PADDINGS options be set on when the ODBC
Driver for SQL Server connects.
With ANSI_NULLS set on, the server enforces ANSI rules regarding comparing columns for NULL. The ANSI
syntax "IS NULL" or "IS NOT NULL" must be used for all NULL comparisons. The Transact-SQL syntax "= NULL"
is not supported.
With ANSI_WARNINGS set on, SQL Server issues warning messages for conditions that violate ANSI rules but
do not violate the rules of Transact-SQL. Examples of such errors are data truncation on execution of an INSERT
or UPDATE statement, or encountering a null value during an aggregate function.
With ANSI_PADDING set on, trailing blanks on varchar values and trailing zeroes on varbinar y values are not
automatically trimmed.
Application intent
Declares the application workload type when connecting to a server. Possible values are ReadOnly and
ReadWrite .
Multi-subnet failover
If your application is connecting to a high-availability, disaster recovery (AlwaysOn Availability Groups)
availability group (AG) on different subnets, enabling Multi-subnet failover. configures ODBC Driver for SQL
Server to provide faster detection of and connection to the (currently) active server.
Transparent Network IP Resolution
Alters the behavior of Multi-subnet failover to allow for faster reconnection during failover. For more
information, see Using Transparent Network IP Resolution.
Column Encryption
Enables automatic decryption and encryption of data transfers to and from columns encrypted with the Always
Encrypted feature available in SQL Server 2016 and later.
Use FMTONLY metadata discovery
Use the legacy SET FMTONLY metadata discovery method when connecting to SQL Server 2012 or newer.
Enable this option only when using queries not supported by sp_describe_first_result_set, such as those
containing temporary tables.
Next
Proceeds to the next screen of the wizard.
Back
Returns to the previous screen of the wizard.
Next steps
Data Source Wizard Screen 2
Data Source Wizard Screen 4
Data Source Wizard Screen 4
4/27/2022 • 4 minutes to read • Edit Online
Specify the language to be used for SQL Server messages, the character set translation, and whether the ODBC
driver for SQL Server should use regional settings. You can also control the logging of long-running queries and
driver statistics settings.
Options
Change the language of SQL Server system messages to
Each instance of SQL Server can have multiple sets of system messages, with each set in a different language
(for example, English, Spanish, French, and so on). If a data source is defined against a server that has multiple
sets of system messages, you can specify which language you want to use for system messages. In the list, select
the language. This option is unavailable if only one language is installed on the SQL Server.
Use strong encryption for data
When selected, data that is passed through connections that are made using this DSN will be encrypted. Logins
are encrypted by default, even if the check box is cleared. This option is available in ODBC Driver 17 and older.
Connection Encryption
Declares the connection encryption mode to be used when connections are made using this DSN. Selecting the
Optional or Mandator y option is equivalent to having Use strong encr yption for data unselected or
selected, respectively. When Strict is used, connections will be encrypted using TDS 8.0. This option is available
in ODBC Driver 18 and newer.
Trust server certificate
This option is applicable only when Use strong encr yption for data is enabled (ODBC Driver 17 and older),
or when Connection Encr yption is set to Optional or Mandator y (ODBC Driver 18 and newer). When
selected, the server's certificate won't be validated to have the correct hostname of the server and be issued by a
trusted certificate authority. The server's certificate will always be validated when using the Strict encryption
mode.
Hostname in certificate (optional)
Specifies the hostname to be used when validating the server's certificate. When left blank, the server name is
used as the hostname for validation. A hostname can only be specified when Trust ser ver cer tificate is
unselected. This option is available in ODBC Driver 18 and newer.
Perform translation for character data
When this check box is selected, the ODBC driver for SQL Server converts ANSI strings sent between the client
computer and SQL Server by using Unicode. The ODBC driver sometimes converts between the SQL Server
code page and Unicode on the client computer. This option requires that the code page used by SQL Server is
one of the code pages available on the client computer.
When this check box is cleared, no translation of extended characters in ANSI character strings is done when
they're sent between the client application and the server. If the client computer is using an ANSI code page
(ACP) different from the SQL Server code page, extended characters in ANSI character strings may be
misinterpreted. If the client computer is using the same code page for its ACP that SQL Server is using, the
extended characters are interpreted correctly.
Use regional settings when outputting currency, numbers, dates, and times
Specifies that the driver use the regional settings of the client computer for formatting currency, numbers, dates,
and times in character output strings. The driver uses the default regional setting for the Windows login account
of the user connecting through the data source. Select this option for applications that only display data, not for
applications that process data.
Save long running queries to the log file
Specifies that the driver log any query that takes longer than the Long quer y time value. Long-running
queries are logged to the specified file. To specify a log file, either type the full path and file name in the box, or
select Browse to select a log file by navigating through existing file directories.
Long query time (milliseconds)
Specifies a threshold value, in milliseconds, for long-running query logging. Any query that takes longer than
this number of milliseconds to run is logged.
Log ODBC driver statistics to the log file
Specifies that statistics be logged. Statistics are logged to the specified file. To specify a log file, either type the
full path and file name in the box or select Browse to select a log file by navigating through existing file
directories.
The statistics log is a tab-delimited file that can be analyzed in Microsoft Excel or any other application that
supports tab-delimited files.
Connect retry count
Specifies the number of times to retry an unsuccessful connection attempt.
Connect retry interval (seconds)
Specifies the number of seconds between each connection retry attempt. For more information on the operation
of this option and the Connect retr y count options, see Connection Resiliency.
Back
Select this button to go back to the previous page of the wizard.
Finish
If the information specified on this screen is complete, you can select Finish . The DSN is created using all
attributes specified on this and other screens of the wizard, and you're given an opportunity to test the newly
created DSN.
Next steps
Data Source Wizard Screen 3
SQL Server Login Dialog Box (ODBC)
4/27/2022 • 3 minutes to read • Edit Online
When you call an ODBC connection without specifying enough information for the driver to connect to a SQL
Server, the ODBC driver displays the SQL Ser ver Login dialog box.
Options
Server
The name of an instance of SQL Server on your network. Select a server\instance name from the list, or type the
server\instance name in the Ser ver box. Optionally, you can create a server alias on the client computer using
SQL Ser ver Configuration Manager , and type that name in the Ser ver box.
You can enter "(local)" when you are using the same computer as SQL Server. You can then connect to a local
instance of SQL Server, even when running a non-networked version of SQL Server.
For more information about server names for different types of networks, see the SQL Server installation
documentation in SQL Server Books Online.
Authentication Mode
Selects the authentication mode from one of the following:
SQL Ser ver with login ID and password
Windows Integrated authentication using the currently logged-in user's account
Active Director y Password with login ID and password
Active Director y Integrated authentication using the currently logged-in user's account
Active Director y Interactive authentication with login ID
Managed Ser vice Identity authentication with Managed Identity
Active Director y Ser vice Principal authentication with Azure Active Directory service principal
See Data Source Wizard Screen 2 for more information on the authentication modes.
Server SPN
If you use a trusted connection, you can specify a service principal name (SPN) for the server.
Login ID
Specifies the SQL Server or Azure Active Directory login ID to use for the connection if Authentication Mode
is set to SQL Ser ver , Active Director y Password , Active Director y Interactive , Managed Ser vice
Identity , or Active Director y Ser vice Principal . Otherwise, the Login ID box is disabled.
Password
Specifies the password for the SQL Server or Azure Active Directory login ID used for the connection if
Authentication Mode is set to SQL Ser ver or Active Director y Password . Otherwise, the Password box is
disabled.
Options
Displays or hides the Options group. The Options button is enabled if Ser ver has a value.
Change Password
When this box is selected, displays the New Password and Confirm New Password boxes.
New Password
Specifies the new password.
Confirm New Password
Specifies the new password a second time, for confirmation.
Database
Specifies the default database to use on the connection. This setting overrides the default database specified for
the login on the server. If no database is specified, the connection uses the default database specified for the
login on the server.
Mirror Server
Specifies the name of the failover partner of the database to be mirrored.
Mirror SPN
Optionally, you can specify an SPN for the mirror server. The SPN for the mirror server is used for mutual
authentication between client and server.
Language
Specifies the national language to use for SQL Server system messages. The computer running SQL Server
must have the language installed. This setting overrides the default language specified for the login on the
server. If no language is specified, the connection uses the default language specified for the login on the server.
Application Name
(Optional) Specifies the application name to be stored in the program_name column in the row for this
connection in sys.sysprocesses .
Workstation ID
(Optional) Specifies the workstation ID to be stored in the hostname column in the row for this connection in
sys.sysprocesses .
Use strong encryption for data
When selected, data that is passed through the connection will be encrypted. Logins are encrypted by default,
even if the check box is cleared. This option is available in ODBC Driver 17 and older.
Connection Encryption
Declares the connection encryption mode to be used. Selecting the Optional or Mandator y option is
equivalent to having Use strong encr yption for data unselected or selected, respectively. When Strict is
used, the connection will be encrypted using TDS 8.0. This option is available in ODBC Driver 18 and newer.
Hostname in certificate (optional)
Specifies the hostname to be used when validating the server's certificate. When left blank, the server name is
used as the hostname for validation. A hostname can only be specified when Trust ser ver cer tificate is
unselected. This option is available in ODBC Driver 18 and newer.
Trust server certificate
This option is applicable only when Use strong encr yption for data is enabled (ODBC Driver 17 and older),
or when Connection Encr yption is set to Optional or Mandator y (ODBC Driver 18 and newer). When
selected, the server's certificate won't be validated to have the correct hostname of the server and be issued by a
trusted certificate authority. The server's certificate will always be validated when using the Strict encryption
mode.
See Also
Microsoft ODBC Driver for SQL Server on Windows
Connection resiliency in the ODBC driver
4/27/2022 • 4 minutes to read • Edit Online
IMPORTANT
The connection resiliency feature is supported on Microsoft Azure SQL Database and SQL Server 2014 (and later) server
versions.
The feature is available on Windows starting with Microsoft ODBC Driver 11 for SQL Server. It is available on Linux
starting in version 17.2 of Microsoft ODBC Driver 17 for SQL Server.
For more information about idle connection resiliency, see Technical Article - Idle Connection Resiliency.
To control reconnect behavior, the ODBC Driver for SQL Server on Windows has two options:
Connection retry count.
Connect retry count controls the number of reconnection attempts if there's a connection failure. Valid
values range from 0 to 255. Zero (0) means don't attempt to reconnect. The default value is one
reconnection attempt.
You can modify the number of connection retries when you:
Define or modify a data source that uses the ODBC Driver for SQL Server with the Connection
Retr y Count control.
Use the ConnectRetryCount connection string keyword.
To retrieve the number of connection retry attempts, use the SQL_COPT_SS_CONNECT_RETRY_COUNT
(read only) connection attribute. If an application connects to a server that doesn't support
connection resiliency, SQL_COPT_SS_CONNECT_RETRY_COUNT returns 0.
Connect retry interval.
The connect retry interval specifies the number of seconds between each connection retry attempt. Valid
values are 1-60. The total time to reconnect can't exceed the connection timeout
(SQL_ATTR_QUERY_TIMEOUT in SQLSetStmtAttr). The default value is 10 seconds.
You can modify the connection retry interval when you:
Define or modify a data source that uses the ODBC Driver for SQL Server with the Connect Retr y
Inter val control.
Use the ConnectRetryInterval connection string keyword.
To retrieve the length of the connection retry interval, use the SQL_COPT_SS_CONNECT_RETRY_INTERVAL
(read only) connection attribute.
If an application establishes a connection with SQL_DRIVER_COMPLETE_REQUIRED and later tries to execute a
statement over a broken connection, the ODBC driver won't display the dialog box again. Also, during recovery
in progress,
During recovery, any call to SQLGetConnectAttr(SQL_COPT_SS_CONNECTION_DEAD) , must return SQL_CD_FALSE .
If recovery fails, any call to SQLGetConnectAttr(SQL_COPT_SS_CONNECTION_DEAD) , must return SQL_CD_TRUE .
The following state codes are returned by any function that executes a command on the server:
STAT E M ESSA GE
IMC03 The server did not preserve the exact client TDS
version requested during a recovery attempt,
connection recovery is not possible.
IMC04 The server did not preserve the exact server major
version requested during a recovery attempt,
connection recovery is not possible.
Example
The following sample contains two functions. func1 shows how you can connect with a data source name
(DSN) that uses the ODBC Driver for SQL Server on Windows. The DSN uses SQL Server Authentication, and it
specifies the user ID. func1 then retrieves the number of connection retries with
SQL_COPT_SS_CONNECT_RETRY_COUNT .
func2 uses SQLDriverConnect , ConnectRetryCount connection string keyword, and connection attributes to
retrieve the setting for connection retries and retry interval.
// Connection_resiliency.cpp
// compile with: odbc32.lib
#include <windows.h>
#include <stdio.h>
#include <sqlext.h>
#include <msodbcsql.h>
void func1() {
SQLHENV henv;
SQLHDBC hdbc;
SQLHSTMT hstmt;
SQLRETURN retcode;
SQLSMALLINT i = 21;
// Process data
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
}
SQLDisconnect(hdbc);
}
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
}
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
}
void func2() {
SQLHENV henv;
SQLHDBC hdbc1;
SQLHSTMT hstmt;
SQLRETURN retcode;
SQLSMALLINT i = 21;
SQLSMALLINT cbConnStrOut = 0;
int main() {
func1();
func2();
}
See also
Microsoft ODBC Driver for SQL Server
Custom Keystore Providers
4/27/2022 • 18 minutes to read • Edit Online
Overview
The column encryption feature of SQL Server 2016 requires that the Encrypted Column Encryption Keys
(ECEKs) stored on the server are retrieved by the client and then decrypted to Column Encryption Keys (CEKs) in
order to access the data stored in encrypted columns. ECEKs are encrypted by Column Master Keys (CMKs), and
the security of the CMK is important to the security of column encryption. Thus, the CMK should be stored in a
secure location; the purpose of a Column Encryption Keystore Provider is to provide an interface to allow the
ODBC driver to access these securely stored CMKs. For users with their own secure storage, the Custom
Keystore Provider Interface provides a framework for implementing access to secure storage of the CMK for the
ODBC driver, which can then be used to perform CEK encryption and decryption.
Each keystore provider contains and manages one or more CMKs, which are identified by key paths - strings of
a format defined by the provider. This CMK, along with the encryption algorithm, also a string defined by the
provider, can be used to perform the encryption of a CEK and the decryption of an ECEK. The algorithm, along
with the ECEK and the name of the provider, are stored in the database's encryption metadata. For more
information, see CREATE COLUMN MASTER KEY and CREATE COLUMN ENCRYPTION KEY. Thus, the two
fundamental operations of key management are:
-and-
where the CEKeystoreProvider_name is used to identify the specific Column Encryption Keystore Provider
(CEKeystoreProvider), and the other arguments are used by the CEKeystoreProvider to encrypt/decrypt the
(E)CEK. The name and key path are provided by the CMK metadata, while the algorithm and ECEK value are
provided by the CEK metadata. Multiple keystore providers may be present alongside the default built-in
provider(s). Upon performing an operation that requires the CEK, the driver uses the CMK metadata to find the
appropriate keystore provider by name, and executes its decryption operation, which can be expressed as:
Although the driver has no need to encrypt CEKs, a key management tool may need to do so in order to
implement operations such as CMK creation and rotation. These actions require performing the inverse
operation:
CEKeyStoreProvider interface
This document describes in detail the CEKeyStoreProvider interface. A keystore provider that implements this
interface can be used by the Microsoft ODBC Driver for SQL Server. CEKeyStoreProvider implementers can use
this guide to develop custom keystore providers usable by the driver.
A keystore provider library ("provider library") is a dynamic-link library that can be loaded by the ODBC driver,
and contains one or more keystore providers. The symbol CEKeystoreProvider must be exported by a provider
library, and be the address of a null-terminated array of pointers to CEKeystoreProvider structures, one for each
keystore provider within the library.
A CEKeystoreProvider structure defines the entry points of a single keystore provider:
Name The name of the keystore provider. It must not be the same
as any other keystore provider previously loaded by the
driver or present in this library. Null-terminated, wide-
character* string.
EncryptCEK CEK encryption function. The driver does not call this
function, but it is provided to allow for programmatic access
to ECEK creation by key management tools. May be null if
not required.
Except for Free, the functions in this interface all have a pair of parameters, ctx and onError . The former
identifies the context in which the function is called, while the latter is used for reporting errors. For more
information, see Contexts and Error Handling below.
int Init(CEKEYSTORECONTEXT *ctx, errFunc onError);
Placeholder name for a provider-defined initialization function. The driver calls this function once, after a
provider has been loaded, but before the first time it needs it to perform ECEK decryption or Read()/Write()
requests. Use this function to perform any initialization it needs.
int Read(CEKEYSTORECONTEXT *ctx, errFunc onError, void *data, unsigned int *len);
Placeholder name for a provider-defined communication function. The driver calls this function when the
application requests to read data from a (previously written to) provider using the
SQL_COPT_SS_CEKEYSTOREDATA connection attribute, allowing the application to read arbitrary data from the
provider. For more information, see Communicating with Keystore Providers.
int Write(CEKEYSTORECONTEXT *ctx, errFunc onError, void *data, unsigned int len);
Placeholder name for a provider-defined communication function. The driver calls this function when the
application requests to write data to a provider using the SQL_COPT_SS_CEKEYSTOREDATA connection attribute,
allowing the application to write arbitrary data to the provider. For more information, see Communicating with
Keystore Providers.
int (*DecryptCEK)( CEKEYSTORECONTEXT *ctx, errFunc *onError, const wchar_t *keyPath, const wchar_t *alg,
unsigned char *ecek, unsigned short ecekLen, unsigned char **cekOut, unsigned short *cekLen);
Placeholder name for a provider-defined ECEK decryption function. The driver calls this function to decrypt an
ECEK encrypted by a CMK associated with this provider into a CEK.
keyPath [Input] The value of the KEY_PATH metadata attribute for the
CMK referenced by the given ECEK. Null-terminated wide-
character* string. This value is intended to identify a CMK
handled by this provider.
int (*EncryptCEK)( CEKEYSTORECONTEXT *ctx, errFunc *onError, const wchar_t *keyPath, const wchar_t *alg,
unsigned char *cek,unsigned short cekLen, unsigned char **ecekOut, unsigned short *ecekLen);
Placeholder name for a provider-defined CEK encryption function. The driver does not call this function nor
expose its functionality through the ODBC interface, but it is provided to allow for programmatic access to ECEK
creation by key management tools.
keyPath [Input] The value of the KEY_PATH metadata attribute for the
CMK referenced by the given ECEK. Null-terminated wide-
character* string. This value is intended to identify a CMK
handled by this provider.
void (*Free)();
Placeholder name for a provider-defined termination function. The driver may call this function upon normal
termination of the process.
NOTE
Wide-character strings are 2-byte characters (UTF-16) due to how SQL Server stores them.
Error Handling
As errors may occur during a provider's processing, a mechanism is provided to allow it to report errors back to
the driver in more specific detail than a boolean success/failure. Many of the functions have a pair of
parameters, ctx and onError , which are used together for this purpose in addition to the success/failure return
value.
The ctx parameter identifies the context in which a provider operation occurs.
The onError parameter points to an error-reporting function, with the following prototype:
typedef void errFunc(CEKEYSTORECONTEXT *ctx, const wchar_t *msg, ...);
To report when an error has occurred, the provider calls onError, supplying the context parameter passed into
the provider function by the driver and an error message with optional extra parameters to be formatted in it.
The provider may call this function multiple times to post multiple error messages consecutively within one
provider-function invocation. For example:
if (!doSomething(...))
{
onError(ctx, L"An error occurred in doSomething.");
onError(ctx, L"Additional error message with more details.");
return 0;
}
The msg parameter is ordinarily a wide-character string, but more extensions are available:
By using one of the special predefined values with the IDS_MSG macro, generic error messages already existing
and in a localized form in the driver may be utilized. For example, if a provider fails to allocate memory, the
IDS_S1_001 "Memory allocation failure" message can be used:
onError(ctx, IDS_MSG(IDS_S1_001));
For the error to be recognized by the driver, the provider function must return failure. When a failure happens in
the context of an ODBC operation, the posted errors will become accessible on the connection or statement
handle via the standard ODBC diagnostics mechanism ( SQLError , SQLGetDiagRec , and SQLGetDiagField ).
Context Association
The CEKEYSTORECONTEXT structure, in addition to providing context for the error callback, can also be used to
determine the ODBC context in which a provider operation is executed. This context allows a provider to
associate data to each of these contexts, for example, to implement per-connection configuration. For this
purpose, the structure contains three opaque pointers corresponding to the environment, connection, and
statement context:
Each of these contexts is an opaque value which, while not the same as the corresponding ODBC handle, can be
used as a unique identifier for the handle: if handle X is associated with context value Y, then no other
environment, connection, or statement handles that exist simultaneously at the same time as X will have a
context value of Y, and no other context values will be associated with handle X. If the provider operation being
accomplished lacks a particular handle context (for example, SQLSetConnectAttr calls to load and configure
providers, in which there is no statement handle), the corresponding context value in the structure is null.
Example
Keystore Provider
The following code is an example of a minimal keystore provider implementation.
*/
#ifdef _WIN32
#include <windows.h>
#else
#define __stdcall
#endif
#include <stdlib.h>
#include <sqltypes.h>
#include "msodbcsql.h"
#include <sql.h>
#include <sqlext.h>
// Note that in the provider interface, this function would be referenced via the CEKEYSTOREPROVIDER
// structure. However, that does not preclude keystore providers from exporting their own functions,
// as illustrated by this example where the encryption is performed via a separate function (with a
// different prototype than the one in the KSP interface.)
#ifdef _WIN32
__declspec(dllexport)
#endif
int KeystoreEncrypt(CEKEYSTORECONTEXT *ctx, errFunc *onError,
unsigned char *cek, unsigned short cekLen,
unsigned char **ecekOut, unsigned short *ecekLen) {
unsigned int i;
printf("KSP Encrypt() function called (cekLen=%u)\n", cekLen);
if (!g_encryptKey) {
onError(ctx, L"Keystore provider not initialized with key");
return 0;
}
*ecekOut = malloc(cekLen);
if (!*ecekOut) {
onError(ctx, L"Memory Allocation Error");
return 0;
return 0;
}
*ecekLen = cekLen;
for (i = 0; i < cekLen; i++)
(*ecekOut)[i] = cek[i] ^ g_encryptKey[i % g_encryptKeyLen];
return 1;
}
CEKEYSTOREPROVIDER MyCustomKSPName_desc = {
L"MyCustomKSPName",
KeystoreInit,
0,
KeystoreWrite,
KeystoreDecrypt,
0
};
#ifdef _WIN32
__declspec(dllexport)
#endif
CEKEYSTOREPROVIDER *CEKeystoreProvider[] = {
&MyCustomKSPName_desc,
0
};
ODBC Application
The following code is a demo application that uses the keystore provider above. When running it, ensure that
the provider library is in the same directory as the application binary, and that the connection string specifies (or
specifies a DSN that contains) the ColumnEncryption=Enabled setting.
/*
Example application for demonstration of custom keystore provider usage
*/
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include <windows.h>
#else
#define __stdcall
#include <dlfcn.h>
#endif
#include <sql.h>
#include <sqlext.h>
#include "msodbcsql.h"
/* Convenience functions */
int checkRC(SQLRETURN rc, char *msg, int ret, SQLHANDLE h, SQLSMALLINT ht) {
if (rc == SQL_ERROR) {
fprintf(stderr, "Error occurred upon %s\n", msg);
if (h) {
SQLSMALLINT i = 0;
SQLSMALLINT outlen = 0;
char errmsg[1024];
while ((rc = SQLGetDiagField(
ht, h, ++i, SQL_DIAG_MESSAGE_TEXT, errmsg, sizeof(errmsg), &outlen)) == SQL_SUCCESS
|| rc == SQL_SUCCESS_WITH_INFO) {
|| rc == SQL_SUCCESS_WITH_INFO) {
fprintf(stderr, "Err#%d: %s\n", i, errmsg);
}
}
if (ret)
exit(ret);
return 0;
}
else if (rc == SQL_SUCCESS_WITH_INFO && h) {
SQLSMALLINT i = 0;
SQLSMALLINT outlen = 0;
char errmsg[1024];
printf("Success with info for %s:\n", msg);
while ((rc = SQLGetDiagField(
ht, h, ++i, SQL_DIAG_MESSAGE_TEXT, errmsg, sizeof(errmsg), &outlen)) == SQL_SUCCESS
|| rc == SQL_SUCCESS_WITH_INFO) {
fprintf(stderr, "Msg#%d: %s\n", i, errmsg);
}
}
return 1;
}
/* Connect to Server */
rc = SQLAllocHandle(SQL_HANDLE_ENV, NULL, &env);
checkRC(rc, "allocating environment handle", 2, 0, 0);
rc = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
checkRC(rc, "setting ODBC version to 3.0", 3, env, SQL_HANDLE_ENV);
rc = SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
checkRC(rc, "allocating connection handle", 4, env, SQL_HANDLE_ENV);
rc = SQLDriverConnect(dbc, 0, argv[1], strlen(argv[1]), NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
checkRC(rc, "connecting to data source", 5, dbc, SQL_HANDLE_DBC);
rc = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
checkRC(rc, "allocating statement handle", 6, dbc, SQL_HANDLE_DBC);
#ifdef _WIN32
FreeLibrary(hProvLib);
#else
dlclose(hProvLib);
#endif
/* Clean up */
{
SQLExecDirect(stmt, "DROP TABLE CustomKSPTestTable", SQL_NTS);
SQLExecDirect(stmt, "DROP COLUMN ENCRYPTION KEY CustomCEK", SQL_NTS);
SQLExecDirect(stmt, "DROP COLUMN MASTER KEY CustomCMK", SQL_NTS);
printf("Removed table, CEK, and CMK\n");
}
SQLDisconnect(dbc);
SQLFreeHandle(SQL_HANDLE_DBC, dbc);
SQLFreeHandle(SQL_HANDLE_ENV, env);
return 0;
}
See Also
Using Always Encrypted with the ODBC Driver
DSN and Connection String Keywords and
Attributes
4/27/2022 • 8 minutes to read • Edit Online
This page lists the keywords for connection strings and DSNs, and connection attributes for SQLSetConnectAttr
and SQLGetConnectAttr, available in the ODBC Driver for SQL Server.
DSN / C O N N EC T IO N ST RIN G
K EY W O RD C O N N EC T IO N AT T RIB UT E P L AT F O RM
Addr LMW
Address LMW
APP LMW
Description LMW
Driver LMW
DSN LMW
DSN / C O N N EC T IO N ST RIN G
K EY W O RD C O N N EC T IO N AT T RIB UT E P L AT F O RM
Failover_Partner SQL_COPT_SS_FAILOVER_PARTNER W
FailoverPartnerSPN SQL_COPT_SS_FAILOVER_PARTNER_SP W
N
FileDSN LMW
KeystoreAuthentication LMW
KeystorePrincipalId LMW
KeystoreSecret LMW
Language LMW
Net LMW
Network LMW
PWD LMW
QueryLog_On SQL_COPT_SS_PERF_QUERY W
QueryLogFile SQL_COPT_SS_PERF_QUERY_LOG W
QueryLogTIme SQL_COPT_SS_PERF_QUERY_INTERVAL W
Regional LMW
DSN / C O N N EC T IO N ST RIN G
K EY W O RD C O N N EC T IO N AT T RIB UT E P L AT F O RM
Replication LMW
SaveFile LMW
Server LMW
StatsLog_On SQL_COPT_SS_PERF_DATA W
StatsLogFile SQL_COPT_SS_PERF_DATA_LOG W
UID LMW
UseFMTONLY LMW
WSID LMW
SQL_ATTR_ACCESS_MODE LMW
(SQL_ACCESS_MODE)
SQL_ATTR_ASYNC_DBC_EVENT W
SQL_ATTR_ASYNC_DBC_FUNCTIONS_E W
NABLE
SQL_ATTR_ASYNC_DBC_PCALLBACK W
SQL_ATTR_ASYNC_DBC_PCONTEXT W
SQL_ATTR_ASYNC_ENABLE W
SQL_ATTR_AUTO_IPD LMW
SQL_ATTR_AUTOCOMMIT LMW
(SQL_AUTOCOMMIT)
SQL_ATTR_CONNECTION_DEAD LMW
SQL_ATTR_CONNECTION_TIMEOUT LMW
SQL_ATTR_DBC_INFO_TOKEN LMW
DSN / C O N N EC T IO N ST RIN G
K EY W O RD C O N N EC T IO N AT T RIB UT E P L AT F O RM
SQL_ATTR_LOGIN_TIMEOUT LMW
(SQL_LOGIN_TIMEOUT)
SQL_ATTR_METADATA_ID LMW
SQL_ATTR_ODBC_CURSORS LMW
(SQL_ODBC_CURSORS)
SQL_ATTR_PACKET_SIZE LMW
(SQL_PACKET_SIZE)
SQL_ATTR_QUIET_MODE LMW
(SQL_QUIET_MODE)
SQL_ATTR_RESET_CONNECTION LMW
(SQL_COPT_SS_RESET_CONNECTION)
SQL_ATTR_TRACE LMW
(SQL_OPT_TRACE)
SQL_ATTR_TRACEFILE LMW
(SQL_OPT_TRACEFILE)
SQL_ATTR_TRANSLATE_LIB LMW
(SQL_TRANSLATE_DLL)
SQL_ATTR_TRANSLATE_OPTION LMW
(SQL_TRANSLATE_OPTION)
SQL_ATTR_TXN_ISOLATION LMW
(SQL_TXN_ISOLATION)
SQL_COPT_SS_ACCESS_TOKEN LMW
SQL_COPT_SS_ANSI_OEM W
SQL_COPT_SS_AUTOBEGINTXN LMW
SQL_COPT_SS_BCP LMW
SQL_COPT_SS_BROWSE_CACHE_DATA LMW
SQL_COPT_SS_BROWSE_CONNECT LMW
SQL_COPT_SS_BROWSE_SERVER LMW
SQL_COPT_SS_CEKEYSTOREDATA LMW
SQL_COPT_SS_CEKEYSTOREPROVIDER LMW
DSN / C O N N EC T IO N ST RIN G
K EY W O RD C O N N EC T IO N AT T RIB UT E P L AT F O RM
SQL_COPT_SS_CLIENT_CONNECTION_ LMW
ID
SQL_COPT_SS_CONCAT_NULL LMW
SQL_COPT_SS_CONNECTION_DEAD LMW
SQL_COPT_SS_ENLIST_IN_DTC W
SQL_COPT_SS_ENLIST_IN_XA LMW
SQL_COPT_SS_FALLBACK_CONNECT LMW
SQL_COPT_SS_INTEGRATED_AUTHENT LMW
ICATION_METHOD
SQL_COPT_SS_MUTUALLY_AUTHENTI LMW
CATED
SQL_COPT_SS_OLDPWD LMW
SQL_COPT_SS_PERF_DATA_LOG_NOW W
SQL_COPT_SS_PRESERVE_CURSORS LMW
SQL_COPT_SS_TXN_ISOLATION LMW
SQL_COPT_SS_USER_DATA LMW
SQL_COPT_SS_WARN_ON_CP_ERROR LMW
ClientCertificate LMW
ClientKey LMW
Here are some connection string keywords and connection attributes, which aren't documented in Using
Connection String Keywords with SQL Server Native Client, SQLSetConnectAttr, and SQLSetConnectAttr
Function.
Description
Used to describe the data source.
SQL_COPT_SS_ANSI_OEM
Controls ANSI to OEM conversion of data.
SQL_COPT_SS_AUTOBEGINTXN
Version 17.6+ While autocommit is off, controls automatic BEGIN TRANSACTION after ROLLBACK or COMMIT.
SQL_COPT_SS_FALLBACK_CONNECT
Controls the use of SQL Server Fallback Connections. This one is no longer supported.
NOTE
When using Authentication keyword or attribute, explicitly specify Encrypt setting to the desired value in connection
string / DSN / connection attribute. Refer to Using Connection String Keywords with SQL Server Native Client for details.
ColumnEncryption - SQL_COPT_SS_COLUMN_ENCRYPTION
Controls transparent column encryption (Always Encrypted). For more information, see Using Always Encrypted
(ODBC).
Encrypt
Specifies whether connections use TLS encryption over the network. Possible values are yes / mandatory
(18.0+), no / optional (18.0+), and strict (18.0+). The default value is yes in version 18.0+ and no in
previous versions.
Regardless of the setting for Encrypt , the server login credentials (user name and password) are always
encrypted.
Encrypt , TrustServerCertificate , and server-side Force Encryption settings play a part in whether
connections are encrypted over the network. The following tables show the effect of these settings.
ODBC Driver 18 and newer
SERVER F O RC E
EN C RY P T SET T IN G T RUST SERVER C ERT IF IC AT E EN C RY P T IO N RESULT
Strict - - TrustServerCertificate is
ignored. Server certificate is
checked.
Data sent between client
and server is encrypted.
NOTE
Strict is only available against servers that support TDS 8.0 connections.
TransparentNetworkIPResolution - SQL_COPT_SS_TNIR
Controls the Transparent Network IP Resolution feature, which interacts with MultiSubnetFailover to allow faster
reconnection attempts. For more information, see Using Transparent Network IP Resolution.
UseFMTONLY
Controls the use of SET FMTONLY for metadata when connecting to SQL Server 2012 and newer.
K EY W O RD VA L UE DESC RIP T IO N
Replication
Specifies the use of a replication login on ODBC Driver version 17.8 and newer.
K EY W O RD VA L UE DESC RIP T IO N
Yes Triggers with the NOT FOR REPLICATION option won't fire
on the connection.
ClientCertificate
Specifies the certificate to be used for authentication. The options are:
O P T IO N VA L UE DESC RIP T IO N
In case if certificate is in PFX format and private key inside the PFX certificate is password protected, the
password keyword is required. For certificates in PEM and DER formats ClientKey attribute is required
ClientKey
Specifies a file location of the private key for PEM or DER certificates that are specified by the ClientCertificate
attribute. Format:
O P T IO N VA L UE DESC RIP T IO N
In case if private key file is password protected then password keyword is required. If the password contains any
" , " characters, an extra " , " character is added immediately after each one. For example, if the password is "
a,b,c ", the escaped password present in the connection string is " a,,b,,c ".
HostnameInCertificate
Specifies the hostname to be expected in the server's certificate when encryption is negotiated, if it's different
from the default value derived from Addr/Address/Server.
SQL_COPT_SS_ACCESS_TOKEN
Allows the use of an Azure Active Directory access token for authentication. For more information, see Using
Azure Active Directory.
SQL_COPT_SS_CEKEYSTOREDATA
Communicates with a loaded keystore provider library. See Controls transparent column encryption (Always
Encrypted). This attribute has no default value. For more information, see Custom Keystore Providers.
SQL_COPT_SS_CEKEYSTOREPROVIDER
Loads a keystore provider library for Always Encrypted, or retrieves the names of loaded keystore provider
libraries. For more information, see Custom Keystore Providers. This attribute has no default value.
SQL_COPT_SS_ENLIST_IN_XA
To enable XA transactions with an XA-compliant Transaction Processor (TP), the application needs to call
SQLSetConnectAttr with SQL_COPT_SS_ENLIST_IN_XA and a pointer to an XACALLPARAM object. This option is
supported on Windows (17.3 and above), Linux, and macOS.
To associate an XA transaction with an ODBC connection only, provide TRUE or FALSE with
SQL_COPT_SS_ENLIST_IN_XA instead of the pointer when calling SQLSetConnectAttr . This setting is only valid
on Windows and can't be used to specify XA operations through a client application.
VA L UE DESC RIP T IO N P L AT F O RM S
XACALLPARAM object* The pointer to XACALLPARAM object. Windows, Linux, and macOS
Yes Converts data from long types to max types when sending.
SQL_COPT_SS_SPID
Retrieves the server process ID of the connection. This property is equivalent to the T-SQL @@SPID variable,
except that it doesn't incur an extra round trip to the server.
DWORD SPID
Using Always Encrypted with the ODBC Driver for
SQL Server
4/27/2022 • 35 minutes to read • Edit Online
Applicable to
ODBC Driver 13.1+ for SQL Server
Introduction
This article provides information on how to develop ODBC applications using Always Encrypted (Database
Engine) or Always Encrypted with secure enclaves and the ODBC Driver for SQL Server.
Always Encrypted allows client applications to encrypt sensitive data and never reveal the data or the encryption
keys to SQL Server or Azure SQL Database. An Always Encrypted enabled driver, such as the ODBC Driver for
SQL Server, achieves this security by transparently encrypting and decrypting sensitive data in the client
application. The driver automatically determines which query parameters correspond to sensitive database
columns (protected using Always Encrypted), and encrypts the values of those parameters before passing the
data to SQL Server or Azure SQL Database. Similarly, the driver transparently decrypts data retrieved from
encrypted database columns in query results. Always Encrypted with secure enclaves extends this feature to
enable richer functionality on sensitive data while keeping the data confidential.
For more information, see Always Encrypted (Database Engine) and Always Encrypted with secure enclaves.
Prerequisites
Configure Always Encrypted in your database. This process involves provisioning Always Encrypted keys and
setting up encryption for selected database columns. If you don't already have a database with Always
Encrypted configured, follow the directions in Getting Started with Always Encrypted. In particular, your
database should contain the metadata definitions for a Column Master Key (CMK), a Column Encryption Key
(CEK), and a table containing one or more columns encrypted using that CEK.
If you're using Always Encrypted with secure enclaves, see Develop applications using Always Encrypted with
secure enclaves for more prerequisites.
Enabling Always Encrypted in an ODBC application
The easiest way to enable both parameter encryption and resultset encrypted column decryption is by setting
the value of the ColumnEncryption connection string keyword to Enabled . The following code is an example of a
connection string that enables Always Encrypted:
Always Encrypted may also be enabled in the DSN configuration, using the same key and value (which will be
overridden by the connection string setting, if present), or programmatically with the
SQL_COPT_SS_COLUMN_ENCRYPTION pre-connection attribute. Setting it this way overrides the value set in the
connection string or DSN:
SQLSetConnectAttr(hdbc, SQL_COPT_SS_COLUMN_ENCRYPTION, (SQLPOINTER)SQL_COLUMN_ENCRYPTION_ENABLE, 0);
Once enabled for the connection, the behavior of Always Encrypted may be adjusted for individual queries. For
more information, see Controlling the Performance Impact of Always Encrypted below.
Enabling Always Encrypted isn't sufficient for encryption or decryption to succeed; you also need to make sure
that:
The application has the VIEW ANY COLUMN MASTER KEY DEFINITION and VIEW ANY COLUMN
ENCRYPTION KEY DEFINITION database permissions, required to access the metadata about Always
Encrypted keys in the database. For details, see Database Permissions.
The application can access the CMK that protects the CEKs for the queried encrypted columns. This
behavior is dependent on the keystore provider that stores the CMK. For more information, see Working
with Column Master Key Stores.
Enabling Always Encrypted with secure enclaves
NOTE
On Linux and macOS, OpenSSL version 1.0.1 or later is required to use Always Encrypted with secure enclaves.
Beginning with version 17.4, the driver supports Always Encrypted with secure enclaves. To enable the use of
the enclave when connecting to a database, set the ColumnEncryption DSN key, connection string keyword, or
connection attribute to the following value: <attestation protocol>\<attestation URL> , where:
<attestation protocol> - specifies a protocol used for enclave attestation.
If you're using SQL Server and Host Guardian Service (HGS), <attestation protocol> should be
VBS-HGS .
If you're using Azure SQL Database and Microsoft Azure Attestation, <attestation protocol> should
be SGX-AAS .
<attestation URL> - specifies an attestation URL (an attestation service endpoint). You need to obtain an
attestation URL for your environment from your attestation service administrator.
If you're using SQL Server and Host Guardian Service (HGS), see Determine and share the HGS
attestation URL.
If you're using Azure SQL Database and Microsoft Azure Attestation, see Determine the attestation
URL for your attestation policy.
Examples of connection strings enabling enclave computations for a database connection:
SQL Server:
A L WAY S EN C RY P T ED IS A L WAY S EN C RY P T ED IS
EN A B L ED A N D EN A B L ED A N D
A P P L IC AT IO N C A N A C C ESS A P P L IC AT IO N C A N 'T
T H E K EY S A N D K EY A C C ESS T H E K EY S O R K EY A L WAY S EN C RY P T ED IS
Q UERY C H A RA C T ERIST IC M ETA DATA M ETA DATA DISA B L ED
Retrieving data from Results from encrypted Error Results from encrypted
encrypted columns, without columns are transparently columns aren't decrypted.
parameters targeting decrypted. The application The application receives
encrypted columns. receives plaintext column encrypted values as byte
values. arrays.
The following examples illustrate retrieving and modifying data in encrypted columns. The examples assume a
table with the following schema. The SSN and BirthDate columns are encrypted.
SQL_DATE_STRUCT date;
SQLLEN cbdate; // size of date structure
SQLCHAR SSN[12];
strcpy_s((char*)SSN, _countof(SSN), "795-73-9838");
// Size of structures
cbdate = sizeof(SQL_DATE_STRUCT);
SQLRETURN rc = 0;
string queryText = "INSERT INTO [dbo].[Patients] ([SSN], [FirstName], [LastName], [BirthDate]) VALUES
(?, ?, ?, ?) ";
//SSN
rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 11, 0, (SQLPOINTER)SSN, 0,
&cbSSN);
//FirstName
rc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WCHAR, 50, 0, (SQLPOINTER)firstName,
0, &cbFirstName);
//LastName
rc = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WCHAR, 50, 0, (SQLPOINTER)lastName, 0,
&cbLastName);
//BirthDate
rc = SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_TYPE_DATE, SQL_TYPE_DATE, 10, 0,
(SQLPOINTER)&date, 0, &cbdate);
rc = SQLExecute(hstmt);
NOTE
Queries can perform equality comparisons on encrypted columns only if the encryption is deterministic, or if the secure
enclave is enabled. For more information, see Selecting Deterministic or Randomized encryption.
SQLCHAR SSN[12];
strcpy_s((char*)SSN, _countof(SSN), "795-73-9838");
SQLRETURN rc = 0;
string empty = "";
string queryText = "SELECT [SSN], [FirstName], [LastName], [BirthDate] " + empty +
"FROM [dbo].[Patients]" +
"WHERE " +
"[SSN] = ? ";
//SSN
rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 11, 0, (SQLPOINTER)SSN, 0, &cbSSN);
rc = SQLExecute(hstmt);
HandleDiagnosticRecord(hstmt, SQL_HANDLE_STMT, rc);
SQL_DATE_STRUCT dateVal;
SQLWCHAR firstNameVal[50];
SQLWCHAR lastNameVal[50];
SQLCHAR SSNVal[12];
SQLLEN cbdate; // size of date structure
int rowcount = 0;
while (SQL_SUCCEEDED(SQLFetch(hstmt)))
{
rowcount++;
SQLGetData(hstmt, 1, SQL_C_CHAR, &SSNVal, 11, &cbSSN);
SQLGetData(hstmt, 2, SQL_C_WCHAR, &firstNameVal, 50, &cbFirstName);
SQLGetData(hstmt, 3, SQL_C_WCHAR, &lastNameVal, 50, &cbLastName);
SQLGetData(hstmt, 4, SQL_C_TYPE_DATE, &dateVal, 10, &cbdate);
}
SQLCHAR SSN[12];
strcpy_s((char*)SSN, _countof(SSN), "795-73-9838");
SQLRETURN rc = 0;
string empty = "";
string queryText = "SELECT [SSN], [FirstName], [LastName], [BirthDate] " + empty +
"FROM [dbo].[Patients]" +
"WHERE " +
"[LastName] = ?";
//LastName
rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WCHAR, 50, 0, (SQLPOINTER)lastName, 0,
&cbLastName);
rc = SQLExecute(hstmt);
HandleDiagnosticRecord(hstmt, SQL_HANDLE_STMT, rc);
SQL_DATE_STRUCT dateVal;
SQLWCHAR firstNameVal[50];
SQLWCHAR lastNameVal[50];
SQLCHAR SSNVal[12];
SQLLEN cbdate; // size of date structure
int rowcount = 0;
while (SQL_SUCCEEDED(SQLFetch(hstmt)))
{
rowcount++;
SQLGetData(hstmt, 1, SQL_C_CHAR, &SSNVal, 11, &cbSSN);
SQLGetData(hstmt, 2, SQL_C_WCHAR, &firstNameVal, 50, &cbFirstName);
SQLGetData(hstmt, 3, SQL_C_WCHAR, &lastNameVal, 50, &cbLastName);
SQLGetData(hstmt, 4, SQL_C_TYPE_DATE, &dateVal, 10, &cbdate);
}
Money/SmallMoney encryption
Starting with driver version 17.7 it's possible to use Always Encrypted with MONEY and SMALLMONEY.
However there are some extra steps to take. When inserting into encrypted MONEY or SMALLMONEY columns,
use one of the following C types:
SQL_C_CHAR
SQL_C_WCHAR
SQL_C_SHORT
SQL_C_LONG
SQL_C_FLOAT
SQL_C_DOUBLE
SQL_C_BIT
SQL_C_TINYINT
SQL_C_SBIGINT
SQL_C_NUMERIC
and a SQL type of either SQL_NUMERIC or SQL_DOUBLE (precision may be lost when using this type).
Bin din g t h e variable
Whenever binding a MONEY/SMALLMONEY variable in an encrypted column the following descriptor field(s)
must be set:
SQLHANDLE ipd = 0;
SQLGetStmtAttr(hStmt, SQL_ATTR_IMP_PARAM_DESC, (SQLPOINTER)&ipd, SQL_IS_POINTER, NULL);
SQLSetDescField(ipd, n, SQL_CA_SS_SERVER_TYPE, isSmallMoney ? (SQLPOINTER)SQL_SS_TYPE_SMALLMONEY :
(SQLPOINTER)SQL_SS_TYPE_MONEY,
SQL_IS_INTEGER);
Always Encrypted supports few conversions for encrypted data types. See Always Encrypted (Database Engine)
for the detailed list of supported type conversions. To avoid data type conversion errors, make sure that you
observe the following points when using SQLBindParameter with parameters targeting encrypted columns:
The SQL type of the parameter is either exactly the same as the type of the targeted column, or the
conversion from the SQL type to the type of the column is supported.
The precision and scale of parameters targeting columns of the decimal and numeric SQL Server data
types is the same as the precision and scale configured for the target column.
The precision of parameters targeting columns of datetime2 , datetimeoffset , or time SQL Server data
types isn't greater than the precision for the target column, in queries that modify the target column.
Er r o r s d u e t o p a ssi n g p l a i n t e x t i n st e a d o f e n c r y p t e d v a l u e s
Any value that targets an encrypted column needs to be encrypted before being sent to the server. An attempt
to insert, modify, or filter by a plaintext value on an encrypted column will result in an error. To prevent such
errors, make sure that:
Always Encrypted is enabled (in the DSN, the connection string, before connecting by setting the
SQL_COPT_SS_COLUMN_ENCRYPTION connection attribute for a specific connection, or the
SQL_SOPT_SS_COLUMN_ENCRYPTION statement attribute for a specific statement).
You use SQLBindParameter to send data targeting encrypted columns. The example below shows a query
that incorrectly filters by a literal/constant on an encrypted column (SSN), instead of passing the literal as
an argument to SQLBindParameter.
string queryText = "SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE SSN='795-
73-9838'";
VA L UE DESC RIP T IO N
SQL_CE_RESULTSETONLY (1) Decryption Only. Result sets and return values are
decrypted, and parameters aren't encrypted
SQL_CE_ENABLED (3) Always Encrypted is enabled and used for both parameters
and results
New statement handles created from a connection with Always Encrypted enabled default to SQL_CE_ENABLED.
Handles created from a connection with it disabled default to SQL_CE_DISABLED (and it isn't possible to enable
Always Encrypted on them.)
If most of the queries of a client application access encrypted columns, the following points are recommended:
Set the ColumnEncryption connection string keyword to Enabled .
Set the SQL_SOPT_SS_COLUMN_ENCRYPTION attribute to SQL_CE_DISABLED on statements that don't access any
encrypted columns. This setting will disable both calling sys.sp_describe_parameter_encryption and
attempts to decrypt any values in the result set.
Set the SQL_SOPT_SS_COLUMN_ENCRYPTION attribute to SQL_CE_RESULTSETONLY on statements that don't have
any parameters requiring encryption, but retrieve data from encrypted columns. This setting will disable
calling sys.sp_describe_parameter_encryption and parameter encryption. Results containing encrypted
columns will continue to be decrypted.
Use prepared statements for queries that will be executed more than once; prepare the query with
SQLPrepare and save the statement handle, reusing it with SQLExecute each time it's executed. This
method is the preferred approach for performance even when there are no encrypted columns, and
allows the driver to take advantage of cached metadata.
SQLHDESC ipd;
SQLGetStmtAttr(hStmt, SQL_ATTR_IMP_PARAM_DESC, &ipd, 0, 0);
SQLSetDescField(ipd, paramNum, SQL_CA_SS_FORCE_ENCRYPT, (SQLPOINTER)TRUE, SQL_IS_SMALLINT);
If SQL Server informs the driver that the parameter doesn't need to be encrypted, queries using that parameter
will fail. This behavior provides extra protection against security attacks that involve a compromised SQL Server
providing incorrect encryption metadata to the client, which may lead to data disclosure.
Column encryption key caching
To reduce the number of calls to a column master key store to decrypt column encryption keys, the driver
caches the plaintext CEKs in memory. The CEK cache is global to the driver and not associated with any one
connection. After receiving the ECEK from database metadata, the driver first tries to find the plaintext CEK
corresponding to the encrypted key value in the cache. The driver calls the key store containing the CMK only if
it can't find the corresponding plaintext CEK in the cache.
NOTE
In the ODBC Driver for SQL Server, the entries in the cache are evicted after a two hour timeout. This behavior means
that for a given ECEK, the driver contacts the key store only once during the lifetime of the application or every two
hours, whichever is less.
Starting with the ODBC Driver 17.1 for SQL Server, the CEK cache timeout can be adjusted using the
SQL_COPT_SS_CEKCACHETTL connection attribute, which specifies the number of seconds a CEK will remain in the
cache. Because of the global nature of the cache, this attribute can be adjusted from any connection handle valid
for the driver. When the cache TTL is lowered, existing CEKs that would exceed the new TTL are also evicted. If it's
0, no CEKs are cached.
Trusted key paths
Starting with the ODBC Driver 17.1 for SQL Server, the SQL_COPT_SS_TRUSTEDCMKPATHS connection attribute allows
an application to require that Always Encrypted operations only use a specified list of CMKs, identified by their
key paths. By default, this attribute is NULL, which means that the driver accepts any key path. To use this
feature, set SQL_COPT_SS_TRUSTEDCMKPATHS to point to a null-delimited, null-terminated wide-character string that
lists the allowed key path(s). The memory pointed to by this attribute must remain valid during encryption or
decryption operations using the connection handle on which it's set --- upon which the driver will check if the
CMK path as specified by the server metadata is case-insensitively in this list. If the CMK path isn't in the list, the
operation fails. The application can change the contents of memory this attribute points at, to change its list of
trusted CMKs, without setting the attribute again.
Azure Key Vault Stores CMKs in an Azure AZURE_KEY_VAULT Windows, macOS, Linux
Key Vault
You (or your DBA) need to make sure that the provider name, configured in the column master key
metadata, is correct and the column master key path complies with the key path format for the given
provider. It's recommended that you configure the keys using tools such as SQL Server Management
Studio, which automatically generates the valid provider names and key paths when issuing the CREATE
COLUMN MASTER KEY (Transact-SQL) statement.
Ensure your application can access the key in the keystore. This process may involve granting your
application access to the key and/or the keystore, depending on the keystore, or doing other keystore-
specific configuration steps. For example, to access an Azure Key Vault, you must provide the correct
credentials to the keystore.
Using the Azure Key Vault provider
Azure Key Vault (AKV) is a convenient option to store and manage column master keys for Always Encrypted
(especially if your applications are hosted in Azure). The ODBC Driver for SQL Server on Linux, macOS, and
Windows includes a built-in column master key store provider for Azure Key Vault. For more information on
configuring an Azure Key Vault for Always Encrypted, see Azure Key Vault - Step by Step, Getting Started with
Key Vault, and Creating Column Master Keys in Azure Key Vault.
NOTE
The ODBC Driver only supports AKV authentication directly against Azure Active Directory. If you are using Azure Active
Directory authentication to AKV and your Active Directory configuration requires authentication against an Active
Directory Federation Services endpoint, authentication may fail. On Linux and macOS, for driver version 17.2 and later,
libcurl is required to use this provider, but is not an explicit dependency since other operations with the driver do not
require it. If you encounter an error regarding libcurl , ensure it is installed.
The driver supports authenticating to Azure Key Vault using the following credential types:
Username/Password - with this method, the credentials are the name of an Azure Active Directory user
and its password.
Client ID/Secret - with this method, the credentials are an application client ID and an application secret.
Managed Identity (17.5.2+) - either system or user-assigned; for more information, see Managed
Identities for Azure resources.
Azure Key Vault Interactive (17.7+ Windows drivers) - with this method, the credentials are authenticated
through Azure Active Directory with Login ID.
To allow the driver to use CMKs stored in AKV for column encryption, use the following connection-string-only
keywords:
Starting in v17.8, the KeystoreAuthentication and KeystorePrincipalId can be edited using the DSN configuration
UI in the ODBC Datasource Administrator.
Example connection strings
The following connection strings show how to authenticate to Azure Key Vault with the two credential types:
C l i e n t I D / Se c r e t
M a n a g e d I d e n t i t y (sy st e m - a ssi g n e d )
M a n a g e d I d e n t i t y (u se r- a ssi g n e d )
A KV In t er ac t i ve
No other ODBC application changes are required to use AKV for CMK storage.
NOTE
The driver contains a list of AKV endpoints which it trusts. Starting with driver version 17.5.2, this list is configurable: set
the AKVTrustedEndpoints property in the driver or DSN's ODBCINST.INI or ODBC.INI registry key (Windows) or
odbcinst.ini or odbc.ini file section (Linux/macOS) to a semicolon-delimited list. Setting it in the DSN takes
precedence over a setting in the driver. If the value begins with a semicolon, it extends the default list; otherwise, it
replaces the default list. The default list (as of 17.5) is
vault.azure.net;vault.azure.cn;vault.usgovcloudapi.net;vault.microsoftazure.de . Starting with 17.7, the list
also includes
managedhsm.azure.net;managedhsm.azure.cn;managedhsm.usgovcloudapi.net;managedhsm.microsoftazure.de .
NOTE
The Azure Key Vault provider built in to the ODBC driver supports both Vaults and Managed HSMs in Azure Key Vault.
SQL_COPT_SS_CEKEYSTOREDATA
The former is used to load and enumerate loaded keystore providers, while the latter enables application-
provider communications. These connection attributes may be used at any time, before or after establishing a
connection, since application-provider interaction doesn't involve communication with SQL Server. However,
because the driver hasn't been loaded yet, setting and getting these attributes before connecting will cause them
to be processed by the Driver Manager, and may not yield the expected results.
Loading a keystore provider
Setting the SQL_COPT_SS_CEKEYSTOREPROVIDER connection attribute enables a client application to load a provider
library, making available for use the keystore providers contained there.
The driver attempts to load the library identified by the ValuePtr parameter using the platform-defined dynamic
library loading mechanism ( dlopen() on Linux and macOS, LoadLibrary() on Windows), and adds any
providers defined there to the list of providers known to the driver. The following errors may occur:
SQLSetConnectAttr returns the usual error or success values, and more information is available for any errors
that occurred via the standard ODBC diagnostic mechanism.
NOTE
The application programmer must ensure that any custom providers are loaded before any query requiring them is sent
over any connection. Failure to do so results in the error:
NOTE
Keystore provider implementors should avoid the use of MSSQL in the name of their custom providers. This term is
reserved exclusively for Microsoft use and may cause conflicts with future built-in providers. Using this term in the name
of a custom provider may result in an ODBC warning.
To allow retrieving the entire list, every Get operation returns the current provider's name, and increments an
internal counter to the next one. Once this counter reaches the end of the list, an empty string ("") is returned,
and the counter is reset; successive Get operations then continue again from the beginning of the list.
Communicating with keystore providers
The SQL_COPT_SS_CEKEYSTOREDATA connection attribute enables a client application to communicate with loaded
keystore providers for configuring more parameters, keying material, and so on. The communication between a
client application and a provider follows a simple request-response protocol, based on Get and Set requests
using this connection attribute. Communication is initiated only by the client application.
NOTE
Due to the nature of the ODBC calls CEKeyStoreProvider's respond to (SQLGet/SetConnectAttr), the ODBC interface only
supports setting data at the resolution of the connection context.
The application communicates with keystore providers through the driver via the CEKeystoreData structure:
name [Input] Upon Set, the name of the provider to which the
data is sent. Ignored upon Get. Null-terminated, wide-
character string.
dataSize [Input] The size of the data array following the structure.
data [InOut] Upon Set, the data to be sent to the provider. This
data may be arbitrary; the driver makes no attempt to
interpret it. Upon Get, the buffer to receive the data read
from the provider.
The caller must ensure that a buffer of sufficient length following the CEKEYSTOREDATA structure is allocated for
the provider to write into. Upon return, its dataSize field is updated with the actual length of data read from the
provider. More detailed error information may be obtained via SQLGetDiacRec.
This interface places no extra requirements on the format of data transferred between an application and a
keystore provider. Each provider can define its own protocol/data format, depending on its needs.
For an example of implementing your own keystore provider, see Custom Keystore Providers
Connection attributes
NAME TYPE DESC RIP T IO N
NAME TYPE DESC RIP T IO N
Statement attributes
NAME DESC RIP T IO N
Descriptor fields
IP D F IEL D SIZ E/ T Y P E DEFA ULT VA L UE DESC RIP T IO N
IP D F IEL D SIZ E/ T Y P E DEFA ULT VA L UE DESC RIP T IO N
When nonzero: if
encryption metadata is
available for this parameter,
it's encrypted. Otherwise,
the request fails with error
[CE300] [Microsoft][ODBC
Driver 17 for SQL
Server]Mandatory
encryption was specified for
a parameter but no
encryption metadata was
provided by the server.
bcp_control options
O P T IO N N A M E DEFA ULT VA L UE DESC RIP T IO N
Troubleshooting
When having difficulties using Always Encrypted, start by checking the following points:
The CEK that encrypts the desired column is present and accessible on the server.
The CMK that encrypts the CEK has accessible metadata on the server and is also accessible from the
client.
ColumnEncryption is enabled in the DSN, connection string, or connection attribute, and if using the
secure enclave, has the correct format.
Additionally, when using the secure enclave, attestation failures identify the step in the attestation process where
the failure occurred, according to the following table:
ST EP DESC RIP T IO N
Purpose
The Microsoft ODBC Driver for SQL Server version 13.1 or above allows ODBC applications to connect to an
instance of Azure SQL Database using a federated identity in Azure Active Directory. The identity can use a
username/password, an Azure Active Directory access token, an Azure Active Directory managed identity
(17.3+), or Windows-Integrated Authentication (17.6+ on Linux/macOS). For the ODBC Driver version 13.1, the
Azure Active Directory access token authentication is Windows only. The ODBC Driver version 17 and above
support this authentication across all platforms (Windows, Linux, and macOS). A new Azure Active Directory
interactive authentication with Login ID is introduced in ODBC Driver version 17.1 for Windows. A new Azure
Active Directory managed identity authentication method was added in ODBC Driver version 17.3.1.1 for both
system-assigned and user-assigned identities. All of these options are accomplished by using new DSN and
connection string keywords, and connection attributes.
To use Azure Active Directory authentication, you must configure your Azure SQL data source. For more
information, see Configure and manage Azure AD authentication with Azure SQL.
NOTE
The ODBC Driver on Linux and macOS before version 17.6 only supports Azure Active Directory authentication directly
against Azure Active Directory. If you are using Azure Active Directory username/password authentication from a Linux or
macOS client and your Active Directory configuration requires the client to authenticate against an Active Directory
Federation Services endpoint, authentication may fail. As of driver version 17.6, this limitation has been removed.
Authentication (not set), (empty string), (not set) Controls the authentication
SqlPassword , mode.
ActiveDirectoryPassword
, VA L U E D ESCR IP TIO
N
ActiveDirectoryIntegrated
, (not set) Authentica
ActiveDirectoryInteractive tion mode
, ActiveDirectoryMsi , determine
ActiveDirectoryServicePrincipal d by other
keywords
(existing
legacy
connectio
n options.)
NAME VA L UES DEFA ULT (empty
DESC RIP T IO N (Connectio
string) n string
only.)
Override
and unset
an
Authentication
value set
in the
DSN.
SqlPassword Directly
authentica
te to a
SQL
Server
instance
using a
username
and
password.
Authentica
ActiveDirectoryPassword
te with an
Azure
Active
Directory
identity
using a
username
and
password.
Windows,
ActiveDirectoryIntegrated
and
Linux/Mac
17.6+,
driver
only.
Authentica
te with an
Azure
Active
Directory
identity
using
integrated
authentica
tion.
Windows
ActiveDirectoryInteractive
driver
only.
Authentica
te with an
Azure
Active
Directory
identity
using
interactive
authentica
tion.
NAME VA L UES DEFA ULT DESC RIP T IO N Authentica
ActiveDirectoryMsi
te with
Azure
Active
Directory
identity
using
managed
identity
authentica
tion. For
user-
assigned
identity,
UID is set
to the
object ID
of the
user
identity.
(17.7+)
ActiveDirectoryServicePrincipal
Authentica
te with
Azure
Active
Directory
identity
using
service
principal
authentica
tion. UID
is set to
the client
ID of the
service
principal.
PWD is set
to the
client
secret.
NAME VA L UES DEFA ULT DESC RIP T IO N
Encrypt (not set), Yes / Mandatory (see description) Controls encryption for a
(18.0+), No / Optional connection. If the pre-
(18.0+), Strict (18.0+) attribute value of the
Authentication setting is
not none in the DSN or
connection string, the
default is Yes . The default
is also Yes in versions
18.0.1+. Otherwise, the
default is No . If the
attribute
SQL_COPT_SS_AUTHENTICATION
overrides the pre-attribute
value of Authentication ,
explicitly set the value of
Encryption in the DSN or
connection string or
connection attribute. The
pre-attribute value of
Encryption is Yes if the
value is set to Yes in
either the DSN or
connection string.
SQL_COPT_SS_AUTHENTICATION
SQL_IS_INTEGER SQL_AU_NONE , (not set) See description of
SQL_AU_PASSWORD , Authentication
SQL_AU_AD_INTEGRATED keyword above.
, SQL_AU_NONE is
SQL_AU_AD_PASSWORD provided to explicitly
, override a set
SQL_AU_AD_INTERACTIVE Authentication
, SQL_AU_AD_MSI , value in the DSN
SQL_AU_AD_SPA , and/or connection
SQL_AU_RESET
string, while
SQL_AU_RESET
unsets the attribute if
it was set, allowing
the DSN or
connection string
value to take
precedence.
AT T RIB UT E TYPE VA L UES DEFA ULT DESC RIP T IO N
SQL_COPT_SS_ACCESS_TOKEN
S QL_IS_POINTER Pointer to NULL If non-null, specifies
ACCESSTOKEN or the AzureAD Access
NULL Token to use. It's an
error to specify an
access token and also
UID , PWD ,
Trusted_Connection
, or
Authentication
connection string
keywords or their
equivalent attributes.
NOTE: ODBC Driver
version 13.1 only
supports this setting
on Windows.
Password expiration
for SQL Server
Authentication was
introduced in SQL
Server 2005. The
SQL_COPT_SS_OLDPWD
attribute was added
to allow the client to
provide both the old
and the new
password for the
connection. When
this property is set,
the provider won't
use the connection
pool for the first
connection or for
future connections,
since the connection
string will contain the
"old password",
which has now
changed.
SQL_COPT_SS_INTEGRATED_SECURITY
SQL_IS_INTEGER SQL_IS_OFF , SQL_IS_OFF Deprecated; use
SQL_IS_ON SQL_COPT_SS_AUTHENTICATION
set to
SQL_AU_AD_INTEGRATED
instead.
Forces use of
Windows
Authentication
(Kerberos on Linux
and macOS) for
access validation on
server login. When
Windows
Authentication is
used, the driver
ignores user identifier
and password values
provided as part of
SQLConnect ,
SQLDriverConnect ,
or
SQLBrowseConnect
processing.
UI Additions for Azure Active Directory (Windows driver only)
The DSN setup and connection UIs of the driver have been enhanced with the more options necessary for using
authentication with Azure AD.
Creating and editing DSNs in the UI
It's possible to use the new Azure AD authentication options when creating or editing an existing DSN using the
driver's setup UI:
Authentication=ActiveDirectoryIntegrated for Azure Active Directory Integrated authentication to Azure SQL
Database
NOTE
As of driver version 17.9, the interactive authentication behavior has changed. Users will always be prompted for
credentials unless the driver has a valid access token cached. This change prevents users on Azure Active Directory joined
devices from skipping the prompt and automatically signing in with cached credentials when using
ActiveDirectoryInteractive authentication.
These options correspond to the same six available in the DSN setup UI above.
Example connection strings
1. SQL Server Authentication - legacy syntax. Server certificate isn't validated, and encryption is used only if the
server enforces it. The username/password is passed in the connection string.
server=Server;database=Database;UID=UserName;PWD=Password;
2. SQL Authentication - new syntax. The client requests encryption (the default value of Encrypt is true ) and
the server certificate gets validated, whatever the encryption setting (unless TrustServerCertificate is set to
true ). The username/password is passed in the connection string.
server=Server;database=Database;UID=UserName;PWD=Password;Authentication=SqlPassword;
3. Integrated Windows Authentication (Kerberos on Linux and macOS) using SSPI (to SQL Server or SQL IaaS) -
current syntax. Server certificate isn't validated, unless encryption is used.
server=Server;database=Database;Trusted_Connection=yes;
4. (Windows driver only.) Integrated Windows Authentication using SSPI (if the target database is in SQL Server
or SQL IaaS) - new syntax. The client requests encryption (the default value of Encrypt is true ) and the
server certificate gets validated, whatever the encryption setting (unless TrustServerCertificate is set to
true ). server=Server;database=Database;Authentication=ActiveDirectoryIntegrated;
5. Azure Active Directory Username/Password Authentication (if the target database is in Azure SQL Database).
Server certificate gets validated, whatever the encryption setting (unless TrustServerCertificate is set to
true ). The username/password is passed in the connection string.
server=Server;database=Database;UID=UserName;PWD=Password;Authentication=ActiveDirectoryPassword;
6. (Windows, and Linux/macOS 17.6+, driver only.) Integrated Windows Authentication using ADAL or
Kerberos, which involves redeeming Windows account credentials for an Azure AD-issued access token,
assuming the target database is in Azure SQL Database. Server certificate gets validated, whatever the
encryption setting (unless TrustServerCertificate is set to true ). On Linux/macOS, a suitable Kerberos
ticket needs to be available. For more information, see the section below on Federated Accounts and Using
Integrated Authentication. server=Server;database=Database;Authentication=ActiveDirectoryIntegrated;
7. (Windows driver only.) Azure AD Interactive Authentication uses Azure Active Directory Multi-Factor
Authentication technology to set up connection. In this mode, by providing the login ID, an Azure
Authentication dialog is triggered and allows the user to input the password to complete the connection. The
username is passed in the connection string.
server=Server;database=Database;UID=UserName;Authentication=ActiveDirectoryInteractive;
8. Azure Active Directory Managed Identity Authentication uses system-assigned or user-assigned identity for
authentication to set up connection. For user-assigned identity, UID is set to the object ID of the user identity.
For system-assigned identity,
server=Server;database=Database;Authentication=ActiveDirectoryMsi;
For user-assigned identity with object ID equals to myObjectId,
server=Server;database=Database;UID=myObjectId;Authentication=ActiveDirectoryMsi;
9. Azure Active Directory Service Principal Authentication
server=Server;database=Database;UID=clientId;PWD=clientSecret;Authentication=ActiveDirectoryServicePrincipal;
NOTE
When using the Active Directory options with the Windows ODBC driver prior to version 17.4.2, ensure that the
Active Directory Authentication Library for SQL Server has been installed. When using the Linux and macOS drivers,
ensure that libcurl has been installed. For driver version 17.2 and later, this is not an explicit dependency since it is
not required for the other authentication methods or ODBC operations.
When Azure Active Directory configuration includes Conditional Access policies, and the client is Windows 10 or Server
2016 or later, authentication via Integrated or username/password may fail. Conditional Access policies require the use
of Web Account Manager (WAM), which is supported in driver version 17.6 or later for Windows. To use WAM, create
a new string or DWORD value named ADALuseWAM in
HKLM\Software\ODBC\ODBCINST.INI\ODBC Driver 17 for SQL Server ,
HKCU\Software\ODBC\ODBC.INI\<your-user-DSN-name> , or
HKLM\Software\ODBC\ODBC.INI\<your-system-DSN-name> for global, user DSN, or system DSN-scoped configuration
respectively, and set it to a value of 1. Note that authentication with WAM does not support running the application
as a different user with runas . Scenarios which require Condtitional Access policies are not supported for Linux or
macOS.
To connect using a SQL Server account username and password, you may now use the new SqlPassword option,
which is recommended especially for Azure SQL since this option enables more secure connection defaults.
To connect using an Azure Active Directory account username and password, specify
Authentication=ActiveDirectoryPassword in the connection string and the UID and PWD keywords with the
username and password, respectively.
To connect using Windows Integrated or Active Directory Integrated (Windows, and Linux/macOS 17.6+, driver only)
authentication, specify Authentication=ActiveDirectoryIntegrated in the connection string. The driver will choose
the correct authentication mode automatically. For driver versions 17.7 or earlier, UID and PWD must not be
specified. Beginning with driver version 17.8, UID and PWD are ignored.
To connect using Active Directory Interactive (Windows driver only) authentication, UID must be specified. For driver
versions 17.7 and earlier, PWD must not be specified. Beginning with driver version 17.8, PWD is ignored.
The ACCESSTOKEN is a variable-length structure consisting of a 4-byte length followed by length bytes of opaque
data that form the access token. Because of how SQL Server handles access tokens, one obtained via an OAuth
2.0 JSON response must be expanded so that each byte is followed by a zero padding byte, similar to a UCS-2
string containing only ASCII characters. However, the token is an opaque value and the length specified, in bytes,
must NOT include any null terminator. Because of their considerable length and format constraints, this method
of authentication is only available programmatically via the SQL_COPT_SS_ACCESS_TOKEN connection attribute.
There's no corresponding DSN or connection string keyword. The connection string must not contain UID , PWD ,
Authentication , or Trusted_Connection keywords.
NOTE
The ODBC Driver version 13.1 only supports this authentication on Windows. Subsequent versions support this
authentication on all platforms.
...
SQLCHAR connString[] = "Driver={ODBC Driver 17 for SQL Server};Server=
{server};UID=myuser;PWD=myPass;Authentication=ActiveDirectoryPassword"
...
SQLDriverConnect(hDbc, NULL, connString, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
...
The following sample shows the code required to connect to SQL Server using Azure Active Directory with
access token authentication. In this case, it's necessary to modify application code to process the access token
and set the associated connection attribute.
The following sample connection string is for use with Azure Active Directory Interactive Authentication. It
doesn't contain PWD field as the password would be entered on the Azure Authentication screen.
The following sample connection string is for use with Azure Active Directory Managed Identity Authentication.
UID is set to the object ID of the user identity when using a user-assigned identity.
Linux
On SuSE 11, the default Kerberos library version of 1.6.x doesn't support the Enterprise Principal option
necessary to use alternate UPN suffixes. To use alternate UPN suffixes with Azure AD Integrated authentication,
upgrade the Kerberos library to 1.7 or newer.
On Alpine Linux, the default libcurl doesn't support the SPNEGO/Kerberos authentication required for Azure
AD Integrated authentication.
macOS
The system Kerberos library kinit supports Enterprise Principal with the --enterprise option, but also
implicitly does name canonicalization, which prevents the use of alternate UPN suffixes. To use alternate UPN
suffixes with Azure AD Integrated authentication, install a newer Kerberos library via brew install krb5 and use
its kinit with the -E option as described above.
See Also
Token-based authentication support for Azure SQL Database using Azure AD auth
Using Integrated Authentication
Using Transparent Network IP Resolution with the
ODBC Driver
4/27/2022 • 2 minutes to read • Edit Online
(default) (default) 0
(default) Enabled 1
(default) Disabled 0
Enabled (default) 0
Enabled Enabled 1
Enabled Disabled 0
Disabled (default) 2
Disabled Enabled 1
Disabled Disabled 2
The TransparentNetworkIPResolution connection string and DSN keyword controls this setting at the connection-
string level. The default is enabled.
The SQL_COPT_SS_TNIR pre-connection attribute allows an application to control this setting programmatically:
C O N N EC T IO N
AT T RIB UT E SIZ E/ T Y P E DEFA ULT VA L UE DESC RIP T IO N
Overview
For managing sensitive data, SQL Server and Azure SQL Server introduced the ability to provide database
columns with sensitivity metadata that allows the client application to handle different types of sensitive data
(such as health, financial, etc.) in accordance with data protection policies.
For more information on how to assign classification to columns, see SQL Data Discovery and Classification.
Microsoft ODBC Driver 17.2 or later allows the retrieval of this metadata via SQLGetDescField using the
SQL_CA_SS_DATA_CLASSIFICATION field identifier.
Format
SQLGetDescField has the following syntax:
SQLRETURN SQLGetDescField(
SQLHDESC DescriptorHandle,
SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier,
SQLPOINTER ValuePtr,
SQLINTEGER BufferLength,
SQLINTEGER * StringLengthPtr);
DescriptorHandle
[Input] IRD (Implementation Row Descriptor) handle. Can be retrieved by a call to SQLGetStmtAttr with
SQL_ATTR_IMP_ROW_DESC statement attribute
RecNumber
[Input] 0
FieldIdentifier
[Input] SQL_CA_SS_DATA_CLASSIFICATION
ValuePtr
[Output] Output buffer
BufferLength
[Input] Length of output buffer in bytes
StringLengthPtr [Output] Pointer to the buffer in which to return the total number of bytes available to return in
ValuePtr.
NOTE
If the size of the buffer is unknown, it can be determined by calling SQLGetDescField with ValuePtr as NULL and
examining the value of StringLengthPtr.
If Data Classification information isn't available, an Invalid Descriptor Field error will be returned.
Upon a successful call to SQLGetDescField, the buffer pointed to by ValuePtr will contain the following data:
nn nn [n sensitivitylabels] tt tt [t informationtypes] cc cc [c columnsensitivitys]
NOTE
nn nn , tt tt , and cc cc are multibyte integers, which are stored with the least significant byte at the lowest
address.
struct IDnamePair {
BYTE nameLen;
USHORT name[nameLen];
BYTE idLen;
USHORT id[idLen];
};
struct SensitivityProp {
USHORT labelIdx;
USHORT infoTypeIdx;
};
USHORT nLabels;
struct IDnamePair labels[nLabels];
USHORT nInfoTypes;
struct IDnamePair infotypes[nInfoTypes];
USHORT nColumns;
struct {
USHORT nProps;
struct SensitivityProp[nProps];
} columnClassification[nColumns];
Code sample
Test application that demonstrates how to read Data Classification metadata. On Windows it can be compiled
using cl /MD dataclassification.c /I (directory of msodbcsql.h) /link odbc32.lib and run with a connection
string, and a SQL query (that returns classified columns) as parameters:
#ifdef _WIN32
#include <windows.h>
#endif
#include <sql.h>
#include <sql.h>
#include <sqlext.h>
#include <msodbcsql.h>
#include <stdio.h>
SQLHANDLE env, dbc, stmt;
void checkRC_exit(SQLRETURN rc, SQLHANDLE hand, SQLSMALLINT htype, int retcode, char *action)
{
if ((rc == SQL_ERROR || rc == SQL_SUCCESS_WITH_INFO) && hand)
{
char msg[1024], state[6];
int i = 0;
SQLRETURN rc2;
SQLINTEGER err;
SQLSMALLINT lenout;
while ((rc2 = SQLGetDiagRec(htype, hand, ++i, state, &err, msg, sizeof(msg), &lenout)) ==
SQL_SUCCESS ||
rc2 == SQL_SUCCESS_WITH_INFO)
printf("%d (%d)[%s]%s\n", i, err, state, msg);
}
if (rc == SQL_ERROR && retcode)
{
printf("Error occurred%s%s\n", action ? " upon " : "", action ? action : "");
exit(retcode);
}
}
void printLabelInfo(char *type, char **pptr)
{
char *ptr = *pptr;
unsigned short nlabels;
printf("----- %s(%u) -----\n", type, nlabels = *(unsigned short*)ptr);
ptr += sizeof(unsigned short);
while (nlabels--)
{
int namelen, idlen;
char *nameptr, *idptr;
namelen = *ptr++;
nameptr = ptr;
ptr += namelen * 2;
idlen = *ptr++;
idptr = ptr;
ptr += idlen * 2;
wprintf(L"Name: \"%.*s\" Id: \"%.*s\"\n", namelen, nameptr, idlen, idptr);
}
*pptr = ptr;
}
int main(int argc, char **argv)
{
unsigned char *dcbuf;
unsigned int dclen = 0;
SQLRETURN rc;
SQLHANDLE ird;
if (argc < 3)
{
fprintf(stderr, "usage: dataclassification connstr query\n");
return 1;
}
checkRC_exit(SQLAllocHandle(SQL_HANDLE_ENV, 0, &env), 0, 0,
2, "allocate environment");
checkRC_exit(SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0), env,
SQL_HANDLE_ENV,
3, "set ODBC version");
checkRC_exit(SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc), env, SQL_HANDLE_ENV,
4, "allocate connection");
checkRC_exit(SQLDriverConnect(dbc, 0, argv[1], SQL_NTS, 0, 0, 0, SQL_DRIVER_NOPROMPT), dbc,
SQL_HANDLE_DBC,
5, "connect to server");
checkRC_exit(SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt), dbc, SQL_HANDLE_DBC,
6, "allocate statement");
checkRC_exit(SQLExecDirect(stmt, argv[2], SQL_NTS), stmt, SQL_HANDLE_STMT,
7, "execute query");
checkRC_exit(SQLGetStmtAttr(stmt, SQL_ATTR_IMP_ROW_DESC, (SQLPOINTER)&ird, SQL_IS_POINTER, 0), stmt,
SQL_HANDLE_STMT,
8, "get IRD handle");
rc = SQLGetDescFieldW(ird, 0, SQL_CA_SS_DATA_CLASSIFICATION, dcbuf, 0, &dclen);
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
{
checkRC_exit(rc, ird, SQL_HANDLE_DESC, 0, 0);
printf("Error reading SQL_CA_SS_DATA_CLASSIFICATION IRD field. Ensure that the driver and\n"
"server both support the Data Classification feature, and that the query returns columns\n"
"with classification information.\n");
}
else
{
SQLINTEGER dclenout;
unsigned char *dcptr;
unsigned short ncols;
printf("Data Classification information (%u bytes):\n", dclen);
if (!(dcbuf = malloc(dclen)))
{
printf("Memory Allocation Error");
return 9;
}
checkRC_exit(SQLGetDescFieldW(ird, 0, SQL_CA_SS_DATA_CLASSIFICATION, dcbuf, dclen, &dclenout),
ird, SQL_HANDLE_DESC, 10, "reading SQL_CA_SS_DATA_CLASSIFICATION");
dcptr = dcbuf;
printLabelInfo("Labels", &dcptr);
printLabelInfo("Information Types", &dcptr);
printf("----- Column Sensitivities(%u) -----\n", ncols = *(unsigned short*)dcptr);
dcptr += sizeof(unsigned short);
while (ncols--)
{
unsigned short nprops = *(unsigned short*)dcptr;
dcptr += sizeof(unsigned short);
while (nprops--)
{
unsigned short labelidx, typeidx;
labelidx = *(unsigned short*)dcptr; dcptr += sizeof(unsigned short);
typeidx = *(unsigned short*)dcptr; dcptr += sizeof(unsigned short);
printf(labelidx == 0xFFFF ? "(none) " : "%u ", labelidx);
printf(typeidx == 0xFFFF ? "(none)\n" : "%u\n", typeidx);
}
printf("-----\n");
}
if (dcptr != dcbuf + dclen)
{
printf("Error: unexpected parse of DATACLASSIFICATION data\n");
return 11;
}
free(dcbuf);
}
return 0;
}
Supported Version
Microsoft ODBC Driver 17.2 allows the retrieval of Data Classification information via SQLGetDescField if
FieldIdentifier is set to SQL_CA_SS_DATA_CLASSIFICATION (1237).
Starting from Microsoft ODBC Driver 17.4.1.1, it's possible to retrieve the version of Data Classification
supported by a server via SQLGetDescField using the SQL_CA_SS_DATA_CLASSIFICATION_VERSION (1238) field
identifier. In 17.4.1.1, the supported data classification version is set to "2".
Starting from 17.4.2.1, the default version of data classification is set to "1" and is the version the driver reports
to SQL Server as supported. A new connection attribute SQL_COPT_SS_DATACLASSIFICATION_VERSION (1400) can
allow application to change the supported version of Data Classification from "1" up to the maximum
supported.
Example:
To set the version, this call should be made right before the SQLConnect or SQLDriverConnect call:
The value of the currently supported version of Data Classification can be retrieved via SQLGetConnectAttr call:
Overview
The Microsoft ODBC Driver for SQL Server, starting from version 17.3, provides support for XA transactions
with the Distributed Transaction Coordinator (DTC) on Windows, Linux, and macOS. The XA implementation on
the driver side enables the client application to send serial operations (such as start, commit, rollback a
transaction branch, and so on) to the Transaction Manager (TM). And then the TM will communicate with the
Resource Manager (RM) according to these operations. For more information about the XA Specification and the
Microsoft implementation for DTC (MS DTC), see How It Works: SQL Server DTC(MSDTC and XA Transactions).
sizeParam
Size of the XACALLPARAM structure. This size excludes the size of the data following XACALLPARAM .
operation
The XA operation to be passed to the TM. Possible operations are defined in xadefs.h.
xid
Transaction branch identifier.
flags
Flags associated with the TM request. Possible values are defined in xadefs.h.
status
Return status from the TM. See xadefs.h header for possible return statuses.
sizeData
Size of the data buffer following XACALLPARAM .
sizeReturned
Size of data returned.
To make a TM request, the SQLSetConnectAttr function needs to be called with attribute
SQL_COPT_SS_ENLIST_IN_XA and a pointer to the XACALLPARAM object.
SQLSetConnectAttr(hdbc, SQL_COPT_SS_ENLIST_IN_XA, param, SQL_IS_POINTER); // XACALLPARAM *param
Code Sample
The following example shows how to communicate with the TM for XA transactions and execute different
operations from a client application. If the test is run against Microsoft SQL Server, the MS DTC needs to be
properly configured to enable XA transactions. The XA definitions can be found in the xadefs.h header file.
#include "sqlwindef.h"
#include "xplatsec.h"
#include <sql.h>
#include <sqlext.h>
#include "XaTestRunner.h"
#include <iostream>
#include <string>
#include <memory>
#include <thread>
#include <chrono>
rc = SQLFetch(hstmt);
XaTestRunner::CheckRC(rc, "GetRowCount::SQLFetch", hstmt, SQL_HANDLE_STMT);
if (!SQL_SUCCEEDED(rc))
{
return rc;
}
return rc;
}
bool TestXaRunner(HDBC hdbc, const char* connString, TestType testType, int timeout = 0)
{
SQLRETURN rc = SQLDriverConnect(hdbc, NULL, (SQLCHAR*)connString, SQL_NTS, NULL, 0, NULL,
SQL_DRIVER_NOPROMPT);
XaTestRunner::CheckRC(rc, "TestXaRunner::Connecting", hdbc, SQL_HANDLE_DBC);
if (!SQL_SUCCEEDED(rc))
{
return false;
}
SQLHSTMT hstmt;
rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
XaTestRunner::CheckRC(rc, "TestXaRunner::Alloc statement", hdbc, SQL_HANDLE_DBC);
const int ROWS_TO_TEST = 10;
int rowCount = 0;
bool result = false;
if (SQL_SUCCEEDED(rc))
{
std::string tableName;
auto testRunner = std::make_shared<XaTestRunner>(hdbc);
testRunner->GetUniqueName(tableName);
bool isTableCreated = false;
RETCODE xaStatus = SQL_ERROR;
bool isTimeoutTest = false;
XID xid;
XaTestRunner::GetUniqueXid(xid);
do
{
if (!(isTableCreated = testRunner->CreateTable(tableName)))
{
std::cout << "TestXaRunner::Failed to create table " << tableName.c_str() << std::endl;
break;
}
if (timeout > 0)
{
testRunner->SetTimeout(timeout);
isTimeoutTest = true;
}
if (isTimeoutTest)
{
auto timeToSleep = timeout + 5;
std::cout << "Sleep for " << timeToSleep << " seconds" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(timeToSleep));
}
switch (testType)
{
case TestType::Commit:
rc = testRunner->Prepare(xid, xaStatus);
if (xaStatus < 0)
{
std::cout << "TestXaRunner::XA Prepare failed status=" << xaStatus << std::endl;
}
else
{
rc = testRunner->Commit(xid, false, xaStatus);
if (xaStatus < 0)
{
std::cout << "TestXaRunner::XA Commit failed status=" << xaStatus << std::endl;
}
}
break;
case TestType::Commit1Phase:
case TestType::Commit1Phase:
rc = testRunner->Commit(xid, true, xaStatus);
if (xaStatus < 0)
{
std::cout << "TestXaRunner::XA Commit one phase failed status=" << xaStatus <<
std::endl;
}
break;
case TestType::Rollback:
rc = testRunner->Rollback(xid, xaStatus);
if (xaStatus < 0)
{
std::cout << "TestXaRunner::XA Rollback failed status=" << xaStatus << std::endl;
}
break;
case TestType::Recover:
break;
default:
break;
}
}
else
{
std::cout << "TestXaRunner::XA Start failed status=" << xaStatus << std::endl;
}
} while (false);
if (isTimeoutTest)
{
result = xaStatus == XAER_NOTA;
std::cout << "TestXaRunner::TimeoutTest" " xaStatus=" << xaStatus << " test " << (result ?
"Succeded" : "Failed") << std::endl;
}
else
{
auto isCommit = testType == TestType::Commit || testType == TestType::Commit1Phase;
std::cout << "TestXaRunner::" << (isCommit ? "Commit" : "Rollback") << " rowCount=" << rowCount
<< " xaStatus=" << xaStatus << " test " << (result ? "Succeded" : "Failed") << std::endl;
}
if (isTableCreated)
{
testRunner->DropTable(tableName);
}
rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
rc = SQLDisconnect(hdbc);
}
return result;
}
return result;
}
XID xid;
XaTestRunner::GetUniqueXid(xid);
rc = testRunner->Start(xid, TMNOFLAGS, xaStatus);
if (xaStatus < 0)
{
std::cout << "TestXaRunner::XA Start failed status=" << xaStatus << std::endl;
break;
}
rc = testRunner->ExecuteInsertSequence(tableNames[tr], ROWS_TO_TEST);
std::cout << "Completed transaction " << tr << " formatId=" <<xid.formatID <<std::endl;
numCompletedTransactions++;
rc = testRunner->Prepare(xid, xaStatus);
std::cout << "Prepared transaction " << tr << std::endl;
} while (false);
}
std::cout << "Sleep for " << sleepTime << "seconds" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(sleepTime));
SQLDisconnect(hdbc);
return result;
}
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 0;
}
The XATestRunner class implements the possible XA calls when communicating with the server.
XaTestRunner.h
#pragma once
#include "xadefs.h"
#include "sqlwindef.h"
#include "xplatsec.h"
#include <sql.h>
#include <sqlext.h>
#include <random>
struct RandomProvider
{
std::random_device rd;
};
class XidMgr
{
public:
static void GetUniqueXid(XID& xid);
static void GetUniqueXid(XID& xid, int formatId, unsigned char* globalId = nullptr, unsigned int
sizeGlobalId = 0);
static int GetRandomNumber(int low = 0, int high = 0xffffffff);
static void GetRandomBuffer(unsigned char* buffer, unsigned int sizeBuffer);
};
class XaTestRunner
{
public:
XaTestRunner(HDBC dbc);
~XaTestRunner();
static int CheckRC(SQLRETURN rc, const char *msg, SQLHANDLE handle, SQLSMALLINT htype);
private:
HDBC m_hdbc;
std::string m_tableName;
std::string m_commandCreateTable;
std::string m_commandInsertRow;
bool ExecuteQuery(const char* query, const char* msg, SQLHSTMT stmt = NULL);
RETCODE IssueXaCall(const XID* xid, int operation, const int flags, unsigned char* buffer, unsigned int&
sizeBuffer, RETCODE& xaStatus);
};
XaTestRunner.cpp
#include "XaTestRunner.h"
#include <chrono>
#include <thread>
#include <ctime>
#include <atomic>
RandomProvider XidMgr::rndPrv;
XaTestRunner::XaTestRunner(HDBC dbc)
: m_hdbc(dbc)
{
GetUniqueName(m_tableName);
m_commandCreateTable = COMMAND_CREATE_TABLE;
m_commandInsertRow = COMMAND_INSERT_ROW;
}
XaTestRunner::~XaTestRunner()
{
}
void XidMgr::GetUniqueXid(XID& xid, int formatId, unsigned char* globalId, unsigned int sizeGlobalId)
{
auto isGlobalIdDefined = globalId != nullptr && sizeGlobalId > 0 && sizeGlobalId <= 64;
xid.formatID = formatId;
xid.bqual_length = 64;
xid.gtrid_length = isGlobalIdDefined ? sizeGlobalId : 64;
if (!isGlobalIdDefined)
{
GetRandomBuffer(&xid.data[0], xid.gtrid_length);
}
else
{
memcpy_s(&xid.data[0], sizeof(xid.data), globalId, xid.gtrid_length);
}
GetRandomBuffer(&xid.data[xid.gtrid_length], xid.bqual_length);
}
int XaTestRunner::CheckRC(SQLRETURN rc, const char *msg, SQLHANDLE handle, SQLSMALLINT htype)
{
if (rc == SQL_ERROR)
{
printf("Error occurred upon [%s]\n", msg);
if (handle)
{
SQLSMALLINT i = 0;
SQLSMALLINT outlen = 0;
SQLCHAR errmsg[1024];
SQLCHAR sql_state[6];
SQLINTEGER native_error = 0;
return 0;
}
else if (rc == SQL_SUCCESS_WITH_INFO && handle)
{
SQLSMALLINT i = 0;
SQLSMALLINT outlen = 0;
SQLSMALLINT outlen = 0;
SQLCHAR errmsg[1024];
SQLCHAR sql_state[6];
SQLINTEGER native_error = 0;
RETCODE XaTestRunner::IssueXaCall(const XID* pXid, int operation, const int flags, unsigned char* buffer,
unsigned int& sizeBuffer, RETCODE& xaStatus)
{
auto sizeLimit = sizeBuffer;
unsigned int sizeParam = sizeof(XACALLPARAM) + sizeBuffer;
std::vector<unsigned char> buff(sizeParam);
PXACALLPARAM param = (PXACALLPARAM)(void*)&buff[0];
memset(param, 0, sizeof(XACALLPARAM));
param->flags = flags;
param->operation = operation;
param->sizeParam = sizeParam;
if (pXid)
{
param->xid = *pXid;
}
if (sizeBuffer > 0)
{
param->sizeData = sizeBuffer;
memcpy_s(¶m[1], sizeBuffer, buffer, sizeBuffer);
}
return rc;
RETCODE XaTestRunner::Recover(const int flags, unsigned char* buffer, unsigned int& sizeBuffer, RETCODE&
xaStatus)
{
return IssueXaCall(nullptr, OP_RECOVER, flags, buffer, sizeBuffer, xaStatus);
}
int XaTestRunner::GetTimeout()
{
int timeout = 0;
unsigned int sizeBuffer = sizeof(timeout);
RETCODE xaStatus;
IssueXaCall(nullptr, OP_GETTIMEOUT, TMNOFLAGS, (unsigned char*)&timeout, sizeBuffer, xaStatus);
return timeout;
}
if (isAllocateStatement)
{
rc = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &hstmt);
rc = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &hstmt);
}
if (SQL_SUCCEEDED(rc))
{
rc = SQLExecDirectA(hstmt, (SQLCHAR*)query, SQL_NTS);
if (!SQL_SUCCEEDED(rc))
{
CheckRC(rc, msg, hstmt, SQL_HANDLE_STMT);
}
if (isAllocateStatement)
{
SQLFreeStmt(hstmt, SQL_CLOSE);
}
}
else
{
CheckRC(rc, "Alloc Statement", m_hdbc, SQL_HANDLE_DBC);
}
return SQL_SUCCEEDED(rc);
if (isAllocateStatement)
{
rc = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &hstmt);
if (!SQL_SUCCEEDED(rc))
{
CheckRC(rc, "Alloc Statement", m_hdbc, SQL_HANDLE_DBC);
return false;
}
}
if (isAllocateStatement)
{
SQLFreeStmt(hstmt, SQL_CLOSE);
SQLFreeStmt(hstmt, SQL_CLOSE);
}
return true;
}
Appendix
xadefs.h
#pragma once
// from xa.h
/*
* Transaction branch identification: XID and NULLXID:
*/
#define XIDDATASIZE 128 /* size in bytes */
#define MAXGTRIDSIZE 64 /* maximum size in bytes of gtrid */
#define MAXBQUALSIZE 64 /* maximum size in bytes of bqual */
#ifndef _XID_T_DEFINED
#define _XID_T_DEFINED
struct xid_t
{
int formatID; /* format identifier */
int gtrid_length; /* value not to exceed 64 */
int bqual_length; /* value not to exceed 64 */
unsigned char data[XIDDATASIZE];
};
#endif
/*
* xa_() return codes (resource manager reports to transaction manager)
*/
#define XA_RBBASE 100 /* The inclusive lower bound of the rollback codes */
#define XA_RBROLLBACK XA_RBBASE /* The rollback was caused by an unspecified reason */
#define XA_RBCOMMFAIL XA_RBBASE+1 /* The rollback was caused by a communication failure */
#define XA_RBDEADLOCK XA_RBBASE+2 /* A deadlock was detected */
#define XA_RBINTEGRITY XA_RBBASE+3 /* A condition that violates the integrity of the resources was
detected */
#define XA_RBOTHER XA_RBBASE+4 /* The resource manager rolled back the transaction branch for a
reason not on this list */
#define XA_RBPROTO XA_RBBASE+5 /* A protocol error occurred in the resource manager */
#define XA_RBTIMEOUT XA_RBBASE+6 /* A transaction branch took too long */
#define XA_RBTRANSIENT XA_RBBASE+7 /* May retry the transaction branch */
#define XA_RBEND XA_RBTRANSIENT /* The inclusive upper bound of the rollback codes */
enum class XaOperation { start, end, prepare, commit, rollback, forget, recover, getTimeout, setTimeout,
prepareEx, rollbackEx, forgetEx };
const int OP_START = 0;
const int OP_END = 1;
const int OP_PREPARE = 2;
const int OP_COMMIT = 3;
const int OP_ROLLBACK = 4;
const int OP_FORGET = 5;
const int OP_RECOVER = 6;
const int OP_GETTIMEOUT = 7;
const int OP_SETTIMEOUT = 8;
This page contains a listing of bugs fixed in each release, starting with Microsoft ODBC Driver 17 for SQL Server.
Bug fixes in the Microsoft ODBC Driver 18.0 for SQL Server
Fix UI issues where text was cut off and position of items was off.
Fix issue with Active Directory Interactive login where attempting to login after closing the window of the
first failure would automatically succeed if cached credentials were available.
Fixed use of XADTC with Azure SQL Managed Instance.
Fixed loss of Azure Active Directory authentication mode when reconnecting an idle connection.
Fix an issue with federated authentication when using PingFed.
Bug fixes in the Microsoft ODBC Driver 17.9 for SQL Server
Fix UI issues where text was cut off and position of items was off.
Fix issue with Active Directory Interactive login where attempting to login after closing the window of the
first failure would automatically succeed if cached credentials were available.
Fixed use of XADTC with Azure SQL Managed Instance.
Fixed loss of Azure Active Directory authentication mode when reconnecting an idle connection.
Fix an issue with federated authentication when using PingFed.
Bug fixes in the Microsoft ODBC Driver 17.8 for SQL Server
Fix for restrictions on connection string regarding usage of UID and PWD keywords
Fix for inconsistent fonts in non-English dialogs
Fix issue with having multiple connections with different AKV credentials
Fix issue with NVDA not reading connection test results in DSN configuration UI
Bug fixes in the Microsoft ODBC Driver 17.7.2 for SQL Server
Fix issue with 404 Not Found errors when using Managed Service Identity authentication
Fix for intermittent Encryption Not Supported errors under high multithreaded loads
Fix for intermittent crash under high multithreaded loads
Bug fixes in the Microsoft ODBC Driver 17.7 for SQL Server
Fix character encoding of VARIANT columns in BCP NATIVE mode
Fix setting of SQL_ATTR_PARAMS_PROCESSED_PTR under specific conditions
Fix SQLDescribeParam in FMTONLY mode for statements containing comments
Fix an issue with federated authentication when using Okta
Fix excessive memory usage on multi-processor systems
Fix Azure AD authentication for some variants of Azure SQL DB
Bug fixes in the Microsoft ODBC Driver 17.6 for SQL Server
Fix ADAL error when authenticating with a federated account (Windows)
Fix an issue where the driver becomes unresponsive when a timeout occurs during an asynchronous
notification operation
Fix driver reference count upon upgrade in Alpine Linux
Fix libc6 dependency version for Ubuntu
Add missing defines to Linux/Mac msodbcsql.h
Bug fixes in the Microsoft ODBC Driver 17.5.2.2 for SQL Server (Alpine Linux only)
Fix a crash when using Always Encrypted with secure enclaves on Alpine Linux
Bug fixes in the Microsoft ODBC Driver 17.5.2 for SQL Server
Added msodbcsql.h to Alpine Linux package
Bug fixes in the Microsoft ODBC Driver 17.5 for SQL Server
Fix AKV CMK metadata hash computation on Linux/macOS
Fix error when loading OpenSSL 1.0.0
Fix conversion issues when using ISO-8859-1 and ISO-8859-2 codepages
Fix internal library name on macOS to include version number
Fix setting of null indicator when separate length and indicator bindings are used
Bug fixes in the Microsoft ODBC Driver 17.4.2 for SQL Server
Fix for an issue where process ID and application name would not be sent correctly to SQL Server (for
sys.dm_exec_sessions analysis) (Linux)
Removed redundant dependency on libuuid (Linux)
Fix for a bug with sending UTF8 data to SQL Server 2019
Fix for a bug where locales that end in "@euro" were not being correctly detected (Linux)
Fix for XML data being returned incorrectly when fetched as an output parameter while using Always
Encrypted
Bug fixes in the Microsoft ODBC Driver 17.4 for SQL Server
Fix for intermittent issue when Multiple Active Results Sets (MARS) is enabled where the driver stops
responding
Fix connection resiliency issue when async notification is enabled where the driver stops responding
Fix crash when retrieving diagnostic records for multithreaded connection attempts
Fix 'Encryption not supported' upon reconnect after calling SQLGetInfo() with SQL_USER_NAME and
SQL_DATA_SOURCE_READ_ONLY
Fix COM initialization error during Azure Active Directory Interactive Authentication
Fix SQLGetData() for multi-byte UTF8 data
Fix retrieving length of sql_variant columns using SQLGetData()
Fix importing of sql_variant columns containing more than 7992 bytes using bcp
Fix sending of correct encoding to server for narrow character data
Bug fixes in the Microsoft ODBC Driver 17.3 for SQL Server
Fixed TCP send notification event handle memory leak
Fixed redefinition issue of enum _SQL_FILESTREAM_DESIRED_ACCESS in msodbcsql.h header file
Fixed missing ACCESS_TOKEN and AUTHENTICATION related definition in msodbcsql.h header file for Linux
Bug fixes in the Microsoft ODBC Driver 17.2 for SQL Server
Fixed an error message about Azure Active Directory Authentication
Fixed encoding detection when locale environment variables are set differently
Fixed a crash upon disconnect with connection recovery in progress
Fixed detection of connection liveness
Fixed incorrect detection of closed sockets
Fixed an infinite wait when attempting to release a statement handle during failed recovery
Fixed incorrect uninstallation behavior when both version 13 and 17 are installed on Windows
Fixed decryption behavior on older Windows platform (Windows 7, 8 and Server 2012)
Fixed a cache issue when using ADAL Authentication on Windows
Fixed an issue which was locking and overwriting trace logs on Windows
Bug fixes in the Microsoft ODBC Driver 17.1 for SQL Server
Fixed 1-second delay when calling SQLFreeHandle with MARS enabled and connection attribute
"Encrypt=yes"
Fixed an error 22003 crash in SQLGetData when the size of the buffer passed in is smaller then the data
being retrieved (Windows)
Fixed truncated ADAL error messages
Fixed a rare bug on 32-bit Windows when converting a floating point number to an integer
Fixed an issue where inserting double into decimal field with Always Encrypted on would return data
truncation error
Fixed a warning on macOS installer
Fixed sending incorrect state to SQL Server during Session Recovery attempt when Connection Resiliency
and Connection Pooling both are enabled, causing session to be dropped by the Server
Bug fixes in the Microsoft ODBC Driver 17 for SQL Server
Fixed a bug where when using Kerberos authentication, bulk insert could fail with "access denied" error
Removed workaround for a unixODBC bug present in version below 2.3.1 (driver doubled the sizes of certain
buffers passed to unixODBC)
Fixed Connection Resiliency (reconnect) stopping to respond when using ColumnEncryption=enabled
Fixed DSN creation bug, where when using "Active Directory Interactive authentication" option Azure
Authentication window could become unresponsive (Windows)
Fixed a rare crash during ODBC shutdown when asynchronous execution is enabled (happened when
clearing connection handle)
Fixed an issue where SQL Driver caused high CPU consumption while executing long stored procedures
Fixed inability to retrieve data in an encrypted varbinary(max) column without conversion
Fixed a problem where after a null varchar(max) encrypted column is fetched using SQLGetData() on a static
cursor, the following column is also nulled even if it has data
Fixed an issue with fetching varbinary(max) field with Always Encrypted on
Fixed a problem of setlocale() not working with Always Encrypted
Fixed an issue with SQLDescribeParam() returning error when called on XML-type stored procedure
parameter with Always Encrypted on
Fixed escaped underscores not working in SQLTables
Fixed a bug where Hebrew data (varchar) is truncated when returned as wide chars on Linux
Fixed an issue with querying Shift-JIS encoded char/varchar from UTF-8 application
Fixed the bug where calling SQLGetInfo with SQL_DRIVER_NAME parameter returned Linux-style filename
on macOS
Fixed an issue where loading Windows-1252 character data, using input files larger than 32k bytes into
VARCHAR columns using the BCP utility would result in failures
C / C++ ODBC example application accesses an
SQL database
4/27/2022 • 10 minutes to read • Edit Online
Applies to: SQL Server (all supported versions) Azure SQL Database
This C / C++ sample application demonstrates how to use the ODBC APIs to connect to and access an SQL
database.
Between October 2013 and July 2019, this sample C++ ODBC application was downloaded 47,300 times. In July
2019, this application source was moved from Microsoft's Code Gallery to this webpage.
A. ReadMe.txt
Environment Where Tested
===============================
Visual Studio 2012
Win32
Windows Server 2012 R2
Windows 8.1
ODBC Sample
===============================
This sample demonstrates how to use ODBC APIs to Connect to and access database.
Files:
=============================================
odbcsql.sln
odbcsql.vcxproj
odbcsql.cpp
B. odbcsql.cpp code
/*******************************************************************************
/* ODBCSQL: a sample program that implements an ODBC command line interpreter.
/*
/* USAGE: ODBCSQL DSN=<dsn name> or
/* ODBCSQL FILEDSN=<file dsn> or
/* ODBCSQL DRIVER={driver name}
/*
/*
/* Copyright(c) Microsoft Corporation. This is a WDAC sample program and
/* is not suitable for use in production environments.
/*
/******************************************************************************/
/* Modules:
/* Main Main driver loop, executes queries.
/* DisplayResults Display the results of the query if any
/* AllocateBindings Bind column data
/* DisplayTitles Print column titles
/* SetConsole Set console display mode
/* HandleError Show ODBC error messages
/******************************************************************************/
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <stdlib.h>
#include <sal.h>
/*******************************************/
/* Macro to call ODBC functions and */
/* report an error on failure. */
/* Takes handle, handle type, and stmt */
/*******************************************/
/******************************************/
/* Forward references */
/******************************************/
/*****************************************/
/* Some constants */
/*****************************************/
// Allocate an environment
TRYODBC(hEnv,
SQL_HANDLE_ENV,
SQLSetEnvAttr(hEnv,
SQL_ATTR_ODBC_VERSION,
(SQLPOINTER)SQL_OV_ODBC3,
0));
// Allocate a connection
TRYODBC(hEnv,
SQL_HANDLE_ENV,
SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc));
if (argc > 1)
{
pwszConnStr = *++argv;
}
else
{
pwszConnStr = L"";
}
TRYODBC(hDbc,
SQL_HANDLE_DBC,
SQLDriverConnect(hDbc,
GetDesktopWindow(),
pwszConnStr,
SQL_NTS,
NULL,
0,
0,
NULL,
SQL_DRIVER_COMPLETE));
fwprintf(stderr, L"Connected!\n");
TRYODBC(hDbc,
SQL_HANDLE_DBC,
SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt));
if (!(*wszInput))
{
wprintf(L"SQL COMMAND>");
continue;
}
RetCode = SQLExecDirect(hStmt,wszInput, SQL_NTS);
switch(RetCode)
{
case SQL_SUCCESS_WITH_INFO:
{
HandleDiagnosticRecord(hStmt, SQL_HANDLE_STMT, RetCode);
// fall through
}
case SQL_SUCCESS:
{
// If this is a row-returning query, display
// results
TRYODBC(hStmt,
SQL_HANDLE_STMT,
SQLNumResultCols(hStmt,&sNumResults));
if (sNumResults > 0)
{
DisplayResults(hStmt,sNumResults);
}
else
{
SQLLEN cRowCount;
TRYODBC(hStmt,
SQL_HANDLE_STMT,
SQLRowCount(hStmt,&cRowCount));
if (cRowCount >= 0)
{
wprintf(L"%Id %s affected\n",
cRowCount,
cRowCount == 1 ? L"row" : L"rows");
}
}
break;
}
case SQL_ERROR:
{
HandleDiagnosticRecord(hStmt, SQL_HANDLE_STMT, RetCode);
break;
}
}
default:
fwprintf(stderr, L"Unexpected return code %hd!\n", RetCode);
}
TRYODBC(hStmt,
SQL_HANDLE_STMT,
SQLFreeStmt(hStmt, SQL_CLOSE));
wprintf(L"SQL COMMAND>");
}
Exit:
if (hStmt)
{
SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
}
if (hDbc)
{
SQLDisconnect(hDbc);
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
}
if (hEnv)
{
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
}
wprintf(L"\nDisconnected.");
return 0;
/************************************************************************
/* DisplayResults: display results of a select query
/*
/* Parameters:
/* hStmt ODBC statement handle
/* cCols Count of columns
/************************************************************************/
do {
// Fetch a row
// Fetch a row
while(!fEnterReceived)
{
wprintf(L" ");
SetConsole(cDisplaySize+2, TRUE);
wprintf(L" Press ENTER to continue, Q to quit (height:%hd)", gHeight);
SetConsole(cDisplaySize+2, FALSE);
nInputChar = _getch();
wprintf(L"\n");
if ((nInputChar == 'Q') || (nInputChar == 'q'))
{
goto Exit;
}
else if ('\r' == nInputChar)
{
fEnterReceived = true;
}
// else loop back to display prompt again
}
iCount = 1;
DisplayTitles(hStmt, cDisplaySize+1, pFirstBinding);
}
if (RetCode == SQL_NO_DATA_FOUND)
{
fNoData = true;
}
else
{
SetConsole(cDisplaySize+2, TRUE);
wprintf(L"%*.*s", cDisplaySize+2, cDisplaySize+2, L" ");
SetConsole(cDisplaySize+2, FALSE);
SetConsole(cDisplaySize+2, FALSE);
wprintf(L"\n");
Exit:
// Clean up the allocated buffers
while (pFirstBinding)
{
pThisBinding = pFirstBinding->sNext;
free(pFirstBinding->wszBuffer);
free(pFirstBinding);
pFirstBinding = pThisBinding;
}
}
/************************************************************************
/* AllocateBindings: Get column information and allocate bindings
/* for each column.
/*
/* Parameters:
/* hStmt Statement handle
/* cCols Number of columns in the result set
/* *lppBinding Binding pointer (returned)
/* lpDisplay Display size of one line
/************************************************************************/
*pDisplay = 0;
if (iCol == 1)
{
*ppBinding = pThisBinding;
}
else
{
pLastBinding->sNext = pThisBinding;
}
pLastBinding = pThisBinding;
TRYODBC(hStmt,
SQL_HANDLE_STMT,
SQLColAttribute(hStmt,
iCol,
SQL_DESC_DISPLAY_SIZE,
NULL,
0,
NULL,
&cchDisplay));
TRYODBC(hStmt,
SQL_HANDLE_STMT,
SQLColAttribute(hStmt,
iCol,
SQL_DESC_CONCISE_TYPE,
NULL,
0,
NULL,
&ssType));
pThisBinding->sNext = NULL;
if (!(pThisBinding->wszBuffer))
{
fwprintf(stderr, L"Out of memory!\n");
exit(-100);
}
TRYODBC(hStmt,
SQL_HANDLE_STMT,
SQLBindCol(hStmt,
iCol,
SQL_C_TCHAR,
(SQLPOINTER) pThisBinding->wszBuffer,
(cchDisplay + 1) * sizeof(WCHAR),
&pThisBinding->indPtr));
TRYODBC(hStmt,
SQL_HANDLE_STMT,
SQLColAttribute(hStmt,
iCol,
SQL_DESC_NAME,
NULL,
0,
&cchColumnNameLength,
NULL));
return;
Exit:
exit(-1);
return;
}
/************************************************************************
/* DisplayTitles: print the titles of all the columns and set the
/* shell window's width
/*
/* Parameters:
/* hStmt Statement handle
/* cDisplaySize Total display size
/* pBinding list of binding information
/************************************************************************/
SetConsole(cDisplaySize+2, TRUE);
wprintf(DISPLAY_FORMAT_C,
PIPE,
pBinding->cDisplaySize,
pBinding->cDisplaySize,
wszTitle);
}
Exit:
}
/************************************************************************
/* SetConsole: sets console display size and video mode
/*
/* Parameters
/* siDisplaySize Console display size
/* fInvert Invert video?
/************************************************************************/
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole != INVALID_HANDLE_VALUE)
{
if (GetConsoleScreenBufferInfo(hConsole, &csbInfo))
{
if (csbInfo.dwSize.X < (SHORT) dwDisplaySize)
{
csbInfo.dwSize.X = (SHORT) dwDisplaySize;
SetConsoleScreenBufferSize(hConsole, csbInfo.dwSize);
}
gHeight = csbInfo.dwSize.Y;
}
if (fInvert)
{
SetConsoleTextAttribute(hConsole, (WORD)(csbInfo.wAttributes | BACKGROUND_BLUE));
}
else
{
SetConsoleTextAttribute(hConsole, (WORD)(csbInfo.wAttributes & ~(BACKGROUND_BLUE)));
}
}
}
/************************************************************************
/* HandleDiagnosticRecord : display error/warning information
/*
/* Parameters:
/* hHandle ODBC handle
/* hType Type of handle (HANDLE_STMT, HANDLE_ENV, HANDLE_DBC)
/* RetCode Return code of failing command
/************************************************************************/
if (RetCode == SQL_INVALID_HANDLE)
{
fwprintf(stderr, L"Invalid handle!\n");
return;
}
while (SQLGetDiagRec(hType,
while (SQLGetDiagRec(hType,
hHandle,
++iRec,
wszState,
&iError,
wszMessage,
(SQLSMALLINT)(sizeof(wszMessage) / sizeof(WCHAR)),
(SQLSMALLINT *)NULL) == SQL_SUCCESS)
{
// Hide data truncated..
if (wcsncmp(wszState, L"01004", 5))
{
fwprintf(stderr, L"[%5.5s] %s (%d)\n", wszState, wszMessage, iError);
}
}
}
C. odbcsql.sln code
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29230.47
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odbcsql", "odbcsql.vcxproj", "{C5948D2C-C53D-4933-9AC5-
48066AD6A560}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C5948D2C-C53D-4933-9AC5-48066AD6A560}.Debug|x64.ActiveCfg = Debug|x64
{C5948D2C-C53D-4933-9AC5-48066AD6A560}.Debug|x64.Build.0 = Debug|x64
{C5948D2C-C53D-4933-9AC5-48066AD6A560}.Debug|x86.ActiveCfg = Debug|Win32
{C5948D2C-C53D-4933-9AC5-48066AD6A560}.Debug|x86.Build.0 = Debug|Win32
{C5948D2C-C53D-4933-9AC5-48066AD6A560}.Release|x64.ActiveCfg = Release|x64
{C5948D2C-C53D-4933-9AC5-48066AD6A560}.Release|x64.Build.0 = Release|x64
{C5948D2C-C53D-4933-9AC5-48066AD6A560}.Release|x86.ActiveCfg = Release|Win32
{C5948D2C-C53D-4933-9AC5-48066AD6A560}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {32894C74-C0AE-427F-969B-5F757A98EAFF}
EndGlobalSection
EndGlobal
D. odbcsql.vcxproj code
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCTargetsPath Condition="'$(VCTargetsPath11)' != '' and '$(VSVersion)' == '' and
'$(VisualStudioVersion)' == ''">$(VCTargetsPath11)</VCTargetsPath>
</PropertyGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{C5948D2C-C53D-4933-9AC5-48066AD6A560}</ProjectGuid>
<RootNamespace>odbcsql</RootNamespace>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>11.0.40930.0</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<PreprocessorDefinitions>_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="odbcsql.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
See also
Download ODBC Driver
Microsoft Open Database Connectivity (ODBC)
4/27/2022 • 2 minutes to read • Edit Online
The Microsoft Open Database Connectivity (ODBC) interface is a C programming language interface that makes
it possible for applications to access data from a variety of database management systems (DBMSs). ODBC is a
low-level, high-performance interface that is designed specifically for relational data stores.
The ODBC interface allows maximum interoperability-an application can access data in diverse DBMSs through
a single interface. Moreover, that application will be independent of any DBMS from which it accesses data.
Users of the application can add software components called drivers, which interface between an application
and a specific DBMS.
Documentation
ODBC Programmer's Reference
Documentation of ODBC interfaces and methods.
ODBC Data Source Administrator
The Microsoft ODBC Data Source Administrator manages database drivers and data sources.
Microsoft-Supplied ODBC Drivers
Documentation for the ODBC Desktop Database Drivers, the ODBC Driver for Oracle, and the Visual FoxPro®
ODBC Driver.
ODBC Test
Microsoft ODBC Test is an ODBC-enabled application that you can use to test ODBC drivers.
ODBC Glossary
Defines terms relevant to ODBC.
ODBCCONF.EXE
Describes the command-line utility for configuring drivers and data source names.
Support
Information about support options can be found on the Microsoft Help and Support Web site.
ODBC Programmer's Reference
4/27/2022 • 3 minutes to read • Edit Online
F O RM AT USED F O R
RETCODE SQLFetch(hdbc) The monospace font is used for sample command lines and
program code.
Recommended Reading
For more information about SQL, the following standards are available:
Database Language - SQL with Integrity Enhancement, ANSI, 1989 ANSI X3.135-1989.
Database Language - SQL: ANSI X3H2 and ISO/IEC JTC1/SC21/WG3 9075:1992 (SQL-92).
Open Group, Data Management: Structured Query Language (SQL), Version 2 (The Open Group, 1996).
In addition to standards and vendor-specific SQL guides, many books describe SQL, including:
Date, C. J., with Darwen, Hugh: A Guide to the SQL Standard (Addison-Wesley, 1993).
Emerson, Sandra L., Darnovsky, Marcy, and Bowman, Judith S.: The Practical SQL Handbook (Addison-
Wesley, 1989).
Groff, James R. and Weinberg, Paul N.: Using SQL (Osborne McGraw-Hill, 1990).
Gruber, Martin: Understanding SQL (Sybex, 1990).
Hursch, Jack L. and Carolyn J.: SQL, The Structured Query Language (TAB Books, 1988).
Melton, Jim, and Simon, Alan R.: Understanding the New SQL: A Complete Guide (Morgan Kaufmann
Publishers, 1993).
Pascal, Fabian: SQL and Relational Basics (M & T Books, 1990).
Trimble, J. Harvey, Jr. and Chappell, David: A Visual Introduction to SQL (Wiley, 1989).
Van der Lans, Rick F.: Introduction to SQL (Addison-Wesley, 1988).
Vang, Soren: SQL and Relational Databases (Microtrend Books, 1990).
Viescas, John: Quick Reference Guide to SQL (Microsoft Corp., 1989).
For additional information about transaction processing, see:
Gray, J. N. and Reuter, Andreas: Transaction Processing: Concepts and Techniques (Morgan Kaufmann
Publishers, 1993).
Hackathorn, Richard D.: Enterprise Database Connectivity (Wiley & Sons, 1993).
For more information about Call-Level Interfaces, the following standards are available:
Open Group, Data Management: SQL Call Level Interface (CLI), C451 (Open Group, 1995).
ISO/IEC 9075-3:1995, Call-Level Interface (SQL/CLI).
For additional information about ODBC, a number of books are available, including:
Geiger, Kyle: Inside ODBC (Microsoft Press®, 1995).
Gryphon, Robert, Charpentier, Luc, Oelschlager, Jon, Shoemaker, Andrew, Cross, Jim, and Lilley, Albert W.:
Using ODBC 2 (Que, 1994).
Johnston, Tom and Osborne, Mark: ODBC Developers Guide (Howard W. Sams & Company, 1994).
North, Ken: Windows Multi-DBMS Programming: Using C++, Visual Basic, ODBC, OLE 2 and Tools for
DBMS Projects (John Wiley & Sons, Inc., 1995).
Stegman, Michael O., Signore, Robert, and Creamer, John: The ODBC Solution, Open Database
Connectivity in Distributed Environments (McGraw-Hill, 1995).
Welch, Keith: Using ODBC 2 (Que, 1994).
Whiting, Bill: Teach Yourself ODBC in Twenty-One Days (Howard W. Sams & Company, 1994).
What's New in ODBC 3.8
4/27/2022 • 2 minutes to read • Edit Online
Windows 8 includes an updated version of ODBC 3.8. ODBC 3.8 in Windows 8 includes the following features:
Driver-Aware Connection Pooling
Asynchronous Execution (Notification Method)
Data Access Tracing (Windows 8)
PowerShell commands have been added to help you manage ODBC data sources, ODBC drivers, ODBC
Performance Counter, and data access tracing at the command line. For more information see Windows
Data Access Components PowerShell Commands.
Windows 7 includes an updated version of ODBC, ODBC 3.8. ODBC 3.8 includes the following features:
Executing connection operations asynchronously. For more information, see Asynchronous Execution
(Polling Method).
Streamed output parameters. For more information, see Retrieving Output Parameters Using
SQLGetData.
ODBC C data type extensibility. For more information, see C Data Types in ODBC.
Driver writers should read Upgrading a 3.5 Driver to a 3.8 Driver.
Asynchronous connection operations can be used by ODBC 3.x and ODBC 2.x applications with an ODBC 3.8
driver.
For more information, see Compatibility Matrix.
See Also
ODBC Programmer's Reference
Sample ODBC Program
4/27/2022 • 2 minutes to read • Edit Online
The ODBC code sample prompts you for an ODBC data source name. You will then be prompted to enter a
query and the sample will display the results of the query.
Introduction to ODBC
4/27/2022 • 2 minutes to read • Edit Online
This section provides a brief history of Structured Query Language and ODBC, and includes conceptual
information about the ODBC interface.
This section contains the following topics:
ODBC Overview
Introduction to SQL and ODBC
ODBC Architecture
ODBC 64-Bit Information
ODBC Overview
4/27/2022 • 2 minutes to read • Edit Online
Open Database Connectivity (ODBC) is a widely accepted application programming interface (API) for database
access. It is based on the Call-Level Interface (CLI) specifications from Open Group and ISO/IEC for database
APIs and uses Structured Query Language (SQL) as its database access language.
ODBC is designed for maximum interoperability - that is, the ability of a single application to access different
database management systems (DBMSs) with the same source code. Database applications call functions in the
ODBC interface, which are implemented in database-specific modules called drivers. The use of drivers isolates
applications from database-specific calls in the same way that printer drivers isolate word processing programs
from printer-specific commands. Because drivers are loaded at run time, a user only has to add a new driver to
access a new DBMS; it is not necessary to recompile or relink the application.
This section contains the following topics.
Why Was ODBC Created?
What Is ODBC?
ODBC and the Standard CLI
Why Was ODBC Created?
4/27/2022 • 2 minutes to read • Edit Online
Historically, companies used a single DBMS. All database access was done either through the front end of that
system or through applications written to work exclusively with that system. However, as the use of computers
grew and more computer hardware and software became available, companies started to acquire different
DBMSs. The reasons were many: People bought what was cheapest, what was fastest, what they already knew,
what was latest on the market, what worked best for a single application. Other reasons were reorganizations
and mergers, where departments that previously had a single DBMS now had several.
The issue grew even more complex with the advent of personal computers. These computers brought in a host
of tools for querying, analyzing, and displaying data, along with a number of inexpensive, easy-to-use
databases. From then on, a single corporation often had data scattered across a myriad of desktops, servers, and
minicomputers, stored in a variety of incompatible databases, and accessed by a vast number of different tools,
few of which could get at all of the data.
The final challenge came with the advent of client/server computing, which seeks to make the most efficient use
of computer resources. Inexpensive personal computers (the clients) sit on the desktop and provide both a
graphical front end to the data and a number of inexpensive tools, such as spreadsheets, charting programs, and
report builders. Minicomputers and mainframe computers (the servers) host the DBMSs, where they can use
their computing power and central location to provide quick, coordinated data access. How then was the front-
end software to be connected to the back-end databases?
A similar problem faced independent software vendors (ISVs). Vendors writing database software for
minicomputers and mainframes were usually forced to write one version of an application for each DBMS or
write DBMS-specific code for each DBMS they wanted to access. Vendors writing software for personal
computers had to write data access routines for each different DBMS with which they wanted to work. This often
meant a huge amount of resources were spent writing and maintaining data access routines rather than
applications, and applications were often sold not on their quality but on whether they could access data in a
given DBMS.
What both sets of developers needed was a way to access data in different DBMSs. The mainframe and
minicomputer group needed a way to merge data from different DBMSs in a single application, while the
personal computer group needed this ability as well as a way to write a single application that was independent
of any one DBMS. In short, both groups needed an interoperable way to access data; they needed open database
connectivity.
What Is ODBC?
4/27/2022 • 2 minutes to read • Edit Online
Many misconceptions about ODBC exist in the computing world. To the end user, it is an icon in the Microsoft®
Windows® Control Panel. To the application programmer, it is a library containing data access routines. To
many others, it is the answer to all database access problems ever imagined.
First and foremost, ODBC is a specification for a database API. This API is independent of any one DBMS or
operating system; although this manual uses C, the ODBC API is language-independent. The ODBC API is based
on the CLI specifications from Open Group and ISO/IEC. ODBC 3.x fully implements both of these specifications
- earlier versions of ODBC were based on preliminary versions of these specifications but did not fully
implement them - and adds features commonly needed by developers of screen-based database applications,
such as scrollable cursors.
The functions in the ODBC API are implemented by developers of DBMS-specific drivers. Applications call the
functions in these drivers to access data in a DBMS-independent manner. A Driver Manager manages
communication between applications and drivers.
Although Microsoft provides a driver manager for computers running Microsoft Windows® 95 and later, has
written several ODBC drivers, and calls ODBC functions from some of its applications, anyone can write ODBC
applications and drivers. In fact, the vast majority of ODBC applications and drivers available today are written
by companies other than Microsoft. Furthermore, ODBC drivers and applications exist on the Macintosh® and
a variety of UNIX platforms.
To help application and driver developers, Microsoft offers an ODBC Software Development Kit (SDK) for
computers running Windows 95 and later that provides the driver manager, installer DLL, test tools, and sample
applications. Microsoft has teamed with Visigenic Software to port these SDKs to the Macintosh and a variety of
UNIX platforms.
It is important to understand that ODBC is designed to expose database capabilities, not supplement them. Thus,
application writers should not expect that using ODBC will suddenly transform a simple database into a fully
featured relational database engine. Nor are driver writers expected to implement functionality not found in the
underlying database. An exception to this is that developers who write drivers that directly access file data (such
as data in an Xbase file) are required to write a database engine that supports at least minimal SQL functionality.
Another exception is that the ODBC component of the Windows SDK, formerly included in the Microsoft Data
Access Components (MDAC) SDK, provides a cursor library that simulates scrollable cursors for drivers that
implement a certain level of functionality.
Applications that use ODBC are responsible for any cross-database functionality. For example, ODBC is not a
heterogeneous join engine, nor is it a distributed transaction processor. However, because it is DBMS-
independent, it can be used to build such cross-database tools.
ODBC and the Standard CLI
4/27/2022 • 2 minutes to read • Edit Online
ODBC aligns with the following specifications and standards that deal with the Call-Level Interface (CLI). (The
ODBC features are a superset of each of these standards.)
The Open Group CAE Specification "Data Management: SQL Call-Level Interface (CLI)"
ISO/IEC 9075-3:1995 (E) Call-Level Interface (SQL/CLI)
As a result of this alignment, the following are true:
An application written to the Open Group and ISO CLI specifications will work with an ODBC 3.x driver or
a standards-compliant driver when it is compiled with the ODBC 3.x header files and linked with ODBC
3.x libraries, and when it gains access to the driver through the ODBC 3.x Driver Manager.
A driver written to the Open Group and ISO CLI specifications will work with an ODBC 3.x application or a
standards-compliant application when it is compiled with the ODBC 3.x header files and linked with
ODBC 3.x libraries, and when the application gains access to the driver through the ODBC 3.x Driver
Manager. (For more information, see Standards-Compliant Applications and Drivers.
The Core interface conformance level encompasses all the features in the ISO CLI and all the nonoptional
features in the Open Group CLI. Optional features of the Open Group CLI appear in higher interface
conformance levels. Because all ODBC 3.x drivers are required to support the features in the Core interface
conformance level, the following are true:
An ODBC 3.x driver will support all the features used by a standards-compliant application.
An ODBC 3.x application using only the features in ISO CLI and the nonoptional features of the Open
Group CLI will work with any standards-compliant driver.
In addition to the call-level interface specifications contained in the ISO/IEC and Open Group CLI standards,
ODBC implements the following features. (Some of these features existed in versions of ODBC prior to ODBC
3.x.)
Multirow fetches by a single function call
Binding to an array of parameters
Bookmark support including fetching by bookmark, variable-length bookmarks, and bulk update and
delete by bookmark operations on discontiguous rows
Row-wise binding
Binding offsets
Support for batches of SQL statements, either in a stored procedure or as a sequence of SQL statements
executed through SQLExecute or SQLExecDirect
Exact or approximate cursor row counts
Positioned update and delete operations and batched updates and deletes by function call (SQLSetPos )
Catalog functions that extract information from the information schema without the need for supporting
information schema views
Escape sequences for outer joins, scalar functions, datetime literals, interval literals, and stored
procedures
Code-page translation libraries
Reporting of a driver's ANSI-conformance level and SQL support
On-demand automatic population of implementation parameter descriptor
Enhanced diagnostics and row and parameter status arrays
Datetime, interval, numeric/decimal, and 64-bit integer application buffer types
Asynchronous execution
Stored procedure support, including escape sequences, output parameter binding mechanisms, and
catalog functions
Connection enhancements including support for connection attributes and attribute browsing
Introduction to SQL and ODBC
4/27/2022 • 2 minutes to read • Edit Online
ODBC was created to provide a uniform method of access to different, or heterogeneous, database management
systems (DBMSs). This introduction discusses concepts related to the development of ODBC.
This section contains the following topics.
Structured Query Language (SQL)
Database Access Architecture
Structured Query Language (SQL)
4/27/2022 • 2 minutes to read • Edit Online
A typical DBMS allows users to store, access, and modify data in an organized, efficient way. Originally, the users
of DBMSs were programmers. Accessing the stored data required writing a program in a programming
language such as COBOL. While these programs were often written to present a friendly interface to a
nontechnical user, access to the data itself required the services of a knowledgeable programmer. Casual access
to the data was not practical.
Users were not entirely happy with this situation. While they could access data, it often required convincing a
DBMS programmer to write special software. For example, if a sales department wanted to see the total sales in
the previous month by each of its salespeople and wanted this information ranked in order by each
salesperson's length of service in the company, it had two choices: Either a program already existed that allowed
the information to be accessed in exactly this way, or the department had to ask a programmer to write such a
program. In many cases, this was more work than it was worth, and it was always an expensive solution for one-
time, or ad hoc, inquiries. As more and more users wanted easy access, this problem grew larger and larger.
Allowing users to access data on an ad hoc basis required giving them a language in which to express their
requests. A single request to a database is defined as a query; such a language is called a query language. Many
query languages were developed for this purpose, but one of these became the most popular: Structured Query
Language, invented at IBM in the 1970s. It is more commonly known by its acronym, SQL, and is pronounced
both as "ess-cue-ell" and as "sequel". SQL became an ANSI standard in 1986 and an ISO standard in 1987; it is
used today in a great many database management systems.
Although SQL solved the ad hoc needs of users, the need for data access by computer programs did not go
away. In fact, most database access still was (and is) programmatic, in the form of regularly scheduled reports
and statistical analyses, data entry programs such as those used for order entry, and data manipulation
programs, such as those used to reconcile accounts and generate work orders.
These programs also use SQL, using one of the following three techniques:
Embedded SQL , in which SQL statements are embedded in a host language such as C or COBOL.
SQL modules , in which SQL statements are compiled on the DBMS and called from a host language.
Call-level interface , or CLI, which consists of functions called to pass SQL statements to the DBMS and
to retrieve results from the DBMS.
NOTE
It is a historical accident that the term call-level interface is used instead of application programming interface (API),
another term for the same thing. In the database world, API is used to describe SQL itself: SQL is the API to a DBMS.
Of these choices, embedded SQL is the most commonly used, although most major DBMSs support proprietary
CLIs.
This section contains the following topics.
Processing an SQL Statement
Embedded SQL
SQL Modules
Call-Level Interfaces
Processing a SQL Statement
4/27/2022 • 2 minutes to read • Edit Online
Before discussing the techniques for using SQL programmatically, it is necessary to discuss how an SQL
statement is processed. The steps involved are common to all three techniques, although each technique
performs them at different times. The following illustration shows the steps involved in processing an SQL
statement, which are discussed throughout the rest of this section.
The first technique for sending SQL statements to the DBMS is embedded SQL. Because SQL does not use
variables and control-of-flow statements, it is often used as a database sublanguage that can be added to a
program written in a conventional programming language, such as C or COBOL. This is a central idea of
embedded SQL: placing SQL statements in a program written in a host programming language. Briefly, the
following techniques are used to embed SQL statements in a host language:
Embedded SQL statements are processed by a special SQL precompiler. All SQL statements begin with an
introducer and end with a terminator, both of which flag the SQL statement for the precompiler. The
introducer and terminator vary with the host language. For example, the introducer is "EXEC SQL" in C
and "&SQL(" in MUMPS, and the terminator is a semicolon (;) in C and a right parenthesis in MUMPS.
Variables from the application program, called host variables, can be used in embedded SQL statements
wherever constants are allowed. These can be used on input to tailor an SQL statement to a particular
situation and on output to receive the results of a query.
Queries that return a single row of data are handled with a singleton SELECT statement; this statement
specifies both the query and the host variables in which to return data.
Queries that return multiple rows of data are handled with cursors. A cursor keeps track of the current
row within a result set. The DECLARE CURSOR statement defines the query, the OPEN statement begins
the query processing, the FETCH statement retrieves successive rows of data, and the CLOSE statement
ends query processing.
While a cursor is open, positioned update and positioned delete statements can be used to update or
delete the row currently selected by the cursor.
This section contains the following topics.
Embedded SQL Example
Compiling an Embedded SQL Program
Static SQL
Dynamic SQL
Embedded SQL Example
4/27/2022 • 2 minutes to read • Edit Online
The following code is a simple embedded SQL program, written in C. The program illustrates many, but not all,
of the embedded SQL techniques. The program prompts the user for an order number, retrieves the customer
number, salesperson, and status of the order, and displays the retrieved information on the screen.
int main() {
EXEC SQL INCLUDE SQLCA;
EXEC SQL BEGIN DECLARE SECTION;
int OrderID; /* Employee ID (from user) */
int CustID; /* Retrieved customer ID */
char SalesPerson[10] /* Retrieved salesperson name */
char Status[6] /* Retrieved order status */
EXEC SQL END DECLARE SECTION;
query_error:
printf ("SQL error: %ld\n", sqlca->sqlcode);
exit();
bad_number:
printf ("Invalid order number.\n");
exit();
}
Because an embedded SQL program contains a mix of SQL and host language statements, it cannot be
submitted directly to a compiler for the host language. Instead, it is compiled through a multistep process.
Although this process differs from product to product, the steps are roughly the same for all products.
This illustration shows the steps necessary to compile an embedded SQL program.
The embedded SQL shown in Embedded SQL Example is known as static SQL. It is called static SQL because the
SQL statements in the program are static; that is, they do not change each time the program is run. As described
in the previous section, these statements are compiled when the rest of the program is compiled.
Static SQL works well in many situations and can be used in any application for which the data access can be
determined at program design time. For example, an order-entry program always uses the same statement to
insert a new order, and an airline reservation system always uses the same statement to change the status of a
seat from available to reserved. Each of these statements would be generalized through the use of host
variables; different values can be inserted in a sales order, and different seats can be reserved. Because such
statements can be hard-coded in the program, such programs have the advantage that the statements need to
be parsed, validated, and optimized only once, at compile time. This results in relatively fast code.
Dynamic SQL performance in ODBC
4/27/2022 • 2 minutes to read • Edit Online
Although static SQL works well in many situations, there's a class of applications in which the data access cannot
be determined in advance. For example, suppose a spreadsheet allows a user to enter a query, which the
spreadsheet then sends to the DBMS to retrieve data. The contents of this query obviously cannot be known to
the programmer when the spreadsheet program is written.
Dynamic execution
To solve this problem, the spreadsheet uses a form of embedded SQL called dynamic SQL. Unlike static SQL
statements, which are hard-coded in the program, dynamic SQL statements can be built at run time and placed
in a string host variable. They're then sent to the DBMS for processing. Because the DBMS must generate an
access plan at run time for dynamic SQL statements, dynamic SQL is generally slower than static SQL. When a
program containing dynamic SQL statements is compiled, the dynamic SQL statements aren't stripped from the
program, as in static SQL. Instead, they're replaced by a function call that passes the statement to the DBMS;
static SQL statements in the same program are treated normally.
The simplest way to execute a dynamic SQL statement is with an EXECUTE IMMEDIATE statement. This statement
passes the SQL statement to the DBMS for compilation and execution.
One disadvantage of the EXECUTE IMMEDIATE statement is that the DBMS must go through each of the five
steps of processing an SQL statement each time the statement is executed. The overhead involved in this
process can be significant if many statements are executed dynamically, and it's wasteful if those statements are
similar.
Prepared execution
To address the above situation, dynamic SQL offers an optimized form of execution called prepared execution,
which uses the following steps:
1. The program constructs an SQL statement in a buffer, just as it does for the EXECUTE IMMEDIATE
statement. Instead of host variables, a question mark (?) can be substituted for a constant anywhere in the
statement text to indicate that a value for the constant will be supplied later. The question mark is called
as a parameter marker.
2. The program passes the SQL statement to the DBMS with a PREPARE statement, which requests that the
DBMS parse, validate, and optimize the statement and generate an execution plan for it. The program
then uses an EXECUTE statement (not an EXECUTE IMMEDIATE statement) to execute the PREPARE
statement at a later time. It passes parameter values for the statement through a special data structure
called the SQL Data Area or SQLDA.
3. The program can use the EXECUTE statement repeatedly, supplying different parameter values each time
the dynamic statement is executed.
Prepared execution is still not the same as static SQL. In static SQL, the first four steps of processing an SQL
statement take place at compile time. In prepared execution, these steps still take place at run time, but they're
only done once. Execution of the plan takes place only when EXECUTE is called. This behavior helps eliminate
some of the performance disadvantages inherent in the architecture of dynamic SQL.
See also
EXECUTE (Transact-SQL)
sp_executesql (Transact-SQL)
SQL Modules
4/27/2022 • 2 minutes to read • Edit Online
The second technique for sending SQL statements to the DBMS is through modules. Briefly, a module consists of
a group of procedures, which are called from the host programming language. Each procedure contains a single
SQL statement, and data is passed to and from the procedure through parameters.
A module can be thought of as an object library that is linked to the application code. However, exactly how the
procedures and the rest of the application are linked is implementation-dependent. For example, the procedures
could be compiled into object code and linked directly to the application code, they could be compiled and
stored on the DBMS and calls to access plan identifiers placed in the application code, or they could be
interpreted at run time.
The main advantage of modules is that they cleanly separate SQL statements from the programming language.
In theory, it should be possible to change one without changing the other and simply relink them.
Call-Level Interfaces
4/27/2022 • 2 minutes to read • Edit Online
The final technique for sending SQL statements to the DBMS is through a call-level interface (CLI). A call-level
interface provides a library of DBMS functions that can be called by the application program. Thus, instead of
trying to blend SQL with another programming language, a call-level interface is similar to the routine libraries
most programmers are accustomed to using, such as the string, I/O, or math libraries in C. Note that DBMSs that
support embedded SQL already have a call-level interface, the calls to which are generated by the precompiler.
However, these calls are undocumented and subject to change without notice.
Call-level interfaces are commonly used in client/server architectures, in which the application program (the
client) resides on one computer and the DBMS (the server) resides on a different computer. The application calls
CLI functions on the local system, and those calls are sent across the network to the DBMS for processing.
A call-level interface is similar to dynamic SQL, in that SQL statements are passed to the DBMS for processing at
run time, but it differs from embedded SQL as a whole in that there are no embedded SQL statements and no
precompiler is required.
Using a call-level interface typically involves the following steps:
1. The application calls a CLI function to connect to the DBMS.
2. The application builds an SQL statement and places it in a buffer. It then calls one or more CLI functions to
send the statement to the DBMS for preparation and execution.
3. If the statement is a SELECT statement, the application calls a CLI function to return the results in
application buffers. Typically, this function returns one row or one column of data at a time.
4. The application calls a CLI function to disconnect from the DBMS.
Database Access Architecture
4/27/2022 • 2 minutes to read • Edit Online
One of the questions in the development of ODBC was which part of the database access architecture to
standardize. The SQL programming interfaces described in the previous section - embedded SQL, SQL modules,
and CLIs - are only one part of this architecture. In fact, because ODBC was primarily intended to connect
personal computer-based applications to minicomputer and mainframe DBMSs, there were also a number of
network components, some of which could be standardized.
This section contains the following topics.
Network Database Access
Standard Database Access Architectures
The ODBC Solution
Network Database Access
4/27/2022 • 2 minutes to read • Edit Online
Accessing a database across a network requires a number of components, each of which is independent of, and
resides beneath, the programming interface. These components are shown in the following illustration.
In looking at the database access components described in the preceding section, it turns out that two of them -
programming interfaces and data stream protocols - are good candidates for standardization. The other two
components - IPC mechanism and network protocols - not only reside at too low a level but they are both highly
dependent on the network and operating system. There is also a third approach - gateways - that provides
possibilities for standardization.
This section contains the following topics.
Standard Programming Interface
Standard Data Stream Protocol
Standard Gateway
Standard Programming Interface
4/27/2022 • 2 minutes to read • Edit Online
The programming interface is perhaps the most obvious candidate for standardization. In fact, when ODBC was
being developed, ANSI and ISO already provided standards for embedded SQL and SQL modules. Although no
standards existed for a database CLI, the SQL Access Group - an industry consortium of database vendors - was
considering whether to create one; parts of ODBC later became the basis for their work.
One of the requirements for ODBC was that a single application binary had to work with multiple DBMSs. It is
for this reason that ODBC does not use embedded SQL or module languages. Although the language in
embedded SQL and module languages is standardized, each is tied to DBMS-specific precompilers. Thus,
applications must be recompiled for each DBMS and the resulting binaries work only with a single DBMS. While
this is acceptable for the low-volume applications found in the minicomputer and mainframe worlds, it is
unacceptable in the personal computer world. First, it is a logistical nightmare to deliver multiple versions of
high-volume, shrink-wrapped software to customers; second, personal computer applications often need to
access multiple DBMSs simultaneously.
On the other hand, a call-level interface can be implemented through libraries, or database drivers, that reside
on each local machine; a different driver is required for each DBMS. Because modern operating systems can
load such libraries (such as dynamic-link libraries on the Microsoft® Windows® operating system) at run
time, a single application can access data from different DBMSs without recompilation and can also access data
from multiple databases simultaneously. As new database drivers become available, users can just install these
on their computers without having to modify, recompile, or relink their database applications. Furthermore, a
call-level interface was a good candidate for ODBC because Windows - the platform for which ODBC was
originally developed - already made extensive use of such libraries.
Standard Data Stream Protocol
4/27/2022 • 2 minutes to read • Edit Online
A standard data stream protocol is one way to access data in heterogeneous DBMSs. In fact, a standard data
stream protocol already exists:
The ANSI/ISO Remote Database Access (RDA) standard: ISO/IEC 9579:2000. Although the ANSI/ISO system
shows promise, it is not widely implemented today.
Standard Gateway
4/27/2022 • 2 minutes to read • Edit Online
A gateway is a piece of software that causes one DBMS to look like another. That is, the gateway accepts the
programming interface, SQL grammar, and data stream protocol of a single DBMS and translates it to the
programming interface, SQL grammar, and data stream protocol of the hidden DBMS. For example, applications
written to use Microsoft® SQL Server™ can also access DB2 data through the Micro Decisionware DB2
Gateway; this product causes DB2 to look like SQL Server. When gateways are used, a different gateway must be
written for each target database.
Although gateways are limited by architectural differences among DBMSs, they are a good candidate for
standardization. However, if all DBMSs are to standardize on the programming interface, SQL grammar, and data
stream protocol of a single DBMS, whose DBMS is to be chosen as the standard? Certainly no commercial
DBMS vendor is likely to agree to standardize on a competitor's product. And if a standard programming
interface, SQL grammar, and data stream protocol are developed, no gateway is needed.
The ODBC Solution
4/27/2022 • 4 minutes to read • Edit Online
The question, then, is how does ODBC standardize database access? There are two architectural requirements:
Applications must be able to access multiple DBMSs using the same source code without recompiling or
relinking.
Applications must be able to access multiple DBMSs simultaneously.
And there is one more question, due to marketplace reality:
Which DBMS features should ODBC expose? Only features that are common to all DBMSs or any feature that
is available in any DBMS?
ODBC solves these problems in the following manner:
ODBC is a call-level interface. To solve the problem of how applications access multiple DBMSs using
the same source code, ODBC defines a standard CLI. This contains all of the functions in the CLI
specifications from Open Group and ISO/IEC and provides additional functions commonly required by
applications.
A different library, or driver, is required for each DBMS that supports ODBC. The driver implements the
functions in the ODBC API. To use a different driver, the application does not need to be recompiled or
relinked. Instead, the application simply loads the new driver and calls the functions in it. To access
multiple DBMSs simultaneously, the application loads multiple drivers. How drivers are supported is
operating system-specific. For example, on the Microsoft® Windows® operating system, drivers are
dynamic-link libraries (DLLs).
ODBC defines a standard SQL grammar. In addition to a standard call-level interface, ODBC defines
a standard SQL grammar. This grammar is based on the Open Group SQL CAE specification. Differences
between the two grammars are minor and primarily due to the differences between the SQL grammar
required by embedded SQL (Open Group) and a CLI (ODBC). There are also some extensions to the
grammar to expose commonly available language features not covered by the Open Group grammar.
Applications can submit statements using ODBC or DBMS-specific grammar. If a statement uses ODBC
grammar that is different from DBMS-specific grammar, the driver converts it before sending it to the
data source. However, such conversions are rare because most DBMSs already use standard SQL
grammar.
ODBC provides a Driver Manager to manage simultaneous access to multiple DBMSs.
Although the use of drivers solves the problem of accessing multiple DBMSs simultaneously, the code to
do this can be complex. Applications that are designed to work with all drivers cannot be statically linked
to any drivers. Instead, they must load drivers at run time and call the functions in them through a table
of function pointers. The situation becomes more complex if the application uses multiple drivers
simultaneously.
Rather than forcing each application to do this, ODBC provides a Driver Manager. The Driver Manager
implements all of the ODBC functions - mostly as pass-through calls to ODBC functions in drivers - and is
statically linked to the application or loaded by the application at run time. Thus, the application calls
ODBC functions by name in the Driver Manager, rather than by pointer in each driver.
When an application needs a particular driver, it first requests a connection handle with which to identify
the driver and then requests that the Driver Manager load the driver. The Driver Manager loads the driver
and stores the address of each function in the driver. To call an ODBC function in the driver, the
application calls that function in the Driver Manager and passes the connection handle for the driver. The
Driver Manager then calls the function by using the address it stored earlier.
ODBC exposes a significant number of DBMS features but does not require drivers to
suppor t all of them. If ODBC exposed only features that are common to all DBMSs, it would be of little
use; after all, the reason so many different DBMSs exist today is that they have different features. If ODBC
exposed every feature that is available in any DBMS, it would be impossible for drivers to implement.
Instead, ODBC exposes a significant number of features - more than are supported by most DBMSs - but
requires drivers to implement only a subset of those features. Drivers implement the remaining features
only if they are supported by the underlying DBMS or if they choose to emulate them. Thus, applications
can be written to exploit the features of a single DBMS as exposed by the driver for that DBMS, to use
only those features used by all DBMSs, or to check for support of a particular feature and react
accordingly.
So that an application can determine what features a driver and DBMS support, ODBC provides two
functions (SQLGetInfo and SQLGetFunctions ) that return general information about the driver and
DBMS capabilities and a list of functions the driver supports. ODBC also defines API and SQL grammar
conformance levels, which specify broad ranges of features supported by the driver. For more
information, see Conformance Levels.
It is important to remember that ODBC defines a common interface for all of the features it exposes.
Because of this, applications contain feature-specific code, not DBMS-specific code, and can use any
drivers that expose those features. One advantage of this is that applications do not need to be updated
when the features supported by a DBMS are enhanced; instead, when an updated driver is installed, the
application automatically uses the features because its code is feature-specific, not driver-specific or
DBMS-specific.
ODBC Architecture
4/27/2022 • 2 minutes to read • Edit Online
An application is a program that calls the ODBC API to access data. Although many types of applications are
possible, most fall into three categories, which are used as examples throughout this guide.
Generic Applications These are also referred to as shrink-wrapped applications or off-the-shelf
applications. Generic applications are designed to work with a variety of different DBMSs. Examples
include a spreadsheet or statistics package that uses ODBC to import data for further analysis and a word
processor that uses ODBC to get a mailing list from a database.
An important subcategory of generic applications is application development environments, such as
PowerBuilder or Microsoft® Visual Basic®. Although the applications constructed with these
environments will probably work only with a single DBMS, the environment itself needs to work with
multiple DBMSs.
What all generic applications have in common is that they are highly interoperable among DBMSs and
they need to use ODBC in a relatively generic manner. For more information about interoperability, see
Choosing a Level of Interoperability.
Ver tical Applications Vertical applications perform a single type of task, such as order entry or tracking
manufacturing data, and work with a database schema that is controlled by the developer of the
application. For a particular customer, the application works with a single DBMS. For example, a small
business might use the application with dBase, while a large business might use it with Oracle.
The application uses ODBC in such a manner that the application is not tied to any one DBMS, although it
might be tied to a limited number of DBMSs that provide similar functionality. Thus, the application
developer can sell the application independently from the DBMS. Vertical applications are interoperable
when they are developed but are sometimes modified to include noninteroperable code once the
customer has chosen a DBMS.
Custom Applications Custom applications are used to perform a specific task in a single company. For
example, an application in a large company might gather sales data from several divisions (each of which
uses a different DBMS) and create a single report. ODBC is used because it is a common interface and
saves programmers from having to learn multiple interfaces. Such applications are generally not
interoperable and are written to specific DBMSs and drivers.
A number of tasks are common to all applications, no matter how they use ODBC. Taken together, they largely
define the flow of any ODBC application. The tasks are:
Selecting a data source and connecting to it.
Submitting an SQL statement for execution.
Retrieving results (if any).
Processing errors.
Committing or rolling back the transaction enclosing the SQL statement.
Disconnecting from the data source.
Because most data access work is done with SQL, the primary task for which applications use ODBC is to submit
SQL statements and retrieve the results (if any) generated by those statements. Other tasks for which
applications use ODBC include determining and adjusting to driver capabilities and browsing the database
catalog.
The Driver Manager
4/27/2022 • 2 minutes to read • Edit Online
The Driver Manager is a library that manages communication between applications and drivers. For example, on
Microsoft® Windows® platforms, the Driver Manager is a dynamic-link library (DLL) that is written by
Microsoft and can be redistributed by users of the redistributable MDAC 2.8 SP1 SDK.
The Driver Manager exists mainly as a convenience to application writers and solves a number of problems
common to all applications. These include determining which driver to load based on a data source name,
loading and unloading drivers, and calling functions in drivers.
To see why the latter is a problem, consider what would happen if the application called functions in the driver
directly. Unless the application was linked directly to a particular driver, it would have to build a table of pointers
to the functions in that driver and call those functions by pointer. Using the same code for more than one driver
at a time would add yet another level of complexity. The application would first have to set a function pointer to
point to the correct function in the correct driver, and then call the function through that pointer.
The Driver Manager solves this problem by providing a single place to call each function. The application is
linked to the Driver Manager and calls ODBC functions in the Driver Manager, not the driver. The application
identifies the target driver and data source with a connection handle. When it loads a driver, the Driver Manager
builds a table of pointers to the functions in that driver. It uses the connection handle passed by the application
to find the address of the function in the target driver and calls that function by address.
For the most part, the Driver Manager just passes function calls from the application to the correct driver.
However, it also implements some functions (SQLDataSources , SQLDrivers , and SQLGetFunctions ) and
performs basic error checking. For example, the Driver Manager checks that handles are not null pointers, that
functions are called in the correct order, and that certain function arguments are valid. For a complete
description of the errors checked by the Driver Manager, see the reference section for each function and
Appendix B: ODBC State Transition Tables.
The final major role of the Driver Manager is loading and unloading drivers. The application loads and unloads
only the Driver Manager. When it wants to use a particular driver, it calls a connection function (SQLConnect ,
SQLDriverConnect , or SQLBrowseConnect ) in the Driver Manager and specifies the name of a particular
data source or driver, such as "Accounting" or "SQL Server." Using this name, the Driver Manager searches the
data source information for the driver's file name, such as Sqlsrvr.dll. It then loads the driver (assuming it is not
already loaded), stores the address of each function in the driver, and calls the connection function in the driver,
which then initializes itself and connects to the data source.
When the application is done using the driver, it calls SQLDisconnect in the Driver Manager. The Driver
Manager calls this function in the driver, which disconnects from the data source. However, the Driver Manager
keeps the driver in memory in case the application reconnects to it. It unloads the driver only when the
application frees the connection used by the driver or uses the connection for a different driver, and no other
connections use the driver. For a complete description of the Driver Manager's role in loading and unloading
drivers, see Driver Manager's Role in the Connection Process.
Drivers
4/27/2022 • 2 minutes to read • Edit Online
Drivers are libraries that implement the functions in the ODBC API. Each is specific to a particular DBMS; for
example, a driver for Oracle cannot directly access data in an Informix DBMS. Drivers expose the capabilities of
the underlying DBMSs; they are not required to implement capabilities not supported by the DBMS. For
example, if the underlying DBMS does not support outer joins, then neither should the driver. The only major
exception to this is that drivers for DBMSs that do not have stand-alone database engines, such as Xbase, must
implement a database engine that at least supports a minimal amount of SQL.
This section contains the following topics.
Driver Tasks
Driver Architecture
See Also
Microsoft-Supplied ODBC Drivers
Driver Tasks
4/27/2022 • 2 minutes to read • Edit Online
Driver architecture falls into two categories, depending on which software processes SQL statements:
File-Based Drivers The driver accesses the physical data directly. In this case, the driver acts as both
driver and data source; that is, it processes ODBC calls and SQL statements. For example, dBASE drivers
are file-based drivers because dBASE does not provide a stand-alone database engine the driver can use.
It is important to note that developers of file-based drivers must write their own database engines.
DBMS-Based Drivers The driver accesses the physical data through a separate database engine. In this
case the driver processes only ODBC calls; it passes SQL statements to the database engine for
processing. For example, Oracle drivers are DBMS-based drivers because Oracle has a stand-alone
database engine the driver uses. Where the database engine resides is immaterial. It can reside on the
same machine as the driver or a different machine on the network; it might even be accessed through a
gateway.
Driver architecture is generally interesting only to driver writers; that is, driver architecture generally makes no
difference to the application. However, the architecture can affect whether an application can use DBMS-specific
SQL. For example, Microsoft Access provides a stand-alone database engine. If a Microsoft Access driver is
DBMS-based - it accesses the data through this engine - the application can pass Microsoft Access-SQL
statements to the engine for processing.
However, if the driver is file-based - that is, it contains a proprietary engine that accesses the Microsoft®
Access .mdb file directly - any attempts to pass Microsoft Access-specific SQL statements to the engine are likely
to result in syntax errors. The reason is that the proprietary engine is likely to implement only ODBC SQL.
This section contains the following topics.
File-Based Drivers
DBMS-Based Drivers
Network Example
Other Driver Architectures
File-Based Drivers
4/27/2022 • 2 minutes to read • Edit Online
File-based drivers are used with data sources such as dBASE that do not provide a stand-alone database engine
for the driver to use. These drivers access the physical data directly and must implement a database engine to
process SQL statements. As a standard practice, the database engines in file-based drivers implement the subset
of ODBC SQL defined by the minimum SQL conformance level; for a list of the SQL statements in this
conformance level, see Appendix C: SQL Grammar.
In comparing file-based and DBMS-based drivers, file-based drivers are harder to write because of the database
engine component, less complicated to configure because there are no network pieces, and less powerful
because few people have the time to write database engines as powerful as those produced by database
companies.
The following illustration shows two different configurations of file-based drivers, one in which the data resides
locally and the other in which it resides on a network file server.
DBMS-Based Drivers
4/27/2022 • 2 minutes to read • Edit Online
DBMS-based drivers are used with data sources such as Oracle or SQL Server that provide a stand-alone
database engine for the driver to use. These drivers access the physical data through the stand-alone engine;
that is, they submit SQL statements to and retrieve results from the engine.
Because DBMS-based drivers use an existing database engine, they are usually easier to write than file-based
drivers. Although a DBMS-based driver can be easily implemented by translating ODBC calls to native API calls,
this results in a slower driver. A better way to implement a DBMS-based driver is to use the underlying data
stream protocol, which is usually what the native API does. For example, a SQL Server driver should use TDS
(the data stream protocol for SQL Server) rather than DB Library (the native API for SQL Server). An exception
to this rule is when ODBC is the native API. For example, Watcom SQL is a stand-alone engine that resides on
the same machine as the application and is loaded directly as the driver.
DBMS-based drivers act as the client in a client/server configuration where the data source acts as the server. In
most cases, the client (driver) and server (data source) reside on different machines, although both could reside
on the same machine running a multitasking operating system. A third possibility is a gateway, which sits
between the driver and data source. A gateway is a piece of software that causes one DBMS to look like another.
For example, applications written to use SQL Server can also access DB2 data through the Micro Decisionware
DB2 Gateway; this product causes DB2 to look like SQL Server.
The following illustration shows three different configurations of DBMS-based drivers. In the first configuration,
the driver and data source reside on the same machine. In the second, the driver and data source reside on
different machines. In the third, the driver and data source reside on different machines and a gateway sits
between them, residing on yet another machine.
Network Example
4/27/2022 • 2 minutes to read • Edit Online
This illustration shows how each of the preceding configurations could appear in a single network.
Other Driver Architectures
4/27/2022 • 3 minutes to read • Edit Online
Some ODBC drivers do not strictly conform to the architecture described previously. This might be because the
drivers perform duties other than those of a traditional ODBC driver, or are not drivers in the normal sense.
This architecture provides a common interface for the application to access data from different databases. It can
use a common way to retrieve metadata, such as information about special columns (row identifiers), and it can
call common catalog functions to retrieve data dictionary information. By calling the ODBC function
SQLStatistics , for instance, the application can retrieve information about the indexes on the tables to be
joined, even if the tables are on two separate databases. The query processor does not have to worry about how
the databases store metadata.
The application also has standard access to data types. ODBC defines common SQL data types that DBMS-
specific data types are mapped to. An application can call SQLGetTypeInfo to retrieve information about data
types on different databases.
When the application generates a heterogeneous join statement, the query processor in this architecture parses
the SQL statement and then generates separate SQL statements for each database to be joined. By using
metadata about each driver, the query processor can determine the most efficient, intelligent join. For example, if
the statement joins two tables on one database with one table on another database, the query processor can
join the two tables on the one database before joining the result with the table from the other database.
One advantage of this architecture is efficient software maintenance and configuration. Drivers need only be
updated in one place: on the server. By using system data sources, data sources can be defined on the server for
use by all clients. The data sources need not be defined on the client. Connection pooling can be used to
streamline the process by which clients connect to data sources.
The driver on the client is usually a very small driver that transfers the Driver Manager call to the server. Its
footprint can be significantly smaller than the fully functional ODBC drivers on the server. In this architecture,
client resources can be freed if the server has more computing power. In addition, the efficiency and security of
the entire system can be enhanced by installing backup servers and performing load balancing to optimize
server use.
Data Sources
4/27/2022 • 2 minutes to read • Edit Online
A data source is simply the source of the data. It can be a file, a particular database on a DBMS, or even a live
data feed. The data might be located on the same computer as the program, or on another computer
somewhere on a network. For example, a data source might be an Oracle DBMS running on an OS/2®
operating system, accessed by Novell® Netware; an IBM DB2 DBMS accessed through a gateway; a collection
of Xbase files in a server directory; or a local Microsoft® Access database file.
The purpose of a data source is to gather all of the technical information needed to access the data - the driver
name, network address, network software, and so on - into a single place and hide it from the user. The user
should be able to look at a list that includes Payroll, Inventory, and Personnel, choose Payroll from the list, and
have the application connect to the payroll data, all without knowing where the payroll data resides or how the
application got to it.
The term data source should not be confused with similar terms. In this manual, DBMS or database refers to a
database program or engine. A further distinction is made between desktop databases, designed to run on
personal computers and often lacking in full SQL and transaction support, and server databases, designed to
run in a client/server situation and characterized by a stand-alone database engine and rich SQL and transaction
support. Database also refers to a particular collection of data, such as a collection of Xbase files in a directory or
a database on SQL Server. It is generally equivalent to the term catalog, used elsewhere in this manual, or the
term qualifier in earlier versions of ODBC.
This section contains the following topics.
Types of Data Sources
Using Data Sources
Data Source Example
Types of Data Sources
4/27/2022 • 2 minutes to read • Edit Online
There are two types of data sources: machine data sources and file data sources. Although both contain similar
information about the source of the data, they differ in the way this information is stored. Because of these
differences, they are used in somewhat different manners.
This section contains the following topics.
Machine Data Sources
File Data Sources
Machine Data Sources
4/27/2022 • 2 minutes to read • Edit Online
Machine data sources are stored on the system with a user-defined name. Associated with the data source name
is all of the information the Driver Manager and driver need to connect to the data source. For an Xbase data
source, this might be the name of the Xbase driver, the full path of the directory containing the Xbase files, and
some options that tell the driver how to use those files, such as single-user mode or read-only. For an Oracle
data source, this might be the name of the Oracle driver, the server where the Oracle DBMS resides, the SQL*Net
connection string that identifies the SQL*Net driver to use, and the system ID of the database on the server.
File Data Sources
4/27/2022 • 2 minutes to read • Edit Online
File data sources are stored in a file and allow connection information to be used repeatedly by a single user or
shared among several users. When a file data source is used, the Driver Manager makes the connection to the
data source using the information in a .dsn file. This file can be manipulated like any other file. A file data source
does not have a data source name, as does a machine data source, and is not registered to any one user or
machine.
A file data source streamlines the connection process, because the .dsn file contains the connection string that
would otherwise have to be built for a call to the SQLDriverConnect function. Another advantage of the .dsn
file is that it can be copied to any machine, so identical data sources can be used by many machines as long as
they have the appropriate driver installed. A file data source can also be shared by applications. A shareable file
data source can be placed on a network and used simultaneously by multiple applications.
A .dsn file can also be unshareable. An unshareable .dsn file resides on a single machine and points to a machine
data source. Unshareable file data sources exist mainly to allow the easy conversion of machine data sources to
file data sources so that an application can be designed to work solely with file data sources. When the Driver
Manager is sent the information in an unshareable file data source, it connects as necessary to the machine data
source that the .dsn file points to.
For more information about file data sources, see Connecting Using File Data Sources, or the SQLDriverConnect
function description.
Using Data Sources
4/27/2022 • 2 minutes to read • Edit Online
Data sources usually are created by the end user or a technician with a program called the ODBC Administrator.
The ODBC Administrator prompts the user for the driver to use and then calls that driver. The driver displays a
dialog box that requests the information it needs to connect to the data source. After the user enters the
information, the driver stores it on the system.
Later, the application calls the Driver Manager and passes it the name of a machine data source or the path of a
file containing a file data source. When passed a machine data source name, the Driver Manager searches the
system to find the driver used by the data source. It then loads the driver and passes the data source name to it.
The driver uses the data source name to find the information it needs to connect to the data source. Finally, it
connects to the data source, typically prompting the user for a user ID and password, which generally are not
stored.
When passed a file data source, the Driver Manager opens the file and loads the specified driver. If the file also
contains a connection string, it passes this to the driver. Using the information in the connection string, the
driver connects to the data source. If no connection string was passed, the driver generally prompts the user for
the necessary information.
Data Source Example
4/27/2022 • 2 minutes to read • Edit Online
On computers running Microsoft® Windows NT® Server/Windows 2000 Server, Microsoft Windows NT
Workstation/Windows 2000 Professional, or Microsoft Windows® 95/98, machine data source information is
stored in the registry. Depending on which registry key the information is stored under, the data source is
known as a user data source or a system data source. User data sources are stored under the
HKEY_CURRENT_USER key and are available only to the current user. System data sources are stored under the
HKEY_LOCAL_MACHINE key and can be used by more than one user on one machine. They can also be used by
systemwide services, which can then gain access to the data source even if no user is logged on to the machine.
For more information about user and system data sources, see SQLManageDataSources.
Suppose a user has three user data sources: Personnel and Inventory, which use an Oracle DBMS; and Payroll,
which uses a Microsoft SQL Server DBMS. The registry values for data sources might be:
HKEY_CURRENT_USER
SOFTWARE
ODBC
Odbc.ini
ODBC Data Sources
Personnel : REG_SZ : Oracle
Inventory : REG_SZ : Oracle
Payroll : REG_SZ : SQL Server
and the registry values for the Payroll data source might be:
HKEY_CURRENT_USER
SOFTWARE
ODBC
Odbc.ini
Payroll
Driver : REG_SZ : C:\WINDOWS\SYSTEM\Sqlsrvr.dll
Description : REG_SZ : Payroll database
Server : REG_SZ : PYRLL1
FastConnectOption : REG_SZ : No UseProcForPrepare : REG_SZ
: Yes
OEMTOANSI : REG_SZ : No
LastUser : REG_SZ : smithjo
Database : REG_SZ : Payroll
Language : REG_SZ :
ODBC 64-Bit Information
4/27/2022 • 6 minutes to read • Edit Online
Beginning with Windows Server 2003, Microsoft operating systems have supported the 64-bit ODBC libraries.
The ODBC headers and libraries first shipped with MDAC 2.7 SDK contain changes to allow programmers to
easily write code for the new 64 bit platforms. By ensuring that your code uses the ODBC defined types listed
below, you can compile the same source code both for 64-bit and 32-bit platforms based on the _WIN64 or
WIN32 macros.
There are several points to keep in mind when programming for a 64-bit processor:
Although the size of a pointer has changed from 4 bytes to 8 bytes, integers and longs are still 4 byte
values. The types INT64 and UINT64 have been defined for 8 byte integers. The new ODBC types
SQLLEN and SQLULEN are defined in the ODBC header file as INT64 and UINT64 when _WIN64 has
been defined.
Several functions in ODBC are declared as taking a pointer parameter. In 32-bit ODBC, parameters
defined as pointers were frequently used to pass either an integer value or a pointer to a buffer
depending on the context of the call. This was, of course, possible due to the fact that pointers and
integers had the same size. In 64-bit Windows, this is not the case.
Some ODBC functions that were previously defined with SQLINTEGER and SQLUINTEGER parameters
have been changed where appropriate to use the new SQLLEN and SQLULEN typedefs. These changes
are listed in the next section, Function Declaration Changes.
Some of the descriptor fields that can be set through the various SQLSet and SQLGet functions have
been changed to accommodate 64-bit values while others are still 32-bit values. Make sure that you use
the appropriate sized variable when setting and retrieving these fields. Specifics of which descriptor fields
have changed are listed under Function Declaration Changes.
The definition of SQLSETPOSIROW has changed for both 32-bit and 64-bit compilers:
#ifdef _WIN64
typedef UINT64 SQLSETPOSIROW;
#else
#define SQLSETPOSIROW SQLUSMALLINT
#endif
The definitions of SQLLEN and SQLULEN have changed for 64-bit compilers:
#ifdef _WIN64
typedef INT64 SQLLEN;
typedef UINT64 SQLULEN;
#else
#define SQLLEN SQLINTEGER
#define SQLULEN SQLUINTEGER
#endif
Although SQL_C_BOOKMARK is deprecated in ODBC 3.0, for 64-bit compilers on 2.0 clients, this value has
changed:
#ifdef _WIN64
#define SQL_C_BOOKMARK SQL_C_UBIGINT
#else
#define SQL_C_BOOKMARK SQL_C_ULONG
#endif
See Also
Introduction to ODBC
Developing Applications
4/27/2022 • 2 minutes to read • Edit Online
This section contains information about developing applications that use the ODBC interface and drivers that
implement it.
This section contains the following topics.
ODBC Fundamentals
Basic ODBC Application Steps
Connecting to a Data Source or Driver
Catalog Functions
SQL Statements
Executing Statements
Retrieving Results (Basic)
Retrieving Results (Advanced)
Updating Data Overview
Descriptors
Transactions
Diagnostics
Interoperability
Programming Considerations
See Also
ODBC Programmer's Reference
ODBC Fundamentals
4/27/2022 • 2 minutes to read • Edit Online
Handles are opaque, 32-bit values that identify a particular item; in ODBC, this item can be an environment,
connection, statement, or descriptor. When the application calls SQL AllocHandle , the Driver Manager or driver
creates a new item of the specified type and returns its handle to the application. The application later uses the
handle to identify that item when calling ODBC functions. The Driver Manager and driver use the handle to
locate information about the item.
For example, the following code uses two statement handles (hstmtOrder and hstmtLine) to identify the
statements on which to create result sets of sales orders and sales order line numbers. It later uses these
handles to identify which result set to fetch data from.
// Bind the result sets for the Order table and the Lines table. Bind
// OrderID to the OrderID column in the Orders table. When each row is
// fetched, OrderID will contain the current order ID, which will then be
// passed as a parameter to the statement tofetch line number
// information. Code not shown.
// Fetch and display the sales order data. Code to check if rc equals
// SQL_ERROR or SQL_SUCCESS_WITH_INFO not shown.
while ((rc = SQLFetch(hstmtOrder)) != SQL_NO_DATA) {
// Display the sales order data. Code not shown.
// Create a result set of line numbers for the current sales order.
SQLExecute(hstmtLine);
// Fetch and display the sales order line number data. Code to check
// if rc equals SQL_ERROR or SQL_SUCCESS_WITH_INFO not shown.
while ((rc = SQLFetch(hstmtLine)) != SQL_NO_DATA) {
// Display the sales order line number data. Code not shown.
}
Handles are meaningful only to the ODBC component that created them; that is, only the Driver Manager can
interpret Driver Manager handles and only a driver can interpret its own handles.
For example, suppose the driver in the preceding example allocates a structure to store information about a
statement and returns the pointer to this structure as the statement handle. When the application calls
SQLPrepare , it passes an SQL statement and the handle of the statement used for sales order line numbers.
The driver sends the SQL statement to the data source, which prepares it and returns an access plan identifier.
The driver uses the handle to find the structure in which to store this identifier.
Later, when the application calls SQLExecute to generate the result set of line numbers for a particular sales
order, it passes the same handle. The driver uses the handle to retrieve the access plan identifier from the
structure. It sends the identifier to the data source to tell it which plan to execute.
ODBC has two levels of handles: Driver Manager handles and driver handles. The application uses Driver
Manager handles when calling ODBC functions because it calls those functions in the Driver Manager. The Driver
Manager uses this handle to find the corresponding driver handle and uses the driver handle when calling the
function in the driver. For an example of how driver and Driver Manager handles are used, see Driver Manager's
Role in the Connection Process.
That there are two levels of handles is an artifact of the ODBC architecture; in most cases, it is not relevant to
either the application or driver. Although there is usually no reason to do so, it is possible for the application to
determine the driver handles by calling SQLGetInfo .
This section contains the following topics.
Environment Handles
Connection Handles
Statement Handles
Descriptor Handles
State Transitions
Environment Handles
4/27/2022 • 2 minutes to read • Edit Online
An environment is a global context in which to access data; associated with an environment is any information
that is global in nature, such as:
The environment's state
The current environment-level diagnostics
The handles of connections currently allocated on the environment
The current settings of each environment attribute
Within a piece of code that implements ODBC (the Driver Manager or a driver), an environment handle
identifies a structure to contain this information.
Environment handles are not frequently used in ODBC applications. They are always used in calls to
SQLDataSources and SQLDrivers and sometimes used in calls to SQL AllocHandle , SQLEndTran ,
SQLFreeHandle , SQLGetDiagField , and SQLGetDiagRec .
Each piece of code that implements ODBC (the Driver Manager or a driver) contains one or more environment
handles. For example, the Driver Manager maintains a separate environment handle for each application that is
connected to it. Environment handles are allocated with SQL AllocHandle and freed with SQLFreeHandle .
Connection Handles
4/27/2022 • 2 minutes to read • Edit Online
A connection consists of a driver and a data source. A connection handle identifies each connection. The
connection handle defines not only which driver to use but which data source to use with that driver. Within a
segment of code that implements ODBC (the Driver Manager or a driver), the connection handle identifies a
structure that contains connection information, such as the following:
The state of the connection
The current connection-level diagnostics
The handles of statements and descriptors currently allocated on the connection
The current settings of each connection attribute
ODBC does not prevent multiple simultaneous connections, if the driver supports them. Therefore, in a
particular ODBC environment, multiple connection handles might point to a variety of drivers and data sources,
to the same driver and a variety of data sources, or even to multiple connections to the same driver and data
source. Some drivers limit the number of active connections they support; the
SQL_MAX_DRIVER_CONNECTIONS option in SQLGetInfo specifies how many active connections a particular
driver supports.
Connection handles are primarily used when connecting to the data source (SQLConnect ,
SQLDriverConnect , or SQLBrowseConnect ), disconnecting from the data source (SQLDisconnect ), getting
information about the driver and data source (SQLGetInfo ), retrieving diagnostics (SQLGetDiagField and
SQLGetDiagRec ), and performing transactions (SQLEndTran ). They are also used when setting and getting
connection attributes (SQLSetConnectAttr and SQLGetConnectAttr ) and when getting the native format of
an SQL statement (SQLNativeSql ).
Connection handles are allocated with SQL AllocHandle and freed with SQLFreeHandle .
Statement Handles
4/27/2022 • 2 minutes to read • Edit Online
A statement is most easily thought of as an SQL statement, such as SELECT * FROM Employee . However, a
statement is more than just an SQL statement - it consists of all of the information associated with that SQL
statement, such as any result sets created by the statement and parameters used in the execution of the
statement. A statement does not even need to have an application-defined SQL statement. For example, when a
catalog function such as SQLTables is executed on a statement, it executes a predefined SQL statement that
returns a list of table names.
Each statement is identified by a statement handle. A statement is associated with a single connection, and there
can be multiple statements on that connection. Some drivers limit the number of active statements they
support; the SQL_MAX_CONCURRENT_ACTIVITIES option in SQLGetInfo specifies how many active statements
a driver supports on a single connection. A statement is defined to be active if it has results pending, where
results are either a result set or the count of rows affected by an INSERT , UPDATE , or DELETE statement, or
data is being sent with multiple calls to SQLPutData .
Within a piece of code that implements ODBC (the Driver Manager or a driver), the statement handle identifies a
structure that contains statement information, such as:
The statement's state
The current statement-level diagnostics
The addresses of the application variables bound to the statement's parameters and result set columns
The current settings of each statement attribute
Statement handles are used in most ODBC functions. Notably, they are used in the functions to bind parameters
and result set columns (SQLBindParameter and SQLBindCol ), prepare and execute statements
(SQLPrepare , SQLExecute , and SQLExecDirect ), retrieve metadata (SQLColAttribute and
SQLDescribeCol ), fetch results (SQLFetch ), and retrieve diagnostics (SQLGetDiagField and
SQLGetDiagRec ). They are also used in catalog functions (SQLColumns , SQLTables , and so on) and a
number of other functions.
Statement handles are allocated with SQL AllocHandle and freed with SQLFreeHandle .
Descriptor Handles
4/27/2022 • 2 minutes to read • Edit Online
A descriptor is a collection of metadata that describes the parameters of an SQL statement or the columns of a
result set, as seen by the application or driver (also known as the implementation). Thus, a descriptor can fill any
of four roles:
Application Parameter Descriptor (APD). Contains information about the application buffers bound
to the parameters in an SQL statement, such as their addresses, lengths, and C data types.
Implementation Parameter Descriptor (IPD). Contains information about the parameters in an SQL
statement, such as their SQL data types, lengths, and nullability.
Application Row Descriptor (ARD). Contains information about the application buffers bound to the
columns in a result set, such as their addresses, lengths, and C data types.
Implementation Row Descriptor (IRD). Contains information about the columns in a result set, such
as their SQL data types, lengths, and nullability.
Four descriptors (one filling each role) are allocated automatically when a statement is allocated. These are
known as automatically allocated descriptors and are always associated with that statement. Applications can
also allocate descriptors with SQL AllocHandle . These are known as explicitly allocated descriptors. They are
allocated on a connection and can be associated with one or more statements on that connection to fulfill the
role of an APD or ARD on those statements.
Most operations in ODBC can be performed without explicit use of descriptors by the application. However,
descriptors provide a convenient shortcut for some operations. For example, suppose an application wants to
insert data from two different sets of buffers. To use the first set of buffers, it would repeatedly call
SQLBindParameter to bind them to the parameters in an INSERT statement and then execute the statement.
To use the second set of buffers, it would repeat this process. Alternatively, it could set up bindings to the first set
of buffers in one descriptor and to the second set of buffers in another descriptor. To switch between the sets of
bindings, the application would simply call SQLSetStmtAttr and associate the correct descriptor with the
statement as the APD.
For more information about descriptors, see Types of Descriptors.
State Transitions
4/27/2022 • 2 minutes to read • Edit Online
ODBC defines discrete states for each environment, each connection, and each statement. For example, the
environment has three possible states: Unallocated (in which no environment is allocated), Allocated (in which
an environment is allocated but no connections are allocated), and Connection (in which an environment and
one or more connections are allocated). Connections have seven possible states; statements have 13 possible
states.
A particular item, as identified by its handle, moves from one state to another when the application calls a
certain function or functions and passes the handle to that item. Such movement is called a state transition. For
example, allocating an environment handle with SQL AllocHandle moves the environment from Unallocated to
Allocated, and freeing that handle with SQLFreeHandle returns it from Allocated to Unallocated. ODBC defines
a limited number of legal state transitions, which is another way of saying that functions must be called in a
certain order.
Some functions, such as SQLGetConnectAttr , do not affect state at all. Other functions affect the state of a
single item. For example, SQLDisconnect moves a connection from a Connection state to an Allocated state.
Finally, some functions affect the state of more than one item. For example, allocating a connection handle with
SQL AllocHandle moves a connection from an Unallocated to an Allocated state and moves the environment
from an Allocated to a Connection state.
If an application calls a function out of order, the function returns a state transition error. For example, if an
environment is in a Connection state and the application calls SQLFreeHandle with that environment handle,
SQLFreeHandle returns SQLSTATE HY010 (Function sequence error), because it can be called only when the
environment is in an Allocated state. By defining this as an invalid state transition, ODBC prevents the
application from freeing the environment while there are active connections.
Some state transitions are inherent in the design of ODBC. For example, it is not possible to allocate a
connection handle without first allocating an environment handle, because the function that allocates a
connection handle requires an environment handle. Other state transitions are enforced by the Driver Manager
and the drivers. For example, SQLExecute executes a prepared statement. If the statement handle passed to it is
not in a Prepared state, SQLExecute returns SQLSTATE HY010 (Function sequence error).
From the application's point of view, state transitions are usually straightforward: Legal state transitions tend to
go hand-in-hand with the flow of a well-written application. State transitions are more complex for the Driver
Manager and the drivers because they must track the state of the environment, each connection, and each
statement. Most of this work is done by the Driver Manager; most of the work that must be done by drivers
occurs with statements with pending results.
Parts 1 and 2 of this manual ("Introduction to ODBC" and "Developing Applications and Drivers") tend not to
explicitly mention state transitions. Instead, they describe the order in which functions must be called. For
example, "Executing Statements" states that a statement must be prepared with SQLPrepare before it can be
executed with SQLExecute . For a complete description of states and state transitions, including which
transitions are checked by the Driver Manager and which must be checked by drivers, see Appendix B: ODBC
State Transition Tables.
Buffers
4/27/2022 • 2 minutes to read • Edit Online
A buffer is any piece of application memory used to pass data between the application and the driver. For
example, application buffers can be associated with, or bound to, result set columns with SQLBindCol . As each
row is fetched, the data is returned for each column in these buffers. Input buffers are used to pass data from
the application to the driver; output buffers are used to return data from the driver to the application.
NOTE
If an ODBC function returns SQL_ERROR, the contents of any output arguments to that function are undefined.
This discussion concerns itself primarily with buffers of indeterminate type. The addresses of these buffers
appear as arguments of type SQLPOINTER, such as the TargetValuePtr argument in SQLBindCol . However,
some of the items discussed here, such as the arguments used with buffers, also apply to arguments used to
pass strings to the driver, such as the TableName argument in SQLTables .
These buffers usually come in pairs. Data buffers are used to pass the data itself, while length/indicator buffers
are used to pass the length of the data in the data buffer or a special value such as SQL_NULL_DATA, which
indicates that the data is NULL. The length of the data in a data buffer is different from the length of the data
buffer itself. The following illustration shows the relationship between the data buffer and the length/indicator
buffer.
A length/indicator buffer is required whenever the data buffer contains variable-length data, such as character
or binary data. If the data buffer contains fixed-length data, such as an integer or date structure, a
length/indicator buffer is needed only to pass indicator values because the length of the data is already known.
If an application uses a length/indicator buffer with fixed-length data, the driver ignores any lengths passed in it.
The length of both the data buffer and the data it contains is measured in bytes, as opposed to characters. This
distinction is unimportant for programs that use ANSI strings because lengths in bytes and characters are the
same.
When the data buffer represents a driver-defined descriptor field, diagnostic field, or attribute, the application
should indicate to the Driver Manager the nature of the function argument that indicates the value for the field
or attribute. The application does this by setting the length argument in any function call that sets the field or
attribute to one of the following values. (The same is true for functions that retrieve the values of the field or
attribute, with the exception that the argument points to the values that for the setting function are in the
argument itself.)
If the function argument that indicates the value for the field or attribute is a pointer to a character string,
the length argument is the length of the string or SQL_NTS.
If the function argument that indicates the value for the field or attribute is a pointer to a binary buffer,
the application places the result of the SQL_LEN_BINARY_ATTR(length) macro in the length argument.
This places a negative value in the length argument.
If the function argument that indicates the value for the field or attribute is a pointer to a value other than
a character string or a binary string, the length argument should have the value SQL_IS_POINTER.
If the function argument that indicates the value for the field or attribute contains a fixed-length value, the
length argument is SQL_IS_INTEGER, SQL_IS_UINTEGER, SQL_IS_SMALLINT, or SQL_ISI_USMALLINT, as
appropriate.
This section contains the following topics.
Deferred Buffers
Allocating and Freeing Buffers
Using Data Buffers
Deferred Buffers
4/27/2022 • 2 minutes to read • Edit Online
A deferred buffer is one whose value is used at some time after it is specified in a function call. For example,
SQLBindParameter is used to associate, or bind, a data buffer with a parameter in an SQL statement. The
application specifies the number of the parameter and passes the address, byte length, and type of the buffer.
The driver saves this information but does not examine the contents of the buffer. Later, when the application
executes the statement, the driver retrieves the information and uses it to retrieve the parameter data and send
it to the data source. Therefore, the input of data in the buffer is deferred. Because deferred buffers are specified
in one function and used in another, it is an application programming error to free a deferred buffer while the
driver still expects it to exist; for more information, see Allocating and Freeing Buffers, later in this section.
Both input and output buffers can be deferred. The following table summarizes the uses of deferred buffers.
Note that deferred buffers bound to result set columns are specified with SQLBindCol , and deferred buffers
bound to SQL statement parameters are specified with SQLBindParameter .
All buffers are allocated and freed by the application. If a buffer is not deferred, it need only exist for the duration
of the call to a function. For example, SQLGetInfo returns the value associated with a particular option in the
buffer pointed to by the InfoValuePtr argument. This buffer can be freed immediately after the call to
SQLGetInfo , as shown in the following code example:
SQLSMALLINT InfoValueLen;
SQLCHAR * InfoValuePtr = malloc(50); // Allocate InfoValuePtr.
Because deferred buffers are specified in one function and used in another, it is an application programming
error to free a deferred buffer while the driver still expects it to exist. For example, the address of the *ValuePtr
buffer is passed to SQLBindCol for later use by SQLFetch . This buffer cannot be freed until the column is
unbound, such as with a call to SQLBindCol or SQLFreeStmt as shown in the following code example:
SQLRETURN rc;
SQLINTEGER ValueLenOrInd;
SQLHSTMT hstmt;
// Allocate ValuePtr
SQLCHAR * ValuePtr = malloc(50);
// Fetch each row of data and place the value for column 1 in *ValuePtr.
// Code to check if rc equals SQL_ERROR or SQL_SUCCESS_WITH_INFO
// not shown.
while ((rc = SQLFetch(hstmt)) != SQL_NO_DATA) {
// It is an error to free ValuePtr here.
}
Such an error is easily made by declaring the buffer locally in a function; the buffer is freed when the application
leaves the function. For example, the following code causes undefined and probably fatal behavior in the driver:
SQLRETURN rc;
SQLHSTMT hstmt;
BindAColumn(hstmt);
// Fetch each row of data and try to place the value for column 1 in
// *ValuePtr. Because ValuePtr has been freed, the behavior is undefined
// and probably fatal. Code to check if rc equals SQL_ERROR or
// SQL_SUCCESS_WITH_INFO not shown.
while ((rc = SQLFetch(hstmt)) != SQL_NO_DATA) {}
.
.
.
Data buffers are described by three pieces of information: their type, address, and byte length. Whenever a
function needs one of these pieces of information and does not already know it, it has an argument with which
the application passes it.
This section contains the following topics.
Data Buffer Type
Data Buffer Address
Data Buffer Length
Data Buffer Type
4/27/2022 • 2 minutes to read • Edit Online
The C data type of a buffer is specified by the application. With a single variable, this occurs when the application
allocates the variable. With generic memory - that is, memory pointed to by a pointer of type void - this occurs
when the application casts the memory to a particular type. The driver discovers this type in two ways:
Data buffer type argument. Buffers used to transfer parameter values and result set data, such as the
buffer bound with TargetValuePtr in SQLBindCol , usually have an associated type argument, such as the
TargetType argument in SQLBindCol . In this argument, the application passes the C type identifier that
corresponds to the type of the buffer. For example, in the following call to SQLBindCol , the value
SQL_C_TYPE_DATE tells the driver that the Date buffer is an SQL_DATE_STRUCT:
SQL_DATE_STRUCT Date;
SQLINTEGER DateInd;
SQLBindCol(hstmt, 1, SQL_C_TYPE_DATE, &Date, 0, &DateInd);
For more information about type identifiers, see the Data Types in ODBC section, later in this section.
Predefined type. Buffers used to send and retrieve options or attributes, such as the buffer pointed to
by the InfoValuePtr argument in SQLGetInfo , have a fixed type that depends on the option specified. The
driver assumes that the data buffer is of this type; it is the application's responsibility to allocate a buffer
of this type. For example, in the following call to SQLGetInfo , the driver assumes the buffer is a 32-bit
integer because this is what the SQL_STRING_FUNCTIONS option requires:
SQLUINTEGER StringFuncs;
SQLGetInfo(hdbc, SQL_STRING_FUNCTIONS, (SQLPOINTER) &StringFuncs, 0,
NULL);
The driver uses the C data type to interpret the data in the buffer.
Data Buffer Address
4/27/2022 • 2 minutes to read • Edit Online
The application passes the address of the data buffer to the driver in an argument, often named ValuePtr or a
similar name. For example, in the following call to SQLBindCol , the application specifies the address of the Date
variable:
SQL_DATE_STRUCT Date;
SQLINTEGER DateInd;
SQLBindCol(hstmt, 1, SQL_C_TYPE_DATE, &dsDate, 0, &DateInd);
As mentioned in the Allocating and Freeing Buffers section, the address of a deferred buffer must remain valid
until the buffer is unbound.
Unless it is specifically prohibited, the address of a data buffer can be a null pointer. For buffers used to send
data to the driver, this causes the driver to ignore the information normally contained in the buffer. For buffers
used to retrieve data from the driver, this causes the driver to not return a value. In both cases, the driver ignores
the corresponding data buffer length argument.
Data Buffer Length
4/27/2022 • 2 minutes to read • Edit Online
The application passes the byte length of the data buffer to the driver in an argument, named BufferLength or a
similar name. For example, in the following call to SQLBindCol , the application specifies the length of the
ValuePtr buffer (sizeof( ValuePtr ) ):
SQLCHAR ValuePtr[50];
SQLINTEGER ValueLenOrInd;
SQLBindCol(hstmt, 1, SQL_C_CHAR, ValuePtr, sizeof(ValuePtr), &ValueLenOrInd);
A driver will always return the number of bytes, not the number of characters, in the buffer length argument of
any function that has an output string argument.
Data buffer lengths are required only for output buffers; the driver uses them to avoid writing past the end of
the buffer. However, the driver checks the data buffer length only when the buffer contains variable-length data,
such as character or binary data. If the buffer contains fixed-length data, such as an integer or date structure, the
driver ignores the data buffer length and assumes the buffer is large enough to hold the data; that is, it never
truncates fixed-length data. It is therefore important for the application to allocate a large enough buffer for
fixed-length data.
When a truncation of non-data output strings occurs (such as the cursor name returned for
SQLGetCursorName ), the returned length in the buffer length argument is the maximum character length
possible.
Data buffer lengths are not required for input buffers because the driver does not write to these buffers.
This section contains the following topics.
Using Length/Indicator Values
Data Length, Buffer Length, and Truncation
Character Data and C Strings
Using Length and Indicator Values
4/27/2022 • 3 minutes to read • Edit Online
The length/indicator buffer is used to pass the byte length of the data in the data buffer or a special indicator
such as SQL_NULL_DATA, which indicates that the data is NULL. Depending on the function in which it is used, a
length/indicator buffer is defined to be an SQLINTEGER or an SQLSMALLINT. Therefore, a single argument is
needed to describe it. If the data buffer is a nondeferred input buffer, this argument contains the byte length of
the data itself or an indicator value. It is often named StrLen_or_Ind or a similar name. For example, the
following code calls SQLPutData to pass a buffer full of data; the byte length (ValueLen) is passed directly
because the data buffer (ValuePtr) is an input buffer.
SQLCHAR ValuePtr[50];
SQLINTEGER ValueLen;
If the data buffer is a deferred input buffer, a nondeferred output buffer, or an output buffer, the argument
contains the address of the length/indicator buffer. It is often named StrLen_or_IndPtr or a similar name. For
example, the following code calls SQLGetData to retrieve a buffer full of data; the byte length is returned to the
application in the length/indicator buffer (ValueLenOrInd), whose address is passed to SQLGetData because
the corresponding data buffer (ValuePtr) is a nondeferred output buffer.
SQLCHAR ValuePtr[50];
SQLINTEGER ValueLenOrInd;
SQLGetData(hstmt, 1, SQL_C_CHAR, ValuePtr, sizeof(ValuePtr), &ValueLenOrInd);
Unless it is specifically prohibited, a length/indicator buffer argument can be 0 (if nondeferred input) or a null
pointer (if output or deferred input). For input buffers, this causes the driver to ignore the byte length of the
data. This returns an error when passing variable-length data but is common when passing non-null, fixed-
length data, because neither a length nor an indicator value is needed. For output buffers, this causes the driver
to not return the byte length of the data or an indicator value. This is an error if the data returned by the driver is
NULL but is common when retrieving fixed-length, non-nullable data, because neither a length nor an indicator
value is needed.
As when the address of a deferred data buffer is passed to the driver, the address of a deferred length/indicator
buffer must remain valid until the buffer is unbound.
The following lengths are valid as length/indicator values:
n, where n > 0.
0.
SQL_NTS. A string sent to the driver in the corresponding data buffer is null-terminated; this is a
convenient way for C programmers to pass strings without having to calculate their byte length. This
value is legal only when the application sends data to the driver. When the driver returns data to the
application, it always returns the actual byte length of the data.
The following values are valid as length/indicator values. SQL_NULL_DATA is stored in the
SQL_DESC_INDICATOR_PTR descriptor field; all other values are stored in the SQL_DESC_OCTET_LENGTH_PTR
descriptor field.
SQL_NULL_DATA. The data is a NULL data value, and the value in the corresponding data buffer is
ignored. This value is legal only for SQL data sent to or retrieved from the driver.
SQL_DATA_AT_EXEC. The data buffer does not contain any data. Instead, the data will be sent with
SQLPutData when the statement is executed or when SQLBulkOperations or SQLSetPos is called.
This value is legal only for SQL data sent to the driver. For more information, see SQLBindParameter,
SQLBulkOperations, and SQLSetPos.
Result of the SQL_LEN_DATA_AT_EXEC(length) macro. This value is similar to SQL_DATA_AT_EXEC. For
more information, see Sending Long Data.
SQL_NO_TOTAL. The driver cannot determine the number of bytes of long data still available to return in
an output buffer. This value is legal only for SQL data retrieved from the driver.
SQL_DEFAULT_PARAM. A procedure is to use the default value of an input parameter in a procedure
instead of the value in the corresponding data buffer.
SQL_COLUMN_IGNORE. SQLBulkOperations or SQLSetPos is to ignore the value in the data buffer.
When updating a row of data by a call to SQLBulkOperations or SQLSetPos, the column value is not
changed. When inserting a new row of data by a call to SQLBulkOperations , the column value is set to
its default or, if the column does not have a default, to NULL.
Data Length, Buffer Length, and Truncation
4/27/2022 • 2 minutes to read • Edit Online
The data length is the byte length of the data as it would be stored in the application's data buffer, not as it is
stored in the data source. This distinction is important because the data is often stored in different types in the
data buffer than in the data source. So for data being sent to the data source, this is the byte length of the data
before conversion to the data source's type. For data being retrieved from the data source, this is the byte length
of the data after conversion to the data buffer's type and before any truncation is done.
For fixed-length data, such as an integer or a date structure, the byte length of the data is always the size of the
data type. In general, applications allocate a data buffer that is the size of the data type. If the application
allocates a smaller buffer, the consequences are undefined because the driver assumes the data buffer is the size
of the data type and does not truncate the data to fit into a smaller buffer. If the application allocates a larger
buffer, the extra space is never used.
For variable-length data, such as character or binary data, it is important to recognize that the byte length of the
data is separate from and often different than the byte length of the buffer. The relation of these two lengths is
described in the Buffers section. If the byte length of the data is greater than the byte length of the buffer, the
driver truncates fetched data to the byte length of the buffer and returns SQL_SUCCESS_WITH_INFO with
SQLSTATE 01004 (Data truncated). However, the returned byte length is the length of the untruncated data.
For example, suppose an application allocates 50 bytes for a binary data buffer. If the driver has 10 bytes of
binary data to return, it returns those 10 bytes in the buffer. The byte length of the data is 10, and the byte
length of the buffer is 50. If the driver has 60 bytes of binary data to return, it truncates the data to 50 bytes,
returns those bytes in the buffer, and returns SQL_SUCCESS_WITH_INFO. The byte length of the data is 60 (the
length before truncation), and the byte length of the buffer is still 50.
A diagnostic record is created for each column that is truncated. Because it takes time for the driver to create
these records and for the application to process them, truncation can degrade performance. Usually, an
application can avoid this problem by allocating large enough buffers, although this might not be possible when
working with long data. When data truncation occurs, the application can sometimes allocate a larger buffer and
refetch the data; this is not true in all cases. If truncation occurs while getting data with calls to SQLGetData , the
application need not call SQLGetData for data that has already been returned; for more information, see
Getting Long Data.
Character Data and C Strings
4/27/2022 • 2 minutes to read • Edit Online
Input parameters that refer to variable-length character data (such as column names, dynamic parameters, and
string attribute values) have an associated length parameter. If the application terminates strings with the null
character, as is typical in C, it provides as an argument either the length in bytes of the string (not including the
null-terminator) or SQL_NTS (Null-Terminated String). A non-negative length argument specifies the actual
length of the associated string. The length argument may be 0 to specify a zero-length string, which is distinct
from a NULL value. The negative value SQL_NTS directs the driver to determine the length of the string by
locating the null-termination character.
When character data is returned from the driver to the application, the driver must always null-terminate it. This
gives the application the choice of whether to handle the data as a string or a character array. If the application
buffer is not large enough to return all of the character data, the driver truncates it to the byte length of the
buffer less the number of bytes required by the null-termination character, null-terminates the truncated data,
and stores it in the buffer. Therefore, applications must always allocate extra space for the null-termination
character in buffers used to retrieve character data. For example, a 51-byte buffer is needed to retrieve 50
characters of data.
Special care must be taken by both the application and the driver when sending or retrieving long character
data in parts with SQLPutData or SQLGetData . If the data is passed as a series of null-terminated strings, the
null-termination characters on these strings must be stripped before the data can be reassembled.
A number of ODBC programmers have confused character data and C strings. That this has occurred is an
artifact of using the C language when defining ODBC functions. If an ODBC driver or application uses another
language - remember that ODBC is language-independent - this confusion is less likely to arise.
When C strings are used to hold character data, the null-termination character is not considered to be part of
the data and is not counted as part of its byte length. For example, the character data "ABC" can be held as the C
string "ABC\0" or the character array {'A', 'B', 'C'}. The byte length of the data is 3, whether or not it is treated as
a string or a character array.
Although applications and drivers commonly use C strings (null-terminated arrays of characters) to hold
character data, there is no requirement to do this. In C, character data can also be treated as an array of
characters (without null-termination) and its byte length passed separately in the length/indicator buffer.
Because character data can be held in a non-null-terminated array and its byte length passed separately, it is
possible to embed null characters in character data. However, the behavior of ODBC functions in this case is
undefined and it is driver-specific whether a driver handles this correctly. Thus, interoperable applications should
always handle character data that can contain embedded null characters as binary data.
Data Types in ODBC
4/27/2022 • 2 minutes to read • Edit Online
ODBC uses two sets of data types: SQL data types and C data types. SQL data types are used in the data source,
and C data types are used in C code in the application.
This section contains the following topic.
Type Identifiers
SQL Data Types in ODBC
C Data Types in ODBC
Data Type Conversions
Type Identifiers
4/27/2022 • 2 minutes to read • Edit Online
To describe SQL and C data types, ODBC defines two sets of type identifiers. A type identifier describes the type
of an SQL column or a C buffer. It is a #define value and is generally passed as a function argument or returned
in metadata.
For example, the following call to SQLBindParameter binds a variable of type SQL_DATE_STRUCT to a date
parameter in an SQL statement. The C type identifier SQL_C_TYPE_DATE specifies the type of the Date variable,
and the SQL type identifier SQL_TYPE_DATE specifies the type of the dynamic parameter.
SQL_DATE_STRUCT Date;
SQLINTEGER DateInd = 0;
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_TYPE_DATE, SQL_TYPE_DATE, 0, 0,
&Date, 0, &DateInd);
SQL Data Types in ODBC
4/27/2022 • 2 minutes to read • Edit Online
SQL data types are the types in which data is stored in the data source.
This section contains the following topics.
SQL Type Identifiers
Retrieving Data Type Information with SQLGetTypeInfo
SQL Type Identifiers
4/27/2022 • 2 minutes to read • Edit Online
Each data source defines its own SQL data types. ODBC defines type identifiers and describes the general
characteristics of the SQL data types that might be mapped to each type identifier. It is driver-specific how each
data type in the underlying data source is mapped to an SQL type identifier of ODBC.
For example, SQL_CHAR is the type identifier for a character column with a fixed length, typically between 1 and
254 characters. These characteristics correspond to the CHAR data type found in many SQL data sources. Thus,
when an application discovers that the type identifier for a column is SQL_CHAR, it can assume it is probably
dealing with a CHAR column. However, it should still check the byte length of the column before assuming it is
between 1 and 254 characters; the driver for a non-SQL data source, for example, might map a fixed-length
character column of 500 characters to SQL_CHAR or SQL_LONGVARCHAR, because neither is an exact match.
ODBC defines a wide variety of SQL type identifiers. However, the driver is not required to use all of these
identifiers. Instead, it uses only those identifiers it needs to expose the SQL data types supported by the
underlying data source. If the underlying data source supports SQL data types to which no type identifier
corresponds, the driver can define additional type identifiers. For more information, see Driver-Specific Data
Types, Descriptor Types, Information Types, Diagnostic Types, and Attributes.
For a complete description of SQL type identifiers, see C Data Types in Appendix D: Data Types.
Retrieving Data Type Information with
SQLGetTypeInfo
4/27/2022 • 2 minutes to read • Edit Online
Because the mappings from underlying SQL data types to ODBC type identifiers are approximate, ODBC
provides a function (SQLGetTypeInfo ) through which a driver can completely describe each SQL data type in
the data source. This function returns a result set, each row of which describes the characteristics of a single data
type, such as name, type identifier, precision, scale, and nullability.
This information generally is used by generic applications that allow the user to create and alter tables. Such
applications call SQLGetTypeInfo to retrieve the data type information and then present some or all of it to the
user. Such applications need to be aware of two things:
More than one SQL data type can map to a single type identifier, which can make it difficult to determine
which data type to use. To solve this, the result set is ordered first by type identifier and second by
closeness to the type identifier's definition. In addition, data source-defined data types take precedence
over user-defined data types. For example, suppose that a data source defines the INTEGER and
COUNTER data types to be the same except that COUNTER is auto-incrementing. Suppose also that the
user-defined type WHOLENUM is a synonym of INTEGER. Each of these types maps to SQL_INTEGER. In
the SQLGetTypeInfo result set, INTEGER appears first, followed by WHOLENUM and then COUNTER.
WHOLENUM appears after INTEGER because it is user-defined, but before COUNTER because it more
closely matches the definition of the SQL_INTEGER type identifier.
ODBC does not define data type names for use in CREATE TABLE and ALTER TABLE statements. Instead,
the application should use the name returned in the TYPE_NAME column of the result set returned by
SQLGetTypeInfo . The reason for this is that although most of SQL does not vary much across DBMSs,
data type names vary tremendously. Rather than forcing drivers to parse SQL statements and replace
standard data type names with DBMS-specific data type names, ODBC requires applications to use the
DBMS-specific names in the first place.
Note that SQLGetTypeInfo does not necessarily describe all of the data types an application can encounter. In
particular, result sets might contain data types not directly supported by the data source. For example, the data
types of the columns in result sets returned by catalog functions are defined by ODBC and these data types
might not be supported by the data source. To determine the characteristics of the data types in a result set, an
application calls SQLColAttribute .
C Data Types in ODBC
4/27/2022 • 2 minutes to read • Edit Online
ODBC defines the C data types that are used by application variables and their corresponding type identifiers.
These are used by the buffers that are bound to result set columns and statement parameters. For example,
suppose an application wants to retrieve data from a result set column in character format. It declares a variable
with the SQLCHAR * data type and binds this variable to the result set column with a type identifier of
SQL_C_CHAR. For a complete list of C data types and type identifiers, see Appendix D: Data Types.
ODBC also defines a default mapping from each SQL data type to a C data type. For example, a 2-byte integer in
the data source is mapped to a 2-byte integer in the application. To use the default mapping, an application
specifies the SQL_C_DEFAULT type identifier. However, use of this identifier is discouraged for interoperability
reasons.
All integer C data types defined in ODBC 1.x were signed. Unsigned C data types and their corresponding type
identifiers were added in ODBC 2.0. Because of this, applications and drivers need to be particularly careful
when dealing with 1.x versions.
NOTE
Driver-specific C data types should be described in the driver documentation.
To specify an ODBC compliance level of 3.8, an application calls SQLSetEnvAttr with the
SQL_ATTR_ODBC_VERSION attribute set to SQL_OV_ODBC3_80 . To determine the version of the driver, an
application calls SQLGetInfo with SQL_DRIVER_ODBC_VER.
For more information about ODBC 3.8, see What's New in ODBC 3.8.
See Also
C Data Types
Data Type Conversions
4/27/2022 • 2 minutes to read • Edit Online
Data can be converted from one type to another at one of four times: when data is transferred from one
application variable to another (C to C), when data in an application variable is sent to a statement parameter (C
to SQL), when data in a result set column is returned in an application variable (SQL to C), and when data is
transferred from one data source column to another (SQL to SQL).
Any conversion that occurs when data is transferred from one application variable to another is outside the
scope of this document.
When an application binds a variable to a result set column or statement parameter, the application implicitly
specifies a data type conversion in its choice of the data type of the application variable. For example, suppose a
column contains integer data. If the application binds an integer variable to the column, it specifies that no
conversion be done; if the application binds a character variable to the column, it specifies that the data be
converted from integer to character.
ODBC defines how data is converted between each SQL and C data type. Basically, ODBC supports all
reasonable conversions, such as character to integer and integer to float, and does not support ill-defined
conversions, such as float to date. Drivers are required to support all conversions for each SQL data type they
support. For a complete list of conversions between SQL and C data types, see Converting Data from SQL to C
Data Types and Converting Data from C to SQL Data Types in Appendix D: Data Types.
ODBC also defines a scalar function for converting data from one SQL data type to another. The CONVERT
scalar function is mapped by the driver to the underlying scalar function or functions defined to perform
conversions in the data source. Because this function is mapped to DBMS-specific functions, ODBC does not
define how these conversions work or what conversions must be supported. An application discovers what
conversions are supported by a particular driver and data source through the SQL_CONVERT options in
SQLGetInfo . For more information about the CONVERT scalar function, see Escape Sequences in ODBC and
Explicit Data Type Conversion Function.
Conformance Levels
4/27/2022 • 2 minutes to read • Edit Online
ODBC drivers give the application access to diverse data sources. Each driver lets the application determine at
run time what ODBC capabilities and what SQL grammar the driver and each data source supports. This is not a
requirement of applications designed to work with a single driver or a small, known set of drivers, because these
applications can simply be written to the capabilities of that driver or drivers. To help applications discover driver
and data source capabilities, two areas of conformance are available: the ODBC interface and SQL grammar.
This section contains the following topics.
Interface Conformance Levels
SQL Conformance Levels
Interface Conformance Levels
4/27/2022 • 2 minutes to read • Edit Online
The purpose of leveling is to inform the application what features are available to it from the driver. A leveling
scheme based on functions does not sufficiently achieve this goal. In ODBC 3.x, drivers are classified based on
the features they possess. Supporting the feature can include supporting the function; it can also include
supporting a descriptor field, a statement attribute, a "Y" value for an information type returned by SQLGetInfo ,
and so on.
To simplify specification of interface conformance, ODBC defines three conformance levels. To meet a particular
conformance level, a driver must satisfy all of the requirements of that conformance level. Conformance with a
given level implies complete conformance with all lower levels.
Conformance levels do not always divide neatly into support for a specific list of ODBC functions, but specify
supported features as listed in the following sections. To provide support for a feature, a driver must support
some or all forms of calls to certain ODBC functions (for more information, see Function Conformance), setting
certain attributes (see Attribute Conformance), and certain descriptor fields (see Descriptor Field Conformance).
The application discovers a driver's interface conformance level by connecting to a data source and calling
SQLGetInfo with the SQL_ODBC_INTERFACE_CONFORMANCE option.
Drivers are free to implement features beyond the level to which they claim complete conformance. Applications
discover any such additional capabilities by calling SQLGetFunctions (to determine which ODBC functions are
present) and SQLGetInfo (to query various other ODBC capabilities).
There are three ODBC interface conformance levels: Core, Level 1, and Level 2.
NOTE
These conformance levels have different requirements than the ODBC API conformance levels of the same name in ODBC
2*.x*. In particular, all the features implied by ODBC 2*.x* API conformance Level 1 are now part of the Core interface
conformance level. As a result, many ODBC drivers may report Core-level interface conformance.
All ODBC drivers must exhibit at least Core-level interface conformance. Because the features in the Core level
are those required by most generic interoperable applications, the driver can work with such applications. The
features in the Core level also correspond to the features defined in the ISO CLI specification and to the
nonoptional features defined in the Open Group CLI specification. A Core-level interface-conformant ODBC
driver allows the application to do all of the following:
Allocate and free all types of handles, by calling SQL AllocHandle and SQLFreeHandle .
Use all forms of the SQLFreeStmt function.
Bind result set columns, by calling SQLBindCol .
Handle dynamic parameters, including arrays of parameters, in the input direction only, by calling
SQLBindParameter and SQLNumParams . (Parameters in the output direction are feature 203 in Level
2 Interface Conformance.)
Specify a bind offset.
Use the data-at-execution dialog, involving calls to SQLParamData and SQLPutData .
Manage cursors and cursor names, by calling SQLCloseCursor , SQLGetCursorName , and
SQLSetCursorName .
Gain access to the description (metadata) of result sets, by calling SQLColAttribute , SQLDescribeCol ,
SQLNumResultCols , and SQLRowCount . (Use of these functions on column number 0 to retrieve
bookmark metadata is feature 204 in Level 2 Interface Conformance.)
Query the data dictionary, by calling the catalog functions SQLColumns , SQLGetTypeInfo ,
SQLStatistics , and SQLTables .
The driver is not required to support multipart names of database tables and views. (For more
information, see feature 101 in Level 1 Interface Conformance and feature 201 in Level 2 Interface
Conformance.) However, certain features of the SQL-92 specification, such as column qualification and
names of indexes, are syntactically comparable to multipart naming. The present list of ODBC features is
not intended to introduce new options into these aspects of SQL-92.
Manage data sources and connections, by calling SQLConnect , SQLDataSources , SQLDisconnect ,
and SQLDriverConnect . Obtain information on drivers, no matter which ODBC level they support, by
calling SQLDrivers .
Prepare and execute SQL statements, by calling SQLExecDirect , SQLExecute , and SQLPrepare .
Fetch one row of a result set or multiple rows, in the forward direction only, by calling SQLFetch or by
calling SQLFetchScroll with the FetchOrientation argument set to SQL_FETCH_NEXT.
Obtain an unbound column in parts, by calling SQLGetData .
Obtain current values of all attributes, by calling SQLGetConnectAttr , SQLGetEnvAttr , and
SQLGetStmtAttr , and set all attributes to their default values and set certain attributes to nondefault
values by calling SQLSetConnectAttr , SQLSetEnvAttr , and SQLSetStmtAttr .
Manipulate certain fields of descriptors, by calling SQLCopyDesc , SQLGetDescField , SQLGetDescRec ,
SQLSetDescField , and SQLSetDescRec .
Obtain diagnostic information, by calling SQLGetDiagField and SQLGetDiagRec .
Detect driver capabilities, by calling SQLGetFunctions and SQLGetInfo . Also, detect the result of any
text substitutions made to an SQL statement before it is sent to the data source, by calling
SQLNativeSql .
Use the syntax of SQLEndTran to commit a transaction. A Core-level driver need not support true
transactions; therefore, the application cannot specify SQL_ROLLBACK nor SQL_AUTOCOMMIT_OFF for
the SQL_ATTR_AUTOCOMMIT connection attribute. (For more information, see feature 109 in Level 2
Interface Conformance.)
Call SQLCancel to cancel the data-at-execution dialog and, in multithread environments, to cancel an
ODBC function executing in another thread. Core-level interface conformance does not mandate support
for asynchronous execution of functions, nor the use of SQLCancel to cancel an ODBC function
executing asynchronously. Neither the platform nor the ODBC driver need be multithread for the driver
to conduct independent activities at the same time. However, in multithread environments, the ODBC
driver must be thread-safe. Serialization of requests from the application is a conformant way to
implement this specification, even though it might create serious performance problems.
Obtain the SQL_BEST_ROWID row-identifying column of tables, by calling SQLSpecialColumns .
(Support for SQL_ROWVER is feature 208 in Level 2 Interface Conformance.)
IMPORTANT
ODBC Drivers must implement the functions in the Core interface conformance level.
Level 1 Interface Conformance
4/27/2022 • 2 minutes to read • Edit Online
The Level 1 interface conformance level includes the Core interface conformance level functionality plus
additional features, such as transactions, that are usually available in an OLTP relational DBMS. A Level 1
interface-conformant driver lets the application do the following, in addition to the features in the Core interface
conformance level:
101 Specify the schema of database tables and views (using two-
part naming). (For more information, see the three-part
naming feature 201 in Level 2 Interface Conformance.)
The Level 2 interface conformance level includes the Level 1 interface conformance-level functionality plus the
following features:
203 Use not only input parameters but also output and
input/output parameters, and result values of stored
procedures.
210 The ability to time out login request and SQL queries
(SQL_ATTR_LOGIN_TIMEOUT and
SQL_ATTR_QUERY_TIMEOUT).
211 The ability to change the default isolation level; the ability to
execute transactions with the "serializable" level of isolation.
Function Conformance
4/27/2022 • 2 minutes to read • Edit Online
The following table indicates the conformance level of each ODBC function, where this is well defined.
F UN C T IO N C O N F O RM A N C E L EVEL
SQLBindCol Core
SQLBindParameter Core[1]
SQLBrowseConnect Level 1
SQLBulkOperations Level 1
SQLCancel Core[1]
SQLCloseCursor Core
SQLColAttribute Core[1]
SQLColumnPrivileges Level 2
SQLColumns Core
SQLConnect Core
SQLCopyDesc Core
SQLDataSources Core
SQLDescribeCol Core[1]
SQLDescribeParam Level 2
SQLDisconnect Core
SQLDriverConnect Core
SQLDrivers Core
SQLEndTran Core[1]
SQLExecDirect Core
SQLExecute Core
F UN C T IO N C O N F O RM A N C E L EVEL
SQLFetch Core
SQLFetchScroll Core[1]
SQLForeignKeys Level 2
SQLFreeHandle Core
SQLFreeStmt Core
SQLGetConnectAttr Core
SQLGetCursorName Core
SQLGetData Core
SQLGetDescField Core
SQLGetDescRec Core
SQLGetDiagField Core
SQLGetDiagRec Core
SQLGetEnvAttr Core
SQLGetFunctions Core
SQLGetInfo Core
SQLGetStmtAttr Core
SQLGetTypeInfo Core
SQLMoreResults Level 1
SQLNativeSql Core
SQLNumParams Core
SQLNumResultCols Core
SQLParamData Core
SQLPrepare Core
SQLProcedureColumns Level 1
F UN C T IO N C O N F O RM A N C E L EVEL
SQLProcedures Level 1
SQLPutData Core
SQLRowCount Core
SQLSetConnectAttr Core[2]
SQLSetCursorName Core
SQLSetDescField Core[1]
SQLSetDescRec Core
SQLSetEnvAttr Core[2]
SQLSetStmtAttr Core[2]
SQLSpecialColumns Core[1]
SQLStatistics Core
SQLTablePrivileges Level 2
SQLTables Core
[1] Significant features of this function are available only at higher conformance levels.
[2] Setting certain attributes to nondefault values depends on the conformance level. For more information, see
the next section, Attribute Conformance.
Attribute Conformance
4/27/2022 • 2 minutes to read • Edit Online
The following table indicates the conformance level of each ODBC environment attribute, where this is well
defined.
F UN C T IO N C O N F O RM A N C E L EVEL
SQL_ATTR_CONNECTION_POOLING --[1]
SQL_ATTR_CP_MATCH --[1]
SQL_ATTR_ODBC_VER Core
SQL_ATTR_OUTPUT_NTS --[1]
[1] This is an optional feature and as such is not part of the conformance levels.
The following table indicates the conformance level of each ODBC connection attribute, where this is well
defined.
F UN C T IO N C O N F O RM A N C E L EVEL
SQL_ATTR_ACCESS_MODE Core
SQL_ATTR_AUTO_IPD Level 2
SQL_ATTR_AUTOCOMMIT Level 1
SQL_ATTR_CONNECTION_DEAD Level 1
SQL_ATTR_CONNECTION_TIMEOUT Level 2
SQL_ATTR_CURRENT_CATALOG Level 2
SQL_ATTR_LOGIN_TIMEOUT Level 2
SQL_ATTR_ODBC_CURSORS Core
SQL_ATTR_PACKET_SIZE Level 2
SQL_ATTR_QUIET_MODE Core
SQL_ATTR_TRACE Core
SQL_ATTR_TRACEFILE Core
F UN C T IO N C O N F O RM A N C E L EVEL
SQL_ATTR_TRANSLATE_LIB Core
SQL_ATTR_TRANSLATE_OPTION Core
[1] Applications that support connection-level asynchrony (required for Level 1) must support setting this
attribute to SQL_TRUE by calling SQLSetConnectAttr ; the attribute need not be settable to a value other than
its default value through SQLSetStmtAttr . Applications that support statement-level asynchrony (required for
Level 2) must support setting this attribute to SQL_TRUE using either function.
[2] For Level 1 interface conformance, the driver must support one value in addition to the driver-defined
default value (available by calling SQLGetInfo with the SQL_DEFAULT_TXN_ISOLATION option). For Level 2
interface conformance, the driver must also support SQL_TXN_SERIALIZABLE.
The following table indicates the conformance level of each ODBC statement attribute, where this is well defined.
F UN C T IO N C O N F O RM A N C E L EVEL
SQL_ATTR_APP_PARAM_DESC Core
SQL_ATTR_APP_ROW_DESC Core
SQL_ATTR_CURSOR_SCROLLABLE Level 1
SQL_ATTR_CURSOR_SENSITIVITY Level 2
SQL_ATTR_ENABLE_AUTO_IPD Level 2
SQL_ATTR_FETCH_BOOKMARK_PTR Level 2
SQL_ATTR_IMP_PARAM_DESC Core
SQL_ATTR_IMP_ROW_DESC Core
SQL_ATTR_KEYSET_SIZE Level 2
SQL_ATTR_MAX_LENGTH Level 1
SQL_ATTR_MAX_ROWS Level 1
SQL_ATTR_METADATA_ID Core
SQL_ATTR_NOSCAN Core
F UN C T IO N C O N F O RM A N C E L EVEL
SQL_ATTR_PARAM_BIND_OFFSET_PTR Core
SQL_ATTR_PARAM_BIND_TYPE Core
SQL_ATTR_PARAM_OPERATION_PTR Core
SQL_ATTR_PARAM_STATUS_PTR Core
SQL_ATTR_PARAMS_PROCESSED_PTR Core
SQL_ATTR_PARAMSET_SIZE Core
SQL_ATTR_QUERY_TIMEOUT Level 2
SQL_ATTR_RETRIEVE_DATA Level 1
SQL_ATTR_ROW_ARRAY_SIZE Core
SQL_ATTR_ROW_BIND_OFFSET_PTR Core
SQL_ATTR_ROW_BIND_TYPE Core
SQL_ATTR_ROW_NUMBER Level 1
SQL_ATTR_ROW_OPERATION_PTR Level 1
SQL_ATTR_ROW_STATUS_PTR Core
SQL_ATTR_ROWS_FETCHED_PTR Core
SQL_ATTR_SIMULATE_CURSOR Level 2
SQL_ATTR_USE_BOOKMARKS Level 2
[1] Applications that support connection-level asynchrony (required for Level 1) must support setting this
attribute to SQL_TRUE by calling SQLSetConnectAttr ; the attribute need not be settable to a value other than
its default value through SQLSetStmtAttr . Applications that support statement-level asynchrony (required for
Level 2) must support setting this attribute to SQL_TRUE using either function.
[2] For Level 2 interface conformance, the driver must support SQL_CONCUR_READ_ONLY and at least one
other value.
[3] For Level 1 interface conformance, the driver must support SQL_CURSOR_FORWARD_ONLY and at least one
other value. For Level 2 interface conformance, the driver must support all values defined in this document.
Descriptor Field Conformance
4/27/2022 • 2 minutes to read • Edit Online
The following table indicates the conformance level of each ODBC descriptor header field, where this is well
defined.
F UN C T IO N C O N F O RM A N C E L EVEL
SQL_DESC_ALLOC_TYPE Core
SQL_DESC_ARRAY_SIZE Core
SQL_DESC_ARRAY_STATUS_PTR Core (for APD, IPR, and IRD); Level 1 (for ARD)
SQL_DESC_BIND_OFFSET_PTR Core
SQL_DESC_BIND_TYPE Core
SQL_DESC_COUNT Core
SQL_DESC_ROWS_PROCESSED_PTR Core
The following table indicates the conformance level of each ODBC descriptor record field, where this is well
defined.
F UN C T IO N C O N F O RM A N C E L EVEL
SQL_DESC_AUTO_UNIQUE_VALUE Level 2
SQL_DESC_BASE_COLUMN_NAME Core
SQL_DESC_BASE_TABLE_NAME Level 1
SQL_DESC_CASE_SENSITIVE Core
SQL_DESC_CATALOG_NAME Level 2
SQL_DESC_CONCISE_TYPE Core
SQL_DESC_DATA_PTR Core
SQL_DESC_DISPLAY_SIZE Core
SQL_DESC_FIXED_PREC_SCALE Core
F UN C T IO N C O N F O RM A N C E L EVEL
SQL_DESC_INDICATOR_PTR Core
SQL_DESC_LABEL Level 2
SQL_DESC_LENGTH Core
SQL_DESC_LITERAL_PREFIX Core
SQL_DESC_LITERAL_SUFFIX Core
SQL_DESC_LOCAL_TYPE_NAME Core
SQL_DESC_NAME Core
SQL_DESC_NULLABLE Core
SQL_DESC_OCTET_LENGTH Core
SQL_DESC_OCTET_LENGTH_PTR Core
SQL_DESC_PRECISION Core
SQL_DESC_ROWVER Level 1
SQL_DESC_SCALE Core
SQL_DESC_SCHEMA_NAME Level 1
SQL_DESC_SEARCHABLE Core
SQL_DESC_TABLE_NAME Level 1
SQL_DESC_TYPE Core
SQL_DESC_TYPE_NAME Core
SQL_DESC_UNNAMED Core
SQL_DESC_UNSIGNED Core
SQL_DESC_UPDATABLE Core
[1] Support for these record fields is required only if the driver supports the applicable data types.
[2] For Core-level conformance, the driver must support SQL_PARAM_INPUT. For Level 2 interface conformance,
the driver must also support SQL_PARAM_INPUT_OUTPUT and SQL_PARAM_OUTPUT.
SQL Conformance Levels
4/27/2022 • 2 minutes to read • Edit Online
The level of SQL-92 grammar supported by a driver is indicated by the value returned by a call to SQLGetInfo
with the SQL_SQL_CONFORMANCE information type. This indicates whether the driver conforms to the Entry,
FIPS Transitional, Intermediate, or Full levels defined in SQL-92.
All ODBC drivers must support the minimum SQL grammar described in SQL Minimum Grammar in Appendix
C: SQL Grammar. This grammar is a subset of the Entry level of SQL-92. Drivers may support additional SQL
and be conformant to the SQL-92 Entry, Intermediate, or Full level, or to the FIPS 127-2 Transitional level.
Drivers that comply to a given level of SQL-92 or FIPS 127-2 can support additional features in any of the
higher levels yet not be fully conformant to that level. To determine whether a feature is supported, an
application should call SQLGetInfo with the appropriate information type. The conformance level of an SQL
feature is described in the corresponding information type. (See the SQLGetInfo function description.)
Environment, Connection, and Statement Attributes
4/27/2022 • 2 minutes to read • Edit Online
ODBC defines a number of attributes that are associated with environments, connections, or statements.
Environment attributes affect the entire environment, such as whether connection pooling is enabled.
Environment attributes are set with SQLSetEnvAttr and retrieved with SQLGetEnvAttr .
Connection attributes affect each connection individually, such as how long a driver should wait while
attempting to connect to a data source before timing out. Connection attributes are set with
SQLSetConnectAttr and retrieved with SQLGetConnectAttr . For more information about connection
attributes, see Connection Attributes.
Statement attributes affect each statement individually, such as whether a statement should be executed
asynchronously. Statement attributes are set with SQLSetStmtAttr and retrieved with SQLGetStmtAttr . A few
statement attributes are read-only attributes and cannot be set. For example, the SQL_ATTR_ROW_NUMBER
statement attribute, which is used to retrieve the number of the current row in the cursor, is read-only. For more
information about statement attributes, see Statement Attributes.
In addition to attributes defined by ODBC, a driver can define its own connection and statement attributes.
Driver-defined attributes must be registered with Open Group to ensure that two driver vendors do not assign
the same integer value to different, proprietary attributes. For more information, see Driver-Specific Data Types,
Descriptor Types, Information Types, Diagnostic Types, and Attributes.
For a complete list of attributes, see SQLSetEnvAttr, SQLSetConnectAttr, and SQLSetStmtAttr. Most attributes
are also described in the description of the ODBC function that they affect.
Tables and Views
4/27/2022 • 2 minutes to read • Edit Online
In ODBC functions, tables and views are interchangeable. The term table is used both for tables and for views,
except where the term view is used explicitly.
Basic ODBC Application Steps
4/27/2022 • 2 minutes to read • Edit Online
This section describes the general flow of ODBC applications. It is unlikely that any application calls all of these
functions in exactly this order. However, most applications use some variation of these steps. The basic
application steps are shown in the following illustration.
The first step in any application is to connect to the data source. This phase, including the functions it requires, is
shown in the following illustration.
The first step in connecting to the data source is to load the Driver Manager and allocate the environment
handle with SQL AllocHandle . For more information, see Allocating the Environment Handle.
The application then registers the version of ODBC to which it conforms by calling SQLSetEnvAttr with the
SQL_ATTR_APP_ODBC_VER environment attribute. For more information, see Declaring the Application's ODBC
Version and Backward Compatibility and Standards Compliance.
Next, the application allocates a connection handle with SQL AllocHandle and connects to the data source with
SQLConnect , SQLDriverConnect , or SQLBrowseConnect . For more information, see Allocating a
Connection Handle and Establishing a Connection.
The application then sets any connection attributes, such as whether to manually commit transactions. For more
information, see Connection Attributes.
Step 2: Initialize the Application
4/27/2022 • 2 minutes to read • Edit Online
The second step is to initialize the application, as shown in the following illustration. Exactly what is done here
varies with the application.
At this point, it is common to use SQLGetInfo to discover the capabilities of the driver. For more information,
see Considering Database Features to Use.
All applications need to allocate a statement handle with SQL AllocHandle , and many applications set
statement attributes, such as the cursor type, with SQLSetStmtAttr . For more information, see Allocating a
Statement Handle and Statement Attributes.
Step 3: Build and Execute an SQL Statement
4/27/2022 • 2 minutes to read • Edit Online
The third step is to build and execute an SQL statement, as shown in the following illustration. The methods
used to perform this step are likely to vary tremendously. The application might prompt the user to enter an
SQL statement, build an SQL statement based on user input, or use a hard-coded SQL statement. For more
information, see Constructing SQL Statements.
If the SQL statement contains parameters, the application binds them to application variables by calling
SQLBindParameter for each parameter. For more information, see Statement Parameters.
After the SQL statement is built and any parameters are bound, the statement is executed with SQLExecDirect .
If the statement will be executed multiple times, it can be prepared with SQLPrepare and executed with
SQLExecute . For more information, see Executing a Statement.
The application might also forgo executing an SQL statement altogether and instead call a function to return a
result set containing catalog information, such as the available columns or tables. For more information, see
Uses of Catalog Data.
The application's next action depends on the type of SQL statement executed.
T Y P E O F SQ L STAT EM EN T P RO C EED TO
All other SQL statements Step 3: Build and Execute an SQL Statement (this topic) or
Step 5: Commit the Transaction
Step 4a: Fetch the Results
4/27/2022 • 2 minutes to read • Edit Online
The next step is to fetch the results, as shown in the following illustration.
If the statement executed in "Step 3: Build and Execute an SQL Statement" was a SELECT statement or a catalog
function, the application first calls SQLNumResultCols to determine the number of columns in the result set.
This step is not necessary if the application already knows the number of result set columns, such as when the
SQL statement is hard-coded in a vertical or custom application.
Next, the application retrieves the name, data type, precision, and scale of each result set column with
SQLDescribeCol . Again, this is not necessary for applications such as vertical and custom applications that
already know this information. The application passes this information to SQLBindCol , which binds an
application variable to a column in the result set.
The application now calls SQLFetch to retrieve the first row of data and place the data from that row in the
variables bound with SQLBindCol . If there is any long data in the row, it then calls SQLGetData to retrieve that
data. The application continues to call SQLFetch and SQLGetData to retrieve additional data. After it has
finished fetching data, it calls SQLCloseCursor to close the cursor.
For a complete description of retrieving results, see Retrieving Results (Basic) and Retrieving Results (Advanced).
The application now returns to "Step 3: Build and Execute an SQL Statement" to execute another statement in the
same transaction; or proceeds to "Step 5: Commit the Transaction" to commit or roll back the transaction.
Step 4b: Fetch the Row Count
4/27/2022 • 2 minutes to read • Edit Online
The next step is to fetch the row count, as shown in the following illustration.
If the statement executed in Step 3 was an UPDATE , DELETE , or INSERT statement, the application retrieves the
count of affected rows with SQLRowCount . For more information, see Determining the Number of Affected
Rows.
The application now returns to step 3 to execute another statement in the same transaction or proceeds to step
5 to commit or roll back the transaction.
Step 5: Commit the Transaction
4/27/2022 • 2 minutes to read • Edit Online
The next step is to commit the transaction, as shown in the following illustration.
The fifth step is to call SQLEndTran to commit or roll back the transaction. The application performs this step
only if it set the transaction commit mode to manual-commit; if the transaction commit mode is auto-commit,
which is the default, the transaction is automatically committed when the statement is executed. For more
information, see Transactions.
To execute a statement in a new transaction, the application returns to step 3. To disconnect from the data
source, the application proceeds to step 6.
Step 6: Disconnect from the Data Source
4/27/2022 • 2 minutes to read • Edit Online
The final step is to disconnect from the data source, as shown in the following illustration. First, the application
frees any statement handles by calling SQLFreeHandle . For more information, see Freeing a Statement Handle.
Next, the application disconnects from the data source with SQLDisconnect and frees the connection handle
with SQLFreeHandle . For more information, see Disconnecting from a Data Source or Driver.
Finally, the application frees the environment handle with SQLFreeHandle and unloads the Driver Manager.
For more information, see Allocating the Environment Handle.
Connecting to a Data Source or Driver
4/27/2022 • 2 minutes to read • Edit Online
An application can be connected to any number of drivers and data sources. These can be a variety of drivers
and data sources, the same driver and a variety of data sources, or even multiple connections to the same driver
and data source.
This section contains the following topics.
Allocating the Environment Handle
Declaring the Application's ODBC Version
Choosing a Data Source or Driver
Allocating a Connection Handle
Connection Attributes
Establishing a Connection
Driver Manager Connection Pooling
Disconnecting from a Data Source or Driver
The Driver Manager's Role in the Connection Process
Allocating the Environment Handle
4/27/2022 • 2 minutes to read • Edit Online
The first task for any ODBC application is to load the Driver Manager; how this is done is operating-system
dependent. For example, on a computer running Microsoft® Windows NT® Server/Windows 2000 Server,
Windows NT Workstation/Windows 2000 Professional, or Microsoft Windows® 95/98, the application either
links to the Driver Manager library or calls LoadLibrar y to load the Driver Manager DLL.
The next task, which must be done before an application can call any other ODBC function, is to initialize the
ODBC environment and allocate an environment handle, as follows:
1. The application declares a variable of type SQLHENV. It then calls SQL AllocHandle and passes the
address of this variable and the SQL_HANDLE_ENV option. For example:
SQLHENV henv1;
2. The Driver Manager allocates a structure in which to store information about the environment, and
returns the environment handle in the variable.
The Driver Manager does not call SQL AllocHandle in the driver at this time because it does not know which
driver to call. It delays calling SQL AllocHandle in the driver until the application calls a function to connect to a
data source. For more information, see Driver Manager's Role in the Connection Process, later in this section.
When the application has finished using ODBC, it frees the environment handle with SQLFreeHandle . After
freeing the environment, it is an application programming error to use the environment's handle in a call to an
ODBC function; doing so has undefined but probably fatal consequences.
When SQLFreeHandle is called, the driver releases the structure used to store information about the
environment. Note that SQLFreeHandle cannot be called for an environment handle until after all connection
handles on that environment handle have been freed.
For more information about the environment handle, see Environment Handles.
Declaring the Application's ODBC Version
4/27/2022 • 2 minutes to read • Edit Online
Before an application allocates a connection, it must set the SQL_ATTR_ODBC_VERSION environment attribute.
This attribute states that the application follows the ODBC 2.x or ODBC 3.x specification when using the
following items:
SQLSTATEs . Many SQLSTATE values are different in ODBC 2.x and ODBC 3.x.
Date, Time, and Timestamp Type Identifiers . The following table shows the type identifiers for date,
time, and timestamp data in ODBC 2.x and ODBC 3.x.
O DB C 2. X O DB C 3. X
SQL_DATE SQL_TYPE_DATE
SQL_TIME SQL_TYPE_TIME
SQL_TIMESTAMP SQL_TYPE_TIMESTAMP
C Type Identifiers
SQL_C_DATE SQL_C_TYPE_DATE
SQL_C_TIME SQL_C_TYPE_TIME
SQL_C_TIMESTAMP SQL_C_TYPE_TIMESTAMP
CatalogName Argument in SQLTables . In ODBC 2.x, the wildcard characters ("%" and "_") in the
CatalogName argument are treated literally. In ODBC 3.x, they are treated as wildcard characters. Thus, an
application that follows the ODBC 2.x specification cannot use these as wildcard characters and does not
escape them when using them as literals. An application that follows the ODBC 3.x specification can use
these as wildcard characters or escape them and use them as literals. For more information, see
Arguments in Catalog Functions.
The ODBC 3.x Driver Manager and ODBC 3.x drivers check the version of the ODBC specification to which an
application is written and respond accordingly. For example, if the application follows the ODBC 2.x specification
and calls SQLExecute before calling SQLPrepare , the ODBC 3.x Driver Manager returns SQLSTATE S1010
(Function sequence error). If the application follows the ODBC 3.x specification, the Driver Manager returns
SQLSTATE HY010 (Function sequence error). For more information, see Backward Compatibility and Standards
Compliance.
IMPORTANT
Applications that follow the ODBC 3.x specification must use conditional code to avoid using functionality new to ODBC
3.x when working with ODBC 2.x drivers. ODBC 2.x drivers do not support functionality new to ODBC 3.x just because the
application declares that it follows the ODBC 3.x specification. Furthermore, ODBC 3.x drivers do not cease to support
functionality new to ODBC 3.x just because the application declares that it follows the ODBC 2.x specification.
Choosing a Data Source or Driver
4/27/2022 • 4 minutes to read • Edit Online
The data source or driver used by an application is sometimes hard-coded in the application. For example, a
custom application written by an MIS department to transfer data from one data source to another would
contain the names of those data sources-the application simply would not work with any other data sources.
Another example is a vertical application, such as one used for order entry. Such an application always uses the
same data source, which has a predefined schema known by the application.
Other applications select the data source or driver at run time. Usually, these are generic applications that do ad
hoc queries, such as a spreadsheet that uses ODBC to import data. Such applications usually list the available
data sources or drivers and let users choose the ones they want to work with. Whether a generic application lists
data sources, drivers, or both frequently depends on whether the application uses DBMS-based or file-based
drivers.
DBMS-based drivers usually require a complex set of connection information, such as the network address,
network protocol, database name, and so on. The purpose of a data source is to hide all of this information.
Therefore, the data source paradigm lends itself to use with DBMS-based drivers. An application can display a
list of data sources to the user in one of two ways. It can call SQLDriverConnect with the DSN (Data Source
Name) keyword and no associated value; the Driver Manager will display a list of data source names. If the
application wants control over the appearance of the list, it calls SQLDataSources to retrieve a list of available
data sources and constructs its own dialog box. This function is implemented by the Driver Manager and can be
called before any drivers are loaded. The application then calls a connection function and passes it the name of
the chosen data source.
If a data source is not specified, the default data source indicated by the system information is used. (For more
information, see Default Subkey.) If SQLConnect is called by using a ServerName argument that cannot be
found, is a null pointer, or is "DEFAULT", the Driver Manager connects to the default data source. The default data
source is also used if the connection string that is used in a call to SQLDriverConnect or SQLBrowseConnect
contains the DSN keyword set to "DEFAULT" or if the specified data source is not found. Additionally, the default
data source is used if the connection string that is used in a call to SQLDriverConnect does not contain the
DSN keyword.
With file-based drivers, it is possible to use a file paradigm. For data stored on the local computer, users
frequently know that their data is in a particular file, such as Employee.dbf. Instead of selecting an unknown data
source, it is easier for such users to select the file they know. To implement this, the application first calls
SQLDrivers . This function is implemented by the Driver Manager and can be called before any drivers are
loaded. SQLDrivers returns a list of available drivers; it also returns values for the FileUsage and FileExtns
keywords. The FileUsage keyword explains whether file-based drivers treat files as tables, as does Xbase, or as
databases, as does Microsoft® Access. The FileExtns keyword lists the file name extensions the driver
recognizes, such as .dbf for an Xbase driver. Using this information, the application constructs a dialog box
through which the user chooses a file. Based on the extension of the chosen file, the application then connects to
the driver by calling SQLDriverConnect with the DRIVER keyword.
There is nothing to stop an application from using a data source with a file-based driver or calling
SQLDriverConnect with the DRIVER keyword to connect to a DBMS-based driver. Here are several common
uses of the DRIVER keyword for DBMS-based drivers:
Not creating data sources. For example, a custom application might use a particular driver and
database. If the driver name and all information that is required to connect to the database is hard-coded
in the application, users do not have to create a data source on their computer to run the application. All
they must do is install the application and driver.
A disadvantage of this method is that the application must be recompiled and redistributed if the
connection information changes. If a data source name is hard-coded in the application instead of
complete connection information, each user must change only the information in the data source.
Accessing a par ticular DBMS a single time. For example, a spreadsheet that retrieves data by calling
ODBC functions might contain the DRIVER keyword to identify a particular driver. Because the driver
name is meaningful to any users who have that driver, the spreadsheet could be passed among those
users. If the spreadsheet contained a data source name, each user would have to create the same data
source to use the spreadsheet.
Browsing the system for all databases accessible to a par ticular driver. For more information,
see Connecting with SQLBrowseConnect, later in this section.
Allocating a Connection Handle ODBC
4/27/2022 • 2 minutes to read • Edit Online
Before the application can connect to a data source or driver, it must allocate a connection handle, as follows:
1. The application declares a variable of type SQLHDBC. It then calls SQL AllocHandle and passes the
address of this variable, the handle of the environment in which to allocate the connection, and the
SQL_HANDLE_DBC option. For example:
SQLHDBC hdbc1;
2. The Driver Manager allocates a structure in which to store information about the statement and returns
the connection handle in the variable.
The Driver Manager does not call SQL AllocHandle in the driver at this time because it does not know which
driver to call. It delays calling SQL AllocHandle in the driver until the application calls a function to connect to a
data source. For more information, see Driver Manager's Role in the Connection Process, later in this section.
It is important to note that allocating a connection handle is not the same as loading a driver. The driver is not
loaded until a connection function is called. Thus, after allocating a connection handle and before connecting to
the driver or data source, the only functions the application can call with the connection handle are
SQLSetConnectAttr , SQLGetConnectAttr , or SQLGetInfo with the SQL_ODBC_VER option. Calling other
functions with the connection handle, such as SQLEndTran , returns SQLSTATE 08003 (Connection not open).
For complete details, see Appendix B: ODBC State Transition Tables.
For more information about connection handles, see Connection Handles.
Connection Attributes
4/27/2022 • 2 minutes to read • Edit Online
Connection attributes are characteristics of the connection. For example, because transactions occur at the
connection level, the transaction isolation level is a connection attribute. Similarly, the login timeout, or number
of seconds to wait while trying to connect before timing out, is a connection attribute.
Connection attributes are set with SQLSetConnectAttr and their current settings retrieved with
SQLGetConnectAttr . If SQLSetConnectAttr is called before the driver is loaded, the Driver Manager stores
the attributes in its connection structure and sets them in the driver as part of the connection process. There is
no requirement that an application set any connection attributes; all connection attributes have defaults, some of
which are driver-specific.
A connection attribute can be set before or after connection, or either, depending on the attribute and the driver.
The login timeout (SQL_ATTR_LOGIN_TIMEOUT) applies to the connection process and is effective only if set
before connecting. The attributes that specify whether to use the ODBC cursor library
(SQL_ATTR_ODBC_CURSORS) and the network packet size (SQL_ATTR_PACKET_SIZE) must be set before
connecting, because the ODBC cursor library resides between the Driver Manager and the driver and therefore
must be loaded before the driver.
The attributes to specify whether a data source is read-only or read-write (SQL_ATTR_ACCESS_MODE) and the
current catalog (SQL_ATTR_CURRENT_CATALOG) can be set before or after connecting, depending on the driver.
However, interoperable applications set them before connecting because some drivers do not support changing
these after connecting.
Some connection attributes have a default before the connection is made, while others do not. Those that do are
SQL_ATTR_ACCESS_MODE, SQL_ATTR_AUTOCOMMIT, SQL_ATTR_LOGIN_TIMEOUT,
SQL_ATTR_ODBC_CURSORS, SQL_ATTR_TRACE, and SQL_ATTR_TRACEFILE.
The translation connection attributes (SQL_ATTR_TRANSLATE_DLL and SQL_ATTR_TRANSLATE_OPTION) must
be set after connecting.
All other connection attributes can be set at any time. For more information, see the SQLSetConnectAttr function
description. (Connection attributes cannot be set on the environment level by a call to SQLSetEnvAttr .)
Establishing a Connection
4/27/2022 • 2 minutes to read • Edit Online
After allocating environment and connection handles and setting any connection attributes, the application is
ready to connect to the data source or driver. There are three different functions the application can use to do
this: SQLConnect (Core interface conformance level), SQLDriverConnect (Core), and SQLBrowseConnect
(Level 1). Each of the three is designed to be used in a different scenario. Before connecting, the application can
determine which of these functions is supported with the ConnectFunctions keyword returned by
SQLDrivers .
NOTE
Some drivers limit the number of active connections they support. An application calls SQLGetInfo with the
SQL_MAX_DRIVER_CONNECTIONS option to determine how many active connections a particular driver supports.
The driver may select a data source, called the default data source, in certain cases where the application does
not explicitly specify one:
In a call to SQLConnect where the ServerName argument is a zero-length string, a null pointer, or
DEFAULT.
In a call to SQLDriverConnect where InConnectionString either specifies DSN =DEFAULT or specifies
with the DSN keyword a data source that is not contained in the system information.
It is driver-defined how the default data source is specified. This may involve administrative action and may
depend on the user.
Connecting with SQLConnect
4/27/2022 • 2 minutes to read • Edit Online
SQLConnect is the simplest connection function. It requires a data source name and accepts an optional user ID
and password. It works well for applications that hard-code a data source name and do not require a user ID or
password. It also works well for applications that want to control their own "look and feel" or that have no user
interface. Such applications can build a list of data sources using SQLDataSources , prompt the user for data
source, user ID, and password, and then call SQLConnect .
The following example connects to the Northwind database, using a DSN called Northwind, and retrieves all of
the first and last name fields from all of the records in the Employees table.
// Connecting_with_SQLConnect.cpp
// compile with: user32.lib odbc32.lib
#include <windows.h>
#include <sqlext.h>
#include <mbstring.h>
#include <stdio.h>
class direxec {
RETCODE rc; // ODBC return code
HENV henv; // Environment
HDBC hdbc; // Connection handle
HSTMT hstmt; // Statement handle
public:
direxec(); // Constructor
void sqlconn(); // Allocate env, stat, and conn
void sqlexec(unsigned char *); // Execute SQL statement
void sqldisconn(); // Free pointers to env, stat, conn, and disconnect
void error_out(); // Displays errors
};
// Constructor initializes the string chr_ds_name with the data source name.
// "Northwind" is an ODBC data source (odbcad32.exe) name whose default is the Northwind database
direxec::direxec() {
_mbscpy_s(chr_ds_name, SQL_MAX_DSN_LENGTH, (const unsigned char *)"Northwind");
}
// Allocate environment handle and connection handle, connect to data source, and allocate statement handle.
void direxec::sqlconn() {
SQLAllocEnv(&henv);
SQLAllocConnect(henv, &hdbc);
rc = SQLConnect(hdbc, chr_ds_name, SQL_NTS, NULL, 0, NULL, 0);
rc = SQLAllocStmt(hdbc, &hstmt);
}
// Free the statement handle, disconnect, free the connection handle, and free the environment handle.
void direxec::sqldisconn() {
SQLFreeStmt(hstmt,SQL_DROP);
SQLDisconnect(hdbc);
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);
}
int main () {
direxec x; // Declare an instance of the direxec object.
x.sqlconn(); // Allocate handles, and connect.
x.sqlexec((UCHAR FAR *)"SELECT FirstName, LastName FROM employees"); // Execute SQL command
x.sqldisconn(); // Free handles and disconnect
}
Connection Strings
4/27/2022 • 2 minutes to read • Edit Online
A connection string contains information used for establishing a connection. A complete connection string
contains all the information needed to establish a connection. The connection string is a series of keyword/value
pairs separated by semicolons. (For the complete syntax of a connection string, see the SQLDriverConnect
function description.) The connection string is used by:
SQLDriverConnect , which completes the connection string by interaction with the user.
SQLBrowseConnect , which completes the connection string iteratively with the data source.
SQLConnect does not use a connection string; using SQLConnect is analogous to connecting using a
connection string with exactly three keyword/value pairs (for data source name and, optionally, user ID and
password).
Connecting with SQLDriverConnect
4/27/2022 • 2 minutes to read • Edit Online
SQLDriverConnect is used to connect to a data source using a connection string. SQLDriverConnect is used
instead of SQLConnect for the following scenarios:
Establish a connection using a connection string that contains the data source name, one or more user
IDs, one or more passwords, and other information required by the data source.
Establish a connection using a partial connection string or no additional information; in this case, the
Driver Manager and the driver can each prompt the user for connection information.
Establish a connection to a data source that is not defined in the system information. If the application
supplies a partial connection string, the driver can prompt the user for connection information.
Establish a connection to a data source using a connection string constructed from the information in a
.dsn file.
After a connection is established, SQLDriverConnect returns the completed connection string. The application
can use this string for subsequent connection requests.
This section contains the following topics.
Driver-Specific Connection Information
Prompting the User for Connection Information
Connecting Using File Data Sources
Connecting Directly to Drivers
Driver-Specific Connection Information
4/27/2022 • 2 minutes to read • Edit Online
SQLConnect assumes that a data source name, user ID, and password are sufficient to connect to a data source
and that all other connection information can be stored on the system. This is frequently not the case. For
example, a driver might need one user ID and password to log on to a server and a different user ID and
password to log on to a DBMS. Because SQLConnect accepts a single user ID and password, this means that
the other user ID and password must be stored with the data source information on the system if SQLConnect
is to be used. This is a potential breach of security and should be avoided unless the password is encrypted.
SQLDriverConnect allows the driver to define an arbitrary amount of connection information in the keyword-
value pairs of the connection string. For example, suppose a driver requires a data source name, a user ID and
password for the server, and a user ID and password for the DBMS. A custom program that always uses the XYZ
Corp data source might prompt the user for IDs and passwords and build the following set of keyword-value
pairs, or connection string, to pass to SQLDriverConnect :
NOTE
If you are connecting to a data source provider that supports Windows authentication, you should specify
Trusted_Connection=yes instead of user ID and password information in the connection string.
DSN={MyDataSourceName};UID={MyUserID};PWD={MyServerPassword};UIDDBMS={MyDBMSUserID};PWDDBMS=
{MyDBMSUserPassword};
The DSN (Data Source Name) keyword names the data source, the UID and PWD keywords specify the user ID
and password for the server, and the UIDDBMS and PWDDBMS keywords specify the user ID and password
for the DBMS. Notice that the final semicolon is optional. SQLDriverConnect parses this string; uses the XYZ
Corp data source name to retrieve additional connection information from the system, such as the server
address; and logs on to the server and DBMS using the specified user IDs and passwords.
Keyword-value pairs in SQLDriverConnect must follow certain syntax rules. The keywords and their values
should not contain the []{}(),;?*=!@ characters. The value of the DSN keyword cannot consist only of blanks
and should not contain leading blanks. Because of the registry grammar, keywords and data source names
cannot contain the backslash (\) character. Spaces are not allowed around the equal sign in the keyword-value
pair.
The FILEDSN keyword can be used in a call to SQLDriverConnect to specify the name of a file that contains
data source information (see Connecting Using File Data Sources, later in this section). The SAVEFILE keyword
can be used to specify the name of a .dsn file in which the keyword-value pairs of a successful connection made
by the call to SQLDriverConnect will be saved. For more information about file data sources, see the
SQLDriverConnect function description.
Prompting the User for Connection Information
4/27/2022 • 2 minutes to read • Edit Online
If the application uses SQLConnect and needs to prompt the user for any connection information, such as a
user name and password, it must do so itself. While this allows the application to control its "look and feel," it
might force the application to contain driver-specific code. This occurs when the application needs to prompt the
user for driver-specific connection information. This presents an impossible situation for generic applications,
which are designed to work with any and all drivers, including drivers that do not exist when the application is
written.
SQLDriverConnect can prompt the user for connection information. For example, the custom program
mentioned earlier could pass the following connection string to SQLDriverConnect :
DSN=XYZ Corp;
The driver might then display a dialog box that prompts for user IDs and passwords, similar to the following
illustration.
That the driver can prompt for connection information is particularly useful to generic and vertical applications.
These applications should not contain driver-specific information, and having the driver prompt for the
information it needs keeps that information out of the application. This is shown by the previous two examples.
When the application passed only the data source name to the driver, the application did not contain any driver-
specific information and was therefore not tied to a particular driver. When the application passed a complete
connection string to the driver, it was tied to the driver that could interpret that string.
A generic application might take this one step further and not even specify a data source. When
SQLDriverConnect receives an empty connection string, the Driver Manager displays the following dialog box.
After the user selects a data source, the Driver Manager constructs a connection string specifying that data
source and passes it to the driver. The driver can then prompt the user for any additional information it needs.
The conditions under which the driver prompts the user are controlled by the DriverCompletion flag; there are
options to always prompt, prompt if necessary, or never prompt. For a complete description of this flag, see the
SQLDriverConnect function description.
Connecting Using File Data Sources
4/27/2022 • 2 minutes to read • Edit Online
The connection information for a file data source is stored in a .dsn file. As a result, the connection string can be
used repeatedly by a single user or shared among several users if they have the appropriate driver installed. The
file contains a driver name (or another data source name in the case of an unshareable file data source) and
optionally, a connection string that can be used by SQLDriverConnect . The Driver Manager builds the
connection string for the call to SQLDriverConnect from the keywords in the .dsn file.
A file data source allows an application to specify connection options without having to build a connection string
for use with SQLDriverConnect . The file data source usually is created by specifying the SAVEFILE keyword,
which causes the Driver Manager to save the output connection string created by a call to SQLDriverConnect
to the .dsn file. That connection string can be used repeatedly by calling SQLDriverConnect with the FILEDSN
keyword. This streamlines the connection process and provides a persistent source of the connection string.
File data sources also can be created by calling SQLCreateDataSource in the installer DLL. Information can be
written into the .dsn file by calling SQLWriteFileDSN , and read from the .dsn file by calling SQLReadFileDSN ;
both of these functions are also in the installer DLL. For information about the installer DLL, see Configuring
Data Sources.
The keywords used for connection information are in the [ODBC] section of a .dsn file. The minimum
information that a shareable .dsn file would have in the [ODBC] section is the DRIVER keyword:
When the file data source is unshareable, the .dsn file contains only a DSN keyword. When the Driver Manager
is sent the information in an unshareable file data source, it connects as necessary to the data source indicated
by the DSN keyword. An unshareable .dsn file would contain the following keyword:
DSN = MyDataSource
The connection string used for a file data source is the union of the keywords specified in the .dsn file and the
keywords specified in the connection string in the call to SQLDriverConnect . If any of the keywords in the .dsn
file conflict with keywords in the connection string, the Driver Manager decides which keyword value should be
used. For more information, see SQLDriverConnect.
See Also
https://support.microsoft.com/kb/165866
Connecting Directly to Drivers
4/27/2022 • 2 minutes to read • Edit Online
As was discussed in Choosing a Data Source or Driver, earlier in this section, some applications do not want to
use a data source at all. Instead, they want to connect directly to a driver. SQLDriverConnect provides a way
for the application to connect directly to a driver without specifying a data source. Conceptually, a temporary
data source is created at run time.
To connect directly to a driver, the application specifies the DRIVER keyword in the connection string instead of
the DSN keyword. The value of the DRIVER keyword is the description of the driver as returned by
SQLDrivers . For example, suppose a driver has the description Paradox Driver and requires the name of a
directory containing the data files. To connect to this driver, the application might use either of the following
connection strings:
DRIVER={Paradox Driver};Directory=C:\PARADOX;
DRIVER={Paradox Driver};
With the first string, the driver would not need any additional information. With the second string, the driver
would need to prompt for the name of the directory containing the data files.
Connecting with SQLBrowseConnect
4/27/2022 • 2 minutes to read • Edit Online
The following example shows how SQLBrowseConnect might be used to browse the connections available
with a driver for SQL Server. First, the application requests a connection handle:
Next, the application calls SQLBrowseConnect and specifies the SQL Server driver, using the driver description
returned by SQLDrivers :
Because this is the first call to SQLBrowseConnect , the Driver Manager loads the SQL Server driver and calls
the driver's SQLBrowseConnect function with the same arguments it received from the application.
NOTE
If you are connecting to a data source provider that supports Windows authentication, you should specify
Trusted_Connection=yes instead of user ID and password information in the connection string.
The driver determines that this is the first call to SQLBrowseConnect and returns the second level of
connection attributes: server, user name, password, application name, and workstation ID. For the server
attribute, it returns a list of valid server names. The return code from SQLBrowseConnect is SQL_NEED_DATA.
Here is the browse result string:
"SERVER:Server={red,blue,green,yellow};UID:Login ID=?;PWD:Password=?;
*APP:AppName=?;*WSID:WorkStation ID=?;"
Each keyword in the browse result string is followed by a colon and one or more words before the equal sign.
These words are the user-friendly name that an application can use to build a dialog box. The APP and WSID
keywords are prefixed by an asterisk, which means they are optional. The SERVER , UID , and PWD keywords
are not prefixed by an asterisk; values must be supplied for them in the next browse request string. The value for
the SERVER keyword may be one of the servers returned by SQLBrowseConnect or a user-supplied name.
The application calls SQLBrowseConnect again, specifying the green server and omitting the APP and WSID
keywords and the user-friendly names after each keyword:
The driver attempts to connect to the green server. If there are any nonfatal errors, such as a missing keyword-
value pair, SQLBrowseConnect returns SQL_NEED_DATA and remains in the same state as it was prior to the
error. The application can call SQLGetDiagField or SQLGetDiagRec to determine the error. If the connection is
successful, the driver returns SQL_NEED_DATA and returns the browse result string:
"*DATABASE:Database={master,model,pubs,tempdb};
*LANGUAGE:Language={us_english,Franais};"
Because the attributes in this string are optional, the application can omit them. However, the application must
call SQLBrowseConnect again. If the application chooses to omit the database name and language, it specifies
an empty browse request string. In this example, the application chooses the pubs database and calls
SQLBrowseConnect a final time, omitting the L ANGUAGE keyword and the asterisk before the DATABASE
keyword:
Because the DATABASE attribute is the final connection attribute required by the driver, the browsing process is
complete, the application is connected to the data source, and SQLBrowseConnect returns SQL_SUCCESS.
SQLBrowseConnect also returns the complete connection string as the browse result string:
"DSN=MySQLServer;SERVER=green;UID=Smith;PWD=Sesame;DATABASE=pubs;"
The final connection string returned by the driver does not contain the user-friendly names after each keyword,
nor does it contain optional keywords not specified by the application. The application can use this string with
SQLDriverConnect to reconnect to the data source on the current connection handle (after disconnecting) or
to connect to the data source on a different connection handle. For example:
Connection pooling enables an application to use a connection from a pool of connections that do not need to
be re-established for each use. Once a connection has been created and placed in a pool, an application can
reuse that connection without performing the complete connection process.
Using a pooled connection can result in significant performance gains, because applications can save the
overhead involved in making a connection. This can be particularly significant for middle-tier applications that
connect over a network or for applications that repeatedly connect and disconnect, such as Internet applications.
In addition to performance gains, the connection pooling architecture enables an environment and its associated
connections to be used by multiple components in a single process. This means that stand-alone components in
the same process can interact with each other without being aware of each other. A connection in a connection
pool can be used repeatedly by multiple components.
NOTE
Connection pooling can be used by an ODBC application exhibiting ODBC 2.x behavior, as long as the application can call
SQLSetEnvAttr. When using connection pooling, the application must not execute SQL statements that change the
database or the context of the database, such as changing the <database name>, which changes the catalog used by a
data source.
An ODBC driver must be fully thread-safe, and connections must not have thread affinity to support connection
pooling. This means the driver is able to handle a call on any thread at any time and is able to connect on one
thread, to use the connection on another thread, and to disconnect on a third thread.
The connection pool is maintained by the Driver Manager. Connections are drawn from the pool when the
application calls SQLConnect or SQLDriverConnect and are returned to the pool when the application calls
SQLDisconnect . The size of the pool grows dynamically, based on the requested resource allocations. It shrinks
based on the inactivity timeout: If a connection is inactive for a period of time (it has not been used in a
connection), it is removed from the pool. The size of the pool is limited only by memory constraints and limits
on the server.
The Driver Manager determines whether a specific connection in a pool should be used according to the
arguments passed in SQLConnect or SQLDriverConnect , and according to the connection attributes set after
the connection was allocated.
When the Driver Manager is pooling connections, it needs to be able to determine if a connection is still working
before handing out the connection. Otherwise, the Driver Manager keeps on handing out the dead connection
to the application whenever a transient network failure occurs. A new connection attribute has been defined in
ODBC 3*.x*: SQL_ATTR_CONNECTION_DEAD. This is a read-only connection attribute that returns either
SQL_CD_TRUE or SQL_CD_FALSE. The value SQL_CD_TRUE means that the connection has been lost, while the
value SQL_CD_FALSE means that the connection is still active. (Drivers conforming to earlier versions of ODBC
can also support this attribute.)
A driver must implement this option efficiently or it will impair the connection pooling performance. Specifically,
a call to get this connection attribute should not cause a round trip to the server. Instead, a driver should just
return the last known state of the connection. The connection is dead if the last trip to the server failed, and not
dead if the last trip succeeded.
Remarks
If a connection has been lost (reported via SQL_ATTR_CONNECTION_DEAD), the ODBC Driver Manager will
destroy that connection by calling SQLDisconnect in the driver. New connection requests might not find a usable
connection in the pool. Eventually the Driver Manager might make a new connection, assuming the pool is
empty.
To use a connection pool, an application performs the following steps:
1. Enables connection pooling by calling SQLSetEnvAttr to set the SQL_ATTR_CONNECTION_POOLING
environment attribute to SQL_CP_ONE_PER_DRIVER or SQL_CP_ONE_PER_HENV. This call must be made
before the application allocates the shared environment for which connection pooling is to be enabled.
The environment handle in the call to SQLSetEnvAttr should be set to null, which makes
SQL_ATTR_CONNECTION_POOLING a process-level attribute. If the attribute is set to
SQL_CP_ONE_PER_DRIVER, a single connection pool is supported for each driver. If an application works
with many drivers and few environments, this might be more efficient because fewer comparisons may
be required. If set to SQL_CP_ONE_PER_HENV, a single connection pool is supported for each
environment. If an application works with many environments and few drivers, this might be more
efficient because fewer comparisons may be required. Connection pooling is disabled by setting
SQL_ATTR_CONNECTION_POOLING to SQL_CP_OFF.
2. Allocates an environment by calling SQL AllocHandle with the HandleType argument set to
SQL_HANDLE_ENV. The environment allocated by this call will be an implicit shared environment because
connection pooling has been enabled. The environment to be used is not determined, however, until
SQL AllocHandle with a HandleType of SQL_HANDLE_DBC is called on this environment.
3. Allocates a connection by calling SQL AllocHandle with InputHandle set to SQL_HANDLE_DBC, and the
InputHandle set to the environment handle allocated for connection pooling. The Driver Manager
attempts to find an existing environment that matches the environment attributes set by the application.
If no such environment exists, one is created, with a reference count (maintained by the Driver Manager)
of 1. If a matching shared environment is found, the environment is returned to the application and its
reference count is incremented. (The actual connection to be used is not determined by the Driver
Manager until SQLConnect or SQLDriverConnect is called.)
4. Calls SQLConnect or SQLDriverConnect to make the connection. The Driver Manager uses the
connection options in the call to SQLConnect (or the connection keywords in the call to
SQLDriverConnect ) and the connection attributes set after connection allocation to determine which
connection in the pool should be used.
NOTE
How a requested connection is matched to a pooled connection is determined by the SQL_ATTR_CP_MATCH
environment attribute. For more information, see SQLSetEnvAttr.
ODBC applications using connection pooling should call CoInitializeEx during application initialization
and CoUninitialize when the application closes.
5. Calls SQLDisconnect when done with the connection. The connection is returned to the connection pool
and becomes available for reuse.
For an in-depth discussion, see Pooling in the Microsoft Data Access Components.
NOTE
Do not expect certain settings to be present in the connection state. You should always set the connection state in your
application and ensure that the application removes any unused connection pooling settings.
See Also
Connecting to a Data Source or Driver
Developing an ODBC Driver
Pooling in the Microsoft Data Access Components
Driver-Aware Connection Pooling
4/27/2022 • 2 minutes to read • Edit Online
Driver aware connection pooling is a new feature of the Driver Manager in Windows 8. Driver aware connection
pooling allows driver writers to customize the connection pooling behavior in their ODBC driver.
NOTE
Driver aware connection pooling is not supported with cursor library. An application will receive error message if it
attempts to enable cursor library via SQLSetConnectAttr, when driver aware connection pooling is enabled.
Driver aware connection pooling addresses the following problems related to Driver Manager connection
pooling:
Pool Fragmentation The Driver Manager will only return a connection from the pool if it is an exact match
with the connection string of a new connection request. One reason for the Driver Manager to require an exact
match is that the Driver Manager does not understand every driver-specific connection string keyword and its
value. However, some connection string keyword values (such as the name of the database) may not require an
exact match, since the driver can change the database in less than the time needed to open a new connection
(the exact time difference depends on the data source). And, differences in some connection attributes (such as
SQL_ATTR_CURRENT_CATALOG) can take more time to change than differences in other attributes (such as
SQL_ATTR_LOGIN_TIMEOUT). This, too, can prevent the Driver Manager from using the lowest-cost, reusable
connection from the pool. When a driver has to create many new connections, an application's performance can
decrease and the data source scalability can decrease. Pool fragmentation can be reduced with driver-aware
connection pooling because a driver can better estimate the cost of reusing a connection in the pool for a
connection request.
No consideration of application preference Some data sources can efficiently open new connections
(compared to resetting some attributes), so, an application may prefer to open a new connection instead of
trying to reuse a slightly mismatched connection from the pool and reset some values (although this may be
slower during the connection pool initialization phrase). But some applications may keep the server load smaller
and open fewer connections, although there may be a bigger cost to fix the mismatches for correct behavior.
Without driver-aware connection pooling, you cannot specify this kind of preference effectively, because the
Driver Manager does not recognize all driver-specific connection attributes. Driver-aware connection pooling
allows a driver to obtain the user preference (with a driver-specific attribute of SQLSetConnectAttr) so that it can
better estimate the cost of reusing a connection from the pool based on a user's preference.
For more information about driver-aware connection pooling, see Developing Connection-Pool Awareness in an
ODBC Driver.
See Also
Developing an ODBC Driver
Disconnecting from a Data Source or Driver
4/27/2022 • 2 minutes to read • Edit Online
When an application has finished using a data source, it calls SQLDisconnect . SQLDisconnect frees any
statements that are allocated on the connection and disconnects the driver from the data source. It returns an
error if a transaction is in process.
After disconnecting, the application can call SQLFreeHandle to free the connection. After freeing the
connection, it is an application programming error to use the connection's handle in a call to an ODBC function;
doing so has undefined but probably fatal consequences. When SQLFreeHandle is called, the driver releases
the structure used to store information about the connection.
The application also can reuse the connection, either to connect to a different data source or reconnect to the
same data source. The decision to remain connected, as opposed to disconnecting and reconnecting later,
requires that the application writer consider the relative costs of each option; both connecting to a data source
and remaining connected can be relatively costly depending on the connection medium. In making a correct
tradeoff, the application must also make assumptions about the likelihood and timing of further operations on
the same data source.
Driver Manager's Role in the Connection Process
4/27/2022 • 2 minutes to read • Edit Online
Remember that applications do not call driver functions directly. Instead, they call Driver Manager functions with
the same name and the Driver Manager calls the driver functions. Usually, this happens almost immediately. For
example, the application calls SQLExecute in the Driver Manager and after a few error checks, the Driver
Manager calls SQLExecute in the driver.
The connection process is different. When the application calls SQL AllocHandle with the SQL_HANDLE_ENV
and SQL_HANDLE_DBC options, the function allocates handles only in the Driver Manager. The Driver Manager
does not call this function in the driver because it does not know which driver to call. Similarly, if the application
passes the handle of an unconnected connection to SQLSetConnectAttr or SQLGetConnectAttr , only the
Driver Manager executes the function. It stores or gets the attribute value from its connection handle and
returns SQLSTATE 08003 (Connection not open) when getting a value for an attribute that has not been set and
for which ODBC does not define a default value.
When the application calls SQLConnect , SQLDriverConnect , or SQLBrowseConnect , the Driver Manager
first determines which driver to use. It then checks to determine whether a driver is currently loaded on the
connection:
If no driver is loaded on the connection, the Driver Manager checks whether the specified driver is loaded
on another connection in the same environment. If not, the Driver Manager loads the driver on the
connection and calls SQL AllocHandle in the driver with the SQL_HANDLE_ENV option.
The Driver Manager then calls SQL AllocHandle in the driver with the SQL_HANDLE_DBC option,
whether or not it was just loaded. If the application set any connection attributes, the Driver Manager calls
SQLSetConnectAttr in the driver; if an error occurs, the Driver Manager's connection function returns
SQLSTATE IM006 (Driver's SQLSetConnectAttr failed). Finally, the Driver Manager calls the connection
function in the driver.
If the specified driver is loaded on the connection, the Driver Manager calls only the connection function
in the driver. In this case, the driver must make sure that all connection attributes on the connection
maintain their current settings.
If a different driver is loaded on the connection, the Driver Manager calls SQLFreeHandle in the driver
to free the connection. If there are no other connections that use the driver, the Driver Manager calls
SQLFreeHandle in the driver to free the environment and unloads the driver. The Driver Manager then
performs the same operations as when a driver is not loaded on the connection.
The Driver Manager will lock the environment handle (henv) before calling a driver's SQL AllocHandle and
SQLFreeHandle when HandleType is set to SQL_HANDLE_DBC .
When the application calls SQLDisconnect , the Driver Manager calls SQLDisconnect in the driver. However, it
leaves the driver loaded in case the application reconnects to the driver. When the application calls
SQLFreeHandle with the SQL_HANDLE_DBC option, the Driver Manager calls SQLFreeHandle in the driver. If
the driver is not used by any other connections, the Driver Manager then calls SQLFreeHandle in the driver
with the SQL_HANDLE_ENV option and unloads the driver.
Catalog Functions
4/27/2022 • 2 minutes to read • Edit Online
All databases have a structure that outlines how data will be stored in the database. For example, a simple sales
order database might have the structure shown in the following illustration, in which the ID columns are used to
link the tables.
This structure, along with other information such as privileges, is stored in a set of system tables called the
database's catalog, which is also known as a data dictionary.
An application can discover this structure through calls to the catalog functions. The catalog functions return
information in result sets and are usually implemented through SELECT statements against the tables in the
catalog. For example, an application might request a result set containing information about all the tables on the
system or all the columns in a particular table.
This section contains the following topics.
Uses of Catalog Data
Catalog Functions in ODBC
Uses of Catalog Data
4/27/2022 • 2 minutes to read • Edit Online
Applications use catalog data in a variety of ways. Here are some common uses:
Constructing SQL statements at run time. Vertical applications, such as an order entry application,
contain hard-coded SQL statements. The tables and columns that are used by the application are fixed
ahead of time, as are the statements that access these tables. For example, an order entry application
usually contains a single, parameterized INSERT statement for adding new orders to the system.
Generic applications, such as a spreadsheet program that uses ODBC to retrieve data, often construct SQL
statements at run time based on input from the user. Such an application could require the user to type
the names of the tables and columns to use. However, it would be easier for the user if the application
displayed lists of tables and columns from which the user could make selections. To build these lists, the
application would call the SQLTables and SQLColumns catalog functions.
Constructing SQL statements during development. Application development environments
typically allow the programmer to create database queries while developing a program. The queries are
then hard-coded in the application being built.
Such environments could also use SQLTables and SQLColumns to create lists from which the
programmer could make selections. These environments might also use SQLPrimar yKeys and
SQLForeignKeys to automatically determine and show relationships between selected tables, and use
SQLStatistics to determine and highlight indexed fields so the programmer can create efficient queries.
Constructing cursors. An application, driver, or middleware that provides a scrollable cursor engine
could use SQLSpecialColumns to determine which column or columns uniquely identify a row. The
program could build a keyset containing the values of these columns for each row that has been fetched.
When the application scrolls back to the row, it would then use these values to fetch the most recent data
for the row. For more information about scrollable cursors and keysets, see Scrollable Cursors.
Catalog Functions in ODBC
4/27/2022 • 2 minutes to read • Edit Online
F UN C T IO N DESC RIP T IO N
SQLPrimar yKeys Returns a list of columns that compose the primary key of a
single table.
SQLGetTypeInfo Returns a list of the SQL data types supported by the data
source. These data types are generally used in CREATE
TABLE and ALTER TABLE statements.
Because SQLTables , SQLColumns , SQLStatistics , and SQLSpecialColumns conform to the Open Group CLI,
and SQLGetTypeInfo conforms to the ISO 92 CLI, they are implemented by most drivers. The remaining
catalog functions are in the ODBC conformance level.
This section contains the following topics.
Data Returned by Catalog Functions
Arguments in Catalog Functions
Schema Views
Data Returned by Catalog Functions
4/27/2022 • 2 minutes to read • Edit Online
Each catalog function returns data as a result set. This result set is no different from any other result set. It is
usually generated by a predefined, parameterized SELECT statement that is hard-coded in the driver or stored
in a procedure in the data source. For information about how to retrieve data from a result set, see Was a Result
Set Created?.
The result set for each catalog function is described in the reference entry for that function. In addition to the
listed columns, the result set can contain driver-specific columns after the last predefined column. These
columns (if any) are described in the driver documentation.
Applications should bind driver-specific columns relative to the end of the result set. That is, they should
calculate the number of a driver-specific column as the number of the last column - retrieved with
SQLNumResultCols - less the number of columns that occur after the required column. This saves having to
change the application when new columns are added to the result set in future versions of ODBC or the driver.
For this scheme to work, drivers must add new driver-specific columns before old driver-specific columns so
that column numbers do not change relative to the end of the result set.
Identifiers that are returned in the result set are not quoted, even if they contain special characters. For example,
suppose the identifier quote character (which is driver-specific and returned through SQLGetInfo ) is a double
quotation mark (") and the Accounts Payable table contains a column named Customer Name. In the row
returned by SQLColumns for this column, the value of the TABLE_NAME column is Accounts Payable, not
"Accounts Payable", and the value of the COLUMN_NAME column is Customer Name, not "Customer Name". To
retrieve the names of customers in the Accounts Payable table, the application would quote these names:
All catalog functions accept arguments with which an application can restrict the scope of the data returned. For
example, the first and second calls to SQLTables in the following code return a result set containing information
about all tables, while the third call returns information about the Orders table:
Catalog function string arguments fall into four different types: ordinary argument (OA), pattern value argument
(PV), identifier argument (ID), and value list argument (VL). Most string arguments can be of one of two different
types, depending on the value of the SQL_ATTR_METADATA_ID statement attribute. The following table lists the
arguments for each catalog function and describes the type of the argument for an SQL_TRUE or SQL_FALSE
value of SQL_ATTR_METADATA_ID.
T Y P E W H EN SQ L _ T Y P E W H EN SQ L _
SQLForeignKeys PKCatalogName OA OA OA OA OA OA ID ID ID ID ID ID
PKSchemaName
PKTableName
FKCatalogName
FKSchemaName
FKTableName
When a catalog function string argument is an ordinary argument, it is treated as a literal string. An ordinary
argument accepts neither a string search pattern nor a list of values. The case of an ordinary argument is
significant, and quote characters in the string are taken literally. These arguments are treated as ordinary
arguments if the SQL_ATTR_METADATA_ID statement attribute is set to SQL_FALSE; they are treated as identifier
arguments instead if this attribute is set to SQL_TRUE.
If an ordinary argument is set to a null pointer and the argument is a required argument, the function returns
SQL_ERROR and SQLSTATE HY009 (Invalid use of null pointer). If an ordinary argument is set to a null pointer
and the argument is not a required argument, the argument's behavior is driver-dependent. The required
arguments are listed in the following table.
SQLColumnPrivileges TableName
SQLSpecialColumns TableName
SQLStatistics TableName
Pattern Value Arguments
4/27/2022 • 2 minutes to read • Edit Online
Some arguments in the catalog functions, such as the TableName argument in SQLTables , accept search
patterns. These arguments accept search patterns if the SQL_ATTR_METADATA_ID statement attribute is set to
SQL_FALSE; they are identifier arguments that do not accept a search pattern if this attribute is set to SQL_TRUE.
The search pattern characters are:
An underscore (_), which represents any single character.
A percent sign (%), which represents any sequence of zero or more characters.
An escape character, which is driver-specific and is used to include underscores, percent signs, and the
escape character as literals. If the escape character precedes a non-special character, the escape character
has no special meaning. If the escape character precedes a special character, it escapes the special
character. For example, "\a" would be treated as two characters, "\" and "a", but "\%" would be treated as
the non-special single character "%".
The escape character is retrieved with the SQL_SEARCH_PATTERN_ESCAPE option in SQLGetInfo . It must
precede any underscore, percent sign, or escape character in an argument that accepts search patterns to
include that character as a literal. Examples are shown in the following table.
Special care must be taken to escape search pattern characters in arguments that accept search patterns. This is
particularly true for the underscore character, which is commonly used in identifiers. A common mistake in
applications is to retrieve a value from one catalog function and pass that value to a search pattern argument in
another catalog function. For example, suppose an application retrieves the table name MY_TABLE from the
result set for SQLTables and passes this to SQLColumns to retrieve a list of columns in MY_TABLE. Instead of
getting the columns for MY_TABLE, the application will get the columns for all the tables that match the search
pattern MY_TABLE, such as MY_TABLE, MY1TABLE, MY2TABLE, and so on.
NOTE
ODBC 2.x drivers do not support search patterns in the CatalogName argument in SQLTables . ODBC 3*.x* drivers accept
search patterns in this argument if the SQL_ATTR_ ODBC_VERSION environment attribute is set to SQL_OV_ODBC3; they
do not accept search patterns in this argument if it is set to SQL_OV_ODBC2.
Passing a null pointer to a search pattern argument does not constrain the search for that argument; that is, a
null pointer and the search pattern % (any characters) are equivalent. However, a zero-length search pattern -
that is, a valid pointer to a string of length zero - matches only the empty string ("").
Identifier Arguments
4/27/2022 • 2 minutes to read • Edit Online
If a string in an identifier argument is quoted, the driver removes leading and trailing blanks and treats literally
the string within the quotation marks. If the string is not quoted, the driver removes trailing blanks and folds the
string to uppercase. Setting an identifier argument to a null pointer returns SQL_ERROR and SQLSTATE HY009
(Invalid use of null pointer), unless the argument is a catalog name and catalogs are not supported.
These arguments are treated as identifier arguments if the SQL_ATTR_METADATA_ID statement attribute is set to
SQL_TRUE. In this case, the underscore (_) and the percent sign (%) will be treated as the actual character, not as
a search pattern character. These arguments are treated as either an ordinary argument or a pattern argument,
depending on the argument, if this attribute is set to SQL_FALSE.
Although identifiers containing special characters must be quoted in SQL statements, they must not be quoted
when passed as catalog function arguments, because quote characters passed to catalog functions are
interpreted literally. For example, suppose the identifier quote character (which is driver-specific and returned
through SQLGetInfo ) is a double quotation mark ("). The first call to SQLTables returns a result set containing
information about the Accounts Payable table, while the second call returns information about the "Accounts
Payable" table, which is probably not what was intended.
Quoted identifiers are used to distinguish a true column name from a pseudo-column of the same name, such
as ROWID in Oracle. If "ROWID" is passed in an argument of a catalog function, the function will work with the
ROWID pseudo-column if it exists. If the pseudo-column does not exist, the function will work with the "ROWID"
column. If ROWID is passed in an argument of a catalog function, the function will work with the ROWID
column.
For more information about quoted identifiers, see Quoted Identifiers.
Value List Arguments
4/27/2022 • 2 minutes to read • Edit Online
A value list argument consists of a list of comma-separated values to be used for matching. There is only one
value list argument in the ODBC catalog functions: the TableType argument in SQLTables . Setting TableType to a
null pointer is the same as if it is set to SQL_ALL_TABLE_TYPES, which enumerates all possible members of the
value list. This argument is not affected by the SQL_ATTR_METADATA_ID statement attribute. For more
information, see the SQLTables function description.
Schema Views
4/27/2022 • 2 minutes to read • Edit Online
An application can retrieve metadata information from the DBMS either by calling ODBC catalog functions or by
using INFORMATION_SCHEMA views. The views are defined by the ANSI SQL-92 standard.
If supported by the DBMS and the driver, the INFORMATION_SCHEMA views provide a more powerful and
comprehensive means of retrieving metadata than the ODBC catalog functions provide. An application can
execute its own custom SELECT statement against one of these views, can join views, or can perform a union on
views. While offering greater utility and a wider range of metadata, INFORMATION_SCHEMA views are not often
supported by the DBMS. This might change as more DBMSs and drivers achieve compliance with SQL-92.
To determine which views are supported, an application calls SQLGetInfo with the SQL_INFO_SCHEMA_VIEWS
option. To retrieve metadata from a supported view, the application executes a SELECT statement that specifies
the schema information required.
SQL Statements
4/27/2022 • 2 minutes to read • Edit Online
ODBC applications perform almost all database access by executing SQL statements. The form of these
statements - hard-coded or constructed at run time, interoperable or data source-specific, and so on - depends
on the needs of the application.
This section contains the following topics.
Constructing SQL Statements
Interoperability of SQL Statements
Escape Sequences in ODBC
Constructing SQL Statements
4/27/2022 • 2 minutes to read • Edit Online
SQL statements can be constructed in one of three ways: hard-coded during development, constructed at run
time, or entered directly by the user.
This section contains the following topics.
Hard-Coded SQL Statements
SQL Statements Constructed at Run Time
SQL Statements Entered by the User
Hard-Coded SQL Statements
4/27/2022 • 3 minutes to read • Edit Online
Applications that perform a fixed task usually contain hard-coded SQL statements. For example, an order entry
system might use the following call to list open sales orders:
There are several advantages to hard-coded SQL statements: They can be tested when the application is written;
they are simpler to implement than statements constructed at run time; and they simplify the application.
Using statement parameters and preparing statements provide even better ways to use hard-coded SQL
statements. For example, suppose the Parts table contains the PartID, Description, and Price columns. One way
to insert a new row into this table would be to construct and execute an INSERT statement:
#define DESC_LEN 51
#define STATEMENT_LEN 51
SQLUINTEGER PartID;
SQLCHAR Desc[DESC_LEN], Statement[STATEMENT_LEN];
SQLREAL Price;
An even better way is to use a hard-coded, parameterized statement. This has two advantages over a statement
with hard-coded data values. First, it is easier to construct a parameterized statement because the data values
can be sent in their native types, such as integers and floating-point numbers, rather than converting them to
strings. Second, such a statement can be used more than once simply by changing the parameter values and
reexecuting it; there is no need to rebuild it.
#define DESC_LEN 51
Assuming this statement is to be executed more than once, it can be prepared for even greater efficiency:
#define DESC_LEN 51
Perhaps the most efficient way to use the statement is to construct a procedure containing the statement, as
shown in the following code example. Because the procedure is constructed at development time and stored on
the data source, it does not need to be prepared at run time. A drawback of this method is that the syntax for
creating procedures is DBMS-specific and procedures must be constructed separately for each DBMS on which
the application is to run.
#define DESC_LEN 51
SQLUINTEGER PartID;
SQLCHAR Desc[DESC_LEN];
SQLREAL Price;
SQLINTEGER PartIDInd = 0, DescLenOrInd = SQL_NTS, PriceInd = 0;
For more information about parameters, prepared statements, and procedures, see Executing a Statement.
SQL Statements Constructed at Run Time
4/27/2022 • 2 minutes to read • Edit Online
Applications that perform ad hoc analysis commonly build SQL statements at run time. For example, a
spreadsheet might allow a user to select columns from which to retrieve data:
// SQL_Statements_Constructed_at_Run_Time.cpp
#include <windows.h>
#include <stdio.h>
#include <sqltypes.h>
int main() {
SQLCHAR *Statement = 0, *TableName = 0;
SQLCHAR **TableNamesArray, **ColumnNamesArray = 0;
BOOL *ColumnSelectedArray = 0;
BOOL CommaNeeded;
SQLSMALLINT i = 0, NumColumns = 0;
Another class of applications that commonly constructs SQL statements at run time are application
development environments. However, the statements they construct are hard-coded in the application they are
building, where they can usually be optimized and tested.
Applications that construct SQL statements at run time can provide tremendous flexibility to the user. As can be
seen from the preceding example, which did not even support such common operations as WHERE clauses,
ORDER BY clauses, or joins, constructing SQL statements at run time is vastly more complex than hard-coding
statements. Furthermore, testing such applications is problematic because they can construct an arbitrary
number of SQL statements.
A potential disadvantage of constructing SQL statements at run time is that it takes far more time to construct a
statement than use a hard-coded statement. Fortunately, this is rarely a concern. Such applications tend to be
user-interface intensive, and the time the application spends constructing SQL statements is generally small
compared to the time the user spends entering criteria.
SQL Statements Entered by the User
4/27/2022 • 2 minutes to read • Edit Online
Applications that perform ad hoc analysis also commonly allow the user to enter SQL statements directly. For
example:
This approach simplifies application coding; the application relies on the user to build the SQL statement and on
the data source to check the statement's validity. Because it's difficult to write a graphical user interface that
adequately exposes the intricacies of SQL, simply asking the user to enter the SQL statement text may be a
preferable alternative. However, this requires the user to know not only SQL but also the schema of the data
source being queried. Some applications provide a graphical user interface by which the user can create a basic
SQL statement and also provide a text interface with which the user can modify it.
Interoperability of SQL Statements
4/27/2022 • 2 minutes to read • Edit Online
Like the rest of an application, SQL statements can be interoperable or DBMS-specific. And like the rest of the
application, the choice of how interoperable SQL statements need to be depends on the type of application.
Custom applications are less likely to use interoperable SQL statements because they are usually designed to
exploit the capabilities of one or possibly two DBMSs. Generic applications use interoperable SQL statements
because they are designed to work with a variety of DBMSs. And vertical applications usually fall somewhere in
between, demanding a certain level of functionality but otherwise using interoperable SQL statements.
This section contains the following topics.
Choosing an SQL Grammar
Constructing Interoperable SQL Statements
Choosing an SQL Grammar
4/27/2022 • 2 minutes to read • Edit Online
The first decision to make when constructing SQL statements is which grammar to use. In addition to the
grammars available from the various standards bodies, such as Open Group, ANSI, and ISO, virtually every
DBMS vendor defines its own grammar, each of which varies slightly from the standard.
Appendix C: SQL Grammar, describes the minimum SQL grammar that all ODBC drivers must support. This
grammar is a subset of the Entry level of SQL-92. Drivers may support additional grammar to conform to the
Intermediate, Full, or FIPS 127-2 Transitional levels defined by SQL-92. For more information, see SQL Minimum
Grammar in Appendix C: SQL Grammar, and SQL-92.
Appendix C also defines escape sequences containing standard grammar for commonly available language
features, such as outer joins, that are not covered by the SQL-92 grammar. For more information, see ODBC
Escape Sequences in Appendix C: SQL Grammar, and Escape Sequences, later in this section.
The grammar that is chosen affects how the driver processes the statement. Drivers must modify SQL-92 SQL
and the ODBC-defined escape sequences to DBMS-specific SQL. Because most SQL grammars are based on one
or more of the various standards, most drivers do little or no work to meet this requirement. It often consists
only of searching for the escape sequences defined by ODBC and replacing them with DBMS-specific grammar.
When a driver encounters grammar it does not recognize, it assumes the grammar is DBMS-specific and passes
the SQL statement without modification to the data source for execution.
Therefore, there are really two choices of grammar to use: the SQL-92 grammar (and the ODBC escape
sequences) and a DBMS-specific grammar. Of the two, only the SQL-92 grammar is interoperable, so all
interoperable applications should use it. Applications that are not interoperable can use the SQL-92 grammar or
a DBMS-specific grammar. DBMS-specific grammars have two advantages: They can exploit any features not
covered by SQL-92, and they are marginally faster because the driver does not have to modify them. The latter
feature can be partially enforced by setting the SQL_ATTR_NOSCAN statement attribute, which stops the driver
from searching for and replacing escape sequences.
If the SQL-92 grammar is used, the application can discover how it is modified by the driver by calling
SQLNativeSql . This is often useful when debugging applications. SQLNativeSql accepts an SQL statement
and returns it after the driver has modified it. Because this function is in the Core interface conformance level, it
is supported by all drivers.
Constructing Interoperable SQL Statements
4/27/2022 • 2 minutes to read • Edit Online
As mentioned in the previous sections, interoperable applications should use the ODBC SQL grammar. Beyond
using this grammar, however, a number of additional problems are faced by interoperable applications. For
example, what does an application do if it wants to use a feature, such as outer joins, that is not supported by all
data sources?
At this point, the application writer must make some decisions about which language features are required and
which are optional. In most cases, if a particular driver does not support a feature required by the application,
the application simply refuses to run with that driver. However, if the feature is optional, the application can work
around the feature. For example, it might disable those parts of the interface that allow the user to use the
feature.
To determine which features are supported, applications start by calling SQLGetInfo with the
SQL_SQL_CONFORMANCE option. The SQL conformance level gives the application a broad view of which SQL
is supported. To refine this view, the application calls SQLGetInfo with any of a number of other options. For a
complete list of these options, see the SQLGetInfo function description. Finally, SQLGetTypeInfo returns
information about the data types supported by the data source. The following sections list a number of possible
factors that applications should watch for when constructing interoperable SQL statements.
This section contains the following topics.
Catalog and Schema Usage
Catalog Position
Quoted Identifiers
Identifier Case
Escape Sequences
Literal Prefixes and Suffixes
Parameter Markers in Procedure Calls
DDL Statements
Catalog and Schema Usage
4/27/2022 • 2 minutes to read • Edit Online
Data sources do not necessarily support catalog and schema names as object name identifiers in all SQL
statements. Data sources might support catalog and schema names in one or more of the following classes of
SQL statements: Data Manipulation Language (DML) statements, procedure calls, table definition statements,
index definition statements, and privilege definition statements. To determine the classes of SQL statements in
which catalog and schema names can be used, an application calls SQLGetInfo with the SQL_CATALOG_USAGE
and SQL_SCHEMA_USAGE options.
Catalog Position
4/27/2022 • 2 minutes to read • Edit Online
The position of a catalog name in an identifier and how it is separated from the rest of the identifier varies from
data source to data source. For example, in an Xbase data source, the catalog name is a directory and, in
Microsoft® Windows®, is separated from the table name (which is a file name) by a backslash (\). The
following illustration demonstrates this condition.
In a SQL Server data source, the catalog is a database and is separated from the schema and table names by a
period (.).
In an Oracle data source, the catalog is also the database but follows the table name and is separated from the
schema and table names by an at sign (@).
To determine the catalog separator and the location of the catalog name, an application calls SQLGetInfo with
the SQL_CATALOG_NAME_SEPARATOR and SQL_CATALOG_LOCATION options. Interoperable applications
should construct identifiers according to these values.
When quoting identifiers that contain more than one part, applications must be careful to quote each part
separately and not quote the character that separates the identifiers. For example, the following statement to
select all of the rows and columns of an Xbase table quotes the catalog (\XBASE\SALES\CORP) and table
(Parts.dbf) names, but not the catalog separator (\):
The following statement to select all of the rows and columns of an Oracle table quotes the catalog (Sales),
schema (Corporate), and table (Parts) names, but not the catalog (@) or schema (.) separators:
For information about quoting identifiers, see the next section, Quoted Identifiers.
Quoted Identifiers
4/27/2022 • 2 minutes to read • Edit Online
In an SQL statement, identifiers containing special characters or match keywords must be enclosed in identifier
quote characters; identifiers enclosed in such characters are known as quoted identifiers (also known as
delimited identifiers in SQL-92). For example, the Accounts Payable identifier is quoted in the following SELECT
statement:
The reason for quoting identifiers is to make the statement parseable. For example, if Accounts Payable was not
quoted in the previous statement, the parser would assume there were two tables, Accounts and Payable, and
return a syntax error that they were not separated by a comma. The identifier quote character is driver-specific
and is retrieved with the SQL_IDENTIFIER_QUOTE_CHAR option in SQLGetInfo . The lists of special characters
and of keywords are retrieved with the SQL_SPECIAL_CHARACTERS and SQL_KEYWORDS options in
SQLGetInfo .
To be safe, interoperable applications often quote all identifiers except those for pseudo-columns, such as the
ROWID column in Oracle. SQLSpecialColumns returns a list of pseudo-columns. Also, if there are application-
specific restrictions on where special characters can appear in an object name, it is best for interoperable
applications not to use special characters in those positions.
Identifier Case
4/27/2022 • 2 minutes to read • Edit Online
In SQL statements and catalog function arguments, identifiers and quoted identifiers can be either case-sensitive
or not, which an application can determine by calling SQLGetInfo with the SQL_IDENTIFIER_CASE and
SQL_QUOTED_IDENTIFIER_CASE options.
Each of these options has four possible return values: one stating that the identifier or quoted identifier case is
sensitive and three stating that it is not sensitive. The three values that are not case-sensitive further describe
the case in which identifiers are stored in the system catalog. How identifiers are stored in the system catalog is
relevant only for display purposes, such as when an application displays the results of a catalog function; it does
not change the case-sensitivity of identifiers.
Escape Sequences
4/27/2022 • 2 minutes to read • Edit Online
ODBC defines escape sequences containing standard grammar for date, time, timestamp, and datetime interval
literals, scalar function calls, LIKE predicate escape characters, outer joins, and procedure calls. Interoperable
applications should use these sequences whenever possible.
To determine if a driver supports the escape sequences for date, time, timestamp, or datetime interval literals, an
application calls SQLGetTypeInfo . If the data source supports a date, time, timestamp, or datetime interval data
type, it must also support the corresponding escape sequence. To determine whether the other escape
sequences are supported, an application calls SQLGetInfo .
For more information, see Escape Sequences in ODBC, later in this section.
Literal Prefixes and Suffixes
4/27/2022 • 2 minutes to read • Edit Online
In an SQL statement, a literal is a character representation of an actual data value. For example, in the following
statement, ABC, FFFF, and 10 are literals:
Literals for some data types require special prefixes and suffixes. In the preceding example, the character literal
(ABC) requires a single quotation mark (') as both a prefix and a suffix, the binary literal (FFFF) requires the
characters 0x as a prefix, and the integer literal (10) does not require a prefix or suffix.
For all data types except date, time, and timestamps, interoperable applications should use the values returned
in the LITERAL_PREFIX and LITERAL_SUFFIX columns in the result set created by SQLGetTypeInfo . For date,
time, timestamp, and datetime interval literals, interoperable applications should use the escape sequences
discussed in the preceding section.
Parameter Markers in Procedure Calls
4/27/2022 • 2 minutes to read • Edit Online
When calling procedures that accept parameters, interoperable applications should use parameter markers
instead of literal parameter values. Some data sources do not support the use of literal parameter values in
procedure calls. For more information about parameters, see Statement Parameters. For more information
about calling procedures, see Procedure Calls, later in this section.
DDL Statements
4/27/2022 • 2 minutes to read • Edit Online
Data Definition Language (DDL) statements vary tremendously among DBMSs. ODBC SQL defines statements
for the most common data definition operations: creating and dropping tables, indexes, and views; altering
tables; and granting and revoking privileges. All other DDL statements are data source-specific. Therefore,
interoperable applications cannot perform some data definition operations. In general, this is not a problem,
because such operations tend to be highly DBMS-specific and are best left to the proprietary database
administration software shipped with most DBMSs or the setup program shipped with the driver.
Another problem in data definition is that data type names vary tremendously among DBMSs. Rather than
defining standard data type names and forcing drivers to convert them to DBMS-specific names,
SQLGetTypeInfo provides a way for applications to discover DBMS-specific data type names. Interoperable
applications should use these names in SQL statements to create and alter tables; the names listed in Appendix
C: SQL Grammar, and Appendix D: Data Types, are examples only.
Escape Sequences in ODBC
4/27/2022 • 2 minutes to read • Edit Online
A number of language features, such as outer joins and scalar function calls, are commonly implemented by
DBMSs. However, the syntaxes for these features tend to be DBMS-specific, even when standard syntaxes are
defined by the various standards bodies. Because of this, ODBC defines escape sequences that contain standard
syntaxes for the following language features:
Date, time, timestamp, and datetime interval literals
Scalar functions such as numeric, string, and data type conversion functions
LIKE predicate escape character
Outer joins
Procedure calls
The escape sequence used by ODBC is as follows:
(extension)
Remarks
The escape sequence is recognized and parsed by drivers, which replace the escape sequences with DBMS-
specific grammar. For more information about escape sequence syntax, see ODBC Escape Sequences in
Appendix C: SQL Grammar.
NOTE
In ODBC 2.x, this was the standard syntax of the escape sequence: --(*vendor( vendor-name), product( product-
name) extension *)--
In addition to this syntax, a shorthand syntax was defined of the form: { extension}
In ODBC 3.x, the long form of the escape sequence has been deprecated, and the shorthand form is used exclusively.
Because the escape sequences are mapped by the driver to DBMS-specific syntaxes, an application can use
either the escape sequence or DBMS-specific syntax. However, applications that use the DBMS-specific syntax
will not be interoperable. When using the escape sequence, applications should make sure that the
SQL_ATTR_NOSCAN statement attribute is turned off, which it is by default. Otherwise, the escape sequence will
be sent directly to the data source, where it will generally cause a syntax error.
Drivers support only those escape sequences that they can map to underlying language features. For example, if
the data source does not support outer joins, neither will the driver. To determine which escape sequences are
supported, an application calls SQLGetTypeInfo and SQLGetInfo . For more information, see the next section,
Date, Time, and Timestamp Literals.
This section contains the following topics.
Date, Time, and Timestamp Literals
Scalar Function Calls
LIKE Predicate Escape Character
Outer Joins
Procedure Calls
Date, Time, and Timestamp Literals
4/27/2022 • 2 minutes to read • Edit Online
L IT ERA L -T Y P E M EA N IN G F O RM AT O F VA L UE
d Date yyyy-mm-dd
t Time* hh:mm:ss[1]
[1] The number of digits to the right of the decimal point in a time or timestamp interval literal containing a
seconds component is dependent on the seconds precision, as contained in the SQL_DESC_PRECISION
descriptor field. (For more information, see SQLSetDescField.)
For more information about the date, time, and timestamp escape sequences, see Date, Time, and Timestamp
Escape Sequences in Appendix C: SQL Grammar.
For example, both of the following SQL statements update the open date of sales order 1023 in the Orders table.
The first statement uses the escape sequence syntax. The second statement uses the Oracle Rdb native syntax for
the DATE column and is not interoperable.
The escape sequence for a date, time, or timestamp literal also can be placed in a character variable bound to a
date, time, or timestamp parameter. For example, the following code uses a date parameter bound to a character
variable to update the open date of sales order 1023 in the Orders table:
However, it is usually more efficient to bind the parameter directly to a date structure:
SQL_DATE_STRUCT OpenDate;
SQLINTEGER OpenDateInd = 0;
To determine whether a driver supports the ODBC escape sequences for date, time, or timestamp literals, an
application calls SQLGetTypeInfo . If the data source supports a date, time, or timestamp data type, it must also
support the corresponding escape sequence.
Data sources can also support the datetime literals defined in the ANSI SQL-92 specification, which are different
from the ODBC escape sequences for date, time, or timestamp literals. To determine whether a data source
supports the ANSI literals, an application calls SQLGetInfo with the SQL_ANSI_SQL_DATETIME_LITERALS
option.
To determine whether a driver supports the ODBC escape sequences for interval literals, an application calls
SQLGetTypeInfo . If the data source supports a datetime interval data type, it must also support the
corresponding escape sequence.
Data sources can also support the datetime literals defined in the ANSI SQL-92 specification, which are different
from the ODBC escape sequences for datetime interval literals. To determine whether a data source supports the
ANSI literals, an application calls SQLGetInfo with the SQL_ANSI_SQL_DATETIME_LITERALS option.
Scalar Function Calls
4/27/2022 • 2 minutes to read • Edit Online
Scalar functions return a value for each row. For example, the absolute value scalar function takes a numeric
column as an argument and returns the absolute value of each value in the column. The escape sequence for
calling a scalar function is
{fn scalar-function }
where scalar-function is one of the functions listed in Appendix E: Scalar Functions. For more information about
the scalar function escape sequence, see Scalar Function Escape Sequence in Appendix C: SQL Grammar.
For example, the following SQL statements create the same result set of uppercase customer names. The first
statement uses the escape-sequence syntax. The second statement uses the native syntax for Ingres for OS/2
and is not interoperable.
An application can mix calls to scalar functions that use native syntax and calls to scalar functions that use ODBC
syntax. For example, assume that names in the Employee table are stored as a last name, a comma, and a first
name. The following SQL statement creates a result set of last names of employees in the Employee table. The
statement uses the ODBC scalar function SUBSTRING and the SQL Server scalar function CHARINDEX and
will execute correctly only on SQL Server.
For maximum interoperability, applications should use the CONVERT scalar function to make sure that the
output of a scalar function is the required type. The CONVERT function converts data from one SQL data type
to the specified SQL data type. The syntax of the CONVERT function is
CONVERT( value_exp , data_type)
where value_exp is a column name, the result of another scalar function, or a literal value, and data_type is a
keyword that matches the #define name that is used by an SQL data type identifier as defined in Appendix D:
Data Types. For example, the following SQL statement uses the CONVERT function to make sure that the output
of the CURDATE function is a date, instead of a timestamp or character data:
To determine which scalar functions are supported by a data source, an application calls SQLGetInfo with the
SQL_CONVERT_FUNCTIONS, SQL_NUMERIC_FUNCTIONS, SQL_STRING_FUNCTIONS,
SQL_SYSTEM_FUNCTIONS, and SQL_TIMEDATE_FUNCTIONS options. To determine which conversion
operations are supported by the CONVERT function, an application calls SQLGetInfo with any of the options
that start with SQL_CONVERT.
LIKE Predicate Escape Character
4/27/2022 • 2 minutes to read • Edit Online
In a LIKE predicate, the percent sign (%) matches zero or more of any character and the underscore (_) matches
any one character. To match an actual percent sign or underscore in a LIKE predicate, an escape character must
come before the percent sign or underscore. The escape sequence that defines the LIKE predicate escape
character is:
{escape ' escape-character '}
where escape-character is any character supported by the data source.
For more information about the LIKE escape sequence, see LIKE Escape Sequence in Appendix C: SQL Grammar.
For example, the following SQL statements create the same result set of customer names that start with the
characters "%AAA". The first statement uses the escape-sequence syntax. The second statement uses the native
syntax for Microsoft® Access and is not interoperable. Notice that the second percent character in each LIKE
predicate is a wildcard character that matches zero or more of any character.
SELECT Name FROM Customers WHERE Name LIKE '\%AAA%' {escape '\'}
To determine whether the LIKE predicate escape character is supported by a data source, an application calls
SQLGetInfo with the SQL_LIKE_ESCAPE_CLAUSE option.
Outer Joins
4/27/2022 • 2 minutes to read • Edit Online
ODBC supports the SQL-92 left, right, and full outer join syntax. The escape sequence for outer joins is
{oj outer-join}
where outer-join is
table-reference {LEFT | RIGHT | FULL} OUTER JOIN {table-reference | outer-join} ON search-condition
table-reference specifies a table name, and search-condition specifies the join condition between the table-
references.
An outer join request must appear after the FROM keyword and before the WHERE clause (if one exists). For
complete syntax information, see Outer Join Escape Sequence in Appendix C: SQL Grammar.
For example, the following SQL statements create the same result set that lists all customers and shows which
has open orders. The first statement uses the escape-sequence syntax. The second statement uses the native
syntax for Oracle and is not interoperable.
To determine the types of outer joins that a data source and driver support, an application calls SQLGetInfo
with the SQL_OJ_CAPABILITIES flag. The types of outer joins that might be supported are left, right, full, or
nested outer joins; outer joins in which the column names in the ON clause do not have the same order as their
respective table names in the OUTER JOIN clause; inner joins in conjunction with outer joins; and outer joins
using any ODBC comparison operator. If the SQL_OJ_CAPABILITIES information type returns 0, no outer join
clause is supported.
Procedure Calls
4/27/2022 • 2 minutes to read • Edit Online
A procedure is an executable object stored on the data source. Generally, it is one or more SQL statements that
have been precompiled. The escape sequence for calling a procedure is
{ [?= ]call procedure-name[( [parameter][,[parameter]]...) ]}
where procedure-name specifies the name of a procedure and parameter specifies a procedure parameter.
For more information about the procedure call escape sequence, see Procedure Call Escape Sequence in
Appendix C: SQL Grammar.
A procedure can have zero or more parameters. It can also return a value, as indicated by the optional
parameter marker ?= at the start of the syntax. If parameter is an input or an input/output parameter, it can be a
literal or a parameter marker. However, interoperable applications should always use parameter markers
because some data sources do not accept literal parameter values. If parameter is an output parameter, it must
be a parameter marker. Parameter markers must be bound with SQLBindParameter before the procedure call
statement is executed.
Input and input/output parameters can be omitted from procedure calls. If a procedure is called with
parentheses but without any parameters, such as {call procedure-name()}, the driver instructs the data source to
use the default value for the first parameter. If the procedure does not have any parameters, this might cause the
procedure to fail. If a procedure is called without parentheses, such as {call procedure-name}, the driver does not
send any parameter values.
Literals can be specified for input and input/output parameters in procedure calls. For example, suppose the
procedure Inser tOrder has five input parameters. The following call to Inser tOrder omits the first parameter,
provides a literal for the second parameter, and uses a parameter marker for the third, fourth, and fifth
parameters:
Notice that if a parameter is omitted, the comma delimiting it from other parameters must still appear. If an
input or input/output parameter is omitted, the procedure uses the default value of the parameter. Another way
to specify the default value of an input or input/output parameter is to set the value of the length/indicator
buffer bound to the parameter to SQL_DEFAULT_PARAM.
If an input/output parameter is omitted or if a literal is supplied for the parameter, the driver discards the output
value. Similarly, if the parameter marker for the return value of a procedure is omitted, the driver discards the
return value. Finally, if an application specifies a return value parameter for a procedure that does not return a
value, the driver sets the value of the length/indicator buffer bound to the parameter to SQL_NULL_DATA.
Suppose the procedure PARTS_IN_ORDERS creates a result set that contains a list of orders that contain a
particular part number. The following code calls this procedure for part number 544:
SQLUINTEGER PartID;
SQLINTEGER PartIDInd = 0;
To determine whether a data source supports procedures, an application calls SQLGetInfo with the
SQL_PROCEDURES option.
For more information about procedures, see Procedures.
Executing Statements ODBC
4/27/2022 • 2 minutes to read • Edit Online
ODBC applications perform almost all database access by executing SQL statements. The general sequence of
events is to allocate a statement handle, set any statement attributes, execute the statement, retrieve any results,
and free the statement handle.
This section contains the following topics.
Allocating a Statement Handle
Statement Attributes
Executing a Statement
Statement Parameters
Asynchronous Execution (Polling Method)
Asynchronous Execution (Notification Method)
Freeing a Statement Handle
Allocating a Statement Handle ODBC
4/27/2022 • 2 minutes to read • Edit Online
Before the application can execute a statement, it must allocate a statement handle as follows:
1. The application declares a variable of type HSTMT. It then calls SQL AllocHandle and passes the address
of this variable, the handle of the connection in which to allocate the statement, and the
SQL_HANDLE_STMT option. For example:
SQLHSTMT hstmt1;
2. The Driver Manager allocates a structure in which to store information about the statement and calls
SQL AllocHandle in the driver with the SQL_HANDLE_STMT option.
3. The driver allocates its own structure in which to store information about the statement and returns the
driver statement handle to the Driver Manager.
4. The Driver Manager returns the Driver Manager statement handle to the application in the application
variable.
The statement handle identifies which statement to use when calling ODBC functions. For more information
about statement handles, see Statement Handles.
Statement Attributes
4/27/2022 • 2 minutes to read • Edit Online
Statement attributes are characteristics of the statement. For example, whether to use bookmarks and what kind
of cursor to use with the statement's result set are statement attributes.
Statement attributes are set with SQLSetStmtAttr and their current settings retrieved with SQLGetStmtAttr .
There is no requirement that an application set any statement attributes; all statement attributes have defaults,
some of which are driver-specific.
When a statement attribute can be set depends on the attribute itself. The SQL_ATTR_CONCURRENCY,
SQL_ATTR_CURSOR_TYPE, SQL_ATTR_SIMULATE_CURSOR, and SQL_ATTR_USE_BOOKMARKS statement
attributes must be set before the statement is executed. The SQL_ATTR_ASYNC_ENABLE and
SQL_ATTR_NOSCAN statement attributes can be set at any time but are not applied until the statement is used
again. SQL_ATTR_MAX_LENGTH, SQL_ATTR_MAX_ROWS, and SQL_ATTR_QUERY_TIMEOUT statement attributes
can be set at any time, but it is driver-specific whether they are applied before the statement is used again. The
remaining statement attributes can be set at any time.
NOTE
The ability to set statement attributes at the connection level by calling SQLSetConnectAttr has been deprecated in
ODBC 3.x. ODBC 3.x applications should never set statement attributes at the connection level. ODBC 3.x drivers need
only support this functionality if they should work with ODBC 2.x applications. For more information, see
SQLSetConnectOption Mapping in Appendix G: Driver Guidelines for Backward Compatibility.
An exception to this is the SQL_ATTR_METADATA_ID and SQL_ATTR_ASYNC_ENABLE attributes, which are both connection
attributes and statement attributes and can be set either at the connection level or the statement level.
None of the statement attributes introduced in ODBC 3.x (except for SQL_ATTR_METADATA_ID) can be set at the
connection level.
There are four ways to execute a statement, depending on when they are compiled (prepared) by the database
engine and who defines them:
Direct Execution The application defines the SQL statement. It is prepared and executed at run time in a
single step.
Prepared Execution The application defines the SQL statement. It is prepared and executed at run time
in separate steps. The statement can be prepared once and executed multiple times.
Procedures The application can define and compile one or more SQL statements at development time
and store these statements on the data source as a procedure. The procedure is executed one or more
times at run time. The application can enumerate available stored procedures using catalog functions.
Catalog Functions The driver writer creates a function that returns a predefined result set. Usually, this
function submits a predefined SQL statement or calls a procedure created for this purpose. The function
is executed one or more times at run time.
A particular statement (as identified by its statement handle) can be executed any number of times. The
statement can be executed with a variety of different SQL statements, or it can be executed repeatedly with the
same SQL statement. For example, the following code uses the same statement handle (hstmt1) to retrieve and
display the tables in the Sales database. It then reuses this handle to retrieve the columns in a table selected by
the user.
SQLHSTMT hstmt1;
SQLCHAR * Table;
// Fetch and display the table names; then close the cursor.
// Code not shown.
// Fetch and display the column names in Table; then close the cursor.
// Code not shown.
And the following code shows how a single handle is used to repeatedly execute the same statement to delete
rows from a table.
SQLHSTMT hstmt1;
SQLUINTEGER OrderID;
SQLINTEGER OrderIDInd = 0;
For many drivers, allocating statements is an expensive task, so reusing the same statement in this manner is
usually more efficient than freeing existing statements and allocating new ones. Applications that create result
sets on a statement must be careful to close the cursor over the result set before reexecuting the statement; for
more information, see Closing the Cursor.
Reusing statements also forces the application to avoid a limitation in some drivers of the number of statements
that can be active at one time. The exact definition of "active" is driver-specific, but it often refers to any
statement that has been prepared or executed and still has results available. For example, after an INSERT
statement has been prepared, it is generally considered to be active; after a SELECT statement has been
executed and the cursor is still open, it is generally considered to be active; after a CREATE TABLE statement has
been executed, it is not generally considered to be active.
An application determines how many statements can be active on a single connection at one time by calling
SQLGetInfo with the SQL_MAX_CONCURRENT_ACTIVITIES option. An application can use more active
statements than this limit by opening multiple connections to the data source; because connections can be
expensive, however, the effect on performance should be considered.
Applications can limit the amount of time allotted for a statement to execute with the
SQL_ATTR_QUERY_TIMEOUT statement attribute. If the timeout period expires before the data source returns
the result set, the function executing the SQL statement returns SQLSTATE HYT00 (Timeout expired). By default,
there is no timeout.
This section contains the following topics.
Direct Execution
Prepared Execution
Procedures
Batches of SQL Statements
Executing Catalog Functions
Direct Execution ODBC
4/27/2022 • 2 minutes to read • Edit Online
Direct execution is the simplest way to execute a statement. When the statement is submitted for execution, the
data source compiles it into an access plan and then executes that access plan.
Direct execution is commonly used by generic applications that build and execute statements at run time. For
example, the following code builds an SQL statement and executes it a single time:
SQLCHAR *SQLStatement;
Direct execution works best for statements that will be executed a single time. Its major drawback is that the SQL
statement is parsed every time it is executed. In addition, the application cannot retrieve information about the
result set created by the statement (if any) until after the statement is executed; this is possible if the statement is
prepared and executed in two separate steps.
To execute a statement directly, the application performs the following actions:
1. Sets the values of any parameters. For more information, see Statement Parameters, later in this section.
2. Calls SQLExecDirect and passes it a string containing the SQL statement.
3. When SQLExecDirect is called, the driver:
Modifies the SQL statement to use the data source's SQL grammar without parsing the statement;
this includes replacing the escape sequences discussed in Escape Sequences in ODBC. The
application can retrieve the modified form of an SQL statement by calling SQLNativeSql . Escape
sequences are not replaced if the SQL_ATTR_NOSCAN statement attribute is set.
Retrieves the current parameter values and converts them as necessary. For more information, see
Statement Parameters, later in this section.
Sends the statement and converted parameter values to the data source for execution.
Returns any errors. These include sequencing or state diagnostics such as SQLSTATE 24000
(Invalid cursor state), syntactic errors such as SQLSTATE 42000 (Syntax error or access violation),
and semantic errors such as SQLSTATE 42S02 (Base table or view not found).
Prepared Execution ODBC
4/27/2022 • 3 minutes to read • Edit Online
Prepared execution is an efficient way to execute a statement more than once. The statement is first compiled, or
prepared, into an access plan. The access plan is then executed one or more times at a later time. For more
information about access plans, see Processing an SQL Statement.
Prepared execution is commonly used by vertical and custom applications to repeatedly execute the same,
parameterized SQL statement. For example, the following code prepares a statement to update the prices of
different parts. It then executes the statement multiple times with different parameter values each time.
SQLREAL Price;
SQLUINTEGER PartID;
SQLINTEGER PartIDInd = 0, PriceInd = 0;
// Bind Price to the parameter for the Price column and PartID to
// the parameter for the PartID column.
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,
&Price, 0, &PriceInd);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 10, 0,
&PartID, 0, &PartIDInd);
Prepared execution is faster than direct execution for statements executed more than once, primarily because
the statement is compiled only once; statements executed directly are compiled each time they are executed.
Prepared execution also can provide a reduction in network traffic because the driver can send an access plan
identifier to the data source each time the statement is executed, rather than an entire SQL statement, if the data
source supports access plan identifiers.
The application can retrieve the metadata for the result set after the statement is prepared and before it is
executed. However, returning metadata for prepared, unexecuted statements is expensive for some drivers and
should be avoided by interoperable applications if possible. For more information, see Result Set Metadata.
Prepared execution should not be used for statements executed a single time. For such statements, it is slightly
slower than direct execution because it requires an additional ODBC function call.
IMPORTANT
Committing or rolling back a transaction, either by explicitly calling SQLEndTran or by working in auto-commit mode,
causes some data sources to delete the access plans for all statements on a connection. For more information, see the
SQL_CURSOR_COMMIT_BEHAVIOR and SQL_CURSOR_ROLLBACK_BEHAVIOR options in the SQLGetInfo function
description.
NOTE
Some drivers do not return errors at this point but instead return them when the statement is executed or
when catalog functions are called. Thus, SQLPrepare might appear to have succeeded when in fact it has
failed.
A procedure is an executable object stored on the data source. Generally, it is one or more SQL statements that
have been precompiled.
This section contains the following topics.
When to Use Procedures
Executing Procedures
When to Use Procedures
4/27/2022 • 3 minutes to read • Edit Online
There are a number of advantages to using procedures, all based on the fact that using procedures moves SQL
statements from the application to the data source. What is left in the application is an interoperable procedure
call. These advantages include:
Performance Procedures are usually the fastest way to execute SQL statements. Like prepared
execution, the statement is compiled and executed in two separate steps. Unlike prepared execution,
procedures are executed only at run time. They are compiled at a different time.
Business Rules A business rule is a rule about the way in which a company does business. For example,
only someone with the title Sales Person might be allowed to add new sales orders. Placing these rules in
procedures allows individual companies to customize vertical applications by rewriting the procedures
called by the application without having to modify the application code. For example, an order entry
application might call the procedure Inser tOrder with a fixed number of parameters; exactly how
Inser tOrder is implemented can vary from company to company.
Replaceability Closely related to placing business rules in procedures is the fact that procedures can be
replaced without recompiling the application. If a business rule changes after a company has bought and
installed an application, the company can change the procedure containing that rule. From the
application's standpoint, nothing has changed; it still calls a particular procedure to accomplish a
particular task.
DBMS-specific SQL Procedures provide a way for applications to exploit DBMS-specific SQL and still
remain interoperable. For example, a procedure on a DBMS that supports control-of-flow statements in
SQL might trap and recover from errors, while a procedure on a DBMS that does not support control-of-
flow statements might simply return an error.
Procedures sur vive transactions On some data sources, the access plans for all prepared statements
on a connection are deleted when a transaction is committed or rolled back. By placing SQL statements in
procedures, which are permanently stored in the data source, the statements survive the transaction.
Whether the procedures survive in a prepared, partially prepared, or unprepared state is DBMS-specific.
Separate development Procedures can be developed separately from the rest of the application. In
large corporations, this might provide a way to further exploit the skills of highly specialized
programmers. In other words, application programmers can write user-interface code and database
programmers can write procedures.
Procedures are generally used by vertical and custom applications. These applications tend to perform fixed
tasks, and it is possible to hard-code procedure calls in them. For example, an order entry application might call
the procedures Inser tOrder , DeleteOrder , UpdateOrder , and GetOrders .
There is little reason to call procedures from generic applications. Procedures are usually written to perform a
task in the context of a particular application and so have no use to generic applications. For example, a
spreadsheet has no reason to call the Inser tOrder procedure just mentioned. Furthermore, generic
applications should not construct procedures at run time in hopes of providing faster statement execution; not
only is this likely to be slower than prepared or direct execution, it also requires DBMS-specific SQL statements.
An exception to this is application-development environments, which often provide a way for programmers to
build SQL statements that execute procedures and may provide a way for programmers to test procedures.
Such environments call SQLProcedures to list available procedures and SQLProcedureColumns to list the
input, input/output, and output parameters, the procedure return value, and the columns of any result sets
created by a procedure. However, such procedures must be developed beforehand on each data source; doing
so requires DBMS-specific SQL statements.
There are three major disadvantages to using procedures. The first is that procedures must be written and
compiled for each DBMS with which the application is to run. While this is not a problem for custom
applications, it can significantly increase development and maintenance time for vertical applications designed
to run with a number of DBMSs.
The second disadvantage is that many DBMSs do not support procedures. Again, this is most likely to be a
problem for vertical applications designed to run with a number of DBMSs. To determine whether procedures
are supported, an application calls SQLGetInfo with the SQL_PROCEDURES option.
The third disadvantage, which is particularly applicable to application development environments, is that ODBC
does not define a standard grammar for creating procedures. That is, although applications can call procedures
interoperably, they cannot create them interoperably.
Executing Procedures
4/27/2022 • 2 minutes to read • Edit Online
ODBC defines a standard escape sequence for executing procedures. For the syntax of this sequence and a code
example that uses it, see Procedure Calls.
To execute a procedure, an application performs the following actions:
1. Sets the values of any parameters. For more information, see Statement Parameters, later in this section.
2. Calls SQLExecDirect and passes it a string containing the SQL statement that executes the procedure.
This statement can use the escape sequence defined by ODBC or DBMS-specific syntax; statements that
use DBMS-specific syntax are not interoperable.
3. When SQLExecDirect is called, the driver:
Retrieves the current parameter values and converts them as necessary. For more information, see
Statement Parameters, later in this section.
Calls the procedure in the data source and sends it the converted parameter values. How the
driver calls the procedure is driver-specific. For example, it might modify the SQL statement to use
the data source's SQL grammar and submit this statement for execution, or it might call the
procedure directly using a Remote Procedure Call (RPC) mechanism that is defined in the data
stream protocol of the DBMS.
Returns the values of any input/output or output parameters or the procedure return value,
assuming the procedure succeeds. These values might not be available until after all other results
(row counts and result sets) generated by the procedure have been processed. If the procedure
fails, the driver returns any errors.
Batches of SQL Statements
4/27/2022 • 2 minutes to read • Edit Online
A batch of SQL statements is a group of two or more SQL statements or a single SQL statement that has the
same effect as a group of two or more SQL statements. In some implementations, the entire batch statement is
executed before any results are available. This is often more efficient than submitting statements separately,
because network traffic can often be reduced and the data source can sometimes optimize execution of a batch
of SQL statements. In other implementations, calling SQLMoreResults triggers the execution of the next
statement in the batch. ODBC supports the following types of batches:
Explicit Batches An explicit batch is two or more SQL statements separated by semicolons (;). For
example, the following batch of SQL statements opens a new sales order. This requires inserting rows
into both the Orders and Lines tables. Note that there is no semicolon after the last statement.
Procedures If a procedure contains more than one SQL statement, it is considered to be a batch of SQL
statements. For example, the following SQL Server-specific statement creates a procedure that returns a
result set containing information about a customer and a result set listing all the open sales orders for
that customer:
The CREATE PROCEDURE statement itself is not a batch of SQL statements. However, the procedure it
creates is a batch of SQL statements. No semicolons separate the two SELECT statements because the
CREATE PROCEDURE statement is specific to SQL Server, and SQL Server does not require semicolons
to separate multiple statements in a CREATE PROCEDURE statement.
Arrays of Parameters Arrays of parameters can be used with a parameterized SQL statement as an
effective way to perform bulk operations. For example, arrays of parameters can be used with the
following INSERT statement to insert multiple rows into the Lines table while executing only a single
SQL statement:
If a data source does not support arrays of parameters, the driver can emulate them by executing the SQL
statement once for each set of parameters. For more information, see Statement Parameters and Arrays
of Parameter Values, later in this section.
The different types of batches cannot be mixed in an interoperable manner. That is, how an application
determines the result of executing an explicit batch that includes procedure calls, an explicit batch that uses
arrays of parameters, and a procedure call that uses arrays of parameters is driver-specific.
This section contains the following topics.
Result-Generating and Result-Free Statements
Executing Batches
Errors and Batches
Result-Generating and Result-Free Statements
4/27/2022 • 2 minutes to read • Edit Online
SQL statements can be loosely divided into the following five categories:
Result Set-Generating Statements These are SQL statements that generate a result set. For example, a
SELECT statement.
Row Count-Generating Statements These are SQL statements that generate a count of affected rows.
For example, an UPDATE or DELETE statement.
Data Definition Language (DDL) Statements These are SQL statements that modify the structure of
the database. For example, CREATE TABLE or DROP INDEX .
Context-Changing Statements These are SQL statements that change the context of a database. For
example, the USE and SET statements in SQL Server.
Administrative Statements These are SQL statements used for administrative purposes in a database.
For example, GRANT and REVOKE .
SQL statements in the first two categories are collectively known as result-generating statements. SQL
statements in the latter three categories are collectively known as result-free statements. ODBC defines the
semantics of batches that include only result-generating statements. These semantics vary widely and are
therefore data source-specific. For example, the SQL Server driver does not support dropping an object and
then referring to or re-creating the same object in the same batch. Therefore, the term batch as used in this
manual refers only to batches of result-generating statements.
Executing Batches
4/27/2022 • 2 minutes to read • Edit Online
Before an application executes a batch of statements, it should first check whether they are supported. To do this,
the application calls SQLGetInfo with the SQL_BATCH_SUPPORT, SQL_PARAM_ARRAY_ROW_COUNTS, and
SQL_PARAM_ARRAY_SELECTS options. The first option returns whether row count-generating and result set-
generating statements are supported in explicit batches and procedures, while the latter two options return
information about the availability of row counts and result sets in parameterized execution.
Batches of statements are executed through SQLExecute or SQLExecDirect . For example, the following call
executes an explicit batch of statements to open a new sales order.
SQLCHAR *BatchStmt =
"INSERT INTO Orders (OrderID, CustID, OpenDate, SalesPerson, Status)"
"VALUES (2002, 1001, {fn CURDATE()}, 'Garcia', 'OPEN');"
"INSERT INTO Lines (OrderID, Line, PartID, Quantity) VALUES (2002, 1, 1234, 10);"
"INSERT INTO Lines (OrderID, Line, PartID, Quantity) VALUES (2002, 2, 987, 8);"
"INSERT INTO Lines (OrderID, Line, PartID, Quantity) VALUES (2002, 3, 566, 17);"
"INSERT INTO Lines (OrderID, Line, PartID, Quantity) VALUES (2002, 4, 412, 500)";
When a batch of result-generating statements is executed, it returns one or more row counts or result sets. For
information about how to retrieve these, see Multiple Results.
If a batch of statements includes parameter markers, these are numbered in increasing parameter order as they
are in any other statement. For example, the following batch of statements has parameters numbered from 1
through 21; those in the first INSERT statement are numbered 1 through 5 and those in the last INSERT
statement are numbered 18 through 21.
For more information about parameters, see Statement Parameters, later in this section.
Errors and Batches
4/27/2022 • 2 minutes to read • Edit Online
When an error occurs while executing a batch of SQL statements, one of the following four outcomes are
possible. (Each possible outcome is data source-specific and might even depend on the statements included in
the batch.)
No statements in the batch are executed.
No statements in the batch are executed and the transaction is rolled back.
All of the statements before the error statement are executed.
All of the statements except the error statement are executed.
In the first two cases, SQLExecute and SQLExecDirect return SQL_ERROR. In the latter two cases, they may
return SQL_SUCCESS_WITH_INFO or SQL_SUCCESS, depending on the implementation. In all cases, further
error information can be retrieved with SQLGetDiagField , SQLGetDiagRec , or SQLError . However, the
nature and depth of this information is data source-specific. Furthermore, this information is unlikely to exactly
identify the statement in error.
Executing Catalog Functions
4/27/2022 • 2 minutes to read • Edit Online
Because a catalog function creates a result set, it is equivalent to executing any result set-generating SQL
statement. In fact, catalog functions are often implemented by executing predefined SQL statements or calling
predefined procedures that are shipped with the driver or DBMS. Almost anything that applies to SQL
statements that create result sets also applies to catalog functions. For example, the SQL_ATTR_MAX_ROWS
statement attribute limits the number of rows returned by the catalog function, just as it limits the number of
rows returned by a SELECT statement.
To execute a catalog function, an application just calls the function.
For more information about catalog functions, see Catalog Functions.
Statement Parameters
4/27/2022 • 2 minutes to read • Edit Online
A parameter is a variable in an SQL statement. For example, suppose a Parts table has columns named PartID,
Description, and Price. To add a part without parameters would require constructing an SQL statement such as:
INSERT INTO Parts (PartID, Description, Price) VALUES (2100, 'Drive shaft', 50.00)
Although this statement inserts a new order, it is not a good solution for an order entry application because the
values to insert cannot be hard-coded in the application. An alternative is to construct the SQL statement at run
time, using the values to be inserted. This is also not a good solution, because of the complexity of constructing
statements at run time. The best solution is to replace the elements of the VALUES clause with question marks
(?), or parameter markers:
The parameter markers are then bound to application variables. To add a new row, the application has only to
set the values of the variables and execute the statement. The driver then retrieves the current values of the
variables and sends them to the data source. If the statement will be executed multiple times, the application can
make the process even more efficient by preparing the statement.
The statement just shown might be hard-coded in an order entry application to insert a new row. However,
parameter markers are not limited to vertical applications. For any application, they ease the difficulty of
constructing SQL statements at run time by avoiding conversions to and from text. For example, the part ID just
shown is most likely stored in the application as an integer. If the SQL statement is constructed without
parameter markers, the application must convert the part ID to text and the data source must convert it back to
an integer. By using a parameter marker, the application can send the part ID to the driver as an integer, which
usually can send it to the data source as an integer. This saves two conversions. For long data values, this is very
important, because the text forms of such values frequently exceed the allowed length of an SQL statement.
Parameters are valid only in certain places in SQL statements. For example, they are not allowed in the select list
(the list of columns to be returned by a SELECT statement), nor are they allowed as both operands of a binary
operator such as the equal sign (=), because it would be impossible to determine the parameter type. Generally,
parameters are valid only in Data Manipulation Language (DML) statements, and not in Data Definition
Language (DDL) statements. For more information, see Parameter Markers in Appendix C: SQL Grammar.
When the SQL statement invokes a procedure, named parameters can be used. Named parameters are
identified by their names, not by their position in the SQL statement. They can be bound by a call to
SQLBindParameter , but the parameter is identified by the SQL_DESC_NAME field of the IPD (implementation
parameter descriptor), not by the ParameterNumber argument of SQLBindParameter . They can also be bound
by calling SQLSetDescField or SQLSetDescRec . For more information about named parameters, see Binding
Parameters by Name (Named Parameters), later in this section. For more information about descriptors, see
Descriptors.
This section contains the following topics.
Binding Parameters
Setting Parameter Values
Sending Long Data
Retrieving Output Parameters by SQLGetData
Procedure Parameters
Arrays of Parameter Values
Binding Parameters ODBC
4/27/2022 • 2 minutes to read • Edit Online
Each parameter in an SQL statement must be associated, or bound, to a variable in the application before the
statement is executed. When the application binds a variable to a parameter, it describes that variable - address,
C data type, and so on - to the driver. It also describes the parameter itself - SQL data type, precision, and so on.
The driver stores this information in the structure it maintains for that statement and uses the information to
retrieve the value from the variable when the statement is executed.
Parameters can be bound or rebound at any time before a statement is executed. If a parameter is rebound after
a statement is executed, the binding does not apply until the statement is executed again. To bind a parameter to
a different variable, an application simply rebinds the parameter with the new variable; the previous binding is
automatically released.
A variable remains bound to a parameter until a different variable is bound to the parameter, until all
parameters are unbound by calling SQLFreeStmt with the SQL_RESET_PARAMS option, or until the statement
is released. For this reason, the application must be sure that variables are not freed until after they are
unbound. For more information, see Allocating and Freeing Buffers.
Because parameter bindings are just information stored in the structure maintained by the driver for the
statement, they can be set in any order. They are also independent of the SQL statement that is executed. For
example, suppose an application binds three parameters and then executes the following SQL statement:
on the same statement handle, the parameter bindings for the INSERT statement are used because those are
the bindings stored in the statement structure. In most cases, this is a poor programming practice and should be
avoided. Instead, the application should call SQLFreeStmt with the SQL_RESET_PARAMS option to unbind all
the old parameters and then bind new ones.
This section contains the following topics.
Binding Parameter Markers
Binding Parameters by Name (Named Parameters)
Parameter Binding Offsets
Describing Parameters
Binding Parameter Markers
4/27/2022 • 2 minutes to read • Edit Online
The application binds parameters by calling SQLBindParameter . SQLBindParameter binds one parameter at
a time. With it, the application specifies the following:
The parameter number. Parameters are numbered in increasing parameter order in the SQL statement,
starting with the number 1. While it is legal to specify a parameter number that is higher than the
number of parameters in the SQL statement, the parameter value will be ignored when the statement is
executed.
The parameter type (input, input/output, or output). Except for parameters in procedure calls, all
parameters are input parameters. For more information, see Procedure Parameters, later in this section.
The C data type, address, and byte length of the variable bound to the parameter. The driver must be able
to convert the data from the C data type to the SQL data type or an error is returned. For a list of
supported conversions, see Converting Data from C to SQL Data Types in Appendix D: Data Types.
The SQL data type, precision, and scale of the parameter itself.
The address of a length/indicator buffer. It provides the byte length of binary or character data, specifies
that the data is NULL, or specifies that the data will be sent with SQLPutData . For more information, see
Using Length/Indicator Values.
For example, the following code binds SalesPerson and CustID to parameters for the SalesPerson and CustID
columns. Because SalesPerson contains character data, which is variable length, the code specifies the byte
length of SalesPerson (11) and binds SalesPersonLenOrInd to contain the byte length of the data in SalesPerson.
This information is not necessary for CustID because it contains integer data, which is of fixed length.
SQLCHAR SalesPerson[11];
SQLINTEGER SalesPersonLenOrInd, CustIDInd;
SQLUINTEGER CustID;
// Execute a statement to get data for all orders made to the specified
// customer by the specified salesperson.
SQLExecDirect(hstmt1,"SELECT * FROM Orders WHERE SalesPerson=? AND CustID=?",SQL_NTS);
When SQLBindParameter is called, the driver stores this information in the structure for the statement. When
the statement is executed, it uses the information to retrieve the parameter data and send it to the data source.
NOTE
In ODBC 1.0, parameters were bound with SQLSetParam . The Driver Manager maps calls between SQLSetParam and
SQLBindParameter , depending on the versions of ODBC used by the application and driver.
Binding Parameters by Name (Named Parameters)
4/27/2022 • 2 minutes to read • Edit Online
Certain DBMSs allow an application to specify the parameters to a stored procedure by name instead of by
position in the procedure call. Such parameters are called named parameters. ODBC supports the use of named
parameters. In ODBC, named parameters are used only in calls to stored procedures and cannot be used in
other SQL statements.
The driver checks the value of the SQL_DESC_UNNAMED field of the IPD to determine whether named
parameters are used. If SQL_DESC_UNNAMED is not set to SQL_UNNAMED, the driver uses the name in the
SQL_DESC_NAME field of the IPD to identify the parameter. To bind the parameter, an application can call
SQLBindParameter to specify the parameter information and then can call SQLSetDescField to set the
SQL_DESC_NAME field of the IPD. When named parameters are used, the order of the parameter in the
procedure call is not important and the parameter's record number is ignored.
The difference between unnamed parameters and named parameters is in the relationship between the record
number of the descriptor and the parameter number in the procedure. When unnamed parameters are used, the
first parameter marker is related to the first record in the parameter descriptor, which in turn is related to the
first parameter (in creation order) in the procedure call. When named parameters are used, the first parameter
marker is still related to the first record of the parameter descriptor, but the relationship between the record
number of the descriptor and the parameter number in the procedure does not exist anymore. Named
parameters do not use the mapping of the descriptor record number to the procedure parameter position;
instead, the descriptor record name is mapped to the procedure parameter name.
NOTE
If automatic population of the IPD is enabled, the driver will populate the descriptor such that the order of the descriptor
records will match the order of the parameters in the procedure definition, even if named parameters are used.
If a named parameter is used, all parameters must be named parameters. If any parameter is not a named
parameter, then none of the parameters ca be named parameters. If there were a mixture of named parameters
and unnamed parameters, the behavior would be driver-dependent.
As an example of named parameters, suppose a SQL Server stored procedure has been defined as follows:
In this procedure, the first parameter, @title_id, has a default value of 1. An application can use the following
code to invoke this procedure such that it specifies only one dynamic parameter. This parameter is a named
parameter with the name "@quote".
// Prepare the procedure invocation statement.
SQLPrepare(hstmt, "{call test(?)}", SQL_NTS);
// Get ipd handle and set the SQL_DESC_NAMED and SQL_DESC_UNNAMED fields
// for record #1.
SQLGetStmtAttr(hstmt, SQL_ATTR_IMP_PARAM_DESC, &hIpd, 0, 0);
SQLSetDescField(hIpd, 1, SQL_DESC_NAME, "@quote", SQL_NTS);
An application can specify that an offset is added to bound parameter buffer addresses and the corresponding
length/indicator buffer addresses when SQLExecDirect or SQLExecute is called. The result of these additions
determines the addresses used in these operations.
Bind offsets allow an application to change bindings without calling SQLBindParameter for previously bound
parameters. A call to SQLBindParameter to rebind a parameter changes the buffer address and the
length/indicator pointer. Rebinding with an offset, on the other hand, simply adds an offset to the existing bound
parameter buffer address and length/indicator buffer address. When offsets are used, the bindings are a
"template" of how the application buffers are laid out and the application can move this "template" to different
areas of memory by changing the offset. A new offset can be specified at any time and is always added to the
originally bound values.
To specify a bind offset, the application sets the SQL_ATTR_PARAM_BIND_OFFSET_PTR statement attribute to the
address of an SQLINTEGER buffer. Before the application calls a function that uses the bindings, it places an
offset in bytes in this buffer, as long as neither the parameter buffer address nor the length/indicator buffer
address is 0, and the bound parameter is in the SQL statement. The sum of the address and the offset must be a
valid address. (This means that either or both the offset and the address to which the offset is added can be
invalid, as long as their sum is a valid address.)
NOTE
Binding offsets are not supported by ODBC 2.x drivers.
Describing Parameters
4/27/2022 • 2 minutes to read • Edit Online
SQLBindParameter has arguments that describe the parameter: its SQL type, precision, and scale. The driver
uses this information, or metadata, to convert the parameter value to the type needed by the data source. At first
glance, it might seem that the driver is in a better position to know the parameter metadata than the application;
after all, the driver can easily discover the metadata for a result set column. As it turns out, this is not the case.
First, most data sources do not provide a way for the driver to discover parameter metadata. Second, most
applications already know the metadata.
If an SQL statement is hard-coded in the application, the application writer already knows the type of each
parameter. If an SQL statement is constructed by the application at run time, the application can determine the
metadata as it builds the statement. For example, when the application constructs the clause
WHERE OrderID = ?
To set the value of a parameter, the application simply sets the value of the variable bound to the parameter. It is
not important when this value is set, as long as it is set before the statement is executed. The application can set
the value before or after binding the variable, and it can change the value as many times as it wants. When the
statement is executed, the driver simply retrieves the current value of the variable. This is particularly useful
when a prepared statement is executed more than once; the application sets new values for some or all of the
variables each time the statement is executed. For an example of this, see Prepared Execution, earlier in this
section.
If a length/indicator buffer was bound in the call to SQLBindParameter , it must be set to one of the following
values before the statement is executed:
The byte length of the data in the bound variable. The driver checks this length only if the variable is
character or binary (ValueType is SQL_C_CHAR or SQL_C_BINARY).
SQL_NTS. The data is a null-terminated string.
SQL_NULL_DATA. The data value is NULL, and the driver ignores the value of the bound variable.
SQL_DATA_AT_EXEC or the result of the SQL_LEN_DATA_AT_EXEC macro. The value of the parameter is to
be sent with SQLPutData . For more information, see Sending Long Data, later in this section.
The following table shows the values of the bound variable and the length/indicator buffer that the application
sets for a variety of parameter values.
PA RA M ET ER VA L UE IN VA L UE IN
10 SQL_INTEGER SQL_C_SLONG 10 --
[a] "\0" represents a null-termination character. The null-termination character is required only if the value in the
length/indicator buffer is SQL_NTS.
[b] The numbers in this list are the numbers stored in the fields of the TIME_STRUCT structure.
[c] The string uses the ODBC date escape clause. For more information, see Date, Time, and Timestamp Literals.
[d] Drivers must always check this value to see whether it is a special value, such as SQL_NULL_DATA.
What a driver does with a parameter value at execution time is driver-dependent. If necessary, the driver
converts the value from the C data type and byte length of the bound variable to the SQL data type, precision,
and scale of the parameter. In most cases, the driver then sends the value to the data source. In some cases, it
formats the value as text and inserts it into the SQL statement before sending the statement to the data source.
Sending Long Data
4/27/2022 • 3 minutes to read • Edit Online
DBMSs define long data as any character or binary data over a certain size, such as 254 characters. It might not
be possible to store an entire item of long data in memory, such as when the item represents a long text
document or a bitmap. Because such data cannot be stored in a single buffer, the data source sends it to the
driver in parts with SQLPutData when the statement is executed. Parameters for which data is sent at execution
time are known as data-at-execution parameters.
NOTE
An application can actually send any type of data at execution time with SQLPutData , although only character and
binary data can be sent in parts. However, if the data is small enough to fit in a single buffer, there is generally no reason
to use SQLPutData . It is much easier to bind the buffer and let the driver retrieve the data from the buffer.
To send data at execution time, the application performs the following actions:
1. Passes a 32-bit value that identifies the parameter in the ParameterValuePtr argument in
SQLBindParameter rather than passing the address of a buffer. This value is not analyzed by the driver.
It will be returned to the application later, so it should mean something to the application. For example, it
might be the number of the parameter or the handle of a file containing data.
2. Passes the address of a length/indicator buffer in the StrLen_or_IndPtr argument of SQLBindParameter .
3. Stores SQL_DATA_AT_EXEC or the result of the SQL_LEN_DATA_AT_EXEC(length) macro in the
length/indicator buffer. Both of these values indicate to the driver that the data for the parameter will be
sent with SQLPutData . SQL_LEN_DATA_AT_EXEC(length) is used when sending long data to a data
source that needs to know how many bytes of long data will be sent so that it can preallocate space. To
determine if a data source requires this value, the application calls SQLGetInfo with the
SQL_NEED_LONG_DATA_LEN option. All drivers must support this macro; if the data source does not
require the byte length, the driver can ignore it.
4. Calls SQLExecute or SQLExecDirect . The driver discovers that a length/indicator buffer contains the
value SQL_DATA_AT_EXEC or the result of the SQL_LEN_DATA_AT_EXEC(length) macro and returns
SQL_NEED_DATA as the return value of the function.
5. Calls SQLParamData in response to the SQL_NEED_DATA return value. If long data needs to be sent,
SQLParamData returns SQL_NEED_DATA. In the buffer pointed to by the ValuePtrPtr argument, the
driver returns the value that identifies the data-at-execution parameter. If there is more than one data-at-
execution parameter, the application must use this value to determine which parameter to send data for;
the driver is not required to request data for data-at-execution parameters in any particular order.
6. Calls SQLPutData to send the parameter data to the driver. If the parameter data does not fit into a
single buffer, as is often the case with long data, the application calls SQLPutData repeatedly to send the
data in parts; it is up to the driver and data source to reassemble the data. If the application passes null-
terminated string data, the driver or data source must remove the null-termination character as part of
the reassembly process.
7. Calls SQLParamData again to indicate that it has sent all of the data for the parameter. If there are any
data-at-execution parameters for which data has not been sent, the driver returns SQL_NEED_DATA and
the value that identifies the next parameter; the application returns to step 6. If data has been sent for all
data-at-execution parameters, the statement is executed. SQLParamData returns SQL_SUCCESS or
SQL_SUCCESS_WITH_INFO and can return any return value or diagnostic that SQLExecute or
SQLExecDirect can return.
After SQLExecute or SQLExecDirect returns SQL_NEED_DATA and before data has been completely sent for
the last data-at-execution parameter, the statement is in a Need Data state. While a statement is in a Need Data
state, the application can call only SQLPutData , SQLParamData , SQLCancel , SQLGetDiagField , or
SQLGetDiagRec ; all other functions return SQLSTATE HY010 (Function sequence error). Calling SQLCancel
cancels execution of the statement and returns it to its previous state. For more information, see Appendix B:
ODBC State Transition Tables.
For an example of sending data at execution time, see the SQLPutData function description.
Retrieving Output Parameters Using SQLGetData
4/27/2022 • 10 minutes to read • Edit Online
Before ODBC 3.8, an application could only retrieve the output parameters of a query with a bound output
buffer. However, it is difficult to allocate a very large buffer when the size of the parameter value is very large
(for example, a large image). ODBC 3.8 introduces a new way to retrieve output parameters in parts. An
application can now call SQLGetData with a small buffer multiple times to retrieve a large parameter value.
This is similar to retrieving large column data.
To bind an output parameter or input/output parameter to be retrieved in parts, call SQLBindParameter with
the InputOutputType argument set to SQL_PARAM_OUTPUT_STREAM or
SQL_PARAM_INPUT_OUTPUT_STREAM. With SQL_PARAM_INPUT_OUTPUT_STREAM, an application can use
SQLPutData to input data into the parameter, and then use SQLGetData to retrieve the output parameter. The
input data must be in the data-at-execution (DAE) form, using SQLPutData instead of binding it to a
preallocated buffer.
This feature can be used by ODBC 3.8 applications or recompiled ODBC 3.x and ODBC 2.x applications, and
these applications must have an ODBC 3.8 driver that supports retrieving output parameters using
SQLGetData and ODBC 3.8 Driver Manager. For information about how to enable an older application to use
new ODBC features, see Compatibility Matrix.
Usage Example
For example, consider executing a stored procedure, {CALL sp_f(?,?)} , where both parameters are bound as
SQL_PARAM_OUTPUT_STREAM, and the stored procedure returns no result set (later in this topic you will find a
more complex scenario):
1. For each parameter, call SQLBindParameter with InputOutputType set to
SQL_PARAM_OUTPUT_STREAM and ParameterValuePtr set to a token, such as a parameter number, a
pointer to data, or a pointer to a structure that the application uses to bind input parameters. This
example will use the parameter ordinal as the token.
2. Execute the query with SQLExecDirect or SQLExecute . SQL_PARAM_DATA_AVAILABLE will be returned,
indicating that there are streamed output parameters available for retrieval.
3. Call SQLParamData to get the parameter that is available for retrieval. SQLParamData will return
SQL_PARAM_DATA_AVAILABLE with the token of the first available parameter, which is set in
SQLBindParameter (step 1). The token is returned in the buffer that the ValuePtrPtr points to.
4. Call SQLGetData with the argument Col_or_Param_Num set to the parameter ordinal to retrieve the
data of the first available parameter. If SQLGetData returns SQL_SUCCESS_WITH_INFO and SQLState
01004 (data truncated), and the type is variable length on both the client and server, there is more data to
retrieve from the first available parameter. You can continue to call SQLGetData until it returns
SQL_SUCCESS or SQL_SUCCESS_WITH_INFO with a different SQLState .
5. Repeat step 3 and step 4 to retrieve the current parameter.
6. Call SQLParamData again. If it returns anything except SQL_PARAM_DATA_AVAILABLE, there is no more
streamed parameter data to retrieve, and the return code will be the return code of the next statement
that is executed.
7. Call SQLMoreResults to process the next set of parameters until it returns SQL_NO_DATA.
SQLMoreResults will return SQL_NO_DATA in this example if the statement attribute
SQL_ATTR_PARAMSET_SIZE was set to 1. Otherwise, SQLMoreResults will return
SQL_PARAM_DATA_AVAILABLE to indicate that there are streamed output parameters available for the
next set of parameters to retrieve.
Similar to a DAE input parameter, the token used in the argument ParameterValuePtr in SQLBindParameter
(step 1) can be a pointer that points to an application data structure, which contains the ordinal of the parameter
and more application-specific information, if necessary.
The order of the returned streamed output or input/output parameters is driver specific and might not always
be the same as the order specified in the query.
If the application does not call SQLGetData in step 4, the parameter value is discarded. Similarly, if the
application calls SQLParamData before all of a parameter value has been read by SQLGetData , the remainder
of the value is discarded, and the application can process the next parameter.
If the application calls SQLMoreResults before all streamed output parameters are processed
(SQLParamData does still return SQL_PARAM_DATA_AVAILABLE), all remaining parameters are discarded.
Similarly, if the application calls SQLMoreResults before all of a parameter value has been read by
SQLGetData , the remainder of the value and all remaining parameters are discarded, and the application can
continue to process the next parameter set.
Note that an application can specify the C data type in both SQLBindParameter and SQLGetData . The C data
type specified with SQLGetData overrides the C data type specified in SQLBindParameter , unless the C data
type specified in SQLGetData is SQL_APD_TYPE.
Although a streamed output parameter is more useful when the data type of the output parameter is of type
BLOB, this functionality can also be used with any data type. The data types supported by streamed output
parameters are specified in the driver.
If there are SQL_PARAM_INPUT_OUTPUT_STREAM parameters to be processed, SQLExecute or
SQLExecDirect will return SQL_NEED_DATA first. An application can call SQLParamData and SQLPutData to
send DAE parameter data. When all DAE input parameters are processed, SQLParamData returns
SQL_PARAM_DATA_AVAILABLE to indicate streamed output parameters are available.
When there are streamed output parameters and bound output parameters to be processed, the driver
determines the order for processing output parameters. So, if an output parameter is bound to a buffer (the
SQLBindParameter parameter InputOutputType is set to SQL_PARAM_INPUT_OUTPUT or
SQL_PARAM_OUTPUT), the buffer may not be populated until SQLParamData returns SQL_SUCCESS or
SQL_SUCCESS_WITH_INFO. An application should read a bound buffer only after SQLParamData returns
SQL_SUCCESS or SQL_SUCCESS_WITH_INFO that is after all streamed output parameters are processed.
The data source can return a warning and result set, in addition to the streamed output parameter. In general,
warnings and result sets are processed separately from a streamed output parameter by calling
SQLMoreResults . Process warnings and the result set before processing the streamed output parameter.
The following table describes different scenarios of a single command sent to the server, and how the
application should work.
Data includes a result set and SQL_SUCCESS Retrieve the result set with
streamed output parameters SQLBindCol and SQLGetData .
Query with DAE input parameters, for SQL NEED_DATA Call SQLParamData and
example, a streamed input/output SQLPutData to send DAE input
(DAE) parameter parameter data.
retcode = SQLExecute(hstmt);
if ( retcode == SQL_ERROR )
return FALSE;
// Assume that the retrieved picture exists. Use SQLBindCol or SQLGetData to retrieve the result-set.
// Process the result set and move to the streamed output parameters.
retcode = SQLMoreResults( hstmt );
return TRUE;
}
// First bind the parameters, before preparing the statement that binds the output streamed parameter.
SQLBindParameter(
hstmt,
1, // The first parameter.
SQL_PARAM_INPUT_OUTPUT_STREAM, // I/O-streamed parameter: The Picture.
SQL_C_BINARY, // The C Data Type.
SQL_VARBINARY, // The SQL Data Type.
0, // ColumnSize: The maximum size of varbinary(max).
0, // DecimalDigits is ignored.
(SQLPOINTER)1, // An application defined token.
0, // BufferLength is ignored for streamed I/O parameters.
&statusOfPicture); // The status variable.
return TRUE;
}
See Also
Statement Parameters
Procedure Parameters
4/27/2022 • 2 minutes to read • Edit Online
Parameters in procedure calls can be input, input/output, or output parameters. This is different from
parameters in all other SQL statements, which are always input parameters.
Input parameters are used to send values to the procedure. For example, suppose the Parts table has PartID,
Description, and Price columns. The InsertPart procedure might have an input parameter for each column in the
table. For example:
A driver should not modify the contents of an input buffer until SQLExecDirect or SQLExecute returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_NO_DATA. The
contents of the input buffer should not be modified while SQLExecDirect or SQLExecute returns
SQL_NEED_DATA or SQL_STILL_EXECUTING.
Input/output parameters are used both to send values to procedures and retrieve values from procedures. Using
the same parameter as both an input and an output parameter tends to be confusing and should be avoided.
For example, suppose a procedure accepts an order ID and returns the ID of the customer. This can be defined
with a single input/output parameter:
{call GetCustID(?)}
It might be better to use two parameters: an input parameter for the order ID and an output or input/output
parameter for the customer ID:
Output parameters are used to retrieve the procedure return value and to retrieve values from procedure
arguments; procedures that return values are sometimes known as functions. For example, suppose the
GetCustID procedure just mentioned returns a value that indicates whether it was able to find the order. In the
following call, the first parameter is an output parameter used to retrieve the procedure return value, the second
parameter is an input parameter used to specify the order ID, and the third parameter is an output parameter
used to retrieve the customer ID:
Drivers handle values for input and input/output parameters in procedures no differently than input parameters
in other SQL statements. When the statement is executed, they retrieve the values of the variables bound to
these parameters and send them to the data source.
After the statement has been executed, drivers store the returned values of input/output and output parameters
in the variables bound to those parameters. These returned values are not guaranteed to be set until after all
results returned by the procedure have been fetched and SQLMoreResults has returned SQL_NO_DATA. If
executing the statement results in an error, the contents of the input/output parameter buffer or output
parameter buffer are undefined.
An application calls SQLProcedure to determine whether a procedure has a return value. It calls
SQLProcedureColumns to determine the type (return value, input, input/output, or output) of each procedure
parameter.
Arrays of Parameter Values
4/27/2022 • 2 minutes to read • Edit Online
It is often useful for applications to pass arrays of parameters. For example, using arrays of parameters and a
parameterized INSERT statement, an application can insert a number of rows at once. There are several
advantages to using arrays. First, network traffic is reduced because the data for many statements is sent in a
single packet (if the data source supports parameter arrays natively). Second, some data sources can execute
SQL statements using arrays faster than executing the same number of separate SQL statements. Finally, when
the data is stored in an array, as is often the case for screen data, the application can bind all of the rows in a
particular column with a single call to SQLBindParameter and update them by executing a single statement.
Unfortunately, not many data sources support parameter arrays. However, a driver can emulate parameter
arrays by executing an SQL statement once for each set of parameter values. This can lead to increases in speed
because the driver can then prepare the statement that it plans to execute once for each parameter set. It might
also lead to simpler application code.
This section contains the following topics.
Binding Arrays of Parameters
Using Arrays of Parameters
Binding Arrays of Parameters
4/27/2022 • 5 minutes to read • Edit Online
Applications that use arrays of parameters bind the arrays to the parameters in the SQL statement. There are
two binding styles:
Bind an array to each parameter. Each data structure (array) contains all the data for a single parameter.
This is called column-wise binding because it binds a column of values for a single parameter.
Define a structure to hold the parameter data for an entire set of parameters and bind an array of these
structures. Each data structure contains the data for a single SQL statement. This is called row-wise
binding because it binds a row of parameters.
As when the application binds single variables to parameters, it calls SQLBindParameter to bind arrays to
parameters. The only difference is that the addresses passed are array addresses, not single-variable addresses.
The application sets the SQL_ATTR_PARAM_BIND_TYPE statement attribute to specify whether it is using
column-wise (the default) or row-wise binding. Whether to use column-wise or row-wise binding is largely a
matter of application preference. Depending on how the processor accesses memory, row-wise binding might
be faster. However, the difference is likely to be negligible except for very large numbers of rows of parameters.
Column-Wise Binding
When using column-wise binding, an application binds one or two arrays to each parameter for which data is to
be provided. The first array holds the data values, and the second array holds length/indicator buffers. Each
array contains as many elements as there are values for the parameter.
Column-wise binding is the default. The application also can change from row-wise binding to column-wise
binding by setting the SQL_ATTR_PARAM_BIND_TYPE statement attribute. The following illustration shows how
column-wise binding works.
For example, the following code binds 10-element arrays to parameters for the PartID, Description, and Price
columns, and executes a statement to insert 10 rows. It uses column-wise binding.
#define DESC_LEN 51
#define ARRAY_SIZE 10
memset(DescLenOrIndArray, 0, sizeof(DescLenOrIndArray));
memset(PartIDIndArray, 0, sizeof(PartIDIndArray));
memset(PriceIndArray, 0, sizeof(PriceIndArray));
case SQL_PARAM_ERROR:
printf("%13d Error\n", i);
break;
case SQL_PARAM_UNUSED:
printf("%13d Not processed\n", i);
break;
case SQL_PARAM_DIAG_UNAVAILABLE:
printf("%13d Unknown\n", i);
break;
}
}
Row-Wise Binding
When using row-wise binding, an application defines a structure for each set of parameters. The structure
contains one or two elements for each parameter. The first element holds the parameter value, and the second
element holds the length/indicator buffer. The application then allocates an array of these structures, which
contains as many elements as there are values for each parameter.
The application declares the size of the structure to the driver with the SQL_ATTR_PARAM_BIND_TYPE statement
attribute. The application binds the addresses of the parameters in the first structure of the array. Thus, the
driver can calculate the address of the data for a particular row and column as
where rows are numbered from 1 to the size of the parameter set. The offset, if defined, is the value pointed to
by the SQL_ATTR_PARAM_BIND_OFFSET_PTR statement attribute. The following illustration shows how row-
wise binding works. The parameters can be placed in the structure in any order but are shown in sequential
order for clarity.
The following code creates a structure with elements for the values to store in the PartID, Description, and Price
columns. It then allocates a 10-element array of these structures and binds it to parameters for the PartID,
Description, and Price columns, using row-wise binding. It then executes a statement to insert 10 rows.
#define DESC_LEN 51
#define ARRAY_SIZE 10
typedef tagPartStruct {
SQLREAL Price;
SQLUINTEGER PartID;
SQLCHAR Desc[DESC_LEN];
SQLINTEGER PriceInd;
SQLINTEGER PartIDInd;
SQLINTEGER DescLenOrInd;
} PartStruct;
PartStruct PartArray[ARRAY_SIZE];
SQLCHAR * Statement = "INSERT INTO Parts (PartID, Description,
Price) "
"VALUES (?, ?, ?)";
SQLUSMALLINT i, ParamStatusArray[ARRAY_SIZE];
SQLULEN ParamsProcessed;
case SQL_PARAM_ERROR:
printf("%13d Error\n", i);
break;
case SQL_PARAM_UNUSED:
printf("%13d Not processed\n", i);
break;
case SQL_PARAM_DIAG_UNAVAILABLE:
printf("%13d Unknown\n", i);
break;
}
Using Arrays of Parameters
4/27/2022 • 6 minutes to read • Edit Online
To use arrays of parameters, the application calls SQLSetStmtAttr with an Attribute argument of
SQL_ATTR_PARAMSET_SIZE to specify the number of sets of parameters. It calls SQLSetStmtAttr with an
Attribute argument of SQL_ATTR_PARAMS_PROCESSED_PTR to specify the address of a variable in which the
driver can return the number of sets of parameters processed, including error sets. It calls SQLSetStmtAttr
with an Attribute argument of SQL_ATTR_PARAM_STATUS_PTR to point to an array in which to return status
information for each row of parameter values. The driver stores these addresses in the structure it maintains for
the statement.
NOTE
In ODBC 2.x, SQLParamOptions was called to specify multiple values for a parameter. In ODBC 3.x, the call to
SQLParamOptions has been replaced by calls to SQLSetStmtAttr to set the SQL_ATTR_PARAMSET_SIZE and
SQL_ATTR_PARAMS_PROCESSED_ARRAY attributes.
Before executing the statement, the application sets the value of each element of each bound array. When the
statement is executed, the driver uses the information it stored to retrieve the parameter values and send them
to the data source; if possible, the driver should send these values as arrays. Although the use of arrays of
parameters is best implemented by executing the SQL statement with all of the parameters in the array with a
single call to the data source, this capability is not widely available in DBMSs today. However, drivers can
simulate it by executing an SQL statement multiple times, each with a single set of parameters.
Before an application uses arrays of parameters, it must be sure that they are supported by the drivers used by
the application. There are two ways to do this:
Use only drivers known to support arrays of parameters. The application can hard-code the names of
these drivers, or the user can be instructed to use only these drivers. Custom applications and vertical
applications commonly use a limited set of drivers.
Check for support of arrays of parameters at run time. A driver supports arrays of parameters if it is
possible to set the SQL_ATTR_PARAMSET_SIZE statement attribute to a value greater than 1. Generic
applications and vertical applications commonly check for support of arrays of parameters at run time.
The availability of row counts and result sets in parameterized execution can be determined by calling
SQLGetInfo with the SQL_PARAM_ARRAY_ROW_COUNTS and SQL_PARAM_ARRAY_SELECTS options. For
INSERT , UPDATE , and DELETE statements, the SQL_PARAM_ARRAY_ROW_COUNTS option indicates whether
individual row counts (one for each parameter set) are available (SQL_PARC_BATCH) or whether row counts are
rolled up into one (SQL_PARC_NO_BATCH). For SELECT statements, the SQL_PARAM_ARRAY_SELECTS option
indicates whether a result set is available for each set of parameters (SQL_PAS_BATCH) or whether only one
result set is available (SQL_PAS_NO_BATCH). If the driver does not allow result set-generating statements to be
executed with an array of parameters, SQL_PARAM_ARRAY_SELECTS returns SQL_PAS_NO_SELECT. It is data
source-specific whether arrays of parameters can be used with other types of statements, especially because the
use of parameters in these statements would be data source-specific and would not follow ODBC SQL grammar.
The array pointed to by the SQL_ATTR_PARAM_OPERATION_PTR statement attribute can be used to ignore rows
of parameters. If an element of the array is set to SQL_PARAM_IGNORE, the set of parameters corresponding to
that element is excluded from the SQLExecute or SQLExecDirect call. The array pointed to by the
SQL_ATTR_PARAM_OPERATION_PTR attribute is allocated and filled in by the application and read by the driver.
If fetched rows are used as input parameters, the values of the row status array can be used in the parameter
operation array.
Error Processing
If an error occurs while executing the statement, the execution function returns an error and sets the row
number variable to the number of the row containing the error. It is data source-specific whether all rows except
the error set are executed or whether all rows before (but not after) the error set are executed. Because it
processes sets of parameters, the driver sets the buffer specified by the SQL_ATTR_PARAMS_PROCESSED_PTR
statement attribute to the number of the row currently being processed. If all sets except the error set are
executed, the driver sets this buffer to SQL_ATTR_PARAMSET_SIZE after all rows are processed.
If the SQL_ATTR_PARAM_STATUS_PTR statement attribute has been set, SQLExecute or SQLExecDirect returns
the parameter status array, which provides the status of each set of parameters. The parameter status array is
allocated by the application and filled in by the driver. Its elements indicate whether the SQL statement was
executed successfully for the row of parameters or whether an error occurred while processing the set of
parameters. If an error occurred, the driver sets the corresponding value in the parameter status array to
SQL_PARAM_ERROR and returns SQL_SUCCESS_WITH_INFO. The application can check the status array to
determine which rows were processed. Using the row number, the application can often correct the error and
resume processing.
How the parameter status array is used is determined by the SQL_PARAM_ARRAY_ROW_COUNTS and
SQL_PARAM_ARRAY_SELECTS options returned by a call to SQLGetInfo . For INSERT , UPDATE , and DELETE
statements, the parameter status array is filled in with status information if SQL_PARC_BATCH is returned for
SQL_PARAM_ARRAY_ROW_COUNTS, but not if SQL_PARC_NO_BATCH is returned. For SELECT statements, the
parameter status array is filled in if SQL_PAS_BATCH is returned for SQL_PARAM_ARRAY_SELECT, but not if
SQL_PAS_NO_BATCH or SQL_PAS_NO_SELECT is returned.
Data-at-Execution Parameters
If any of the values in the length/indicator array are SQL_DATA_AT_EXEC or the result of the
SQL_LEN_DATA_AT_EXEC(length) macro, the data for those values is sent with SQLPutData in the usual way.
The following aspects of this process bear special comment because they are not readily obvious:
When the driver returns SQL_NEED_DATA, it must set the address of the row number variable to the row
for which it needs data. As in the single-valued case, the application cannot make any assumptions about
the order in which the driver will request parameter values within a single set of parameters. If an error
occurs in the execution of a data-at-execution parameter, the buffer specified by the
SQL_ATTR_PARAMS_PROCESSED_PTR statement attribute is set to the number of the row on which the
error occurred, the status for the row in the row status array specified by the
SQL_ATTR_PARAM_STATUS_PTR statement attribute is set to SQL_PARAM_ERROR, and the call to
SQLExecute , SQLExecDirect , SQLParamData , or SQLPutData returns SQL_ERROR. The contents of
this buffer are undefined if SQLExecute , SQLExecDirect , or SQLParamData return
SQL_STILL_EXECUTING.
Because the driver does not interpret the value in the ParameterValuePtr argument of
SQLBindParameter for data-at-execution parameters, if the application provides a pointer to an array,
SQLParamData does not extract and return an element of this array to the application. Instead, it returns
the scalar value the application had supplied. This means the value returned by SQLParamData is not
sufficient to specify the parameter for which the application needs to send data; the application also
needs to consider the current row number.
When only some of the elements of an array of parameters are data-at-execution parameters, the
application must pass the address of an array in ParameterValuePtr that contains elements for all the
parameters. This array is interpreted normally for the parameters that are not data-at-execution
parameters. For the data-at-execution parameters, the value that SQLParamData provides to the
application, which normally could be used to identify the data that the driver is requesting on this
occasion, is always the address of the array.
Asynchronous Execution
4/27/2022 • 2 minutes to read • Edit Online
ODBC supports asynchronous operations for both statement and connection operations. There are two ways to
determine when an asynchronous operation is complete:
1. Asynchronous Execution (Polling Method)
2. Asynchronous Execution (Notification Method)
See Also
Executing Statements ODBC
Asynchronous Execution (Polling Method)
4/27/2022 • 11 minutes to read • Edit Online
Prior to ODBC 3.8 and the Windows 7 SDK, asynchronous operations were permitted only on statement
functions. For more information, see the Executing Statement Operations Asynchronously , later in this
topic.
ODBC 3.8 in the Windows 7 SDK introduced asynchronous execution on connection-related operations. For
more information, see the Executing Connection Operations Asynchronously section, later in this topic.
In the Windows 7 SDK, for asynchronous statement or connection operations, an application determined that
the asynchronous operation was complete using the polling method. Beginning in the Windows 8 SDK, you can
determine that an asynchronous operation is complete using the notification method. For more information, see
Asynchronous Execution (Notification Method).
By default, drivers execute ODBC functions synchronously; that is, the application calls a function and the driver
does not return control to the application until it has finished executing the function. However, some functions
can be executed asynchronously; that is, the application calls the function, and the driver, after minimal
processing, returns control to the application. The application can then call other functions while the first
function is still executing.
Asynchronous execution is supported for most functions that are largely executed on the data source, such as
the functions to establish connections, prepare and execute SQL statements, retrieve metadata, fetch data, and
commit transactions. It is most useful when the task being executed on the data source takes a long time, such
as a login process or a complex query against a large database.
When the application executes a function with a statement or connection that is enabled for asynchronous
processing, the driver performs a minimal amount of processing (such as checking arguments for errors), hands
processing to the data source, and returns control to the application with the SQL_STILL_EXECUTING return
code. The application then performs other tasks. To determine when the asynchronous function has finished, the
application polls the driver at regular intervals by calling the function with the same arguments as it originally
used. If the function is still executing, it returns SQL_STILL_EXECUTING; if it has finished executing, it returns the
code it would have returned had it executed synchronously, such as SQL_SUCCESS, SQL_ERROR, or
SQL_NEED_DATA.
Whether a function executes synchronously or asynchronously is driver specific. For example, suppose the result
set metadata is cached in the driver. In this case, it takes very little time to execute SQLDescribeCol and the
driver should simply execute the function rather than artificially delay execution. On the other hand, if the driver
needs to retrieve the metadata from the data source, it should return control to the application while it is doing
this. Therefore, the application must be able to handle a return code other than SQL_STILL_EXECUTING when it
first executes a function asynchronously.
While a function is executing asynchronously, the application can call functions on any other statements. The
application can also call functions on any connection, except the one associated with the asynchronous
statement. But the application can only call the original function and the following functions (with the statement
handle or its associated connection, environment handle), after a statement operation returns
SQL_STILL_EXECUTING:
SQLCancel
SQLCancelHandle (on the statement handle)
SQLGetDiagField
SQLGetDiagRec
SQLAllocHandle
SQLGetEnvAttr
SQLGetConnectAttr
SQLDataSources
SQLDrivers
SQLGetInfo
SQLGetFunctions
SQLNativeSql
If the application calls any other function with the asynchronous statement or with the connection associated
with that statement, the function returns SQLSTATE HY010 (Function sequence error), for example.
SQLHDBC hdbc1, hdbc2;
SQLHSTMT hstmt1, hstmt2, hstmt3;
SQLCHAR * SQLStatement = "SELECT * FROM Orders";
SQLUINTEGER InfoValue;
SQLRETURN rc;
When an application calls a function to determine whether it is still executing asynchronously, it must use the
original statement handle. This is because asynchronous execution is tracked on a per-statement basis. The
application must also supply valid values for the other arguments - the original arguments will do - to get past
error checking in the Driver Manager. However, after the driver checks the statement handle and determines that
the statement is executing asynchronously, it ignores all other arguments.
While a function is executing asynchronously - that is, after it has returned SQL_STILL_EXECUTING and before it
returns a different code - the application can cancel it by calling SQLCancel or SQLCancelHandle with the
same statement handle. This is not guaranteed to cancel function execution. For example, the function might
have already finished. Furthermore, the code returned by SQLCancel or SQLCancelHandle only indicates
whether the attempt to cancel the function was successful, not whether it actually canceled the function. To
determine whether the function was canceled, the application calls the function again. If the function was
canceled, it returns SQL_ERROR and SQLSTATE HY008 (Operation canceled). If the function was not canceled, it
returns another code, such as SQL_SUCCESS, SQL_STILL_EXECUTING, or SQL_ERROR with a different SQLSTATE.
To disable asynchronous execution of a particular statement when the driver supports statement-level
asynchronous processing, the application calls SQLSetStmtAttr with the SQL_ATTR_ASYNC_ENABLE attribute
and sets it to SQL_ASYNC_ENABLE_OFF. If the driver supports connection-level asynchronous processing, the
application calls SQLSetConnectAttr to set SQL_ATTR_ASYNC_ENABLE to SQL_ASYNC_ENABLE_OFF, which
disables asynchronous execution of all statements on the connection.
The application should process diagnostic records in the repeating loop of the original function. If
SQLGetDiagField or SQLGetDiagRec is called when an asynchronous function is executing, it will return the
current list of diagnostic records. Each time the original function call is repeated, it clears previous diagnostic
records.
Examples
A. Enable asynchronous execution of connection functions
The following example shows how to use SQLSetConnectAttr to enable asynchronous execution for
connection-related functions.
BOOL AsyncConnect (SQLHANDLE hdbc)
{
SQLRETURN r;
SQLHANDLE hdbc;
if (r == SQL_ERROR)
{
// Use SQLGetDiagRec to process the error.
// If SQLState is HY114, the driver does not support asynchronous execution.
return FALSE;
}
while (r == SQL_STILL_EXECUTING)
{
// Do something else.
return TRUE;
}
See Also
Executing Statements ODBC
Asynchronous Execution (Notification Method)
4/27/2022 • 12 minutes to read • Edit Online
ODBC allows asynchronous execution of connection and statement operations. An application thread can call an
ODBC function in asynchronous mode and the function can return before the operation is complete, allowing
the application thread to perform other tasks. In the Windows 7 SDK, for asynchronous statement or connection
operations, an application determined that the asynchronous operation was complete using the polling method.
For more information, see Asynchronous Execution (Polling Method). Beginning in the Windows 8 SDK, you can
determine that an asynchronous operation is complete using the notification method.
In the polling method, applications need to call the asynchronous function each time it wants the status of the
operation. The notification method is similar to callback and wait in ADO.NET. ODBC, however, uses Win32
events as the notification object.
The ODBC Cursor Library and ODBC asynchronous notification cannot be used at the same time. Setting both
attributes will return an error with SQLSTATE S1119 (Cursor Library and Asynchronous Notification cannot be
enabled at the same time).
See Notification of Asynchronous Function Completion for information for driver developers.
NOTE
The notification method is not supported with cursor library. An application will receive error message if it attempts to
enable cursor library via SQLSetConnectAttr, when the notification method is enabled.
Overview
When an ODBC function is called in asynchronous mode, the control is returned to the calling application
immediately with the return code SQL_STILL_EXECUTING. The application must repeatedly poll the function until
it returns something other than SQL_STILL_EXECUTING. The polling loop increases CPU utilization, causing poor
performance in many asynchronous scenarios.
Whenever the notification model is used, the polling model is disabled. Applications should not call the original
function again. Call SQLCompleteAsync Function to complete the asynchronous operation. If an application calls
the original function again before the asynchronous operation is complete, the call will return SQL_ERROR with
SQLSTATE IM017 (Polling is disabled in Asynchronous Notification Mode).
When using the notification model, the application can call SQLCancel or SQLCancelHandle to cancel a
statement or connection operation. If the cancel request is successful, ODBC will return SQL_SUCCESS. This
message does not indicate that the function was actually canceled; it indicates that the cancel request was
processed. Whether the function is actually canceled is driver-dependent and data source-dependent. When an
operation is canceled, the Driver Manager will still signal the event. The Driver Manager returns SQL_ERROR in
the return code buffer and the state is SQLSTATE HY008 (Operation canceled) to indicate the cancelation is
successful. If the function completed its normal processing, the Driver Manager returns SQL_SUCCESS or
SQL_SUCCESS_WITH_INFO.
Downlevel Behavior
The ODBC Driver Manager version supporting this notification on complete is ODBC 3.81.
A P P L IC AT IO N O DB C
VERSIO N DRIVER M A N A GER VERSIO N DRIVER VERSIO N B EH AVIO R
New application of any ODBC 3.81 ODBC 3.80 Driver Application can use this
ODBC version feature if the driver
supports this feature,
otherwise the Driver
Manager will error out.
New application of any ODBC 3.81 Pre-ODBC 3.80 Driver The Driver Manager will
ODBC version error out if the driver does
not support this feature.
New application of any Pre-ODBC 3.81 Any When the application uses
ODBC version this feature, an old Driver
Manager will regard the
new attributes as driver-
specific attributes, and the
driver should error out. A
new Driver Manager will
not pass these attributes to
the driver.
An application should check the Driver Manager version before using this feature. Otherwise, if a poorly written
driver does not error out and the Driver Manager version is pre ODBC 3.81, behavior is undefined.
Use Cases
This section shows use cases for asynchronous execution and the polling mechanism.
Integrate Data from Multiple ODBC Sources
A data integration application asynchronously fetches data from multiple data sources. Some of the data are
from remote data sources and some data are from local files. The application cannot continue until the
asynchronous operations are completed.
Instead of repeatedly polling an operation to determine if it is complete, the application can create an event
object and associate it with an ODBC connection handle or an ODBC statement handle. The application then calls
operating system synchronization APIs to wait on one event object or many event objects (both ODBC events
and other Windows events). ODBC will signal the event object when the corresponding ODBC asynchronous
operation is completed.
On Windows, Win32 event objects will be used and that will provide the user a unified programming model.
Driver Managers on other platforms can use the event object implementation specific to those platforms.
The following code sample demonstrates the use of connection and statement asynchronous notification:
// This function opens NUMBER_OPERATIONS connections and executes one query on statement of each connection.
// Asynchronous Notification is used
#define NUMBER_OPERATIONS 5
int AsyncNotificationSample(void)
{
RETCODE rc;
rc = SQLSetEnvAttr(hEnv,
SQL_ATTR_ODBC_VERSION,
(SQLPOINTER) SQL_OV_ODBC3_80,
SQL_IS_INTEGER);
if ( !SQL_SUCCEEDED(rc) ) goto Cleanup;
goto Cleanup;
}
// Now, call SQLCompleteAsync to complete the operation and get return code
// Now, call SQLCompleteAsync to complete the operation and get return code
for (int i=0; i<NUMBER_OPERATIONS; i++)
{
SQLCompleteAsync(SQL_HANDLE_STMT, arhStmt[i], &arrcSTMT[i]);
}
Cleanup:
if (hEnv)
{
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
hEnv = NULL;
}
return 0;
}
SQLUINTEGER InfoValue;
SQLLEN cbInfoLength;
SQLRETURN retcode;
retcode = SQLGetInfo (hDbc,
SQL_ASYNC_NOTIFICATION,
&InfoValue,
sizeof(InfoValue),
NULL);
if (SQL_SUCCEEDED(retcode))
{
if (SQL_ASYNC_NOTIFICATION_CAPABLE == InfoValue)
{
// The driver supports asynchronous notification
}
else if (SQL_ASYNC_NOTIFICATION_NOT_CAPABLE == InfoValue)
{
// The driver does not support asynchronous notification
}
}
An application can temporally disable asynchronous operation mode. ODBC ignores values of
SQL_ATTR_ASYNC_DBC_EVENT if the connection level asynchronous operation is disabled. ODBC ignores values
of SQL_ATTR_ASYNC_STMT_EVENT if the statement level asynchronous operation is disabled.
Synchronous call of SQLSetStmtAttr and SQLSetConnectAttr
SQLSetConnectAttr supports asynchronous operations but the invocation of SQLSetConnectAttr to
set SQL_ATTR_ASYNC_DBC_EVENT is always synchronous.
SQLSetStmtAttr does not support asynchronous execution.
Error-out scenario
When SQLSetConnectAttr is called before making a connection, the Driver Manager cannot determine which
driver to use. Therefore, the Driver Manager returns success for SQLSetConnectAttr but the attribute may not
be ready to set in the driver. The Driver Manager will set these attributes when the application calls a connection
function. The Driver Manager may error-out because driver does not support asynchronous operations.
Inheritance of connection attributes
Usually, the statements of a connection will inherit the connection attributes. However, the attribute
SQL_ATTR_ASYNC_DBC_EVENT is not inheritable and only affects the connection operations.
To associate an event handle with an ODBC connection handle, an ODBC application calls ODBC API
SQLSetConnectAttr and specifies SQL_ATTR_ASYNC_DBC_EVENT as the attribute and the event handle as the
attribute value. The new ODBC attribute SQL_ATTR_ASYNC_DBC_EVENT is of type SQL_IS_POINTER.
HANDLE hEvent;
hEvent = CreateEvent(
NULL, // default security attributes
FALSE, // auto-reset event
FALSE, // initial state is non-signaled
NULL // no name
);
Usually, applications create auto-reset event objects. ODBC will not reset the event object. Applications must
make sure that the object is not in signaled state before calling any asynchronous ODBC function.
SQLRETURN retcode;
retcode = SQLSetConnectAttr ( hDBC,
SQL_ATTR_ASYNC_DBC_EVENT, // Attribute name
(SQLPOINTER) hEvent, // Win32 Event handle
SQL_IS_POINTER); // Length Indicator
SQL_ATTR_ASYNC_DBC_EVENT is a Driver Manager-only attribute that will not be set in the driver.
The default value of SQL_ATTR_ASYNC_DBC_EVENT is NULL. If the driver does not support asynchronous
notification, getting or setting SQL_ATTR_ASYNC_DBC_EVENT will return SQL_ERROR with SQLSTATE HY092
(Invalid attribute/option identifier).
If the last SQL_ATTR_ASYNC_DBC_EVENT value set on an ODBC connection handle is not NULL and the
application enabled asynchronous mode by setting attribute SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE with
SQL_ASYNC_DBC_ENABLE_ON, calling any ODBC connection function that supports asynchronous mode will
get a completion notification. If the last SQL_ATTR_ASYNC_DBC_EVENT value set on an ODBC connection handle
is NULL, ODBC will not send the application any notification, regardless whether asynchronous mode is enabled.
An application can set SQL_ATTR_ASYNC_DBC_EVENT before or after setting the attribute
SQL_ATTR_ASYNC_DBC_FUNCTION_ENABLE.
Applications can set the SQL_ATTR_ASYNC_DBC_EVENT attribute on an ODBC connection handle before calling
a connection function (SQLConnect , SQLBrowseConnect , or SQLDriverConnect ). Because the ODBC Driver
Manager does not know which ODBC driver the application will use, it will return SQL_SUCCESS. When the
application calls a connection function, the ODBC Driver Manager will check whether the driver supports
asynchronous notification. If the driver does not support asynchronous notification, the ODBC Driver Manager
will return SQL_ERROR with SQLSTATE S1_118 (Driver does not support asynchronous notification). If the driver
supports asynchronous notification, the ODBC Driver Manager will call the driver and set the corresponding
attributes SQL_ATTR_ASYNC_DBC_NOTIFICATION_CALLBACK and
SQL_ATTR_ASYNC_DBC_NOTIFICATION_CONTEXT.
Similarly, an application calls SQLSetStmtAttr on an ODBC statement handle and specifies the
SQL_ATTR_ASYNC_STMT_EVENT attribute to enable or disable statement level asynchronous notification.
Because a statement function is always called after the connection is established, SQLSetStmtAttr will return
SQL_ERROR with SQLSTATE S1_118 (Driver does not support asynchronous notification) immediately if the
corresponding driver does not support asynchronous operations or the driver supports asynchronous
operation but does not support asynchronous notification.
SQLRETURN retcode;
retcode = SQLSetStmtAttr ( hSTMT,
SQL_ATTR_ASYNC_STMT_EVENT, // Attribute name
(SQLPOINTER) hEvent, // Win32 Event handle
SQL_IS_POINTER); // length Indicator
SQL_ATTR_ASYNC_STMT_EVENT, which can be set to NULL, is a Driver Manager-only attribute that will not be
set in the driver.
The default value of SQL_ATTR_ASYNC_STMT_EVENT is NULL. If the driver does not support asynchronous
notification, getting or setting the SQL_ATTR_ASYNC_ STMT_EVENT attribute will return SQL_ERROR with
SQLSTATE HY092 (Invalid attribute/option identifier).
An application should not associate the same event handle with more than one ODBC handle. Otherwise, one
notification will be lost if two asynchronous ODBC function invocations complete on two handles that share the
same event handle. To avoid a statement handle inheriting the same event handle from the connection handle,
ODBC returns SQL_ERROR with SQLSTATE IM016 (Cannot set statement attribute into connection handle) if an
application sets SQL_ATTR_ASYNC_STMT_EVENT on a connection handle.
Calling Asynchronous ODBC Functions
After enabling asynchronous notification and starting an asynchronous operation, the application can call any
ODBC function. If the function belongs to the set of functions that support asynchronous operation, the
application will get a completion notification when the operation completes, regardless of whether the function
failed or succeeded. The only exception is that the application calls an ODBC function with an invalid connection
or statement handle. In this case, ODBC will not get the event handle and set it to the signaled state.
The application must ensure that the associated event object is in a non-signaled state before starting an
asynchronous operation on the corresponding ODBC handle. ODBC will not reset the event object.
Getting Notification from ODBC
An application thread can call WaitForSingleObject to wait on one event handle or call
WaitForMultipleObjects to wait on an array of event handles and be suspended until one or all of the event
objects become signaled or the time-out interval elapses.
If (dwStatus == WAIT_TIMEOUT)
{
// time-out interval elapsed before all the events are signaled.
}
Else
{
// Call the corresponding Asynchronous ODBC API to complete all processing and retrieve the return code.
}
Freeing a Statement Handle ODBC
4/27/2022 • 2 minutes to read • Edit Online
As mentioned earlier, it is more efficient to reuse statements than to drop them and allocate new ones. Before
executing a new SQL statement on a statement, applications should be sure that the current statement settings
are appropriate. These include statement attributes, parameter bindings, and result set bindings. Generally,
parameters and result sets for the old SQL statement need to be unbound (by calling SQLFreeStmt with the
SQL_RESET_PARAMS and SQL_UNBIND options) and rebound for the new SQL statement.
When the application has finished using the statement, it calls SQLFreeHandle to free the statement. After
freeing the statement, it is an application programming error to use the statement's handle in a call to an ODBC
function; doing so has undefined but probably fatal consequences.
When SQLFreeHandle is called, the driver releases the structure used to store information about the
statement.
SQLDisconnect automatically frees all statements on a connection.
Retrieving Results (Basic)
4/27/2022 • 2 minutes to read • Edit Online
A result set is a set of rows on the data source that matches certain criteria. It is a conceptual table that results
from a query and that is available to an application in tabular form. SELECT statements, catalog functions, and
some procedures create result sets. In the following example, the first SQL statement creates a result set
containing all the rows and all the columns in the Orders table, and the second SQL statement creates a result
set containing OrderID, SalesPerson, and Status columns for the rows in the Orders table in which the Status is
OPEN:
A result set can be empty, which is different from no result set at all. For example, the following SQL statement
creates an empty result set:
An empty result set is no different from any other result set except that it has no rows. For example, the
application can retrieve metadata for the result set, can attempt to fetch rows, and must close the cursor over
the result set.
The process of retrieving rows from the data source and returning them to the application is called fetching. This
section explains the basic parts of that process. For information about more advanced topics, such as block and
scrollable cursors, see Block Cursors and Scrollable Cursors. For information about updating, deleting, and
inserting rows, see Updating Data Overview.
This section contains the following topics.
Was a Result Set Created?
Result Set Metadata
Binding Columns
Fetching Data
Closing the Cursor
Was a Result Set Created?
4/27/2022 • 2 minutes to read • Edit Online
In most situations, application programmers know whether the statements their application executes will create
a result set. This is the case if the application uses hard-coded SQL statements written by the programmer. It is
usually the case when the application constructs SQL statements at run time: The programmer can easily include
code that flags whether a SELECT statement or an INSERT statement is being constructed. In a few situations,
the programmer cannot possibly know whether a statement will create a result set. This is true if the application
provides a way for the user to enter and execute an SQL statement. It is also true when the application
constructs a statement at run time to execute a procedure.
In such cases, the application calls SQLNumResultCols to determine the number of columns in the result set. If
this is 0, the statement did not create a result set; if it is any other number, the statement did create a result set.
The application can call SQLNumResultCols at any time after the statement is prepared or executed. However,
because some data sources cannot easily describe the result sets that will be created by prepared statements,
performance will suffer if SQLNumResultCols is called after a statement is prepared but before it is executed.
Some data sources also support determining the number of rows that an SQL statement returns in a result set.
To do so, the application calls SQLRowCount . Exactly what the row count represents is indicated by the setting
of the SQL_DYNAMIC_CURSOR_ATTRIBUTES2, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2,
SQL_KEYSET_CURSOR_ATTRIBUTES2, or SQL_STATIC_CURSOR_ATTRIBUTES2 option (depending on the type of
the cursor) returned by a call to SQLGetInfo . This bitmask indicates for each cursor type whether the row count
returned is exact, approximate, or is not available at all. Whether row counts for static or keyset-driven cursors
are affected by changes made through SQLBulkOperations or SQLSetPos , or by positioned update or delete
statements, depends on other bits returned by the same option arguments listed previously. For more
information, see the SQLGetInfo function description.
Result Set Metadata
4/27/2022 • 2 minutes to read • Edit Online
Metadata is data that describes other data. For example, result set metadata describes the result set, such as the
number of columns in the result set, the data types of those columns, their names, precision, nullability, and so
on.
Interoperable applications should always check the metadata of result set columns. The metadata for a column
in a result set might differ from the metadata for the column as returned by a catalog function. For example,
suppose that an updatable column is included in a result set created by joining two tables. While
SQLColumnPrivileges might indicate that a user can update the column, the result set metadata might not if
the column is on the "many" side of the join; many data sources can update columns on the "one" side of a join
but not on the "many" side. Even data types cannot be assumed to be the same, because the data source might
promote the data type while creating the result set.
This section contains the following topics.
How is Metadata Used?
SQLDescribeCol and SQLColAttribute
How is Metadata Used?
4/27/2022 • 2 minutes to read • Edit Online
Applications require metadata for most result set operations. For example, the application uses the data type of
a column to determine what kind of variable to bind to that column. It uses the byte length of a character
column to determine how much space it needs to display data from that column. How an application determines
the metadata for a column depends on the type of the application.
Vertical applications work with predefined tables and perform predefined operations on those tables. Because
the result set metadata for such applications is defined before the application is even written and is controlled
by the application developer, it can be hard-coded into the application. For example, if an order ID column is
defined as a 4-byte integer in the data source, the application can always bind a 4-byte integer to that column.
When metadata is hard-coded in the application, a change to the tables used by the application generally
implies a change to the application code. This is rarely a problem, because such changes are usually made as
part of a new release of the application.
Like vertical applications, custom applications generally work with predefined tables and perform predefined
operations on those tables. For example, an application might be written to transfer data among three different
data sources; the data to be transferred is usually known when the application is written. Thus, custom
applications also tend to have hard-coded metadata.
Generic applications, especially those that support ad hoc queries, almost never know the metadata of the result
sets they create. Therefore, they must discover the metadata at run time using the functions
SQLNumResultCols , SQLDescribeCol , and SQLColAttribute , which are described in the next section,
SQLDescribeCol and SQLColAttribute.
All applications, regardless of their type, can hard-code metadata for the result sets returned by the catalog
functions. These result sets are defined in the reference section of this manual.
SQLDescribeCol and SQLColAttribute
4/27/2022 • 2 minutes to read • Edit Online
SQLDescribeCol and SQLColAttribute are used to retrieve result set metadata. The difference between these
two functions is that SQLDescribeCol always returns the same five pieces of information (a column's name,
data type, precision, scale, and nullability), while SQLColAttribute returns a single piece of information
requested by the application. However, SQLColAttribute can return a much richer selection of metadata,
including a column's case-sensitivity, display size, updatability, and searchability.
Many applications, especially ones that only display data, require only the metadata returned by
SQLDescribeCol . For these applications, it is faster to use SQLDescribeCol than SQLColAttribute because
the information is returned in a single call. Other applications, especially ones that update data, require the
additional metadata returned by SQLColAttribute and therefore use both functions. In addition,
SQLColAttribute supports driver-specific metadata; for more information, see Driver-Specific Data Types,
Descriptor Types, Information Types, Diagnostic Types, and Attributes.
An application can retrieve result set metadata at any time after a statement has been prepared or executed and
before the cursor over the result set is closed. Very few applications require result set metadata after the
statement is prepared and before it is executed. If possible, applications should wait to retrieve metadata until
after the statement is executed, because some data sources cannot return metadata for prepared statements and
emulating this capability in the driver is often a slow process. For example, the driver might generate a zero-row
result set by replacing the WHERE clause of a SELECT statement with the clause WHERE 1 = 2 and executing
the resulting statement.
Metadata is often expensive to retrieve from the data source. Because of this, drivers should cache any metadata
they retrieve from the server and hold it for as long as the cursor over the result set is open. Also, applications
should request only the metadata they absolutely need.
Binding Columns
4/27/2022 • 2 minutes to read • Edit Online
Data fetched from the data source is returned to the application in variables that the application has allocated
for this purpose. Before this can be done, the application must associate, or bind, these variables to the columns
of the result set; conceptually, this process is the same as binding application variables to statement parameters.
When the application binds a variable to a result set column, it describes that variable - address, data type, and
so on - to the driver. The driver stores this information in the structure it maintains for that statement and uses
the information to return the value from the column when the row is fetched.
This section contains the following topics.
Binding Result Set Columns
Using SQLBindCol
Binding Result Set Columns
4/27/2022 • 2 minutes to read • Edit Online
Applications can bind as many or as few columns of the result set as they choose, including binding no columns
at all. When a row of data is fetched, the driver returns the data for the bound columns to the application.
Whether the application binds all of the columns in the result set depends on the application. For example,
applications that generate reports usually have a fixed format; such applications create a result set containing all
of the columns used in the report and then bind and retrieve the data for all of these columns. Applications that
display screens full of data sometimes allow the user to decide which columns to display; such applications
create a result set containing all columns the user might want, but bind and retrieve the data only for those
columns chosen by the user.
Data can be retrieved from unbound columns by calling SQLGetData . This is commonly called to retrieve long
data, which often exceeds the length of a single buffer and must be retrieved in parts.
Columns can be bound at any time, even after rows have been fetched. However, the new bindings do not take
effect until the next time a row is fetched; they are not applied to data from rows already fetched.
A variable remains bound to a column until a different variable is bound to the column, until the column is
unbound by calling SQLBindCol with a null pointer as the variable's address, until all columns are unbound by
calling SQLFreeStmt with the SQL_UNBIND option, or until the statement is released. For this reason, the
application must be sure that all bound variables remain valid as long as they are bound. For more information,
see Allocating and Freeing Buffers.
Because column bindings are just information associated with the statement structure, they can be set in any
order. They are also independent of the result set. For example, suppose an application binds the columns of the
result set generated by the following SQL statement:
on the same statement handle, the column bindings for the first result set are still in effect because those are the
bindings stored in the statement structure. In most cases, this is a poor programming practice and should be
avoided. Instead, the application should call SQLFreeStmt with the SQL_UNBIND option to unbind all the old
columns and then bind new ones.
Using SQLBindCol
4/27/2022 • 6 minutes to read • Edit Online
The application binds columns by calling SQLBindCol . This function binds one column at a time. With it, the
application specifies the following:
The column number. Column 0 is the bookmark column; this column is not included in some result sets.
All other columns are numbered starting with the number 1. It is an error to bind a higher-numbered
column than there are columns in the result set; this error cannot be detected until the result set has been
created, so it is returned by SQLFetch , not SQLBindCol .
The C data type, address, and byte length of the variable bound to the column. It is an error to specify a C
data type to which the SQL data type of the column cannot be converted; this error might not be detected
until the result set has been created, so it is returned by SQLFetch , not SQLBindCol . For a list of
supported conversions, see Converting Data from SQL to C Data Types in Appendix D: Data Types. For
information about the byte length, see Data Buffer Length.
The address of a length/indicator buffer. The length/indicator buffer is optional. It is used to return the
byte length of binary or character data or return SQL_NULL_DATA if the data is NULL. For more
information, see Using Length/Indicator Values.
When SQLBindCol is called, the driver associates this information with the statement. When each row of data is
fetched, it uses the information to place the data for each column in the bound application variables.
For example, the following code binds variables to the SalesPerson and CustID columns. Data for the columns
will be returned in SalesPerson and CustID. Because SalesPerson is a character buffer, the application specifies its
byte length (11) so that the driver can determine whether to truncate the data. The byte length of the returned
title, or whether it is NULL, will be returned in SalesPersonLenOrInd.
Because CustID is an integer variable and has fixed length, there is no need to specify its byte length; the driver
assumes it is sizeof( SQLUINTEGER ) . The byte length of the returned customer ID data, or whether it is NULL,
will be returned in CustIDInd. Note that the application is interested only in whether the salary is NULL, because
the byte length is always sizeof( SQLUINTEGER ) .
SQLCHAR SalesPerson[11];
SQLUINTEGER CustID;
SQLINTEGER SalesPersonLenOrInd, CustIDInd;
SQLRETURN rc;
SQLHSTMT hstmt;
// Fetch and print the data. Print "NULL" if the data is NULL. Code to
// check if rc equals SQL_ERROR or SQL_SUCCESS_WITH_INFO not shown.
while ((rc = SQLFetch(hstmt)) != SQL_NO_DATA) {
if (SalesPersonLenOrInd == SQL_NULL_DATA)
printf("NULL ");
else
printf("%10s ", SalesPerson);
if (CustIDInd == SQL_NULL_DATA)
printf("NULL\n");
else
printf("%d\n", CustID);
}
The following code executes a SELECT statement entered by the user and prints each row of data in the result
set. Because the application cannot predict the shape of the result set created by the SELECT statement, it
cannot bind hard-coded variables to the result set as in the preceding example. Instead, the application allocates
a buffer that holds the data and a length/indicator buffer for each column in that row. For each column, it
calculates the offset to the start of the memory for the column and adjusts this offset so that the data and
length/indicator buffers for the column start on alignment boundaries. It then binds the memory starting at the
offset to the column. From the driver's point of view, the address of this memory is indistinguishable from the
address of a variable bound in the preceding example. For more information about alignment, see Alignment.
// This application allocates a buffer at run time. For each column, this
// buffer contains memory for the column's data and length/indicator.
// For example:
// column 1 column 2 column 3 column 4
// <------------><---------------><-----><------------>
// db1 li1 db2 li2 db3 li3 db4 li4
// | | | | | | | |
// _____V_____V________V_______V___V___V______V_____V_
// |__________|__|_____________|__|___|__|__________|__|
//
// dbn = data buffer for column n
// lin = length/indicator buffer for column n
SQLCHAR SelectStmt[100];
SQLSMALLINT NumCols, *CTypeArray, i;
SQLINTEGER * ColLenArray, *OffsetArray, SQLType, *DataPtr;
SQLRETURN rc;
SQLHSTMT hstmt;
OffsetArray[0] = 0;
for (i = 0; i < NumCols; i++) {
// Determine the column's SQL type. GetDefaultCType contains a switch
// statement that returns the default C type for each SQL type.
SQLColAttribute(hstmt, ((SQLUSMALLINT) i) + 1, SQL_DESC_TYPE, NULL, 0, NULL, (SQLPOINTER) &SQLType);
CTypeArray[i] = GetDefaultCType(SQLType);
// Allocate the data buffer. The size of the buffer is equal to the
// offset to the data buffer for the final column, plus the byte length
// of the data buffer and length/indicator buffer for the last column.
void *DataPtr = malloc(OffsetArray[NumCols - 1] +
ColLenArray[NumCols - 1] + ALIGNBUF(sizeof(SQLINTEGER)));
// For each column, bind the address in the buffer at the start of the
// memory allocated for that column's data and the address at the start
// of the memory allocated for that column's length/indicator buffer.
for (i = 0; i < NumCols; i++)
SQLBindCol(hstmt,
((SQLUSMALLINT) i) + 1,
CTypeArray[i],
(SQLPOINTER)((SQLCHAR *)DataPtr + OffsetArray[i]),
ColLenArray[i],
(SQLINTEGER *)((SQLCHAR *)DataPtr + OffsetArray[i] + ColLenArray[i]));
// Retrieve and print each row. PrintData accepts a pointer to the data,
// its C type, and its byte length/indicator. It contains a switch
// statement that casts and prints the data according to its type. Code
// to check if rc equals SQL_ERROR or SQL_SUCCESS_WITH_INFO not shown.
while ((rc = SQLFetch(hstmt)) != SQL_NO_DATA) {
for (i = 0; i < NumCols; i++) {
PrintData((SQLCHAR *)DataPtr[OffsetArray[i]], CTypeArray[i],
(SQLINTEGER *)((SQLCHAR *)DataPtr[OffsetArray[i] + ColLenArray[i]]));
}
}
// Close the cursor.
SQLCloseCursor(hstmt);
Fetching Data
4/27/2022 • 2 minutes to read • Edit Online
The process of retrieving rows from the result set and returning them to the application is called fetching. This
section describes how to fetch data.
This section contains the following topics.
Cursors
Fetching a Row of Data
Getting Long Data
ODBC Cursors
4/27/2022 • 2 minutes to read • Edit Online
An application fetches data with a cursor. A cursor is different from a result set: A result set is the set of rows
that matches particular search criteria, whereas a cursor is the software that returns those rows to the
application. The name cursor, as it applies to databases, probably originated from the blinking cursor on a
computer terminal. Just as that cursor indicates the current position on the screen and where the typed words
will appear next, a cursor on a result set indicates the current position in the result set and what row will be
returned next.
The cursor model in ODBC is based on the cursor model in embedded SQL. One notable difference between
these models is the way cursors are opened. In embedded SQL, a cursor must be explicitly declared and opened
before it can be used. In ODBC, a cursor is implicitly opened when a statement that creates a result set is
executed. When the cursor is opened, it is positioned before the first row of the result set. In both embedded
SQL and ODBC, a cursor must be closed after the application has finished using it.
Different cursors have different characteristics. The most common type of cursor, which is called a forward-only
cursor, can only move forward through the result set. To return to a previous row, the application must close and
reopen the cursor and then read rows from the beginning of the result set until it reaches the required row.
Forward-only cursors provide a fast mechanism for making a single pass through a result set.
Forward-only cursors are less useful for screen-based applications, in which the user scrolls backward and
forward through the data. Such applications can use a forward-only cursor by reading the result set once,
caching the data locally, and performing scrolling themselves. However, this works well only with small amounts
of data. A better solution is to use a scrollable cursor, which provides random access to the result set. Such
applications can also increase performance by fetching more than one row of data at a time, using what is called
a block cursor. For more information about block cursors, see Using Block Cursors.
The forward-only cursor is the default cursor type in ODBC and is discussed in the following sections. For more
information about block cursors and scrollable cursors, see Block Cursors and Scrollable Cursors.
IMPORTANT
Committing or rolling back a transaction, either by explicitly calling SQLEndTran or by operating in auto-commit mode,
causes some data sources to close all the cursors on all statements on a connection. For more information, see the
SQL_CURSOR_COMMIT_BEHAVIOR and SQL_CURSOR_ROLLBACK_BEHAVIOR attributes in the SQLGetInfo function
description.
Fetching a Row of Data
4/27/2022 • 3 minutes to read • Edit Online
To fetch a row of data, an application calls SQLFetch . SQLFetch can be called with any kind of cursor, but it
only moves the rowset cursor in a forward-only direction. SQLFetch advances the cursor to the next row and
returns the data for any columns that were bound with calls to SQLBindCol . When the cursor reaches the end
of the result set, SQLFetch returns SQL_NO_DATA. For examples of calling SQLFetch , see Using SQLBindCol.
Exactly how SQLFetch is implemented is driver-specific, but the general pattern is for the driver to retrieve the
data for any bound columns from the data source, convert it according to the types of the bound variables, and
place the converted data in those variables. If the driver cannot convert any data, SQLFetch returns an error.
The application can continue fetching rows, but the data for the current row is lost. What happens to the data for
unbound columns depends on the driver, but most drivers either retrieve and discard it or never retrieve it at all.
The driver also sets the values of any length/indicator buffers that have been bound. If the data value for a
column is NULL, the driver sets the corresponding length/indicator buffer to SQL_NULL_DATA. If the data value
is not NULL, the driver sets the length/indicator buffer to the byte length of the data after conversion. If this
length cannot be determined, as is sometimes the case with long data that is retrieved by more than one
function call, the driver sets the length/indicator buffer to SQL_NO_TOTAL. For fixed-length data types, such as
integers and date structures, the byte length is the size of the data type.
For variable-length data, such as character and binary data, the driver checks the byte length of the converted
data against the byte length of the buffer bound to the column; the buffer's length is specified in the
BufferLength argument in SQLBindCol . If the byte length of the converted data is greater than the byte length
of the buffer, the driver truncates the data to fit in the buffer, returns the untruncated length in the
length/indicator buffer, returns SQL_SUCCESS_WITH_INFO, and places SQLSTATE 01004 (Data truncated) in the
diagnostics. The only exception to this is if a variable-length bookmark is truncated when returned by
SQLFetch , which returns SQLSTATE 22001 (String data, right truncated).
Fixed-length data is never truncated, because the driver assumes that the size of the bound buffer is the size of
the data type. Data truncation tends to be rare, because the application usually binds a buffer large enough to
hold the entire data value; it determines the necessary size from the metadata. However, the application might
explicitly bind a buffer it knows to be too small. For example, it might retrieve and display the first 20 characters
of a part description or the first 100 characters of a long text column.
Character data must be null-terminated by the driver before it is returned to the application, even if it has been
truncated. The null-termination character is not included in the returned byte length but does require space in
the bound buffer. For example, suppose an application uses strings composed of character data in the ASCII
character set, a driver has 50 characters of data to return, and the application's buffer is 25 bytes long. In the
application's buffer, the driver returns the first 24 characters followed by a null-termination character. In the
length/indicator buffer, it returns a byte length of 50.
The application can restrict the number of rows in the result set by setting the SQL_ATTR_MAX_ROWS statement
attribute before executing the statement that creates the result set. For example, the preview mode in an
application used to format reports needs only enough data to display the first page of the report. By restricting
the size of the result set, such a feature would run faster. This statement attribute is intended to reduce network
traffic and might not be supported by all drivers.
Getting Long Data
4/27/2022 • 4 minutes to read • Edit Online
DBMSs define long data as any character or binary data over a certain size, such as 255 characters. This data
may be small enough to be stored in a single buffer, such as a part description of several thousand characters.
However, it might be too long to store in memory, such as long text documents or bitmaps. Because such data
cannot be stored in a single buffer, it is retrieved from the driver in parts with SQLGetData after the other data
in the row has been fetched.
NOTE
An application can actually retrieve any type of data with SQLGetData , not just long data, although only character and
binary data can be retrieved in parts. However, if the data is small enough to fit in a single buffer, there is generally no
reason to use SQLGetData . It is much easier to bind a buffer to the column and let the driver return the data in the
buffer.
To retrieve long data from a column, an application first calls SQLFetchScroll or SQLFetch to move to a row
and fetch the data for bound columns. The application then calls SQLGetData . SQLGetData has the same
arguments as SQLBindCol : a statement handle; a column number; the C data type, address, and byte length of
an application variable; and the address of a length/indicator buffer. Both functions have the same arguments
because they perform essentially the same task: They both describe an application variable to the driver and
specify that the data for a particular column should be returned in that variable. The major differences are that
SQLGetData is called after a row is fetched (and is sometimes referred to as late binding for this reason) and
that the binding specified by SQLGetData lasts only for the duration of the call.
Regarding a single column, SQLGetData behaves like SQLFetch : It retrieves the data for the column, converts
it to the type of the application variable, and returns it in that variable. It also returns the byte length of the data
in the length/indicator buffer. For more information about how SQLFetch returns data, see Fetching a Row of
Data.
SQLGetData differs from SQLFetch in one important respect. If it is called more than once in succession for
the same column, each call returns a successive part of the data. Each call except the last call returns
SQL_SUCCESS_WITH_INFO and SQLSTATE 01004 (String data, right truncated); the last call returns
SQL_SUCCESS. This is how SQLGetData is used to retrieve long data in parts. When there is no more data to
return, SQLGetData returns SQL_NO_DATA. The application is responsible for putting the long data together,
which might mean concatenating the parts of the data. Each part is null-terminated; the application must
remove the null-termination character if concatenating the parts. Retrieving data in parts can be done for
variable-length bookmarks as well as for other long data. The value returned in the length/indicator buffer
decreases in each call by the number of bytes returned in the previous call, although it is common for the driver
to be unable to discover the amount of available data and return a byte length of SQL_NO_TOTAL. For example:
// Declare a binary buffer to retrieve 5000 bytes of data at a time.
SQLCHAR BinaryPtr[5000];
SQLUINTEGER PartID;
SQLINTEGER PartIDInd, BinaryLenOrInd, NumBytes;
SQLRETURN rc;
SQLHSTMT hstmt;
// Retrieve the picture data in parts. Send each part and the number
// of bytes in each part to a function that displays it. The number
// of bytes is always 5000 if there were more than 5000 bytes
// available to return (cbBinaryBuffer > 5000). Code to check if
// rc equals SQL_ERROR or SQL_SUCCESS_WITH_INFO not shown.
while ((rc = SQLGetData(hstmt, 2, SQL_C_BINARY, BinaryPtr, sizeof(BinaryPtr),
&BinaryLenOrInd)) != SQL_NO_DATA) {
NumBytes = (BinaryLenOrInd > 5000) || (BinaryLenOrInd == SQL_NO_TOTAL) ?
5000 : BinaryLenOrInd;
DisplayNextPictPart(BinaryPtr, NumBytes);
}
}
There are several restrictions on using SQLGetData . Generally, columns accessed with SQLGetData :
Must be accessed in order of increasing column number (because of the way the columns of a result set
are read from the data source). For example, it is an error to call SQLGetData for column 5 and then call
it for column 4.
Cannot be bound.
Must have a higher column number than the last bound column. For example, if the last bound column is
column 3, it is an error to call SQLGetData for column 2. For this reason, applications should make sure
to place long data columns at the end of the select list.
Cannot be used if SQLFetch or SQLFetchScroll was called to retrieve more than one row. For more
information, see Using Block Cursors.
Some drivers do not enforce these restrictions. Interoperable applications should either assume they exist or
determine which restrictions are not enforced by calling SQLGetInfo with the SQL_GETDATA_EXTENSIONS
option.
If the application does not need all the data in a character or binary data column, it can reduce network traffic in
DBMS-based drivers by setting the SQL_ATTR_MAX_LENGTH statement attribute before executing the
statement. This restricts the number of bytes of data that will be returned for any character or binary column.
For example, suppose a column contains long text documents. An application that browses the table containing
this column might have to display only the first page of each document. Although this statement attribute can
be simulated in the driver, there is no reason to do this. In particular, if an application wants to truncate character
or binary data, it should bind a small buffer to the column with SQLBindCol and let the driver truncate the
data.
Closing the Cursor
4/27/2022 • 2 minutes to read • Edit Online
When an application has finished using a cursor, it calls SQLCloseCursor to close the cursor. For example:
SQLCloseCursor(hstmt);
Until the application closes the cursor, the statement on which the cursor is opened cannot be used for most
other operations, such as executing another SQL statement. For a complete list of functions that can be called
while a cursor is open, see Appendix B: ODBC State Transition Tables.
NOTE
To close a cursor, an application should call SQLCloseCursor , not SQLCancel.
Cursors remain open until they are explicitly closed, except when a transaction is committed or rolled back, in
which case some data sources close the cursor. In particular, reaching the end of the result set, when SQLFetch
returns SQL_NO_DATA, does not close a cursor. Even cursors on empty result sets (result sets created when a
statement executed successfully but which returned no rows) must be explicitly closed.
Retrieving Results (Advanced)
4/27/2022 • 2 minutes to read • Edit Online
An application can specify that an offset is added to bound data buffer addresses and the corresponding
length/indicator buffer addresses when SQLBulkOperations , SQLFetch , SQLFetchScroll , or SQLSetPos is
called. The results of these additions determine the addresses used in these operations.
Bind offsets allow an application to change bindings without calling SQLBindCol for previously bound
columns. A call to SQLBindCol to rebind data changes the buffer address and the length/indicator pointer.
Rebinding with an offset, on the other hand, simply adds an offset to the existing bound data buffer address and
length/indicator buffer address. When offsets are used, the bindings are a "template" of how the application
buffers are laid out and the application can move this "template" to different areas of memory by changing the
offset. A new offset can be specified at any time and is always added to the originally bound values.
To specify a bind offset, the application sets the SQL_ATTR_ROW_BIND_OFFSET_PTR statement attribute to the
address of an SQLINTEGER buffer. Before the application calls a function that uses the bindings, such as
SQLBulkOperations , SQLFetch , SQLFetchScroll , or SQLSetPos , it places an offset in bytes in this buffer, as
long as neither the data buffer address nor the length/indicator buffer address is 0, and as long as the bound
column is in the result set. The sum of the address and the offset must be a valid address. (This means that
either or both the offset and the address to which the offset is added can be invalid, as long as their sum is a
valid address.) The SQL_ATTR_ROW_BIND_OFFSET_PTR statement attribute is a pointer so that the offset value
can be applied to more than one set of binding data, all of which can be changed by changing one offset value.
An application must make sure that the pointer remains valid until the cursor is closed.
NOTE
Binding offsets are not supported by ODBC 2.x drivers.
Many applications spend a significant amount of time bringing data across the network. Part of this time is
spent actually bringing the data across the network, and part of it is spent on network overhead, such as the call
made by the driver to request a row of data. The latter time can be reduced if the application makes efficient use
of block, or fat, cursors, which can return more than one row at a time.
An application always has the option of using a block cursor. On data sources from which only one row at a time
can be fetched, block cursors must be simulated in the driver. This can be done by performing multiple single-
row fetches. While this is unlikely to provide any performance gains, it opens opportunities for applications.
Such applications will then experience performance increases as DBMSs implement block cursors natively and
the drivers associated with those DBMSs expose them.
The rows returned in a single fetch with a block cursor are called the rowset. It is important not to confuse the
rowset with the result set. The result set is maintained at the data source, while the rowset is maintained in
application buffers. While the result set is fixed, the rowset is not - it changes position and contents each time a
new set of rows is fetched. Just as a single-row cursor such as the traditional SQL forward-only cursor points to
a current row, a block cursor points to the rowset, which can be thought of as current rows.
To perform operations that operate on a single row when multiple rows have been fetched, the application must
first indicate which row is the current row. The current row is required by calls to SQLGetData and positioned
update and delete statements. When a block cursor first returns a rowset, the current row is the first row of the
rowset. To change the current row, the application calls SQLSetPos or SQLBulkOperations (to update by
bookmark). The following illustration shows the relationship of the result set, rowset, current row, rowset cursor,
and block cursor. For more information, see Using Block Cursors, later in this section, and Positioned Update and
Delete Statements and Updating Data with SQLSetPos.
Whether a cursor is a block cursor is independent of whether it is scrollable. For example, most of the work in a
report application is spent retrieving and printing rows. Because of this, it will work fastest with a forward-only,
block cursor. It uses a forward-only cursor to avoid the expense of a scrollable cursor, and a block cursor to
reduce the network traffic.
This section contains the following topics.
Binding Columns for Use with Block Cursors
Using Block Cursors
Row Status Array
Binding Columns for Use with Block Cursors
4/27/2022 • 2 minutes to read • Edit Online
Because block cursors return multiple rows, applications that use them must bind an array of variables to each
column instead of a single variable. These arrays are collectively known as the rowset buffers. Following are the
two styles of binding:
Bind an array to each column. This is called column-wise binding because each data structure (array)
contains data for a single column.
Define a structure to hold the data for an entire row and bind an array of these structures. This is called
row-wise binding because each data structure contains the data for a single row.
As when the application binds single variables to columns, it calls SQLBindCol to bind arrays to columns. The
only difference is that the addresses passed are array addresses, not single variable addresses. The application
sets the SQL_BIND_BY_COLUMN statement attribute to specify whether it is using column-wise or row-wise
binding. Whether to use column-wise or row-wise binding is largely a matter of application preference. Row-
wise binding might correspond more closely to the application's layout of data, in which case it would provide
better performance.
This section contains the following topics.
Column-Wise Binding
Row-Wise Binding
Column-Wise Binding
4/27/2022 • 2 minutes to read • Edit Online
When using column-wise binding, an application binds one or two, or in some cases three, arrays to each
column for which data is to be returned. The first array holds the data values, and the second array holds
length/indicator buffers. Indicators and length values can be stored in separate buffers by setting the
SQL_DESC_INDICATOR_PTR and SQL_DESC_OCTET_LENGTH_PTR descriptor fields to different values; if this is
done, a third array is bound. Each array contains as many elements as there are rows in the rowset.
The application declares that it is using column-wise binding with the SQL_ATTR_ROW_BIND_TYPE statement
attribute, which determines the bind type for rowset buffers as opposed to parameter set buffers. The driver
returns the data for each row in successive elements of each array. The following illustration shows how
column-wise binding works.
For example, the following code binds 10-element arrays to the OrderID, SalesPerson, and Status columns:
#define ROW_ARRAY_SIZE 10
// Fetch up to the rowset size number of rows at a time. Print the actual
// number of rows fetched; this number is returned in NumRowsFetched.
// Check the row status array to print only those rows successfully
// fetched. Code to check if rc equals SQL_SUCCESS_WITH_INFO or
// SQL_ERROR not shown.
while ((rc = SQLFetchScroll(hstmt,SQL_FETCH_NEXT,0)) != SQL_NO_DATA) {
for (i = 0; i < NumRowsFetched; i++) {
if ((RowStatusArray[i] == SQL_ROW_SUCCESS) ||
(RowStatusArray[i] == SQL_ROW_SUCCESS_WITH_INFO)) {
if (OrderIDIndArray[i] == SQL_NULL_DATA)
printf(" NULL ");
else
printf("%d\t", OrderIDArray[i]);
if (SalesPersonLenOrIndArray[i] == SQL_NULL_DATA)
printf(" NULL ");
else
printf("%s\t", SalesPersonArray[i]);
if (StatusLenOrIndArray[i] == SQL_NULL_DATA)
printf(" NULL\n");
else
printf("%s\n", StatusArray[i]);
}
}
}
When using row-wise binding, an application defines a structure containing one or two, or in some cases three,
elements for each column for which data is to be returned. The first element holds the data value, and the
second element holds the length/indicator buffer. Indicators and length values can be stored in separate buffers
by setting the SQL_DESC_INDICATOR_PTR and SQL_DESC_OCTET_LENGTH_PTR descriptor fields to different
values; if this is done, the structure contains a third element. The application then allocates an array of these
structures, which contains as many elements as there are rows in the rowset.
The application declares the size of the structure to the driver with the SQL_ATTR_ROW_BIND_TYPE statement
attribute and binds the address of each member in the first element of the array. Thus, the driver can calculate
the address of the data for a particular row and column as
where rows are numbered from 1 to the size of the rowset. (One is subtracted from the row number because
array indexing in C is zero-based.) The following illustration shows how row-wise binding works. Generally, only
columns that will be bound are included in the structure. The structure can contain fields that are unrelated to
result set columns. The columns can be placed in the structure in any order but are shown in sequential order
for clarity.
For example, the following code creates a structure with elements in which to return data for the OrderID,
SalesPerson, and Status columns, and length/indicators for the SalesPerson and Status columns. It allocates 10
of these structures and binds them to the OrderID, SalesPerson, and Status columns.
#define ROW_ARRAY_SIZE 10
SQLULEN NumRowsFetched;
SQLUSMALLINT RowStatusArray[ROW_ARRAY_SIZE], i;
SQLRETURN rc;
SQLHSTMT hstmt;
SQLHSTMT hstmt;
// Fetch up to the rowset size number of rows at a time. Print the actual
// number of rows fetched; this number is returned in NumRowsFetched.
// Check the row status array to print only those rows successfully
// fetched. Code to check if rc equals SQL_SUCCESS_WITH_INFO or
// SQL_ERRORnot shown.
while ((rc = SQLFetchScroll(hstmt,SQL_FETCH_NEXT,0)) != SQL_NO_DATA) {
for (i = 0; i < NumRowsFetched; i++) {
if (RowStatusArray[i] == SQL_ROW_SUCCESS|| RowStatusArray[i] ==
SQL_ROW_SUCCESS_WITH_INFO) {
if (OrderInfoArray[i].OrderIDInd == SQL_NULL_DATA)
printf(" NULL ");
else
printf("%d\t", OrderInfoArray[i].OrderID);
if (OrderInfoArray[i].SalesPersonLenOrInd == SQL_NULL_DATA)
printf(" NULL ");
else
printf("%s\t", OrderInfoArray[i].SalesPerson);
if (OrderInfoArray[i].StatusLenOrInd == SQL_NULL_DATA)
printf(" NULL\n");
else
printf("%s\n", OrderInfoArray[i].Status);
}
}
}
Support for block cursors is built into ODBC 3.x. SQLFetch can be used only for multirow fetches when called in
ODBC 3.x; if an ODBC 2.x application calls SQLFetch , it will open only a single-row, forward-only cursor. When
an ODBC 3.x application calls SQLFetch in an ODBC 2.x driver, it returns a single row unless the driver supports
SQLExtendedFetch . For more information, see Block Cursors, Scrollable Cursors, and Backward Compatibility
in Appendix G: Driver Guidelines for Backward Compatibility.
To use block cursors, the application sets the rowset size, binds the rowset buffers (as described in the previous
section), optionally sets the SQL_ATTR_ROWS_FETCHED_PTR and SQL_ATTR_ROW_STATUS_PTR statement
attributes, and calls SQLFetch or SQLFetchScroll to fetch a block of rows. The application can change the
rowset size and bind new rowset buffers (by calling SQLBindCol or specifying a bind offset) even after rows
have been fetched.
This section contains the following topics.
Rowset Size
Number of Rows Fetched and Status
SQLGetData and Block Cursors; block curso
Rowset Size
4/27/2022 • 2 minutes to read • Edit Online
Which rowset size to use depends on the application. Screen-based applications commonly follow one of two
strategies. The first is to set the rowset size to the number of rows displayed on the screen; if the user resizes the
screen, the application changes the rowset size accordingly. The second is to set the rowset size to a larger
number, such as 100, which reduces the number of calls to the data source. The application scrolls locally within
the rowset when possible and fetches new rows only when it scrolls outside the rowset.
Other applications, such as reports, tend to set the rowset size to the largest number of rows the application can
reasonably handle - with a larger rowset, the network overhead per row is sometimes reduced. Exactly how
large a rowset can be depends on the size of each row and the amount of memory available.
Rowset size is set by a call to SQLSetStmtAttr with an Attribute argument of SQL_ATTR_ROW_ARRAY_SIZE.
The application can change the rowset size, bind new rowset buffers (by calling SQLBindCol or specifying a
binding offset) even after rows have been fetched, or both. The implications of changing the rowset size depend
on the function:
SQLFetch and SQLFetchScroll use the rowset size at the time of the call to determine how many rows
to fetch. However, SQLFetchScroll with a FetchOrientation of SQL_FETCH_NEXT increments the cursor
based on the rowset of the previous fetch and then fetches a rowset based on the current rowset size.
SQLSetPos uses the rowset size that is in effect as of the preceding call to SQLFetch or
SQLFetchScroll , because SQLSetPos operates on a rowset that has already been set. SQLSetPos also
will pick up the new rowset size if SQLBulkOperations has been called after the rowset size was
changed.
SQLBulkOperations uses the rowset size in effect at the time of the call, because it performs operations
on a table independent of any fetched rowset.
Number of Rows Fetched and Status
4/27/2022 • 2 minutes to read • Edit Online
If the SQL_ATTR_ROWS_FETCHED_PTR statement attribute has been set, it specifies a buffer that returns the
number of rows fetched by the call to SQLFetch or SQLFetchScroll , and error rows. (This number is a count of
all rows that do not have the status SQL_ROW_NO_ROWS.) After a call to SQLBulkOperations or SQLSetPos ,
the buffer contains the number of rows that were affected by a bulk operation performed by the function. If the
SQL_ATTR_ROW_STATUS_PTR statement attribute has been set, SQLFetch or SQLFetchScroll returns the row
status array, which provides the status of each returned row. Both of the buffers pointed to by these fields are
allocated by the application and populated by the driver. An application must make sure that these pointers
remain valid until the cursor is closed.
Entries in the row status array state whether each row was fetched successfully, whether it was updated, added,
or deleted since it was last fetched, and whether an error occurred while fetching the row. If SQLFetch or
SQLFetchScroll encounters an error while retrieving one row of a multirow rowset, or if SQLBulkOperations
with an Operation argument of SQL_FETCH_BY_BOOKMARK encounters an error while performing a bulk fetch,
it sets the corresponding value in the row status array to SQL_ROW_ERROR, continues fetching rows, and
returns SQL_SUCCESS_WITH_INFO. For more information about error handling and the row status array, see the
SQLFetch and SQLFetchScroll function descriptions.
SQLGetData and Block Cursors
4/27/2022 • 2 minutes to read • Edit Online
SQLGetData operates on a single column of a single row and cannot fetch an array containing data from
multiple rows. This is because the primary use of SQLGetData is to fetch long data in parts, and there is little or
no reason to do this for more than one row at a time.
To use SQLGetData with a block cursor, an application first calls SQLSetPos to position the cursor on a single
row. It then calls SQLGetData for a column in that row. However, this behavior is optional. To determine if a
driver supports the use of SQLGetData with block cursors, an application calls SQLGetInfo with the
SQL_GETDATA_EXTENSIONS option.
Row Status Array
4/27/2022 • 2 minutes to read • Edit Online
In addition to data, SQLFetch and SQLFetchScroll can return an array that gives the status of each row in the
rowset. This array is specified through the SQL_ATTR_ROW_STATUS_PTR statement attribute. This array is
allocated by the application and must have as many elements as are specified by the
SQL_ATTR_ROW_ARRAY_SIZE statement attribute. The values in the array are set by SQLBulkOperations ,
SQLFetch , SQLFetchScroll , and SQLSetPos. The values describe the status of the row and whether that
status has changed since it was last fetched.
SQL_ROW_SUCCESS The row was successfully fetched and has not changed since
it was last fetched.
SQL_ROW_SUCCESS_WITH_INFO The row was successfully fetched and has not changed since
it was last fetched. However, a warning was returned about
the row.
SQL_ROW_UPDATED The row was successfully fetched and has been updated
since it was last fetched. If the row is fetched again or
refreshed by SQLSetPos , its status is changed to the new
status.
SQL_ROW_DELETED The row has been deleted since it was last fetched.
SQL_ROW_NOROW The rowset overlapped the end of the result set, and no row
was returned that corresponded to this element of the row
status array.
Scrollable Cursors
4/27/2022 • 2 minutes to read • Edit Online
In modern screen-based applications, the user scrolls backward and forward through the data. For such
applications, returning to a previously fetched row is a problem. One possibility is to close and reopen the
cursor and then fetch rows until the cursor reaches the required row. Another possibility is to read the result set,
cache it locally, and implement scrolling in the application. Both possibilities work well only with small result
sets, and the latter possibility is difficult to implement. A better solution is to use a scrollable cursor, which can
move backward and forward in the result set.
A scrollable cursor is commonly used in modern screen-based applications in which the user scrolls back and
forth through the data. However, applications should use scrollable cursors only when forward-only cursors will
not do the job, as scrollable cursors are generally more expensive than forward-only cursors.
The ability to move backward raises a question not applicable to forward-only cursors: Should a scrollable
cursor detect changes made to rows previously fetched? That is, should it detect updated, deleted, and newly
inserted rows?
This question arises because the definition of a result set - the set of rows that matches certain criteria - does
not state when rows are checked to see whether they match that criteria, nor does it state whether rows must
contain the same data each time they are fetched. The former omission makes it possible for scrollable cursors
to detect whether rows have been inserted or deleted, while the latter makes it possible for them to detect
updated data.
The ability to detect changes is sometimes useful, sometimes not. For example, an accounting application needs
a cursor that ignores all changes; balancing books is impossible if the cursor shows the latest changes. On the
other hand, an airline reservation system needs a cursor that shows the latest changes to the data; without such
a cursor, it must continually requery the database to show the most up-to-date flight availability.
To cover the needs of different applications, ODBC defines four different types of scrollable cursors. These
cursors vary both in expense and in their ability to detect changes to the result set. Note that if a scrollable
cursor can detect changes to rows, it can only detect them when it attempts to refetch those rows; there is no
way for the data source to notify the cursor of changes to the currently fetched rows. Note as well that visibility
of changes is also controlled by the transaction isolation level; for more information, see Transaction Isolation.
This section contains the following topics.
Scrollable Cursor Types
Using Scrollable Cursors
Relative and Absolute Scrolling
Bookmarks
Scrollable Cursor Types
4/27/2022 • 2 minutes to read • Edit Online
The four types of scrollable cursors are static, dynamic, keyset-driven, and mixed. Static cursors detect few or no
changes but are relatively cheap to implement. Dynamic cursors detect all changes but are expensive to
implement. Keyset-driven and mixed cursors lie in between, detecting most changes but at less expense than
dynamic cursors.
The following terms are used to define the characteristics of each type of scrollable cursor:
Own updates, deletes, and inser ts. Updates, deletes, and inserts made through the cursor, either with
a call to SQLBulkOperations or SQLSetPos or with a positioned update or delete statement.
Other updates, deletes, and inser ts. Updates, deletes, and inserts not made by the cursor, including
those made by other operations in the same transaction, those made through other transactions, and
those made by other applications.
Membership. The set of rows in the result set.
Order. The order in which rows are returned by the cursor.
Values. The values in each row in the result set.
For information about how to update, delete, and insert data, see Updating Data Overview.
This section contains the following topics.
ODBC Static Cursors
ODBC Dynamic Cursors
Keyset-Driven Cursors
Mixed Cursors
ODBC Static Cursors
4/27/2022 • 2 minutes to read • Edit Online
A static cursor is one in which the result set appears to be static. It does not usually detect changes that were
made to the membership, order, or values of the result set after the cursor is opened. For example, suppose a
static cursor fetches a row and another application then updates that row. If the static cursor refetches the row,
the values it sees are unchanged, despite the changes that were made by the other application.
Static cursors can detect their own updates, deletes, and inserts, although they are not required to do this.
Whether a particular static cursor detects these changes is reported through the SQL_STATIC_SENSITIVITY
option in SQLGetInfo . Static cursors never detect other updates, deletes, and inserts.
The row status array specified by the SQL_ATTR_ROW_STATUS_PTR statement attribute can contain
SQL_ROW_SUCCESS, SQL_ROW_SUCCESS_WITH_INFO, or SQL_ROW_ERROR for any row. It returns
SQL_ROW_UPDATED, SQL_ROW_DELETED, or SQL_ROW_ADDED for rows updated, deleted, or inserted by the
cursor, assuming that the cursor can detect such changes.
Static cursors are typically implemented by locking the rows in the result set or by making a copy, or snapshot,
of the result set. Although locking rows is relatively easy to do, it has the drawback of significantly reducing
concurrency. Making a copy allows for greater concurrency and allows the cursor to keep track of its own
updates, deletes, and inserts by modifying the copy. However, a copy is more expensive to make and can diverge
from the underlying data as that data is changed by others.
ODBC Dynamic Cursors
4/27/2022 • 2 minutes to read • Edit Online
A dynamic cursor is just that: dynamic. It can detect any changes made to the membership, order, and values of
the result set after the cursor is opened. For example, suppose a dynamic cursor fetches two rows and another
application then updates one of those rows and deletes the other. If the dynamic cursor then attempts to refetch
those rows, it will not find the deleted row but will return the new values for the updated row.
Dynamic cursors detect all updates, deletes, and inserts, both their own and those made by others. (This is
subject to the isolation level of the transaction, as set by the SQL_ATTR_TXN_ISOLATION connection attribute.)
The row status array specified by the SQL_ATTR_ROW_STATUS_PTR statement attribute reflects these changes
and can contain SQL_ROW_SUCCESS, SQL_ROW_SUCCESS_WITH_INFO, SQL_ROW_ERROR,
SQL_ROW_UPDATED, and SQL_ROW_ADDED. It cannot return SQL_ROW_DELETED because a dynamic cursor
does not return deleted rows outside the rowset and therefore no longer recognizes the existence of the deleted
row in the result set or its corresponding element in the row status array. SQL_ROW_ADDED is returned only
when a row is updated by a call to SQLSetPos , not when it is updated by another cursor.
One way of implementing dynamic cursors in the database is by creating a selective index that defines the
membership and ordering of the result set. Because the index is updated when others make changes, a cursor
based on such an index is sensitive to all changes. Additional selection within the result set defined by this index
is possible by processing along the index.
Dynamic cursors can be simulated by requiring the result set to be ordered by a unique key. With such a
restriction, fetches are made by executing a SELECT statement each time the cursor fetches rows. For example,
suppose the result set is defined by this statement:
To fetch the next rowset in this result set, the simulated cursor sets the parameters in the following SELECT
statement to the values in the last row of the current rowset, and then executes it:
This statement creates a second result set, the first rowset of which is the next rowset in the original result set -
in this case, the set of rows in the Customers table. The cursor returns this rowset to the application.
It is interesting to note that a dynamic cursor implemented in this manner actually creates many result sets,
which allows it to detect changes to the original result set. The application never learns of the existence of these
auxiliary result sets; it simply appears as if the cursor is able to detect changes to the original result set.
Keyset-Driven Cursors
4/27/2022 • 2 minutes to read • Edit Online
A keyset-driven cursor lies between a static and a dynamic cursor in its ability to detect changes. Like a static
cursor, it does not always detect changes to the membership and order of the result set. Like a dynamic cursor, it
does detect changes to the values of rows in the result set (subject to the isolation level of the transaction, as set
by the SQL_ATTR_TXN_ISOLATION connection attribute).
When a keyset-driven cursor is opened, it saves the keys for the entire result set; this fixes the apparent
membership and order of the result set. As the cursor scrolls through the result set, it uses the keys in this
keyset to retrieve the current data values for each row. For example, suppose a keyset-driven cursor fetches a
row and another application then updates that row. If the cursor refetches the row, the values it sees are the new
ones because it refetched the row using its key. Because of this, the keyset-driven cursors always detect changes
made by themselves and others.
When the cursor attempts to retrieve a row that has been deleted, this row appears as a "hole" in the result set:
The key for the row exists in the keyset, but the row no longer exists in the result set. If the key values in a row
are updated, the row is considered to have been deleted and then inserted, so such rows also appear as holes in
the result set. While a keyset-driven cursor can always detect rows deleted by others, it can optionally remove
the keys for rows it deletes itself from the keyset. Keyset-driven cursors that do this cannot detect their own
deletes. Whether a particular keyset-driven cursor detects its own deletes is reported through the
SQL_STATIC_SENSITIVITY option in SQLGetInfo .
Rows inserted by others are never visible to a keyset-driven cursor because no keys for these rows exist in the
keyset. However, a keyset-driven cursor can optionally add the keys for rows it inserts itself to the keyset. Keyset-
driven cursors that do this can detect their own inserts. Whether a particular keyset-driven cursor detects its
own inserts is reported through the SQL_STATIC_SENSITIVITY option in SQLGetInfo .
The row status array specified by the SQL_ATTR_ROW_STATUS_PTR statement attribute can contain
SQL_ROW_SUCCESS, SQL_ROW_SUCCESS_WITH_INFO, or SQL_ROW_ERROR for any row. It returns
SQL_ROW_UPDATED, SQL_ROW_DELETED, or SQL_ROW_ADDED for rows it detects as updated, deleted, or
inserted.
Keyset-driven cursors are commonly implemented by creating a temporary table that contains the keys for each
row in the result set. Because the cursor must also determine whether rows have been updated, this table also
commonly contains a column with row versioning information.
To scroll over the original result set, the keyset-driven cursor opens a static cursor over the temporary table. To
retrieve a row in the original result set, the cursor first retrieves the appropriate key from the temporary table
and then retrieves the current values for the row. If block cursors are used, the cursor must retrieve multiple
keys and rows.
Mixed Cursors
4/27/2022 • 2 minutes to read • Edit Online
A mixed cursor is a combination of a keyset-driven cursor and a dynamic cursor. It is used when the result set is
too large to reasonably save keys for the entire result set. Mixed cursors are implemented by creating a keyset
that is smaller than the entire result set but larger than the rowset.
As long as the application scrolls within the keyset, the behavior is keyset-driven. When the application scrolls
outside the keyset, the behavior is dynamic: The cursor fetches the requested rows and creates a new keyset.
After the new keyset is created, the behavior reverts to keyset-driven within that keyset.
For example, suppose a result set has 1,000 rows and uses a mixed cursor with a keyset size of 100 and a rowset
size of 10. When the first rowset is fetched, the cursor creates a keyset consisting of the keys for the first 100
rows. It then returns the first 10 rows, as requested.
Now suppose another application deletes rows 11 and 101. If the cursor attempts to retrieve row 11, it will
encounter a gap because it has a key for this row but no row exists; this is keyset-driven behavior. If the cursor
attempts to retrieve row 101, the cursor will not detect that the row is missing because it does not have a key for
the row. Instead, it will retrieve what was previously row 102. This is dynamic cursor behavior.
A mixed cursor is equivalent to a keyset-driven cursor when the keyset size is equal to the result set size. A
mixed cursor is equivalent to a dynamic cursor when the keyset size is equal to 1.
Using Scrollable Cursors
4/27/2022 • 2 minutes to read • Edit Online
The following four options in SQLGetInfo describe what types of cursors are supported and what their
capabilities are:
SQL_CURSOR_SENSITIVITY. Indicates whether a cursor is sensitive to changes made by another cursor.
SQL_SCROLL_OPTIONS. Lists the supported cursor types (forward-only, static, keyset-driven, dynamic, or
mixed). All data sources must support forward-only cursors.
SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1,
SQL_KEYSET_CURSOR_ATTRIBUTES1, or SQL_STATIC_CURSOR_ATTRIBUTES1 (depending on the type of
the cursor). Lists the fetch types supported by scrollable cursors. The bits in the return value correspond
to the fetch types in SQLFetchScroll .
SQL_KEYSET_CURSOR_ATTRIBUTES2 or SQL_STATIC_CURSOR_ATTRIBUTES2 (depending on the type of
the cursor). Lists whether static and keyset-driven cursors can detect their own updates, deletes, and
inserts.
An application can determine cursor capabilities at run time by calling SQLGetInfo with these options. This is
commonly done by generic applications. Cursor capabilities also can be determined during application
development and their use hard-coded into the application. This is commonly done by vertical and custom
applications but can also be done by generic applications that use a client-side cursor implementation such as
the ODBC cursor library.
Setting Up the Cursor
4/27/2022 • 2 minutes to read • Edit Online
The application can specify the cursor type before executing a statement that creates a result set. It does this
with the SQL_ATTR_CURSOR_TYPE statement attribute. If the application does not explicitly specify a type, a
forward-only cursor will be used. To get a mixed cursor, an application specifies a keyset-driven cursor but
declares a keyset size less than the result set size.
For keyset-driven and mixed cursors, the application can also specify the keyset size. It does this with the
SQL_ATTR_KEYSET_SIZE statement attribute. If the keyset size is set to 0, which is the default, the keyset size is
set to the result set size and a keyset-driven cursor is used. The keyset size can be changed after the cursor has
been opened.
The application can also set the rowset size; for more information, see Using Block Cursors, earlier in this
section.
Cursor Characteristics and Cursor Type
4/27/2022 • 2 minutes to read • Edit Online
An application can specify the characteristics of a cursor instead of specifying the cursor type (forward-only,
static, keyset-driven, or dynamic). To do this, the application selects the cursor's scrollability (by setting the
SQL_ATTR_CURSOR_SCROLLABLE statement attribute) and sensitivity (by setting the
SQL_ATTR_CURSOR_SENSITIVITY statement attribute) before opening the cursor on the statement handle. The
driver then chooses the cursor type that most efficiently provides the characteristics that the application
requested.
Whenever an application sets any of the statement attributes SQL_ATTR_CONCURRENCY,
SQL_ATTR_CURSOR_SCROLLABLE, SQL_ATTR_CURSOR_SENSITIVITY, or SQL_ATTR_CURSOR_TYPE, the driver
makes any required change to the other statement attributes in this set of four attributes so that their values
remain consistent. As a result, when the application specifies a cursor characteristic, the driver can change the
attribute that indicates cursor type based on this implicit selection; when the application specifies a type, the
driver can change any of the other attributes to be consistent with the characteristics of the selected type. For
more information about these statement attributes, see the SQLSetStmtAttr function description.
An application that sets statement attributes to specify both a cursor type and cursor characteristics runs the risk
of obtaining a cursor that is not the most efficient method available on that driver of meeting the application's
requirements.
The implicit setting of statement attributes is driver-defined except that it must follow these rules:
Forward-only cursors are never scrollable; see the definition of SQL_ATTR_CURSOR_SCROLLABLE in
SQLSetStmtAttr.
Insensitive cursors are never updatable (and thus their concurrency is read-only); this is based on their
definition of insensitive cursors in the ISO SQL standard.
Consequently, the implicit setting of statement attributes occurs in the cases described in the following table.
SQL_ATTR_CURSOR_TYPE to SQL_CURSOR_STATIC.
A P P L IC AT IO N SET S AT T RIB UT E TO OT H ER AT T RIB UT ES SET IM P L IC IT LY
SQL_ATTR_CURSOR_TYPE to
SQL_CURSOR_FORWARD_ONLY, SQL_CURSOR_STATIC,
SQL_CURSOR_KEYSET_DRIVEN, or SQL_CURSOR_DYNAMIC,
as specified by the driver.
SQL_ATTR_CURSOR_TYPE to
SQL_CURSOR_FORWARD_ONLY, SQL_CURSOR_STATIC,
SQL_CURSOR_KEYSET_DRIVEN, or SQL_CURSOR_DYNAMIC,
as specified by the driver.
SQL_ATTR_CURSOR_TYPE to SQL_ATTR_CURSOR_SCROLLABLE to
SQL_CURSOR_FORWARD_ONLY SQL_NONSCROLLABLE.
SQL_ATTR_SENSITIVITY to SQL_UNSPECIFIED or
SQL_SENSITIVE (according to driver-defined criteria, if
SQL_ATTR_CONCURRENCY is not
SQL_CONCUR_READ_ONLY).
SQL_ATTR_SENSITIVITY to SQL_UNSPECIFIED or
SQL_SENSITIVE (if SQL_ATTR_CONCURRENCY is not
SQL_CONCUR_READ_ONLY).
Scrolling and Fetching Rows (ODBC)
4/27/2022 • 2 minutes to read • Edit Online
When using a scrollable cursor, applications call SQLFetchScroll to position the cursor and fetch rows.
SQLFetchScroll supports relative scrolling (next, prior, and relative n rows), absolute scrolling (first, last, and
row n), and positioning by bookmark. The FetchOrientation and FetchOffset arguments in SQLFetchScroll
specify which rowset to fetch, as shown in the following diagrams.
NOTE
Scrolling is supported in ODBC 2.x drivers by SQLExtendedFetch . For more information, see Block Cursors, Scrollable
Cursors, and Backward Compatibilityin Appendix G: Driver Guidelines for Backward Compatibility.
Relative and Absolute Scrolling
4/27/2022 • 2 minutes to read • Edit Online
Most of the scrolling options in SQLFetchScroll position the cursor relative to the current position or to an
absolute position. SQLFetchScroll supports fetching the next, prior, first, and last rowsets, as well as relative
fetching (fetch the rowset n rows from the start of the current rowset) and absolute fetching (fetch the rowset
starting at row n). If n is negative in an absolute fetch, rows are counted from the end of the result set. Thus, an
absolute fetch of row -1 means to fetch the rowset that starts with the last row in the result set.
Dynamic cursors detect rows inserted into and deleted from the result set, so there is no easy way for dynamic
cursors to retrieve the row at a particular number other than reading from the start of the result set, which is
likely to be slow. Furthermore, absolute fetching is not very useful in dynamic cursors because row numbers
change as rows are inserted and deleted; therefore, successively fetching the same row number can yield
different rows.
Applications that use SQLFetchScroll only for its block cursor capabilities, such as reports, are likely to pass
through the result set a single time, using only the option to fetch the next rowset. Screen-based applications, on
the other hand, can take advantage of all the capabilities of SQLFetchScroll . If the application sets the rowset
size to the number of rows displayed on the screen and binds the screen buffers to the result set, it can translate
scroll bar operations directly to calls to SQLFetchScroll .
SC RO L L B A R O P ERAT IO N SQ L F ETC H SC RO L L SC RO L L IN G O P T IO N
Page up SQL_FETCH_PRIOR
Such applications also need to position the scroll box after a scrolling operation, which requires the current row
number and the number of rows. For the current row number, applications can either keep track of the current
row number or call SQLGetStmtAttr with the SQL_ATTR_ROW_NUMBER attribute to retrieve it.
The number of rows in the cursor, which is the size of the result set, is available as the
SQL_DIAG_CURSOR_ROW_COUNT field of the diagnostic header. The value in this field is defined only after
SQLExecute , SQLExecDirect , or SQLMoreResult has been called. This count can be either an approximate
count or an exact count, depending on the capabilities of the driver. The driver's support can be determined by
calling SQLGetInfo with the cursor attributes information types and checking whether the
SQL_CA2_CRC_APPROXIMATE or SQL_CA2_CRC_EXACT bit is returned for the type of cursor.
An exact row count is never supported for a dynamic cursor. For other types of cursors, the driver can support
either exact or approximate row counts, but not both. If the driver supports neither exact nor approximate row
counts for a specific cursor type, the SQL_DIAG_CURSOR_ROW_COUNT field contains the number of rows that
have been fetched so far. Regardless of what the driver supports, SQLFetchScroll with an Operation of
SQL_FETCH_LAST will cause the SQL_DIAG_CURSOR_ROW_COUNT field to contain the exact row count.
Bookmarks (ODBC)
4/27/2022 • 2 minutes to read • Edit Online
A bookmark is a value used to identify a row of data. The meaning of the bookmark value is known only to the
driver or data source. For example, it might be as simple as a row number or as complex as a disk address.
Bookmarks in ODBC are a bit different from bookmarks in real books. In a real book, the reader places a
bookmark at a specific page and then looks for that bookmark to return to the page. In ODBC, the application
requests a bookmark for a particular row, stores it, and passes it back to the cursor to return to the row. Thus,
bookmarks in ODBC are similar to a reader writing down a page number, remembering it, and then looking up
the page again.
To determine a driver's support of bookmarks, an application calls SQLGetInfo with the
SQL_BOOKMARK_PERSISTENCE option. The bits in this value describe what operations bookmarks survive, such
as whether bookmarks are still valid after the cursor is closed.
This section contains the following topics.
Bookmark Types
Retrieving Bookmarks
Scrolling by Bookmark
Updating, Deleting, or Fetching by Bookmark
Comparing Bookmarks
Bookmark Types
4/27/2022 • 2 minutes to read • Edit Online
All bookmarks in ODBC 3.x are variable-length bookmarks. This allows a primary key or a unique index
associated with a table to be used as a bookmark. The bookmark also can be a 32-bit value, as was used in
ODBC 2.x. To specify that a bookmark is used with a cursor, an ODBC 3.x application sets the
SQL_ATTR_USE_BOOKMARK statement attribute to SQL_UB_VARIABLE. A variable-length bookmark is
automatically used.
An application can call SQLColAttribute with the FieldIdentifier argument set to SQL_DESC_OCTET_LENGTH to
obtain the length of the bookmark. Because a variable-length bookmark can be a long value, an application
should not bind to column 0 unless it will use the bookmark for many of the rows in the rowset.
Fixed-length bookmarks are supported only for backward compatibility. If an ODBC 2.x application working with
an ODBC 3.x driver calls SQLSetStmtOption to set SQL_USE_BOOKMARKS to SQL_UB_ON, it is mapped in the
Driver Manager to SQL_UB_VARIABLE. A variable-length bookmark is used, even if only 32 bits of it are
populated. If a driver supports fixed-length bookmarks, it will support variable-length bookmarks. If an ODBC
3.x application working with an ODBC 2.x driver calls SQLSetStmtAttr to set SQL_ATTR_USE_BOOKMARKS to
SQL_UB_VARIABLE, it is mapped in the Driver Manager to SQL_UB_ON and a 32-bit fixed-length bookmark is
used. The SQL_ATTR_FETCH_BOOKMARK_PTR statement attribute must then point to a 32-bit bookmark. If the
bookmarks used are longer than 32 bits, such as when primary keys are used as bookmarks, the cursor must
map the actual values to 32-bit values. It could, for example, build a hash table of them. When an ODBC 3.x
application working with an ODBC 2.x driver binds a bookmark, the buffer length must be 4.
Retrieving Bookmarks
4/27/2022 • 2 minutes to read • Edit Online
If the application will use bookmarks, it must set the SQL_ATTR_USE_BOOKMARKS statement attribute to
SQL_UB_VARIABLE before preparing or executing the statement. This is necessary because building and
maintaining bookmarks can be an expensive operation, so bookmarks should be enabled only when an
application can make good use of them.
Bookmarks are returned as column 0 of the result set. There are three ways an application can retrieve them:
Bind column 0 of the result set. SQLFetch or SQLFetchScroll returns the bookmarks for each row in
the rowset along with the data for other bound columns.
Call SQLSetPos to position to a row in the rowset and then call SQLGetData for column 0. If a driver
supports bookmarks, it must always support the ability to call SQLGetData for column 0, even if it does
not allow applications to call SQLGetData for other columns before the last bound column.
Call SQLBulkOperations with the Operation argument set to SQL_ADD, and column 0 bound. The
cursor inserts the row and returns the bookmark for the row in the bound buffer.
Scrolling by Bookmark
4/27/2022 • 2 minutes to read • Edit Online
When fetching rows with SQLFetchScroll , an application can use a bookmark as a basis for selecting the
starting row. This is a form of absolute addressing because it does not depend on the current cursor position. To
scroll to a bookmarked row, the application calls SQLFetchScroll with a FetchOrientation of
SQL_FETCH_BOOKMARK. This operation uses the bookmark pointed to by the
SQL_ATTR_FETCH_BOOKMARK_PTR statement attribute. It returns the rowset starting with the row identified by
that bookmark. An application can specify an offset for this operation in the FetchOffset argument of the call to
SQLFetchScroll . When an offset is specified, the first row of the returned rowset is determined by adding the
number in the FetchOffset argument to the number of the row identified by the bookmark. This use of the
FetchOffset argument is not supported when used with ODBC 2.x drivers; when an application calls
SQLFetchScroll in an ODBC 2.x driver with FetchOrientation set to SQL_FETCH_BOOKMARK, the FetchOffset
argument must be set to 0.
Updating, Deleting, or Fetching by Bookmark
4/27/2022 • 2 minutes to read • Edit Online
Bookmarks can be used to identify data to be updated in the result set, deleted from the result set, or fetched
from the result set to the rowset buffers. These operations are performed by a call to SQLBulkOperations with
an Option argument of SQL_UPDATE_BY_BOOKMARK, SQL_DELETE_BY_BOOKMARK, or
SQL_FETCH_BY_BOOKMARK. The bookmarks used in these operations are stored in column 0 of the rowset
buffers. When updating by bookmark, the data that result set columns are updated to is retrieved from the
rowset buffers. For more information, see Updating Data with SQLBulkOperations.
Comparing Bookmarks
4/27/2022 • 2 minutes to read • Edit Online
Because bookmarks are byte-comparable, they can be compared for equality or inequality. To do so, an
application treats each bookmark as an array of bytes and compares two bookmarks byte-by-byte. Because
bookmarks are guaranteed to be distinct only within a result set, it makes no sense to compare bookmarks that
were obtained from different result sets.
The ODBC Cursor Library
4/27/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan
to modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
Block and scrollable cursors are very useful additions to many applications. However, not all drivers support
block and scrollable cursors. The same is true of positioned update and delete statements and SQLSetPos ,
which are discussed in Updating Data. Therefore, the ODBC component of the Windows SDK, formerly included
in the Microsoft Data Access Components (MDAC) SDK, includes a cursor library. The cursor library implements
block, static cursors, positioned update and delete statements, and SQLSetPos for any driver that meets the
Open Group Standard CLI conformance level. The cursor library may be redistributed with ODBC applications;
see the licensing agreement in the SDK for more information.
To use the cursor library, an application sets the SQL_ATTR_ODBC_CURSORS connection attribute before it
connects to the data source. For more information about the cursor library, see Appendix F: ODBC Cursor
Library.
Multiple Results
4/27/2022 • 2 minutes to read • Edit Online
A result is something returned by the data source after a statement is executed. ODBC has two types of results:
result sets and row counts. Row counts are the number of rows affected by an update, delete, or insert
statement. Batches, described in Batches of SQL Statements, can generate multiple results.
The following table lists the SQLGetInfo options an application uses to determine whether a data source
returns multiple results for each different type of batch. In particular, a data source can return a single row count
for the entire batch of statements or individual row counts for each statement in the batch. In the case of a result
set-generating statement executed with an array of parameters, the data source can return a single result set for
all sets of parameters or individual result sets for each set of parameters.
[a] Row count-generating statements in a batch may be supported, yet the return of the row counts not
supported. The SQL_BATCH_SUPPORT option in SQLGetInfo indicates whether row count-generating
statements are allowed in batches; the SQL_BATCH_ROW_COUNTS option indicates whether these row counts
are returned to the application.
[b] Explicit batches and procedures always return multiple result sets when they include multiple result set-
generating statements.
NOTE
The SQL_MULT_RESULT_SETS option introduced in ODBC 1.0 provides only general information about whether multiple
result sets can be returned. In particular, it is set to "Y" if the SQL_BS_SELECT_EXPLICIT or SQL_BS_SELECT_PROC bits are
returned for SQL_BATCH_SUPPORT or if SQL_PAS_BATCH is returned for SQL_PARAM_ARRAYS_SELECT.
To process multiple results, an application calls SQLMoreResults . This function discards the current result and
makes the next result available. It returns SQL_NO_DATA when no more results are available. For example,
suppose the following statements are executed as a batch:
After these statements are executed, the application fetches rows from the result set created by the SELECT
statement. When it is done fetching rows, it calls SQLMoreResults to make available the number of parts that
were repriced. If necessary, SQLMoreResults discards unfetched rows and closes the cursor. The application
then calls SQLRowCount to determine how many parts were repriced by the UPDATE statement.
It is driver-specific whether the entire batch statement is executed before any results are available. In some
implementations, this is the case; in others, calling SQLMoreResults triggers the execution of the next
statement in the batch.
If one of the statements in a batch fails, SQLMoreResults will return either SQL_ERROR or
SQL_SUCCESS_WITH_INFO. If the batch was aborted when the statement failed or the failed statement was the
last statement in the batch, SQLMoreResults will return SQL_ERROR. If the batch was not aborted when the
statement failed and the failed statement was not the last statement in the batch, SQLMoreResults will return
SQL_SUCCESS_WITH_INFO. SQL_SUCCESS_WITH_INFO indicates that at least one result set or count was
generated and that the batch was not aborted.
Updating Data Overview
4/27/2022 • 2 minutes to read • Edit Online
Applications can update data either by executing SQL statements or by calling SQLSetPos or
SQLBulkOperations . UPDATE , DELETE , and INSERT statements act directly on the data source and are
usually supported by drivers. Searched update and delete statements contain a specification of the rows to
change. Positioned update and delete statements and SQLSetPos act on the data source through a cursor and
are less widely supported.
Whether cursors can detect changes made to the result set with the methods described in this section depends
on the type of the cursor and how it is implemented. Forward-only cursors do not revisit rows and therefore will
not detect any changes. For information about whether scrollable cursors can detect changes, see Scrollable
Cursors.
This section contains the following topics.
UPDATE, DELETE, and INSERT Statements
Positioned Update and Delete Statements
Simulating Positioned Update and Delete Statements
Determining the Number of Affected Rows
Updating Data with SQLSetPos
Updating Data with SQLBulkOperations
Long Data and SQLSetPos and SQLBulkOperations
UPDATE, DELETE, and INSERT Statements
4/27/2022 • 2 minutes to read • Edit Online
SQL-based applications make changes to tables by executing the UPDATE , DELETE , and INSERT statements.
These statements are part of the Minimum SQL grammar conformance level and must be supported by all
drivers and data sources.
The syntax of these statements is:
UPDATE table-name
SET column-identifier = {expression | NULL }
[, column-identifier = {expression | NULL }]...
[WHERE search-condition]
DELETE FROM table-name[WHERE search-condition]
INSERT INTO table-name[( column-identifier [, column-identifier]...) ]
{query-specification | VALUES ( insert-value [, insert-value]...) }
Note that the query-specification element is valid only in the Core and Extended SQL grammars, and that the
expression and search-condition elements become more complex in the Core and Extended SQL grammars.
Like other SQL statements, UPDATE , DELETE , and INSERT statements are often more efficient when they use
parameters. For example, the following statement can be prepared and repeatedly executed to insert multiple
rows in the Orders table:
This efficiency can be increased by passing arrays of parameter values. For more information about statement
parameters and arrays of parameter values, see Statement Parameters.
Positioned Update and Delete Statements
4/27/2022 • 3 minutes to read • Edit Online
Applications can update or delete the current row in a result set with a positioned update or delete statement.
Positioned update and delete statements are supported by some data sources, but not all of them. To determine
whether a data source supports positioned update and delete statements, an application calls SQLGetInfo with
the SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1,
SQL_KEYSET_CURSOR_ATTRIBUTES1, or SQL_STATIC_CURSOR_ATTRIBUTES1 InfoType (depending on the type
of the cursor). Note that the ODBC cursor library simulates positioned update and delete statements.
To use a positioned update or delete statement, the application must create a result set with a SELECT FOR
UPDATE statement. The syntax of this statement is:
SELECT [ALL | DISTINCT ] select-list
FROM table-reference-list
[WHERE search-condition]
FOR UPDATE OF [column-name [, column-name]...]
The application then positions the cursor on the row to be updated or deleted. It can do this by calling
SQLFetchScroll to retrieve a rowset containing the required row and calling SQLSetPos to position the
rowset cursor on that row. The application then executes the positioned update or delete statement on a
different statement than the statement being used by the result set. The syntax of these statements is:
UPDATE table-name
SET column-identifier = {expression | NULL }
[, column-identifier = {expression | NULL }]...
WHERE CURRENT OF cursor-name
DELETE FROM table-name WHERE CURRENT OF cursor-name
Notice that these statements require a cursor name. The application either can specify a cursor name with
SQLSetCursorName before executing the statement that creates the result set or can let the data source
automatically generate a cursor name when the cursor is created. In the latter case, the application retrieves this
cursor name for use in positioned update and delete statements by calling SQLGetCursorName .
For example, the following code allows a user to scroll through the Customers table and delete customer
records or update their addresses and phone numbers. It calls SQLSetCursorName to specify a cursor name
before it creates the result set of customers and uses three statement handles: hstmtCust for the result set,
hstmtUpdate for a positioned update statement, and hstmtDelete for a positioned delete statement. Although
the code could bind separate variables to the parameters in the positioned update statement, it updates the
rowset buffers and binds the elements of these buffers. This keeps the rowset buffers synchronized with the
updated data.
SQLUINTEGER CustIDArray[10];
SQLCHAR NameArray[10][51], AddressArray[10][51],
PhoneArray[10][11];
SQLINTEGER CustIDIndArray[10], NameLenOrIndArray[10],
SQLINTEGER CustIDIndArray[10], NameLenOrIndArray[10],
AddressLenOrIndArray[10],
PhoneLenOrIndArray[10];
SQLUSMALLINT RowStatusArray[10], Action, RowNum;
SQLHSTMT hstmtCust, hstmtUpdate, hstmtDelete;
// Call GetAction to get an action and a row number from the user.
while (GetAction(&Action, &RowNum)) {
switch (Action) {
case SQL_FETCH_NEXT:
case SQL_FETCH_PRIOR:
case SQL_FETCH_FIRST:
case SQL_FETCH_LAST:
case SQL_FETCH_ABSOLUTE:
case SQL_FETCH_RELATIVE:
// Fetch and display the requested data.
SQLFetchScroll(hstmtCust, Action, RowNum);
DisplayData(CustIDArray, CustIDIndArray, NameArray, NameLenOrIndArray,
AddressArray, AddressLenOrIndArray, PhoneArray,
PhoneLenOrIndArray, RowStatusArray);
break;
case POSITIONED_UPDATE:
// Get the new data and place it in the rowset buffers.
GetNewData(AddressArray[RowNum - 1], &AddressLenOrIndArray[RowNum - 1],
PhoneArray[RowNum - 1], &PhoneLenOrIndArray[RowNum - 1]);
case POSITIONED_DELETE:
// Position the rowset cursor. The rowset is 1-based.
SQLSetPos(hstmtCust, RowNum, SQL_POSITION, SQL_LOCK_NO_CHANGE);
If the data source does not support positioned update and delete statements, the driver can simulate these. For
example, the ODBC cursor library simulates positioned update and delete statements. The general strategy for
simulating positioned update and delete statements is to convert positioned statements to searched ones. This
is done by replacing the WHERE CURRENT OF clause with a searched WHERE clause that identifies the
current row.
For example, because the CustID column uniquely identifies each row in the Customers table, the positioned
delete statement
might be converted to
The driver may use one of the following row identifiers in the WHERE clause:
Columns whose values serve to identify uniquely every row in the table. For example, calling
SQLSpecialColumns with SQL_BEST_ROWID returns the optimal column or set of columns that serve
this purpose.
Pseudo-columns, provided by some data sources, for the purpose of uniquely identifying every row.
These may also be retrievable by calling SQLSpecialColumns .
A unique index, if available.
All the columns in the result set.
Exactly which columns a driver should use in the WHERE clause it constructs depends on the driver. On some
data sources, determining a row identifier can be costly. However, it is faster to execute and guarantees that a
simulated statement updates or deletes at most one row. Depending on the capabilities of the underlying DBMS,
using a row identifier can be expensive to set up. However, it is faster to execute and guarantees that a simulated
statement will update or delete only one row. The option of using all the columns in the result set is usually
much easier to set up. However, it is slower to execute and, if the columns do not uniquely identify a row, can
result in rows being unintentionally updated or deleted, especially when the select list for the result set does not
contain all the columns that exist in the underlying table.
Depending upon which of the preceding strategies the driver supports, an application can choose which
strategy it wants the driver to use with the SQL_ATTR_SIMULATE_CURSOR statement attribute. Although it
might seem odd for an application to risk unintentionally updating or deleting a row, the application can remove
this risk by ensuring that the columns in the result set uniquely identify each row in the result set. This saves the
driver the effort of having to do this.
If the driver chooses to use a row identifier, it intercepts the SELECT FOR UPDATE statement that creates the
result set. If the columns in the select list do not effectively identify a row, the driver adds the necessary columns
to the end of the select list. Some data sources have a single column that always uniquely identifies a row, such
as the ROWID column in Oracle; if such a column is available, the driver uses this. Otherwise, the driver calls
SQLSpecialColumns for each table in the FROM clause to retrieve a list of the columns that uniquely identify
each row. A common restriction that results from this technique is that cursor simulation fails if there is more
than one table in the FROM clause.
No matter how the driver identifies rows, it usually strips the FOR UPDATE OF clause off the SELECT FOR
UPDATE statement before sending it to the data source. The FOR UPDATE OF clause is used only with
positioned update and delete statements. Data sources that do not support positioned update and delete
statements generally do not support it.
When the application submits a positioned update or delete statement for execution, the driver replaces the
WHERE CURRENT OF clause with a WHERE clause containing the row identifier. The values of these columns
are retrieved from a cache maintained by the driver for each column it uses in the WHERE clause. After the
driver has replaced the WHERE clause, it sends the statement to the data source for execution.
For example, suppose that the application submits the following statement to create a result set:
SELECT Name, Address, Phone FROM Customers FOR UPDATE OF Phone, Address
If the application has set SQL_ATTR_SIMULATE_CURSOR to request a guarantee of uniqueness and if the data
source does not provide a pseudo-column that always uniquely identifies a row, the driver calls
SQLSpecialColumns for the Customers table, discovers that CustID is the key to the Customers table and adds
this to the select list, and strips the FOR UPDATE OF clause:
If the application has not requested a guarantee of uniqueness, the driver strips only the FOR UPDATE OF
clause:
Suppose the application scrolls through the result set and submits the following positioned update statement
for execution, where Cust is the name of the cursor over the result set:
If the application has not requested a guarantee of uniqueness, the driver replaces the WHERE clause and binds
the CustID parameter to the variable in its cache:
If the application has not requested a guarantee of uniqueness, the driver replaces the WHERE clause and binds
the Name, Address, and Phone parameters in this clause to the variables in its cache:
After an application updates, deletes, or inserts rows, it can call SQLRowCount to determine how many rows
were affected. SQLRowCount returns this value whether or not the rows were updated, deleted, or inserted by
executing an UPDATE , DELETE , or INSERT statement, by executing a positioned update or delete statement, or
by calling SQLSetPos .
If a batch of SQL statements is executed, the count of affected rows might be a total count for all statements in
the batch or individual counts for each statement in the batch. For more information, see Batches of SQL
Statements and Multiple Results.
The number of affected rows is also returned in the SQL_DIAG_ROW_COUNT diagnostic header field in the
diagnostic area associated with the statement handle. However, the data in this field is reset after every function
call on the same statement handle, whereas the value returned by SQLRowCount remains the same until a call
to SQLBulkOperations , SQLExecute , SQLExecDirect , SQLPrepare , or SQLSetPos .
Updating Data with SQLSetPos
4/27/2022 • 2 minutes to read • Edit Online
Applications can update or delete any row in the rowset with SQLSetPos . Calling SQLSetPos is a convenient
alternative to constructing and executing an SQL statement. It lets an ODBC driver support positioned updates
even when the data source does not support positioned SQL statements. It is part of the paradigm of achieving
complete database access by means of function calls.
SQLSetPos operates on the current rowset and can be used only after a call to SQLFetchScroll . The
application specifies the number of the row to update, delete, or insert, and the driver retrieves the new data for
that row from the rowset buffers. SQLSetPos can also be used to designate a specified row as the current row,
or to refresh a particular row in the rowset from the data source.
Rowset size is set by a call to SQLSetStmtAttr with an Attribute argument of SQL_ATTR_ROW_ARRAY_SIZE.
SQLSetPos uses a new rowset size, however, only after a call to SQLFetch or SQLFetchScroll . For example, if
the rowset size is changed, SQLSetPos is called and then SQLFetch or SQLFetchScroll is called, and the call
to SQLSetPos uses the old rowset size while SQLFetch or SQLFetchScroll uses the new rowset size.
The first row in the rowset is row number 1. The RowNumber argument in SQLSetPos must identify a row in
the rowset; that is, its value must be in the range between 1 and the number of rows that were most recently
fetched (which may be less than the rowset size). If RowNumber is 0, the operation applies to every row in the
rowset.
Because most interaction with relational databases is done through SQL, SQLSetPos is not widely supported.
However, a driver can easily emulate it by constructing and executing an UPDATE or DELETE statement.
To determine what operations SQLSetPos supports, an application calls SQLGetInfo with the
SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1,
SQL_KEYSET_CURSOR_ATTRIBUTES1, or SQL_STATIC_CURSOR_ATTRIBUTES1 information option (depending on
the type of the cursor).
This section contains the following topics.
Updating Rows in the Rowset with SQLSetPos
Deleting Rows in the Rowset with SQLSetPos
Updating Rows in the Rowset with SQLSetPos
4/27/2022 • 3 minutes to read • Edit Online
The update operation of SQLSetPos makes the data source update one or more selected rows of a table, using
data in the application buffers for each bound column (unless the value in the length/indicator buffer is
SQL_COLUMN_IGNORE). Columns that are not bound will not be updated.
To update rows with SQLSetPos , the application does the following:
1. Places the new data values in the rowset buffers. For information on how to send long data with
SQLSetPos , see Long Data and SQLSetPos and SQLBulkOperations.
2. Sets the value in the length/indicator buffer of each column as necessary. This is the byte length of the
data or SQL_NTS for columns bound to string buffers, the byte length of the data for columns bound to
binary buffers, and SQL_NULL_DATA for any columns to be set to NULL.
3. Sets the value in the length/indicator buffer of those columns which are not to be updated to
SQL_COLUMN_IGNORE. Although the application can skip this step and resend existing data, this is
inefficient and risks sending values to the data source that were truncated when they were read.
4. Calls SQLSetPos with Operation set to SQL_UPDATE and RowNumber set to the number of the row to
update. If RowNumber is 0, all rows in the rowset are updated.
After SQLSetPos returns, the current row is set to the updated row.
When updating all rows of the rowset (RowNumber is equal to 0), an application can disable the update of
certain rows by setting the corresponding elements of the row operation array (pointed to by the
SQL_ATTR_ROW_OPERATION_PTR statement attribute) to SQL_ROW_IGNORE. The row operation array
corresponds in size and number of elements to the row status array (pointed to by the
SQL_ATTR_ROW_STATUS_PTR statement attribute). To update only those rows in the result set that were
successfully fetched and have not been deleted from the rowset, the application uses the row status array from
the function that fetched the rowset as the row operation array to SQLSetPos .
For every row that is sent to the data source as an update, the application buffers should have valid row data. If
the application buffers were filled by fetching and if a row status array has been maintained, its values at each of
these row positions should not be SQL_ROW_DELETED, SQL_ROW_ERROR, or SQL_ROW_NOROW.
For example, the following code allows a user to scroll through the Customers table and update, delete, or add
new rows. It places the new data in the rowset buffers before calling SQLSetPos to update or add new rows. An
extra row is allocated at the end of the rowset buffers to hold new rows; this prevents existing data from being
overwritten when data for a new row is placed in the buffers.
SQLUINTEGER CustIDArray[11];
SQLCHAR NameArray[11][51], AddressArray[11][51],
PhoneArray[11][11];
SQLINTEGER CustIDIndArray[11], NameLenOrIndArray[11],
AddressLenOrIndArray[11],
PhoneLenOrIndArray[11];
SQLUSMALLINT RowStatusArray[10], Action, RowNum;
SQLRETURN rc;
SQLHSTMT hstmt;
// Set the SQL_ATTR_ROW_BIND_TYPE statement attribute to use column-wise
// binding. Declare the rowset size with the SQL_ATTR_ROW_ARRAY_SIZE
// statement attribute. Set the SQL_ATTR_ROW_STATUS_PTR statement
// attribute to point to the row status array.
SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_KEYSET_DRIVEN, 0);
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_BIND_TYPE, SQL_BIND_BY_COLUMN, 0);
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, 10, 0);
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_STATUS_PTR, RowStatusArray, 0);
// Call GetAction to get an action and a row number from the user.
while (GetAction(&Action, &RowNum)) {
switch (Action) {
case SQL_FETCH_NEXT:
case SQL_FETCH_PRIOR:
case SQL_FETCH_FIRST:
case SQL_FETCH_LAST:
case SQL_FETCH_ABSOLUTE:
case SQL_FETCH_RELATIVE:
// Fetch and display the requested data.
SQLFetchScroll(hstmt, Action, RowNum);
DisplayData(CustIDArray, CustIDIndArray,
NameArray, NameLenOrIndArray,
AddressArray, AddressLenOrIndArray,
PhoneArray, PhoneLenOrIndArray, RowStatusArray);
break;
case UPDATE_ROW:
// Place the new data in the rowset buffers and update the
// specified row.
GetNewData(&CustIDArray[RowNum - 1], &CustIDIndArray[RowNum - 1],
NameArray[RowNum - 1], &NameLenOrIndArray[RowNum - 1],
AddressArray[RowNum - 1], &AddressLenOrIndArray[RowNum - 1],
PhoneArray[RowNum - 1], &PhoneLenOrIndArray[RowNum - 1]);
SQLSetPos(hstmt, RowNum, SQL_UPDATE, SQL_LOCK_NO_CHANGE);
break;
case DELETE_ROW:
// Delete the specified row.
SQLSetPos(hstmt, RowNum, SQL_DELETE, SQL_LOCK_NO_CHANGE);
break;
case ADD_ROW:
// Place the new data in the rowset buffers at index 10.
// This is an extra element for new rows so rowset data is
// not overwritten. Insert the new row. Row 11 corresponds
// to index 10.
GetNewData(&CustIDArray[10], &CustIDIndArray[10],
NameArray[10], &NameLenOrIndArray[10],
AddressArray[10], &AddressLenOrIndArray[10],
PhoneArray[10], &PhoneLenOrIndArray[10]);
SQLSetPos(hstmt, 11, SQL_ADD, SQL_LOCK_NO_CHANGE);
break;
break;
}
}
The delete operation of SQLSetPos makes the data source delete one or more selected rows of a table. To
delete rows with SQLSetPos , the application calls SQLSetPos with Operation set to SQL_DELETE and
RowNumber set to the number of the row to delete. If RowNumber is 0, all rows in the rowset are deleted.
After SQLSetPos returns, the deleted row is the current row and its status is SQL_ROW_DELETED. The row
cannot be used in any further positioned operations, such as calls to SQLGetData or SQLSetPos .
When deleting all rows of the rowset (RowNumber is equal to 0), the application can prevent the driver from
deleting certain rows by using the row operation array, in the same way as for the update operation of
SQLSetPos . (See Updating Rows in the Rowset with SQLSetPos.)
Every row that is deleted should be a row that exists in the result set. If the application buffers were filled by
fetching and if a row status array has been maintained, its values at each of these row positions should not be
SQL_ROW_DELETED, SQL_ROW_ERROR, or SQL_ROW_NOROW.
Updating Data with SQLBulkOperations
4/27/2022 • 2 minutes to read • Edit Online
Applications can perform bulk update, delete, fetch, or insertion operations on the underlying table at the data
source with a call to SQLBulkOperations . Calling SQLBulkOperations is a convenient alternative to
constructing and executing an SQL statement. It lets an ODBC driver support positioned updates even when the
data source does not support positioned SQL statements. It is part of the paradigm of achieving complete
database access by means of function calls.
SQLBulkOperations operates on the current rowset and can be used only after a call to SQLFetch or
SQLFetchScroll . The application specifies the rows to update, delete, or refresh by caching their bookmarks.
The driver retrieves the new data for rows to be updated, or the new data to be inserted into the underlying
table, from the rowset buffers.
The rowset size to be used by SQLBulkOperations is set by a call to SQLSetStmtAttr with an Attribute
argument of SQL_ATTR_ROW_ARRAY_SIZE. Unlike SQLSetPos , which uses a new rowset size only after a call to
SQLFetch or SQLFetchScroll , SQLBulkOperations uses the new rowset size after the call to
SQLSetStmtAttr .
Because most interaction with relational databases is done through SQL, SQLBulkOperations is not widely
supported. However, a driver can easily emulate it by constructing and executing an UPDATE , DELETE , or
INSERT statement.
To determine what operations SQLBulkOperation supports, an application calls SQLGetInfo with the
SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1,
SQL_KEYSET_CURSOR_ATTRIBUTES1, or SQL_STATIC_CURSOR_ATTRIBUTES1 information option (depending on
the type of the cursor).
This section contains the following topics.
Updating Rows by Bookmark with SQLBulkOperations
Deleting Rows by Bookmark with SQLBulkOperations
Inserting Rows with SQLBulkOperations
Fetching Rows with SQLBulkOperations
Updating Rows by Bookmark with
SQLBulkOperations
4/27/2022 • 2 minutes to read • Edit Online
When updating a row by bookmark, SQLBulkOperations makes the data source update one or more rows of
the table. The rows are identified by the bookmark in a bound bookmark column. The row is updated using data
in the application buffers for each bound column (except when the value in the length/indicator buffer for a
column is SQL_COLUMN_IGNORE). Unbound columns will not be updated.
To update rows by bookmark with SQLBulkOperations , the application:
1. Retrieves and caches the bookmarks of all rows to be updated. If there is more than one bookmark and
column-wise binding is used, the bookmarks are stored in an array; if there is more than one bookmark
and row-wise binding is used, the bookmarks are stored in an array of row structures.
2. Sets the SQL_ATTR_ROW_ARRAY_SIZE statement attribute to the number of bookmarks and binds the
buffer containing the bookmark value, or the array of bookmarks, to column 0.
3. Places the new data values in the rowset buffers. For information on how to send long data with
SQLBulkOperations , see Long Data and SQLSetPos and SQLBulkOperations.
4. Sets the value in the length/indicator buffer of each column as necessary. This is the byte length of the
data or SQL_NTS for columns bound to string buffers, the byte length of the data for columns bound to
binary buffers, and SQL_NULL_DATA for any columns to be set to NULL.
5. Sets the value in the length/indicator buffer of those columns that are not to be updated to
SQL_COLUMN_IGNORE. Although the application can skip this step and resend existing data, this is
inefficient and risks sending values to the data source that were truncated when they were read.
6. Calls SQLBulkOperations with the Operation argument set to SQL_UPDATE_BY_BOOKMARK.
For every row that is sent to the data source as an update, the application buffers should have valid row data. If
the application buffers were filled by fetching, if a row status array has been maintained, and if the status value
for a row is SQL_ROW_DELETED, SQL_ROW_ERROR, or SQL_ROW_NOROW, invalid data could inadvertently be
sent to the data source.
Deleting Rows by Bookmark with
SQLBulkOperations
4/27/2022 • 2 minutes to read • Edit Online
When deleting a row by bookmark, SQLBulkOperations makes the data source delete one or more selected
rows of the table. The rows are identified by the bookmark in a bound bookmark column.
To delete rows by bookmark with SQLBulkOperations , the application does the following:
1. Retrieves and caches the bookmarks of all rows to be deleted. If there is more than one bookmark and
column-wise binding is used, the bookmarks are stored in an array; if there is more than one bookmark
and row-wise binding is used, the bookmarks are stored in an array of row structures.
2. Sets the SQL_ATTR_ROW_ARRAY_SIZE statement attribute to the number of bookmarks and binds the
buffer containing the bookmark value, or the array of bookmarks, to column 0.
3. Calls SQLBulkOperations with Operation set to SQL_DELETE_BY_BOOKMARK.
Inserting Rows with SQLBulkOperations
4/27/2022 • 2 minutes to read • Edit Online
Inserting data with SQLBulkOperations is similar to updating data with SQLBulkOperations because it uses
data from the bound application buffers.
So that each column in the new row has a value, all bound columns with a length/indicator value of
SQL_COLUMN_IGNORE and all unbound columns must either accept NULL values or have a default.
To insert rows with SQLBulkOperations , the application does the following:
1. Sets the SQL_ATTR_ROW_ARRAY_SIZE statement attribute to the number of rows to insert and places the
new data values in the bound application buffers. For information on how to send long data with
SQLBulkOperations , see Long Data and SQLSetPos and SQLBulkOperations.
2. Sets the value in the length/indicator buffer of each column as necessary. This is the byte length of the
data or SQL_NTS for columns bound to string buffers, the byte length of the data for columns bound to
binary buffers, and SQL_NULL_DATA for any columns to be set to NULL. The application sets the value in
the length/indicator buffer of those columns that are to be set to their default (if one exists) or NULL (if
one does not) to SQL_COLUMN_IGNORE.
3. Calls SQLBulkOperations with the Operation argument set to SQL_ADD.
After SQLBulkOperations returns, the current row is unchanged. If the bookmark column (column 0) is bound,
SQLBulkOperations returns the bookmarks of the inserted rows in the rowset buffer bound to that column.
Fetching Rows with SQLBulkOperations
4/27/2022 • 2 minutes to read • Edit Online
Data can be refetched into a rowset using bookmarks by a call to SQLBulkOperations. The rows to be fetched
are identified by the bookmarks in a bound bookmark column. Columns with a value of SQL_COLUMN_IGNORE
are not fetched.
To perform bulk fetches with SQLBulkOperations , the application does the following:
1. Retrieves and caches the bookmarks of all rows to be updated. If there is more than one bookmark and
column-wise binding is used, the bookmarks are stored in an array; if there is more than one bookmark
and row-wise binding is used, the bookmarks are stored in an array of row structures.
2. Sets the SQL_ATTR_ROW_ARRAY_SIZE statement attribute to the number of rows to fetch and binds the
buffer containing the bookmark value, or the array of bookmarks, to column 0.
3. Sets the value in the length/indicator buffer of each column as necessary. This is the byte length of the
data or SQL_NTS for columns bound to string buffers, the byte length of the data for columns bound to
binary buffers, and SQL_NULL_DATA for any columns to be set to NULL. The application sets the value in
the length/indicator buffer of those columns that are to be set to their default (if one exists) or NULL (if
one does not) to SQL_COLUMN_IGNORE.
4. Calls SQLBulkOperations with the Operation argument set to SQL_FETCH_BY_BOOKMARK.
There is no need for the application to use the row operation array to prevent the operation to be performed on
certain columns. The application selects the rows it wants to fetch by copying only the bookmarks for those
rows into the bound bookmark array.
Long Data and SQLSetPos and SQLBulkOperations
4/27/2022 • 3 minutes to read • Edit Online
As is the case with parameters in SQL statements, long data can be sent when updating rows with
SQLBulkOperations or SQLSetPos or when inserting rows with SQLBulkOperations . The data is sent in
parts, with multiple calls to SQLPutData . Columns for which data is sent at execution time are known as data-
at-execution columns.
NOTE
An application actually can send any type of data at execution time with SQLPutData , although only character and
binary data can be sent in parts. However, if the data is small enough to fit in a single buffer, there is generally no reason
to use SQLPutData . It is much easier to bind the buffer and let the driver retrieve the data from the buffer.
Because long data columns typically are not bound, the application must bind the column before calling
SQLBulkOperations or SQLSetPos and unbind it after calling SQLBulkOperations or SQLSetPos . The
column must be bound because SQLBulkOperations or SQLSetPos operates only on bound columns and
must be unbound so that SQLGetData can be used to retrieve data from the column.
To send data at execution time, the application does the following:
1. Places a 32-bit value in the rowset buffer instead of a data value. This value will be returned to the
application later, so the application should set it to a meaningful value, such as the number of the column
or the handle of a file containing data.
2. Sets the value in the length/indicator buffer to the result of the SQL_LEN_DATA_AT_EXEC(length) macro.
This value indicates to the driver that the data for the parameter will be sent with SQLPutData . The
length value is used when sending long data to a data source that needs to know how many bytes of long
data will be sent so that it can preallocate space. To determine whether a data source requires this value,
the application calls SQLGetInfo with the SQL_NEED_LONG_DATA_LEN option. All drivers must support
this macro; if the data source does not require the byte length, the driver can ignore it.
3. Calls SQLBulkOperations or SQLSetPos . The driver discovers that a length/indicator buffer contains
the result of the SQL_LEN_DATA_AT_EXEC(length) macro and returns SQL_NEED_DATA as the return value
of the function.
4. Calls SQLParamData in response to the SQL_NEED_DATA return value. If long data needs to be sent,
SQLParamData returns SQL_NEED_DATA. In the buffer pointed to by the ValuePtrPtr argument, the
driver returns the unique value that the application placed in the rowset buffer. If there is more than one
data-at-execution column, the application uses this value to determine which column to send data for; the
driver is not required to request data for data-at-execution columns in any particular order.
5. Calls SQLPutData to send the column data to the driver. If the column data does not fit in a single buffer,
as is often the case with long data, the application calls SQLPutData repeatedly to send the data in parts;
it is up to the driver and data source to reassemble the data. If the application passes null-terminated
string data, the driver or data source must remove the null-termination character as part of the
reassembly process.
6. Calls SQLParamData again to indicate that it has sent all of the data for the column. If there are any
data-at-execution columns for which data has not been sent, the driver returns SQL_NEED_DATA and the
unique value for the next data-at-execution column; the application returns to step 5. If data has been sent
for all data-at-execution columns, the data for the row is sent to the data source. SQLParamData then
returns SQL_SUCCESS or SQL_SUCCESS_WITH_INFO and can return any SQLSTATE that
SQLBulkOperations or SQLSetPos can return.
After SQLBulkOperations or SQLSetPos returns SQL_NEED_DATA and before data has been completely sent
for the last data-at-execution column, the statement is in a Need Data state. In this state, the application can call
only SQLPutData , SQLParamData , SQLCancel , SQLGetDiagField , or SQLGetDiagRec ; all other functions
return SQLSTATE HY010 (Function sequence error). Calling SQLCancel cancels execution of the statement and
returns it to its previous state. For more information, see Appendix B: ODBC State Transition Tables.
Descriptors
4/27/2022 • 2 minutes to read • Edit Online
A descriptor handle refers to a data structure that holds information about either columns or dynamic
parameters.
ODBC functions that operate on column and parameter data implicitly set and retrieve descriptor fields. For
instance, when SQLBindCol is called to bind column data, it sets descriptor fields that completely describe the
binding. When SQLColAttribute is called to describe column data, it returns data stored in descriptor fields.
An application calling ODBC functions need not concern itself with descriptors. No database operation requires
that the application gain direct access to descriptors. However, for some applications, gaining direct access to
descriptors streamlines many operations. For example, direct access to descriptors provides a way to rebind
column data, which can be more efficient than calling SQLBindCol again.
NOTE
The physical representation of the descriptor is not defined. Applications gain direct access to a descriptor only by
manipulating its fields by calling ODBC functions with the descriptor handle.
B UF F ER T Y P E RO W S DY N A M IC PA RA M ET ERS
Application buffer Application row descriptor (ARD) Application parameter descriptor (APD)
For either the parameter or the row buffers, if the application specifies different data types in corresponding
records of the implementation and application descriptors, the driver performs data conversion when it uses the
descriptors. For example, it may convert numeric and datetime values to character-string format. (For valid
conversions, see Appendix D: Data Types.)
A descriptor can perform different roles. Different statements can share any descriptor that the application
explicitly allocates. A row descriptor in one statement can serve as a parameter descriptor in another statement.
It is always known whether a given descriptor is an application descriptor or an implementation descriptor, even
if the descriptor has not yet been used in a database operation. For the descriptors that the implementation
implicitly allocates, the implementation records the predefined row relative to the statement handle. Any
descriptor that the application allocates by calling SQL AllocHandle is an application descriptor.
Descriptor Fields
4/27/2022 • 2 minutes to read • Edit Online
Descriptors contain header and record fields that completely describe columns or parameters.
A descriptor contains a single copy of the following header fields. Changing a header field affects all columns or
parameters.
SQL_DESC_ALLOC_TYPE
SQL_DESC_ARRAY_SIZE
SQL_DESC_ARRAY_STATUS_PTR
SQL_DESC_BIND_OFFSET_PTR
SQL_DESC_BIND_TYPE
SQL_DESC_COUNT
SQL_DESC_ROWS_PROCESSED_PTR
A descriptor contains zero or more descriptor records. Each record describes a column or parameter, depending
on the type of descriptor. When a new column or parameter is bound, a new record is added to the descriptor.
When a column or parameter is unbound, a record is removed from the descriptor. Each record contains a single
copy of the following fields:
SQL_DESC_AUTO_UNIQUE_VALUE
SQL_DESC_BASE_COLUMN_NAME
SQL_DESC_BASE_TABLE_NAME
SQL_DESC_CASE_SENSITIVE
SQL_DESC_CATALOG_NAME
SQL_DESC_CONCISE_TYPE
SQL_DESC_DATA_PTR
SQL_DESC_DATETIME_INTERVAL_CODE
SQL_DESC_DATETIME_INTERVAL_PRECISION
SQL_DESC_DISPLAY_SIZE
SQL_DESC_FIXED_PREC_SCALE
SQL_DESC_INDICATOR_PTR
SQL_DESC_LABEL
SQL_DESC_LENGTH
SQL_DESC_LITERAL_PREFIX
SQL_DESC_LITERAL_SUFFIX
SQL_DESC_LOCAL_TYPE_NAME
SQL_DESC_NAME
SQL_DESC_NULLABLE
SQL_DESC_OCTET_LENGTH
SQL_DESC_OCTET_LENGTH_PTR
SQL_DESC_PARAMETER_TYPE
SQL_DESC_PRECISION
SQL_DESC_SCALE
SQL_DESC_SCHEMA_NAME
SQL_DESC_SEARCHABLE
SQL_DESC_TABLE_NAME
SQL_DESC_TYPE
SQL_DESC_TYPE_NAME
SQL_DESC_UNNAMED
SQL_DESC_UNSIGNED
SQL_DESC_UPDATABLE
Many statement attributes correspond to the header field of a descriptor. Setting these attributes through a call
to SQLSetStmtAttr and setting the corresponding descriptor header field by calling SQLSetDescField have
the same effect. The same is true for SQLGetStmtAttr and SQLGetDescField , both of which retrieve the same
information. Calling the statement functions instead of the descriptor functions has the advantage that a
descriptor handle does not have to be retrieved.
The following header fields can be set by setting statement attributes:
SQL_DESC_ARRAY_SIZE
SQL_DESC_ARRAY_STATUS_PTR
SQL_DESC_BIND_OFFSET_PTR
SQL_DESC_BIND_TYPE
SQL_DESC_ROWS_PROCESSED_PTR
This section contains the following topics.
Record Count
Bound Descriptor Records
Deferred Fields
Consistency Check
Record Count
4/27/2022 • 2 minutes to read • Edit Online
The SQL_DESC_COUNT header field of a descriptor is the one-based index of the highest-numbered record that
contains data. This field is not a count of all columns or parameters that are bound. When a descriptor is
allocated, the initial value of SQL_DESC_COUNT is 0.
The driver takes any action necessary to allocate and maintain whatever storage it requires to hold descriptor
information. The application does not explicitly specify the size of a descriptor nor allocate new records. When
the application provides information for a descriptor record whose number is higher than the value of
SQL_DESC_COUNT, the driver automatically increases SQL_DESC_COUNT. When the application unbinds the
highest-numbered descriptor record, the driver automatically decreases SQL_DESC_COUNT to contain the
number of the highest remaining bound record.
Bound Descriptor Records
4/27/2022 • 2 minutes to read • Edit Online
When the application sets the SQL_DESC_DATA_PTR field of a descriptor record so that it no longer contains a
null value, the record is said to be bound.
If the descriptor is an APD, each bound record constitutes a bound parameter. For input parameters, the
application must bind a parameter for each dynamic parameter marker in the SQL statement before executing
the statement. For output parameters, the application need not bind the parameter.
If the descriptor is an ARD, which describes a row of database data, each bound record constitutes a bound
column.
Deferred Fields
4/27/2022 • 2 minutes to read • Edit Online
The values of deferred fields are not used when they are set, but the driver saves the addresses of the variables
for a deferred effect. For an application parameter descriptor, the driver uses the contents of the variables at the
time of the call to SQLExecDirect or SQLExecute . For an application row descriptor, the driver uses the
contents of the variables at the time of the fetch.
The following are deferred fields:
The SQL_DESC_DATA_PTR and SQL_DESC_INDICATOR_PTR fields of a descriptor record.
The SQL_DESC_OCTET_LENGTH_PTR field of an application descriptor record.
In the case of a multirow fetch, the SQL_DESC_ARRAY_STATUS_PTR and
SQL_DESC_ROWS_PROCESSED_PTR fields of a descriptor header.
When a descriptor is allocated, the deferred fields of each descriptor record initially have a null value. The
meaning of the null value is as follows:
If SQL_DESC_ARRAY_STATUS_PTR has a null value, a multirow fetch fails to return this component of the
per-row diagnostic information.
If SQL_DESC_DATA_PTR has a null value, the record is unbound.
If the SQL_DESC_OCTET_LENGTH_PTR field of an ARD has a null value, the driver does not return length
information for that column.
If the SQL_DESC_OCTET_LENGTH_PTR field of an APD has a null value and the parameter is a character
string, the driver assumes that string is null-terminated. For output dynamic parameters, a null value in
this field prevents the driver from returning length information. (If the SQL_DESC_TYPE field does not
indicate a character-string parameter, the SQL_DESC_OCTET_LENGTH_PTR field is ignored.)
The application must not deallocate or discard variables used for deferred fields between the time it associates
them with the fields and the time the driver reads or writes them.
Consistency Check
4/27/2022 • 2 minutes to read • Edit Online
A consistency check is performed by the driver automatically whenever an application sets the
SQL_DESC_DATA_PTR field of the APD, ARD, or IPD. Whenever this field is set, the driver checks that the value of
the SQL_DESC_TYPE field and the values applicable to the SQL_DESC_TYPE field in the same record are valid
and consistent.
The SQL_DESC_DATA_PTR field of an IPD is not normally set; however, an application can do so to force a
consistency check of IPD fields. The value that the SQL_DESC_DATA_PTR field of the IPD is set to is not actually
stored and cannot be retrieved by a call to SQLGetDescField or SQLGetDescRec ; the setting is made only to
force the consistency check. A consistency check cannot be performed on an IRD.
For more information on the consistency check, see SQLSetDescRec.
Allocating and Freeing Descriptors
4/27/2022 • 2 minutes to read • Edit Online
Descriptors are either implicitly or explicitly allocated, as described in the following sections.
Implicitly Allocated Descriptors
Explicitly Allocated Descriptors
Initialization of Descriptor Fields
Automatic Population of the IPD
Freeing Descriptors
Implicitly Allocated Descriptors
4/27/2022 • 2 minutes to read • Edit Online
When a statement handle is allocated, the application implicitly allocates one set of four descriptors. The
application can obtain the handles of these implicitly allocated descriptors as attributes of the statement handle.
When the application frees the statement handle, the driver frees all implicitly allocated descriptors on that
handle.
Explicitly Allocated Descriptors
4/27/2022 • 2 minutes to read • Edit Online
An application can explicitly allocate an application descriptor on a connection at any time it is connected to the
database. By specifying that descriptor handle as an attribute of a statement handle using SQLSetStmtAttr , the
application directs the driver to use that descriptor in place of the corresponding implicitly allocated application
descriptors. The application cannot specify alternate implementation descriptors.
An application can associate an explicitly allocated descriptor with more than one statement. Only when an
application is actually connected to the database can a descriptor be an explicitly allocated descriptor. The
application can free such a descriptor explicitly, or implicitly by freeing its connection.
Initialization of Descriptor Fields
4/27/2022 • 2 minutes to read • Edit Online
When an application row descriptor is allocated, its fields receive initial values as indicated in SQLSetDescField.
The initial value of the SQL_DESC_TYPE field is SQL_DEFAULT. This provides for a standard treatment of
database data for presentation to the application. The application may specify different treatment of the data by
setting fields of the descriptor record.
The initial value of SQL_DESC_ARRAY_SIZE in the descriptor header is 1. The application can modify this field to
enable multirow fetch.
The concept of a default value is not valid for the fields of an IRD. An application can gain access to the fields of
an IRD only when there is a prepared or executed statement associated with it.
Certain fields of an IPD are defined only after the IPD has been automatically populated by the driver. If not, they
are undefined. These fields are SQL_DESC_CASE_SENSITIVE, SQL_DESC_FIXED_PREC_SCALE,
SQL_DESC_TYPE_NAME, SQL_DESC_UNSIGNED, and SQL_DESC_LOCAL_TYPE_NAME.
Automatic Population of the IPD
4/27/2022 • 2 minutes to read • Edit Online
Some drivers are capable of setting the fields of the IPD after a parameterized query has been prepared. The
descriptor fields are automatically populated with information about the parameter, including the data type,
precision, scale, and other characteristics. This is equivalent to supporting SQLDescribeParam . This
information can be particularly valuable to an application when it has no other way to discover it, such as when
an ad hoc query is performed with parameters that the application does not know about.
An application determines whether the driver supports automatic population by calling SQLGetConnectAttr
with an Attribute of SQL_ATTR_AUTO_IPD. If SQL_TRUE is returned, the driver supports it and the application can
enable it by setting the SQL_ATTR_ENABLE_AUTO_IPD statement attribute to SQL_TRUE.
When automatic population is supported and enabled, the driver populates the fields of the IPD after an SQL
statement containing parameter markers has been prepared by a call to SQLPrepare . An application can
retrieve this information by calling SQLGetDescField or SQLGetDescRec , or SQLDescribeParam . The
application can use the information to bind the most appropriate application buffer for a parameter or to specify
a data conversion for it.
Automatic population of the IPD might produce a performance penalty. An application can turn it off by
resetting the SQL_ATTR_ENABLE_AUTO_IPD statement attribute to SQL_FALSE (the default value).
Freeing Descriptors
4/27/2022 • 2 minutes to read • Edit Online
Explicitly allocated descriptors can be freed either explicitly, by calling SQLFreeHandle with HandleType of
SQL_HANDLE_DESC, or implicitly, when the connection handle is freed. When an explicitly allocated descriptor is
freed, all statement handles to which the freed descriptor applied automatically revert to the descriptors
implicitly allocated for them.
Implicitly allocated descriptors can be freed only by calling SQLDisconnect , which drops any statements or
descriptors open on the connection, or by calling SQLFreeHandle with a HandleType of SQL_HANDLE_STMT to
free a statement handle and all the implicitly allocated descriptors associated with the statement. An implicitly
allocated descriptor cannot be freed by calling SQLFreeHandle with a HandleType of SQL_HANDLE_DESC.
Even when freed, an implicitly allocated descriptor remains valid, and SQLGetDescField can be called on its
fields.
Getting and Setting Descriptor Fields
4/27/2022 • 2 minutes to read • Edit Online
This section describes the methods an application can use to retrieve or set the values in descriptor fields.
This section contains the following topics.
Obtaining Descriptor Handles
Retrieving the Values in Descriptor Fields
Setting Descriptor Fields
Copying Descriptors
Using Concise Functions
Obtaining Descriptor Handles
4/27/2022 • 2 minutes to read • Edit Online
An application obtains the handle of any explicitly allocated descriptor as an output argument of the call to
SQL AllocHandle . The handle of an implicitly allocated descriptor is obtained by calling SQLGetStmtAttr .
Retrieving the Values in Descriptor Fields
4/27/2022 • 2 minutes to read • Edit Online
An application can call SQLGetDescField to obtain a single field of a descriptor record. SQLGetDescField
gives the application access to all the descriptor fields defined in ODBC, and to driver-defined fields as well.
SQLGetDescRec can be called to retrieve the settings of multiple descriptor fields that affect the data type and
storage of column or parameter data.
Setting Descriptor Fields
4/27/2022 • 2 minutes to read • Edit Online
To modify the fields of a descriptor, an application can call SQLSetDescField . Some fields are read-only and
cannot be set. (See the SQLSetDescField function description.)
Descriptor record fields are set with a record number (RecNumber) of 1 or higher, while descriptor header fields
are set with a record number of 0. A record number of 0 is also used to set bookmark fields, in accordance with
the convention that bookmarks are contained in column 0. This might leave the impression that bookmark fields
are contained within the descriptor header, but this is not the case. Bookmark fields are distinct from header
fields.
When setting fields individually, the application should follow the sequence defined in SQLSetDescField. Setting
some fields causes the driver to set other fields. This ensures that the descriptor is always ready to use once the
application has specified a data type. When the application sets the SQL_DESC_TYPE field, the driver checks that
other fields that specify the type are valid and consistent.
If a function call that would set a descriptor field fails, the contents of the descriptor field are undefined after the
failed function call.
Copying Descriptors
4/27/2022 • 2 minutes to read • Edit Online
The SQLCopyDesc function is called to copy the fields of one descriptor to another descriptor. Fields can be
copied only to an application descriptor or an IPD, but not to an IRD. Fields can be copied from any type of
descriptor. Only those fields that are defined for both the source and target descriptors are copied.
SQLCopyDesc does not copy the SQL_DESC_ALLOC_TYPE field, because a descriptor's allocation type cannot
be changed. Copied fields overwrite the existing fields.
An ARD on one statement handle can serve as the APD on another statement handle. This allows an application
to copy rows between tables without copying data at the application level. To do this, a row descriptor that
describes a fetched row of a table is reused as a parameter descriptor for a parameter in an INSERT statement.
The SQL_MAX_CONCURRENT_ACTIVITIES information type must be greater than 1 for this operation to
succeed.
Using Concise Functions
4/27/2022 • 2 minutes to read • Edit Online
Some ODBC functions gain implicit access to descriptors. Application writers may find them more convenient
than calling SQLSetDescField or SQLGetDescField . These functions are called concise functions because they
perform a number of functions, including setting or getting descriptor fields. Some concise functions let an
application set or retrieve several related descriptor fields in a single function call.
Concise functions can be called without first retrieving a descriptor handle for use as an argument. These
functions work with the descriptor fields associated with the statement handle that they are called on.
The concise functions SQLBindCol and SQLBindParameter bind a column or parameter by setting the
descriptor fields that correspond to their arguments. Each of these functions performs more tasks than simply
setting descriptors. SQLBindCol and SQLBindParameter provide a complete specification of the binding of a
data column or dynamic parameter. An application can, however, change individual details of a binding by
calling SQLSetDescField or SQLSetDescRec and can completely bind a column or parameter by making a
series of suitable calls to these functions.
The concise functions SQLColAttribute , SQLDescribeCol , SQLDescribeParam , SQLNumParams , and
SQLNumResultCols retrieve values in descriptor fields.
SQLSetDescRec and SQLGetDescRec are concise functions that, with one call, set or get multiple descriptor
fields that affect the data type and storage of column or parameter data. SQLSetDescRec is an effective way to
change the binding of column or parameter data in one step.
SQLSetStmtAttr and SQLGetStmtAttr serve as concise functions in some cases. (See Descriptor Fields.)
Transactions ODBC
4/27/2022 • 2 minutes to read • Edit Online
A transaction is a unit of work that is done as a single,atomic operation; that is, the operation succeeds or fails as
a whole. For example, consider transferring money from one bank account to another. This involves two steps:
withdrawing the money from the first account and depositing it in the second. It is important that both steps
succeed; it is not acceptable for one step to succeed and the other to fail. A database that supports transactions
is able to guarantee this.
Transactions can be completed by either being committed or being rolled back. When a transaction is
committed, the changes made in that transaction are made permanent. When a transaction is rolled back, the
affected rows are returned to the state they were in before the transaction was started. To extend the account
transfer example, an application executes one SQL statement to debit the first account and a different SQL
statement to credit the second account. If both statements succeed, the application then commits the
transaction. But if either statement fails for any reason, the application rolls back the transaction. In either case,
the application guarantees a consistent state at the end of the transaction.
A single transaction can encompass multiple database operations that occur at different times. If other
transactions had complete access to the intermediate results, the transactions might interfere with one another.
For example, suppose one transaction inserts a row, a second transaction reads that row, and the first
transaction is rolled back. The second transaction now has data for a row that does not exist.
To solve this problem, there are various schemes to isolate transactions from one another. Transaction isolation
is generally implemented by locking rows, which precludes more than one transaction from using the same row
at the same time. In some databases, locking a row may also lock other rows.
With increased transaction isolation comes reduced concurrency, or the ability of two transactions to use the
same data at the same time. For more information, see Setting the Transaction Isolation Level.
This section contains the following topics.
Transactions in ODBC
Transaction Isolation
Concurrency Control
Transactions in ODBC ODBC
4/27/2022 • 2 minutes to read • Edit Online
Transactions in ODBC are completed at the connection level; that is, when an application completes a
transaction, it commits or rolls back all work done through all statement handles on that connection.
This section contains the following topics.
Transaction Support
Commit Mode
Committing and Rolling Back Transactions
Effect of Transactions on Cursors and Prepared Statements
Transaction Support
4/27/2022 • 2 minutes to read • Edit Online
The degree of support for transactions is driver-defined. ODBC is designed to be implemented on a single-user
or desktop database that has no need to manage multiple updates to its data. Moreover, some databases that
support transactions do so only for the Data Manipulation Language (DML) statements of SQL; there are
restrictions or special transaction semantics regarding the use of Data Definition Language (DDL) when a
transaction is active. That is, there may be transaction support for multiple simultaneous updates to tables but
not for changing the number and definition of tables during a transaction.
An application determines whether transactions are supported, whether DDL can be included in a transaction,
and any special effects of including DDL in a transaction, by calling SQLGetInfo with the SQL_TXN_CAPABLE
option. For more information, see the SQLGetInfo function description.
If the driver does not support transactions but the application has the ability (using an API other than ODBC) to
lock and unlock data, applications can achieve transaction support by locking and unlocking records and tables
as needed. To implement the account-transfer example, the application would lock the records for both accounts,
copy the current values, debit the first account, credit the second account, and unlock the records. If any steps
failed, the application would reset the accounts using the copies.
Even data sources that support transactions might not be able to support more than one transaction at a time
within a particular environment. Applications call SQLGetInfo with the SQL_MULTIPLE_ACTIVE_TXN option to
determine whether a data source can support simultaneous active transactions on more than one connection in
the same environment. Because there is one transaction per connection, this is only interesting to applications
that have multiple connections to the same data source.
Commit Mode
4/27/2022 • 2 minutes to read • Edit Online
Transactions in ODBC can be in one of two modes: auto-commit mode or manual-commit mode.
This section contains the following topics.
Auto-Commit Mode
Manual-Commit Mode
Setting the Commit Mode
Auto-Commit Mode
4/27/2022 • 2 minutes to read • Edit Online
In auto-commit mode, every database operation is a transaction that is committed when performed. This mode
is suitable for many real-world transactions that consist of a single SQL statement. It is unnecessary to delimit or
specify completion of these transactions. In databases without transaction support, auto-commit mode is the
only supported mode. In such databases, statements are committed when they are executed and there is no way
to roll them back; they are therefore always in auto-commit mode.
If the underlying DBMS does not support auto-commit mode transactions, the driver can emulate them by
manually committing each SQL statement as it is executed.
If a batch of SQL statements is executed in auto-commit mode, it is data source-specific when the statements in
the batch are committed. They can be committed as they are executed or as a whole after the entire batch has
been executed. Some data sources may support both of these behaviors and may provide a way of selecting one
or the others. In particular, if an error occurs in the middle of the batch, it is data source-specific whether the
already-executed statements are committed or rolled back. Thus, interoperable applications that use batches
and require them to be committed or rolled back as a whole should execute batches only in manual-commit
mode.
Manual-Commit Mode
4/27/2022 • 2 minutes to read • Edit Online
In manual-commit mode, applications must explicitly complete transactions by calling SQLEndTran to commit
them or roll them back. This is the normal transaction mode for most relational databases.
Transactions in ODBC do not have to be explicitly initiated. Instead, a transaction begins implicitly whenever the
application starts operating on the database. If the data source requires explicit transaction initiation, the driver
must provide it whenever the application executes a statement requiring a transaction and there is no current
transaction.
Setting the Commit Mode
4/27/2022 • 2 minutes to read • Edit Online
Applications specify the transaction mode with the SQL_ATTR_AUTOCOMMIT connection attribute. By default,
ODBC transactions are in auto-commit mode (unless SQLSetConnectAttr and SQLSetConnectOption are
not supported, which is unlikely). Switching from manual-commit mode to auto-commit mode automatically
commits any open transaction on the connection.
Committing and Rolling Back Transactions
4/27/2022 • 2 minutes to read • Edit Online
To commit or roll back a transaction in manual-commit mode, an application calls SQLEndTran . Drivers for
DBMSs that support transactions typically implement this function by executing a COMMIT or ROLLBACK
statement. The Driver Manager does not call SQLEndTran when the connection is in auto-commit mode; it
simply returns SQL_SUCCESS, even if the application attempts to roll back the transaction. Because drivers for
DBMSs that do not support transactions are always in auto-commit mode, they can either implement
SQLEndTran to return SQL_SUCCESS without doing anything or not implement it at all.
NOTE
Applications should not commit or roll back transactions by executing COMMIT or ROLLBACK statements with
SQLExecute or SQLExecDirect . The effects of doing this are undefined. Possible problems include the driver no longer
knowing when a transaction is active and these statements failing against data sources that do not support transactions.
These applications should call SQLEndTran instead.
If an application passes the environment handle to SQLEndTran but does not pass a connection handle, the
Driver Manager conceptually calls SQLEndTran with the environment handle for each driver that has one or
more active connections in the environment. The driver then commits the transactions on each connection in the
environment. However, it is important to realize that neither the driver nor the Driver Manager performs a two-
phase commit on the connections in the environment; this is merely a programming convenience to
simultaneously call SQLEndTran for all connections in the environment.
(A two-phase commit is generally used to commit transactions that are spread across multiple data sources. In
its first phase, the data sources are polled as to whether they can commit their part of the transaction. In the
second phase, the transaction is actually committed on all data sources. If any data sources reply in the first
phase that they cannot commit the transaction, the second phase does not occur.)
Effect of Transactions on Cursors and Prepared
Statements
4/27/2022 • 2 minutes to read • Edit Online
Committing or rolling back a transaction has one of the following effects on cursors and access plans:
All cursors are closed, and access plans for prepared statements on that connection are deleted, or
All cursors are closed, and access plans for prepared statements on that connection remain intact, or
All cursors remain open, and access plans for prepared statements on that connection remain intact.
For example, suppose a data source exhibits the first behavior in this list, the most restrictive of these behaviors.
Now suppose an application does the following:
1. Sets the commit mode to manual-commit.
2. Creates a result set of sales orders on statement 1.
3. Creates a result set of the lines in a sales order on statement 2, when the user highlights that order.
4. Calls SQLExecute to execute a positioned update statement that has been prepared on statement 3,
when the user updates a line.
5. Calls SQLEndTran to commit the positioned update statement.
Because of the data source's behavior, the call to SQLEndTran in step 5 causes it to close the cursors on
statements 1 and 2 and to delete the access plan on all statements. The application must reexecute statements 1
and 2 to re-create the result sets and reprepare the statement on statement 3.
In auto-commit mode, functions other than SQLEndTran commit transactions:
SQLExecute or SQLExecDirect In the preceding example, the call to SQLExecute in step 4 commits a
transaction. This causes the data source to close the cursors on statements 1 and 2 and delete the access
plan on all statements on that connection.
SQLBulkOperations or SQLSetPos In the preceding example, suppose that in step 4 the application
calls SQLSetPos with the SQL_UPDATE option on statement 2, instead of executing a positioned update
statement on statement 3. This commits a transaction and causes the data source to close the cursors on
statements 1 and 2, and discards all access plans on that connection.
SQLCloseCursor In the preceding example, suppose that when the user highlights a different sales
order, the application calls SQLCloseCursor on statement 2 before creating a result of the lines for the
new sales order. The call to SQLCloseCursor commits the SELECT statement that created the result set
of lines and causes the data source to close the cursor on statement 1, and then discards all access plans
on that connection.
Applications, especially screen-based applications in which the user scrolls around the result set and updates or
deletes rows, must be careful to code around this behavior.
To determine how a data source behaves when a transaction is committed or rolled back, an application calls
SQLGetInfo with the SQL_CURSOR_COMMIT_BEHAVIOR and SQL_CURSOR_ROLLBACK_BEHAVIOR options.
Transaction Isolation
4/27/2022 • 2 minutes to read • Edit Online
Transaction isolation refers to the degree of interaction between multiple concurrent transactions. To see why
this is important, you'll need to first look at the idea of serializability.
This section contains the following topics.
Serializability
Transaction Isolation Levels
Setting the Transaction Isolation Level
Scrollable Cursors and Transaction Isolation
Serializability
4/27/2022 • 2 minutes to read • Edit Online
Ideally, transactions should be serializable. Transactions are said to be serializable if the results of running
transactions simultaneously are the same as the results of running them serially - that is, one after the other. It is
not important which transaction executes first, only that the result does not reflect any mixing of the
transactions.
For example, suppose transaction A multiplies data values by 2 and transaction B adds 1 to data values. Now
suppose that there are two data values: 0 and 10. If these transactions are run one after the other, the new values
will be 1 and 21 if transaction A is run first, or 2 and 22 if transaction B is run first. But what if the order in which
the two transactions are run is different for each value? If transaction A is run first on the first value and
transaction B is run first on the second value, the new values are 1 and 22. If this order is reversed, the new
values are 2 and 21. The transactions are serializable if 1, 21 and 2, 22 are the only possible results. The
transactions are not serializable if 1, 22 or 2, 21 is a possible result.
So why is serializability desirable? In other words, why is it important that it appears that one transaction
finishes before the next transaction starts? Consider the following problem. A salesman is entering orders at the
same time a clerk is sending out bills. Suppose the salesman enters an order from Company X but does not
commit it; the salesman is still talking to the representative from Company X. The clerk requests a list of all open
orders and discovers the order for Company X and sends them a bill. Now the representative from Company X
decides they want to change their order, so the salesman changes it before committing the transaction.
Company X gets an incorrect bill.
If the salesman's and clerk's transactions were serializable, this problem would never have occurred. Either the
salesman's transaction would have finished before the clerk's transaction started, in which case the clerk would
have sent out the correct bill, or the clerk's transaction would have finished before the salesman's transaction
started, in which case the clerk would not have sent a bill to Company X at all.
Transaction Isolation Levels (ODBC)
4/27/2022 • 4 minutes to read • Edit Online
Transaction isolation levels are a measure of the extent to which transaction isolation succeeds. In particular,
transaction isolation levels are defined by the presence or absence of the following phenomena:
Dir ty Reads A dirty read occurs when a transaction reads data that has not yet been committed. For
example, suppose transaction 1 updates a row. Transaction 2 reads the updated row before transaction 1
commits the update. If transaction 1 rolls back the change, transaction 2 will have read data that is
considered never to have existed.
Nonrepeatable Reads A nonrepeatable read occurs when a transaction reads the same row twice but
gets different data each time. For example, suppose transaction 1 reads a row. Transaction 2 updates or
deletes that row and commits the update or delete. If transaction 1 rereads the row, it retrieves different
row values or discovers that the row has been deleted.
Phantoms A phantom is a row that matches the search criteria but is not initially seen. For example,
suppose transaction 1 reads a set of rows that satisfy some search criteria. Transaction 2 generates a new
row (through either an update or an insert) that matches the search criteria for transaction 1. If
transaction 1 reexecutes the statement that reads the rows, it gets a different set of rows.
The four transaction isolation levels (as defined by SQL-92) are defined in terms of these phenomena. In the
following table, an "X" marks each phenomenon that can occur.
T RA N SA C T IO N ISO L AT IO N
L EVEL DIRT Y REA DS N O N REP EATA B L E REA DS P H A N TO M S
Read uncommitted X X X
Read committed -- X X
Repeatable read -- -- X
Serializable -- -- --
The following table describes simple ways that a DBMS might implement the transaction isolation levels.
IMPORTANT
Most DBMSs use more complex schemes than these to increase concurrency. These examples are provided for illustration
purposes only. In particular, ODBC does not prescribe how particular DBMSs isolate transactions from each other.
Read uncommitted Transactions are not isolated from each other. If the DBMS
supports other transaction isolation levels, it ignores
whatever mechanism it uses to implement those levels. So
that they do not adversely affect other transactions,
transactions running at the Read Uncommitted level are
usually read-only.
T RA N SA C T IO N ISO L AT IO N P O SSIB L E IM P L EM EN TAT IO N
The transaction holds a read lock (if it only reads the row) or
write lock (if it updates or deletes the row) on the current
row to prevent other transactions from updating or deleting
it. The transaction releases read locks when it moves off the
current row. It holds write locks until it is committed or rolled
back.
It is important to note that the transaction isolation level does not affect a transaction's ability to see its own
changes; transactions can always see any changes they make. For example, a transaction might consist of two
UPDATE statements, the first of which raises the pay of all employees by 10 percent and the second of which
sets the pay of any employees over some maximum amount to that amount. This succeeds as a single
transaction only because the second UPDATE statement can see the results of the first.
Setting the Transaction Isolation Level
4/27/2022 • 2 minutes to read • Edit Online
To set the transaction isolation level, an application uses the SQL_ATTR_TXN_ISOLATION connection attribute. If
the data source does not support the requested isolation level, the driver or data source can set a higher level. To
determine what transaction isolation levels a data source supports and what the default isolation level is, an
application calls SQLGetInfo with the SQL_TXN_ISOLATION_OPTION and SQL_DEFAULT_TXN_ISOLATION
options, respectively.
Higher levels of transaction isolation offer the most protection for the integrity of database data. Serializable
transactions are guaranteed to be unaffected by other transactions and therefore guaranteed to maintain
database integrity.
However, a higher level of transaction isolation can cause slower performance because it increases the chances
that the application will have to wait for locks on data to be released. An application can specify a lower level of
isolation to increase performance in the following cases:
When it can be guaranteed that no other transactions exist that might interfere with an application's
transactions. This situation occurs only in limited circumstances, such as when one person in a small
company maintains dBASE files that contain personnel data on one computer and does not share these
files.
When speed is more critical than accuracy and any errors are likely to be small. For example, suppose
that a company makes many small sales and that large sales are rare. A transaction that estimates the
total value of all open sales might safely use the Read Uncommitted isolation level. Although the
transaction would include orders that are being opened or closed and are subsequently rolled back, these
would generally cancel each other out and the transaction would be much faster because it is not blocked
every time that it encounters such an order.
For more information, see Optimistic Concurrency.
Scrollable Cursors and Transaction Isolation
4/27/2022 • 2 minutes to read • Edit Online
The following table lists the factors governing the visibility of changes.
The following table summarizes the ability of each cursor type to detect changes made by itself, by other
operations in its own transaction, and by other transactions. The visibility of the latter changes depends on the
cursor type and the isolation level of the transaction containing the cursor.
OT H R OT H R OT H R OT H R
C URSO R OWN T XN T XN T XN T XN
T Y P E\ A C T IO
N SEL F T XN ( RU[ A ] ) ( RC [ A ] ) ( RR[ A ] ) ( S[ A ] )
Static
Insert Maybe[b] No No No No No
Update Maybe[b] No No No No No
Delete Maybe[b] No No No No No
Keyset-driven
Insert Maybe[b] No No No No No
C URSO R OWN T XN T XN T XN T XN
T Y P E\ A C T IO
N SEL F T XN ( RU[ A ] ) ( RC [ A ] ) ( RR[ A ] ) ( S[ A ] )
Dynamic
[a] The letters in parentheses indicate the isolation level of the transaction containing the cursor; the isolation
level of the other transaction (in which the change was made) is irrelevant.
RU: Read uncommitted
RC: Read committed
RR: Repeatable read
S: Serializable
[b] Depends on how the cursor is implemented. Whether the cursor can detect such changes is reported
through the SQL_STATIC_SENSITIVITY option in SQLGetInfo .
Concurrency Control
4/27/2022 • 2 minutes to read • Edit Online
Concurrency is the ability of two transactions to use the same data at the same time, and with increased
transaction isolation usually comes reduced concurrency. This is because transaction isolation is usually
implemented by locking rows, and as more rows are locked, fewer transactions can be completed without being
blocked at least temporarily by a locked row. While reduced concurrency is generally accepted as a trade-off for
the higher transaction isolation levels necessary to maintain database integrity, it can become a problem in
interactive applications with high read/write activity that use cursors.
For example, suppose an application executes the SQL statement SELECT * FROM Orders . It calls
SQLFetchScroll to scroll around the result set and allows the user to update, delete, or insert orders. After the
user updates, deletes, or inserts an order, the application commits the transaction.
If the isolation level is Repeatable Read, the transaction might - depending on how it is implemented - lock each
row returned by SQLFetchScroll . If the isolation level is Serializable, the transaction might lock the entire
Orders table. In either case, the transaction releases its locks only when it is committed or rolled back. So if the
user spends a lot of time reading orders and very little time updating, deleting, or inserting them, the
transaction could easily lock a large number of rows, making them unavailable to other users.
This is a problem even if the cursor is read-only and the application allows the user to read only existing orders.
In this case, the application commits the transaction, and releases locks, when it calls SQLCloseCursor (in auto-
commit mode) or SQLEndTran (in manual-commit mode).
This section contains the following topics.
Concurrency Types
Optimistic Concurrency
Concurrency Types
4/27/2022 • 2 minutes to read • Edit Online
To solve the problem of reduced concurrency in cursors, ODBC exposes four different types of cursor
concurrency:
Read-only The cursor can read data but cannot update or delete data. This is the default concurrency
type. Although the DBMS might lock rows to enforce the Repeatable Read and Serializable isolation
levels, it can use read locks instead of write locks. This results in higher concurrency because other
transactions can at least read the data.
Locking The cursor uses the lowest level of locking necessary to make sure it can update or delete rows
in the result set. This usually results in very low concurrency levels, especially at the Repeatable Read and
Serializable transaction isolation levels.
Optimistic concurrency using row versions and optimistic concurrency using values The
cursor uses optimistic concurrency: It updates or deletes rows only if they have not changed since they
were last read. To detect changes, it compares row versions or values. There is no guarantee that the
cursor will be able to update or delete a row, but concurrency is much higher than when locking is used.
For more information, see the following section, Optimistic Concurrency.
An application specifies what type of concurrency it wants the cursor to use with the SQL_ATTR_CONCURRENCY
statement attribute. To determine what types are supported, it calls SQLGetInfo with the
SQL_SCROLL_CONCURRENCY option.
Optimistic Concurrency
4/27/2022 • 2 minutes to read • Edit Online
Optimistic concurrency derives its name from the optimistic assumption that collisions between transactions
will rarely occur; a collision is said to have occurred when another transaction updates or deletes a row of data
between the time it is read by the current transaction and the time it is updated or deleted. It is the opposite of
pessimistic concurrency, or locking, in which the application developer believes that such collisions are
commonplace.
In optimistic concurrency, a row is left unlocked until the time comes to update or delete it. At that point, the row
is reread and checked to see if it has been changed since it was last read. If the row has changed, the update or
delete fails and must be tried again.
To determine whether a row has been changed, its new version is checked against a cached version of the row.
This checking can be based on the row version, such as the timestamp column in SQL Server, or the values of
each column in the row. Many DBMSs do not support row versions.
Optimistic concurrency can be implemented by the data source or the application. In either case, the application
should use a low transaction isolation level such as Read Committed; using a higher level negates the increased
concurrency gained by using optimistic concurrency.
If optimistic concurrency is implemented by the data source, the application sets the SQL_ATTR_CONCURRENCY
statement attribute to SQL_CONCUR_ROWVER or SQL_CONCUR_VALUES. To update or delete a row, it executes
a positioned update or delete statement or calls SQLSetPos just as it would with pessimistic concurrency; the
driver or data source returns SQLSTATE 01001 (Cursor operation conflict) if the update or delete fails due to a
collision.
If the application itself implements optimistic concurrency, it sets the SQL_ATTR_CONCURRENCY statement
attribute to SQL_CONCUR_READ_ONLY to read a row. If it will compare row versions and does not know the
row version column, it calls SQLSpecialColumns with the SQL_ROWVER option to determine the name of this
column.
The application updates or deletes the row by increasing the concurrency to SQL_CONCUR_LOCK (to gain write
access to the row) and executing an UPDATE or DELETE statement with a WHERE clause that specifies the
version or values the row had when the application read it. If the row has changed since then, the statement will
fail. If the WHERE clause does not uniquely identify the row, the statement might also update or delete other
rows; row versions always uniquely identify rows, but row values uniquely identify rows only if they include the
primary key.
Diagnostics
4/27/2022 • 2 minutes to read • Edit Online
Functions in ODBC return diagnostic information in two ways. The return code indicates the overall success or
failure of the function, while diagnostic records provide detailed information about the function. At least one
diagnostic record - the header record - is returned even if the function succeeds.
Diagnostic information is used at development time to catch programming errors such as invalid handles and
syntax errors in hard-coded SQL statements. It is used at run time to catch run-time errors and warnings such as
data truncation, access violations, and syntax errors in SQL statements entered by the user.
This section contains the following topics.
Return Codes
Diagnostic Records
Using SQLGetDiagRec and SQLGetDiagField
Implementing SQLGetDiagRec and SQLGetDiagField
Diagnostic Handling Examples
Return Codes ODBC
4/27/2022 • 2 minutes to read • Edit Online
Each function in ODBC returns a code, known as its return code, which indicates the overall success or failure of
the function. Program logic is generally based on return codes.
For example, the following code calls SQLFetch to retrieve the rows in a result set. It checks the return code of
the function to determine if the end of the result set was reached (SQL_NO_DATA), if any warning information
was returned (SQL_SUCCESS_WITH_INFO), or if an error occurred (SQL_ERROR).
SQLRETURN rc;
SQLHSTMT hstmt;
The return code SQL_INVALID_HANDLE always indicates a programming error and should never be
encountered at run time. All other return codes provide run-time information, although SQL_ERROR may
indicate a programming error.
The following table defines the return codes.
Associated with each environment, connection, statement, and descriptor handle are diagnostic records. These
records contain diagnostic information about the last function called that used a particular handle. The records
are replaced only when another function is called using that handle. There is no limit to the number of
diagnostic records that can be stored at any one time.
There are two types of diagnostic records: a header record and zero or more status records. The header record is
record 0; the status records are records 1 and above. Diagnostic records are composed of a number of separate
fields, which are different for the header record and the status records. In addition, ODBC components can
define their own diagnostic record fields.
Although diagnostic records can be thought of as structures, there is no requirement for them to actually be
structures; how a driver stores the diagnostic information is driver-specific.
Fields in diagnostic records are retrieved with SQLGetDiagField . The SQLSTATE, native error number, and
diagnostic message fields of status records can be retrieved in a single call with SQLGetDiagRec .
This section contains the following topics.
Header Record
Status Records
Header Record
4/27/2022 • 2 minutes to read • Edit Online
The fields in the header record contain general information about a function's execution, including the return
code, row count, number of status records, and type of statement executed. The header record is always created
unless the function returns SQL_INVALID_HANDLE. For a complete list of fields in the header record, see the
SQLGetDiagField function description.
Status Records
4/27/2022 • 2 minutes to read • Edit Online
The fields in the status records contain information about specific errors or warnings returned by the Driver
Manager, driver, or data source, including the SQLSTATE, native error number, diagnostic message, column
number, and row number. Status records can be created only if the function returns SQL_ERROR,
SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_NEED_DATA, or SQL_STILL_EXECUTING. For a complete list of
fields in the status records, see the SQLGetDiagField function description.
This section contains the following topics.
Sequence of Status Records
SQLSTATEs
Diagnostic Messages
Sequence of Status Records
4/27/2022 • 2 minutes to read • Edit Online
If two or more status records are returned, the Driver Manager and driver rank them according to the following
rules. The record with the highest rank is the first record. The source of a record (Driver Manager, driver,
gateway, and so on) is not considered when ranking records.
Errors Status records that describe errors have the highest rank. Among error records, records that
indicate a transaction failure or possible transaction failure outrank all other records. If two or more
records describe the same error condition, SQLSTATEs defined by the Open Group CLI specification
(classes 03 through HZ) outrank ODBC-defined and driver-defined SQLSTATEs.
Implementation-defined No Data Values Status records that describe driver-defined No Data values
(class 02) have the second highest rank.
Warnings Status records that describe warnings (class 01) have the lowest rank. If two or more records
describe the same warning condition, warning SQLSTATEs defined by the Open Group CLI specification
outrank ODBC-defined and driver-defined SQLSTATEs.
If there are two or more records with the highest rank, it is undefined which record is the first record. The order
of all other records is undefined. In particular, because warnings may appear before errors, applications should
check all status records when a function returns a value other than SQL_SUCCESS.
SQLSTATEs
4/27/2022 • 2 minutes to read • Edit Online
SQLSTATEs provide detailed information about the cause of a warning or error. The SQLSTATEs in this manual
are based on those found in the ISO/IEF CLI specification, although those SQLSTATEs that start with IM are
specific to ODBC.
Unlike return codes, the SQLSTATEs in this manual are guidelines, and drivers are not required to return them.
Therefore, while drivers should return the proper SQLSTATE for any error or warning they are capable of
detecting, applications should not count on this always occurring. The reasons for this situation are twofold:
Incompleteness Although this manual lists a large number of errors and warnings and possible causes
for those errors and warnings, it is not complete and probably never will be; driver implementations
simply vary too much. Any given driver probably will not return all of the SQLSTATEs listed in this manual
and might return SQLSTATEs not listed in this manual.
Complexity Some database engines - particularly relational database engines - return literally
thousands of errors and warnings. The drivers for such engines are unlikely to map all of these errors and
warnings to SQLSTATEs because of the effort involved, the inexactness of the mappings, the large size of
the resulting code, and the low value of the resulting code, which often returns programming errors that
should never be encountered at run time. Therefore, drivers should map as many errors and warnings as
seems reasonable and be sure to map those errors and warnings on which application logic might be
based, such as SQLSTATE 01004 (Data truncated).
Because SQLSTATEs are not returned reliably, most applications just display them to the user along with their
associated diagnostic message, which is often tailored to the specific error or warning that occurred, and native
error code. There is rarely any loss of functionality in doing this, because applications cannot base programming
logic on most SQLSTATEs anyway. For example, suppose SQLExecDirect returns SQLSTATE 42000 (Syntax error
or access violation). If the SQL statement that caused this error is hard-coded or built by the application, this is a
programming error and the code needs to be fixed. If the SQL statement is entered by the user, this is a user
error and the application has done all that is possible by informing the user of the problem.
When applications do base programming logic on SQLSTATEs, they should be prepared for the SQLSTATE not to
be returned or for a different SQLSTATE to be returned. Exactly which SQLSTATEs are returned reliably can be
based only on experience with numerous drivers. However, a general guideline is that SQLSTATEs for errors that
occur in the driver or Driver Manager, as opposed to the data source, are more likely to be returned reliably. For
example, most drivers probably return SQLSTATE HYC00 (Optional feature not implemented), while fewer
drivers probably return SQLSTATE 42021 (Column already exists).
The following SQLSTATEs indicate run-time errors or warnings and are good candidates on which to base
programming logic. However, there is no guarantee that all drivers return them.
01004 (Data truncated)
01S02 (Option value changed)
HY008 (Operation canceled)
HYC00 (Optional feature not implemented)
HYT00 (Timeout expired)
SQLSTATE HYC00 (Optional feature not implemented) is particularly significant because it is the only way in
which an application can determine whether a driver supports a particular statement or connection attribute.
For a complete list of SQLSTATEs and what functions return them, see Appendix A: ODBC Error Codes. For a
detailed explanation of the conditions under which each function might return a particular SQLSTATE, see that
function.
Diagnostic Messages
4/27/2022 • 2 minutes to read • Edit Online
A diagnostic message is returned with each SQLSTATE. The same SQLSTATE is often returned with a number of
different messages. For example, SQLSTATE 42000 (Syntax error or access violation) is returned for most errors
in SQL syntax. However, each syntax error is likely to be described by a different message.
Sample diagnostic messages are listed in the Error column in the table of SQLSTATEs in Appendix A and in each
function. Although drivers can return these messages, they are more likely to return whatever message is
passed to them by the data source.
Applications generally display diagnostic messages to the user, along with the SQLSTATE and native error code.
This helps the user and support personnel determine the cause of any problems. The component information
embedded in the message is particularly helpful in doing this.
Diagnostic messages come from data sources and components in an ODBC connection, such as drivers,
gateways, and the Driver Manager. Typically, data sources do not directly support ODBC. Consequently, if a
component in an ODBC connection receives a message from a data source, it must identify the data source as
the source of the message. It must also identify itself as the component that received the message.
If the source of an error or warning is a component itself, the diagnostic message must explain this. Therefore,
the text of messages has two different formats. For errors and warnings that do not occur in a data source, the
diagnostic message must use this format:
[ vendor-identifier ][ ODBC-component-identifier ] component-supplied-text
For errors and warnings that occur in a data source, the diagnostic message must use this format:
[ vendor-identifier ][ ODBC-component-identifier ][ data-source-identifier ] data-source-supplied-text
The following table shows the meaning of each element.
EL EM EN T M EA N IN G
[1] In this case, the driver is acting as both the driver and the data source.
Brackets ([ ] ) must be included in the message and do not indicate optional items.
Using SQLGetDiagRec and SQLGetDiagField
4/27/2022 • 2 minutes to read • Edit Online
SQLGetDiagRec and SQLGetDiagField are implemented by the Driver Manager and each driver. The Driver
Manager and each driver maintain diagnostic records for each environment, connection, statement, and
descriptor handle, and free those records only when another function is called with that handle or the handle is
freed.
Although both the Driver Manager and each driver must determine the first status record according to the
rankings in Sequence of Status Records, the Driver Manager determines the final sequence of records.
SQLGetDiagRec and SQLGetDiagField do not post diagnostic records about themselves.
This section contains the following topics.
Diagnostic Handling Rules
Role of the Driver Manager
Role of the Driver
Diagnostic Handling Rules
4/27/2022 • 2 minutes to read • Edit Online
The Driver Manager determines the final order in which to return status records that it generates. In particular, it
determines which record has the highest rank and is to be returned first. The driver is responsible for ordering
status records that it generates. If status records are posted by both the Driver Manager and the driver, the
Driver Manager is responsible for ordering them. For more information, see Sequence of Status Records.
The Driver Manager does as much error checking as it can. This saves every driver from checking for the same
errors. For example, if a function argument accepts a discrete number of values, such as Operation in
SQLSetPos , the Driver Manager checks that the specified value is legal.
The following sections describe the types of conditions checked by the Driver Manager. They are not intended to
be exhaustive; for a complete list of the SQLSTATEs the Driver Manager returns, see the "Diagnostics" section of
each function; the description of each check made by the Driver Manager starts with the letters "(DM)." Also see
the state transition tables in Appendix B: ODBC State Transition Tables; errors shown in parentheses are detected
by the Driver Manager.
This section contains the following topics.
Argument Value Checks
State Transition Checks
General Error Checks
Driver Manager Error and Warning Checks
Argument Value Checks
4/27/2022 • 2 minutes to read • Edit Online
The Driver Manager checks the following types of arguments. Unless otherwise noted, the Driver Manager
returns SQL_ERROR for errors in argument values.
Environment, connection, and statement handles usually cannot be null pointers. The Driver Manager
returns SQL_INVALID_HANDLE when it finds a null handle.
Required pointer arguments, such as OutputHandlePtr in SQL AllocHandle and CursorName in
SQLSetCursorName , cannot be null pointers.
Option flags that do not support driver-specific values must be a legal value. For example, Operation in
SQLSetPos must be SQL_POSITION, SQL_REFRESH, SQL_UPDATE, SQL_DELETE, or SQL_ADD.
Option flags must be supported in the version of ODBC supported by the driver. For example, InfoType in
SQLGetInfo cannot be SQL_ASYNC_MODE (introduced in ODBC 3.0) when calling an ODBC 2.0 driver.
Column and parameter numbers must be greater than 0 or greater than or equal to 0, depending on the
function. The driver must check the upper limit of these argument values based on the current result set
or SQL statement.
Length/indicator arguments and data buffer length arguments must contain appropriate values. For
example, the argument that specifies the length of a table name in SQLColumns (NameLength3) must
be SQL_NTS or a value greater than 0; BufferLength in SQLDescribeCol must be greater than or equal
to 0. The driver might also need to check these arguments. For example, it might check that
NameLength3 is less than or equal to the maximum length of a table name in the data source.
State Transition Checks
4/27/2022 • 2 minutes to read • Edit Online
The Driver Manager checks that the state of the environment, connection, or statement is appropriate for the
function being called. For example, a connection must be in an allocated state when SQLConnect is called; a
statement must be in a prepared state when SQLExecute is called. The Driver Manager returns SQL_ERROR for
state transition errors.
General Error Checks
4/27/2022 • 2 minutes to read • Edit Online
The Driver Manager checks one general error. It always returns SQL_ERROR when it encounters the following
error: The function must be supported by the driver.
Driver Manager Error and Warning Checks
4/27/2022 • 2 minutes to read • Edit Online
The Driver Manager completely or partially implements a number of functions and therefore checks for all or
some of the errors and warnings in those functions.
The Driver Manager implements SQLDataSources and SQLDrivers and checks for all errors and
warnings in these functions.
The Driver Manager checks whether a driver implements SQLGetFunctions . If the driver does not
implement SQLGetFunctions , the Driver Manager implements and checks for all errors and warnings in
it.
The Driver Manager partially implements SQL AllocHandle , SQLConnect , SQLDriverConnect ,
SQLBrowseConnect , SQLFreeHandle , SQLGetDiagRec , and SQLGetDiagField and checks for some
errors in these functions. It may return the same errors as the driver for some of these functions because
both perform similar operations. For example, the Driver Manager or driver may return SQLSTATE IM008
(Dialog failed) if either one is unable to display a login dialog box for SQLDriverConnect .
Role of the Driver
4/27/2022 • 2 minutes to read • Edit Online
The driver checks for all errors and warnings not checked by the Driver Manager and orders status records that
it generates. (An ODBC 2.x driver does not order status records.) This includes errors and warnings in data
truncation, data conversion, syntax, and some state transitions. The driver might also check errors and warnings
partially checked by the Driver Manager. For example, although the Driver Manager checks whether the value of
Operation in SQLSetPos is legal, the driver must check whether it is supported.
The driver also maps native errors - that is, errors returned by the data source - to SQLSTATEs. For example, the
driver might map a number of different native errors for illegal SQL syntax to SQLSTATE 42000 (Syntax error or
access violation). The driver returns the native error number in the SQL_DIAG_NATIVE field of the status record.
Driver documentation should show how errors and warnings are mapped from the data source to arguments in
SQLGetDiagRec and SQLGetDiagField .
Diagnostic Handling Examples
4/27/2022 • 2 minutes to read • Edit Online
The following examples show how various components in an ODBC connection might generate diagnostic
messages and how various drivers might return diagnostics to the application with SQLGetDiagRec .
File-Based Driver Diagnostic Example
DBMS-Based Driver Diagnostic Example
Gateways Diagnostic Example
Driver Manager Diagnostic Example
File-Based Driver Diagnostic Example
4/27/2022 • 2 minutes to read • Edit Online
A file-based driver acts both as an ODBC driver and as a data source. It can therefore generate errors and
warnings both as a component in an ODBC connection and as a data source. Because it also is the component
that interfaces with the Driver Manager, it formats and returns arguments for SQLGetDiagRec .
For example, if a Microsoft® driver for dBASE could not allocate sufficient memory, it might return the
following values from SQLGetDiagRec :
SQLSTATE: "HY001"
Native Error: 42052
Diagnostic Msg: "[Microsoft][ODBC dBASE Driver]Unable to allocate sufficient memory."
Because this error was not related to the data source, the driver only added prefixes to the diagnostic message
for the vendor ([Microsoft]) and the driver ([ODBC dBASE Driver]).
If the driver could not find the file Employee.dbf, it might return the following values from SQLGetDiagRec :
SQLSTATE: "42S02"
Native Error: -1305
Diagnostic Msg: "[Microsoft][ODBC dBASE Driver][dBASE]No such table or object"
Because this error was related to the data source, the driver added the file format of the data source ([dBASE]) as
a prefix to the diagnostic message. Because the driver was also the component that interfaced with the data
source, it added prefixes for the vendor ([Microsoft]) and the driver ([ODBC dBASE Driver]).
DBMS-Based Driver Diagnostic Example
4/27/2022 • 2 minutes to read • Edit Online
A DBMS-based driver sends requests to a DBMS and returns information to the application through the Driver
Manager. Because the driver is the component that interfaces with the Driver Manager, it formats and returns
arguments for SQLGetDiagRec .
For example, if, using SQL/Services, a Microsoft driver for Oracle Rdb encountered an invalid cursor name, it
might return the following values from SQLGetDiagRec :
SQLSTATE: "34000"
Native Error: 0
Diagnostic Msg: "[Microsoft][ODBC Rdb Driver]Invalid cursor name: EMPLOYEE_CURSOR."
Because the error occurred in the driver, it added prefixes to the diagnostic message for the vendor ([Microsoft])
and the driver ([ODBC Rdb Driver]).
If the DBMS could not find the table EMPLOYEE, the driver might format and return the following values from
SQLGetDiagRec :
SQLSTATE: "42S02"
Native Error: -1
Diagnostic Msg: "[Microsoft][ODBC Rdb Driver][Rdb] %SQL-F-RELNOTDEF, Table EMPLOYEE "
"is not defined in schema."
Because the error occurred in the data source, the driver added a prefix for the data source identifier ([Rdb]) to
the diagnostic message. Because the driver was the component that interfaced with the data source, it added
prefixes for its vendor ([Microsoft]) and identifier ([ODBC Rdb Driver]) to the diagnostic message.
Gateways Diagnostic Example
4/27/2022 • 2 minutes to read • Edit Online
In a gateway architecture, a driver sends requests to a gateway that supports ODBC. The gateway sends the
requests to a DBMS. Because it is the component that interfaces with the Driver Manager, the driver formats and
returns arguments for SQLGetDiagRec .
For example, if Oracle based a gateway to Rdb on Microsoft Open Data Services and if Rdb could not find the
table EMPLOYEE, the gateway might generate this diagnostic message:
Because the error occurred in the data source, the gateway added a prefix for the data source identifier ([Rdb]) to
the diagnostic message. Because the gateway was the component that interfaced with the data source, it added
prefixes for its vendor ([DEC]) and identifier ([ODS Gateway]) to the diagnostic message. It also added the
SQLSTATE value and the Rdb error code to the beginning of the diagnostic message. This permitted it to
preserve the semantics of its own message structure and still supply the ODBC diagnostic information to the
driver. The driver parses the error information attached to the error statement by the gateway.
Because the gateway driver is the component that interfaces with the Driver Manager, it would use the
preceding diagnostic message to format and return the following values from SQLGetDiagRec :
SQLSTATE: "42S02"
Native Error: -1
Diagnostic Msg: "[DEC][ODS Gateway][Rdb]%SQL-F-RELNOTDEF, Table EMPLOYEE is not "
"defined in schema."
Driver Manager Diagnostic Example
4/27/2022 • 2 minutes to read • Edit Online
The Driver Manager can also generate diagnostic messages. For example, if an application passed an invalid
direction option to SQLDataSources , the Driver Manager might format and return the following values from
SQLGetDiagRec :
SQLSTATE: "HY103"
Native Error: 0
Diagnostic Msg: "[Microsoft][ODBC Driver Manager]Direction option out of range"
Because the error occurred in the Driver Manager, it added prefixes to the diagnostic message for its vendor
([Microsoft]) and its identifier ([ODBC Driver Manager]).
Interoperability
4/27/2022 • 2 minutes to read • Edit Online
Interoperability is the ability of a single application to operate with many different DBMSs. The need to write
generic, interoperable applications was one of the major factors leading to the development of ODBC. However,
interoperability is not a simple path followed from "not interoperable" to "completely interoperable." The path
has many branches, and each requires trade-offs among features, speed, code complexity, and development
time.
The process of writing an interoperable application follows several steps:
1. Deciding whether the application will use ODBC.
2. Choosing a level of interoperability and deciding which trade-offs are necessary to reach that level.
3. Writing interoperable code and testing it as fully as possible.
It should be noted that interoperability is primarily the domain of the application writer. Drivers are designed to
work with a single DBMS and, by definition, are not interoperable. They play a role in interoperability by
correctly implementing and exposing ODBC over a single DBMS.
This section contains the following topics.
Is ODBC the Answer?
Choosing a Level of Interoperability
Determining the Target DBMSs and Drivers
Considering Database Features to Use
Length of the Product Cycle
Writing an Interoperable Application
Testing Interoperable Applications
Is ODBC the Answer?
4/27/2022 • 2 minutes to read • Edit Online
Before delving into the question of interoperability, consider the following question: Should the application use
ODBC at all? This might seem a strange question to ask in a guide to ODBC, but it is, in fact, a legitimate one.
ODBC was not designed to completely replace native database APIs, nor was it designed to provide database
access in all circumstances. It was designed to provide a common interface to databases and was intended to
free application programmers from having to learn about and maintain links to multiple databases.
Custom applications are prime candidates for native database APIs. The main reason is that custom applications
often work with a single DBMS and have no need to be interoperable. Native database APIs might do a better
job than ODBC of exposing the capabilities of a particular DBMS and might expose capabilities not exposed by
ODBC. Furthermore, because the developers of custom applications are usually familiar with the native database
API for their DBMS, there is little reason to learn ODBC. However, it is interesting to note that for some DBMSs,
ODBC is the native database API.
So which applications are candidates for ODBC? The best candidates are applications that work with more than
one DBMS. This includes virtually all generic and vertical applications. It also includes a number of custom
applications. For example, custom applications that use several different DBMSs are much easier and cleaner to
write with ODBC than with multiple native APIs. And custom applications written with ODBC are much easier to
migrate as a company moves from one DBMS to another or deploys the same application against different
DBMSs.
Choosing a Level of Interoperability
4/27/2022 • 2 minutes to read • Edit Online
Assuming the application will use ODBC, the next step is to determine what level of interoperability is required.
The basic level of interoperability is usually a function of the application type: Custom applications tend not to
be interoperable, vertical applications tend to be interoperable among a limited number of DBMSs, and generic
applications tend to be interoperable among all DBMSs.
This section contains the following topics.
Custom Applications
Vertical Applications
Generic Applications
Custom Applications
4/27/2022 • 2 minutes to read • Edit Online
Custom applications typically perform a specific task for a few DBMSs. For example, an application might
retrieve data from a single DBMS and generate a report, or it might transfer data among several DBMSs. What
these applications have in common is that these DBMSs are known before the application is written and are
unlikely to change over the life of the application.
The custom application therefore requires little or no interoperability. The application developer can choose a
single driver for each DBMS and code directly to those drivers. The application can safely contain driver-specific
code to exploit the capabilities of those drivers and might even make calls to the native database API to use
functionality not supported by ODBC.
The major interoperability concern of most custom applications is whether the target DBMSs will change in the
future. If so, this process can be simplified by writing more interoperable code to start with. However, such
changing of DBMSs is rare and generally entails a large amount of work. Because of this, developers of custom
applications rarely choose to increase interoperability at the expense of functionality; they usually choose to
recode that functionality when they change DBMSs.
Vertical Applications
4/27/2022 • 2 minutes to read • Edit Online
Vertical applications typically perform a well-defined task against a single DBMS. For example, an order entry
application tracks the orders in a company. What these types of applications have in common is that the
database schema is usually designed by the application developer and, while the application might work with a
number of different DBMSs, it works with a single DBMS for a single customer.
Because vertical applications usually require certain functionality, such as scrollable cursors or transactions, they
rarely support all DBMSs. Instead, they tend to be highly interoperable among a limited set of DBMSs. Typically,
vertical application developers choose to support those DBMSs that represent a large fraction of the market and
ignore the rest. They might even choose to support specific drivers for those DBMSs to reduce their testing and
product support costs.
Because vertical applications can support a known set of DBMSs, they sometimes contain driver-specific or
DBMS-specific code. However, such code is best kept to a minimum because it requires extra time to maintain.
Generic Applications
4/27/2022 • 2 minutes to read • Edit Online
Generic applications sometimes perform a hard-coded task, such as a spreadsheet retrieving data from a
database. They might also perform a variety of user-defined tasks, such as a generic query application allowing
the user to enter and execute an SQL statement. What generic applications have in common is that they must
work with a variety of different DBMSs and that the developer does not know beforehand what these DBMSs
will be.
Therefore, generic applications need to be highly interoperable. The developer must make many choices, trading
off interoperability for features, and must write code that expects drivers to support a wide range of
functionality. While generic applications might be tuned to work with popular DBMSs, they rarely contain driver-
specific or DBMS-specific code.
Determining the Target DBMSs and Drivers
4/27/2022 • 2 minutes to read • Edit Online
The next question to consider is, what are the target DBMSs for the application, and what drivers are available
that support those DBMSs? Because generic applications tend to be highly interoperable, the question of target
DBMSs is most applicable to custom and vertical applications. However, the question of target drivers applies to
all applications, because drivers vary widely in speed, quality, feature support, and availability. Also, if drivers are
to be redistributed with the application, the cost and availability of licensing plans need to be considered.
For many custom applications, the target DBMSs are obvious: They are existing DBMSs that the application is
designed to access. DBMSs to which future migration is planned should also be considered. However, the major
question for these applications is which driver or drivers to use with them. For other custom applications - those
which are not designed to access an existing DBMS - the target DBMSs can be chosen based on feature support,
concurrent user support, driver availability, and affordability.
For vertical applications, the target DBMSs are usually chosen based on feature support, driver availability, and
market. For example, a vertical application designed for small businesses must target DBMSs that are affordable
to those businesses; a vertical application designed as an add-on to existing DBMSs must target widely used
DBMSs.
When choosing target DBMSs, the differences between desktop and server databases should be considered.
Desktop databases such as dBASE, Paradox, and Btrieve are less powerful than server databases. Because they
are generally accessed through the less powerful SQL engines found in most file-based drivers, they often lack
full transaction support, support fewer concurrent users, and have limited SQL. However, they are inexpensive
and have a large installed base.
Server databases such as Oracle, DB2, and SQL Server provide full transaction support, support many
concurrent users, and have rich SQL. They are much more expensive and have a smaller installed base. On the
other hand, software prices tend to be higher, somewhat offsetting a smaller potential market.
Thus, target DBMSs sometimes can be chosen based on the features required by the application and the
application's target market. For example, an order entry system for large corporations might not target desktop
databases because these lack adequate transaction support. A similar system designed for small businesses
might exclude most server databases on the basis of cost. And developers of generic applications might target
both but avoid using the advanced features found in server databases.
Considering Database Features to Use
4/27/2022 • 3 minutes to read • Edit Online
After the basic level of interoperability is known, the database features used by the application must be
considered. For example, what SQL statements will the application execute? Will the application use scrollable
cursors? Transactions? Procedures? Long data? For ideas about what features might not be supported by all
DBMSs, see the SQLGetInfo, SQLSetConnectAttr, and SQLSetStmtAttr function descriptions, and Appendix C:
SQL Grammar. The features required by an application might eliminate some DBMSs from the list of target
DBMSs. They might also show that the application can easily target many DBMSs.
For example, if the required features are simple, they can usually be implemented with a high degree of
interoperability. An application that executes a simple SELECT statement and retrieves results with a forward-
only cursor is likely to be highly interoperable by virtue of its simplicity: Almost all drivers and DBMSs support
the functionality it needs.
However, if the required features are more complex, such as scrollable cursors, positioned update and delete
statements, and procedures, trade-offs must often be made. There are several possibilities:
Lower interoperability, more features. The application includes the features but works only with
DBMSs that support them.
Higher interoperability, fewer features. The application drops the features but works with more
DBMSs.
Higher interoperability, optional features. The application includes the features but makes them
available only with those DBMSs that support them.
Higher interoperability, more features. The application uses the features with DBMSs that support
them and emulates them for DBMSs that do not.
The first two cases are relatively simple to implement, because the features are used either with all supported
DBMSs or with none. The latter two cases, on the other hand, are more complex. It is necessary in both cases to
check whether the DBMS supports the features and in the last case to write a potentially large amount of code
to emulate these features. Therefore, these schemes are likely to require more development time and may be
slower at run time.
Consider a generic query application that can connect to a single data source. The application accepts a query
from the user and displays the results in a window. Now suppose this application has one feature that allows
users to display the results of multiple queries simultaneously. That is, they can execute a query and look at
some of the results, execute a different query and look at some of its results, and then return to the first query.
This presents an interoperability problem because some drivers support only a single active statement.
The application has a number of choices, based on what the driver returns for the
SQL_MAX_CONCURRENT_ACTIVITIES option in SQLGetInfo :
Always suppor t multiple queries. After connecting to a driver, the application checks the number of
active statements. If the driver supports only one active statement, the application closes the connection
and informs the user that the driver does not support required functionality. The application is easy to
implement and has full functionality but has lower interoperability.
Never suppor t multiple queries. The application drops the feature altogether. It is easy to implement
and has high interoperability but has less functionality.
Suppor t multiple queries only if the driver does. After connecting to a driver, the application
checks the number of active statements. The application allows the user to start a new statement when
one is already active only if the driver supports multiple active statements. The application has higher
functionality and interoperability but is harder to implement.
Always suppor t multiple queries and emulate them when necessar y. After connecting to a
driver, the application checks the number of active statements. The application always allows the user to
start a new statement when one is already active. If the driver supports only one active statement, the
application opens an additional connection to that driver and executes the new statement on that
connection. The application has full functionality and high interoperability but is harder to implement.
Length of the Product Cycle
4/27/2022 • 2 minutes to read • Edit Online
The final question about interoperability is time. Developing an interoperable application usually takes longer
than developing a noninteroperable one. The reason is that the application must check DBMS capabilities,
perform the same tasks differently for different DBMSs, work around functionality supported by some DBMSs
but not others, and so on.
In addition to development time, product lifetime must be considered. If the application is designed to be used
once, such as an application that transfers data when migrating from one DBMS to another, there is no point in
making it interoperable. The application will be used once and discarded.
If the application will exist for a long time, it might be easier to maintain as an interoperable application. This is
true even for custom applications that have a single DBMS as a target. The reason is that interoperable code
uses a limited subset of database features. The driver is required to keep those features available, even in the
face of changes to the underlying DBMS. Thus, interoperable code can shift the burden of coping with changes
to the DBMS from the application developer to the driver developer.
Writing an Interoperable Application
4/27/2022 • 2 minutes to read • Edit Online
Whenever an application uses the same code against more than one driver, that code must be interoperable
among those drivers. In most cases, this is an easy task. For example, the code to fetch rows with a forward-only
cursor is the same for all drivers. In some cases, this can be more difficult. For example, the code to construct
identifiers for use in SQL statements needs to consider identifier case, quoting, and one-part, two-part, and
three-part naming conventions.
In general, interoperable code must cope with problems of feature support and feature variability. Feature
support refers to whether or not a particular feature is supported. For example, not all DBMSs support
transactions, and interoperable code must work correctly regardless of transaction support. Feature variability
refers to variation in the manner in which a particular feature is supported. For example, catalog names are
placed at the start of identifiers in some DBMSs and at the end of identifiers in others.
Applications can deal with feature support and feature variability at design time or at run time. To deal with
feature support and variability at design time, a developer looks at the target DBMSs and drivers and makes
sure that the same code will be interoperable among them. This is generally the way in which applications with
low or limited interoperability deal with these problems.
For example, if the developer guarantees that a vertical application will work only with four particular DBMSs
and if each of those DBMSs supports transactions, the application does not need code to check for transaction
support at run time. It can always assume transactions are available because of the design-time decision to use
only four DBMSs, each of which supports transactions.
To deal with feature support and variability at run time, the application must test for different capabilities at run
time and act accordingly. This is generally the way in which highly interoperable applications deal with these
problems. For feature support problems, this means writing code that makes the feature optional or writing
code that emulates the feature when it is not available. For feature variability problems, this means writing code
that supports all possible variations.
This section contains the following topics.
Checking Feature Support and Variability
Features to Watch For
Checking Feature Support and Variability
4/27/2022 • 2 minutes to read • Edit Online
To check feature support and variability, applications generally call SQLGetInfo , SQLGetFunctions , and
SQLGetTypeInfo . A good starting place is the driver's API and SQL grammar conformance levels. These
describe broad levels of feature support. The application can then call SQLGetInfo with other options to
determine the support or variability of features it needs, SQLGetFunctions to determine whether functions it
needs beyond the returned conformance level are supported, and SQLGetTypeInfo to determine what SQL
data types are supported.
An application can determine whether a statement or connection attribute is supported by calling
SQLSetStmtAttr or SQLSetConnectAttr with that attribute. If the function returns SQL_SUCCESS or
SQL_SUCCESS_WITH_INFO, the attribute is supported; if it returns SQL_ERROR and SQLSTATE HYC00 (Optional
feature not implemented), the attribute is not supported.
Applications can also determine a limited amount of information before connecting to the driver by calling
SQLDrivers .
Features to Watch For
4/27/2022 • 2 minutes to read • Edit Online
This section describes a number of features that application developers often take for granted. In fact, these
features vary widely in support and manner of support among DBMSs; failure to code for them is likely to cause
problems in interoperable applications.
This section does not list all features that application developers need to consider. For that information, see the
SQLGetInfo, SQLSetStmtAttr, and SQLSetConnectAttr function descriptions, Appendix C: SQL Grammar, and the
sections of this manual that discuss each feature.
This section contains the following topics.
Version Number
Multiple Active Statements and Connections
Transaction Support in DBMSs
Commit and Rollback Behavior
NOT NULL in CREATE TABLE Statements
Supported Data Types
ODBC SQL Grammar
Batch Processing
Version Number
4/27/2022 • 2 minutes to read • Edit Online
There are several versions of ODBC, each with different features. An application determines which ODBC version
the Driver Manager and a particular driver support by calling SQLGetInfo with the SQL_ODBC_VER and
SQL_DRIVER_ODBC_VER options.
Multiple Active Statements and Connections
4/27/2022 • 2 minutes to read • Edit Online
Some drivers and DBMSs limit the number of statements and connections that can be active at one time. These
numbers can be as small as one. For more information, see the SQL_MAX_CONCURRENT_ACTIVITIES and
SQL_MAX_DRIVER_CONNECTIONS options in the SQLGetInfo function description, and Statement Handles and
Connection Handles.
Transaction Support in DBMSs
4/27/2022 • 2 minutes to read • Edit Online
Some databases, especially desktop databases such as dBASE, Paradox, and Btrieve, do not support transactions.
Even among databases that support transactions, there is variation in what kinds of SQL statements can be in a
transaction. For more information, see the SQL_TXN_CAPABLE option in the SQLGetInfo function description.
Commit and Rollback Behavior
4/27/2022 • 2 minutes to read • Edit Online
A common behavior among server DBMSs is to close cursors and discard prepared statements when a
statement is committed or rolled back. Desktop databases are more likely to keep cursors open and keep
prepared statements. For more information, see the SQL_CURSOR_COMMIT_BEHAVIOR and
SQL_CURSOR_ROLLBACK_BEHAVIOR options in the SQLGetInfo function description and Effect of Transactions
on Cursors and Prepared Statements.
NOT NULL in CREATE TABLE Statements
4/27/2022 • 2 minutes to read • Edit Online
Some databases, and especially desktop databases, do not support the NOT NULL column constraint in
CREATE TABLE statements. For more information, see the SQL_NON_NULLABLE_COLUMNS option in the
SQLGetInfo function description.
Supported Data Types
4/27/2022 • 2 minutes to read • Edit Online
The data types supported by DBMSs vary considerably. An application can determine the names and
characteristics of supported data types by calling SQLGetTypeInfo . Because of wide variation in data type
names, the application must use the data type names returned by SQLGetTypeInfo in CREATE TABLE
statements. For more information, see Data Types in ODBC.
ODBC SQL Grammar
4/27/2022 • 2 minutes to read • Edit Online
Interoperable applications should always use the ODBC SQL grammar in SQL statements. However,
considerable variation is possible even within this grammar. For more information, see Interoperability of SQL
Statements.
Batch Processing
4/27/2022 • 2 minutes to read • Edit Online
Support for batches of SQL statements is not widespread, so interoperable applications should use them
conditionally or not at all. For more information, see Executing Batches.
Testing Interoperable Applications
4/27/2022 • 2 minutes to read • Edit Online
Testing interoperable applications is at best a time-consuming business and at worst impossible because new
drivers continually appear on the market. However, a reasonable degree of testing is possible. Applications with
limited or low interoperability need only be tested against those drivers they are guaranteed to support.
However, they must be fully tested against these drivers.
Highly interoperable applications cannot be tested practically against all drivers. The best that most application
developers can do is to test them fully against a small number of drivers and cursorily against several more.
Tested drivers should include the most popular drivers for the most popular DBMSs in the application's market;
if the market covers all DBMSs, drivers for both desktop and server DBMSs should be tested.
One of the problems in testing ODBC applications is the number of components involved: the application itself,
the Driver Manager, the driver, the DBMS, and possibly network software or gateways. Applications can make it
easier to track errors by posting the error messages returned by ODBC functions through SQLGetDiagField
and SQLGetDiagRec . These messages identify the manufacturer and component in which errors occur. For
more information, see Diagnostics.
Programming Considerations
4/27/2022 • 2 minutes to read • Edit Online
This section briefly discusses a number of topics related to writing ODBC applications and drivers.
This section contains the following topics.
Multithreading
Alignment
Unicode
Translation DLLs
Diagnostic Tools
Visual Studio Analyzer
Driver-Specific Data Types, Descriptor Types, Information Types, Diagnostic Types, and Attributes
Backward Compatibility and Standards Compliance
ODBC in Windows
Multithreading
4/27/2022 • 2 minutes to read • Edit Online
On multithread operating systems, drivers must be thread-safe. That is, it must be possible for applications to
use the same handle on more than one thread. How this is achieved is driver-specific, and it is likely that drivers
will serialize any attempts to concurrently use the same handle on two different threads.
Applications commonly use multiple threads instead of asynchronous processing. The application creates a
separate thread, calls an ODBC function on it, and then continues processing on the main thread. Rather than
having to continually poll the asynchronous function, as is the case when the SQL_ATTR_ASYNC_ENABLE
statement attribute is used, the application can simply let the newly created thread finish.
Functions that accept a statement handle and are running on one thread can be canceled by calling SQLCancel
with the same statement handle from another thread. Although drivers should not serialize the use of
SQLCancel in this manner, there is no guarantee that calling SQLCancel will actually cancel the function
running on the other thread.
Alignment
4/27/2022 • 2 minutes to read • Edit Online
The alignment issues in an ODBC application are generally no different than they are in any other application.
That is, most ODBC applications have few or no problems with alignment. The penalties for not aligning
addresses vary with the hardware and operating system and might be as minor as a slight performance penalty
or as major as a fatal run-time error. Therefore, ODBC applications, and portable ODBC applications in particular,
should be careful to align data properly.
One example of when ODBC applications encounter alignment issues is when they allocate a large block of
memory and bind different parts of that memory to the columns in a result set. This is most likely to occur when
a generic application must determine the shape of a result set at run time and allocate and bind memory
accordingly.
For example, suppose an application executes a SELECT statement entered by the user and fetches the results
from this statement. Because the shape of this result set is not known when the program is written, the
application must determine the type of each column after the result set is created and bind memory accordingly.
The easiest way to do this is to allocate a large block of memory and bind different addresses in that block to
each column. To access the data in a column, the application casts the memory bound to that column.
The following diagram shows a sample result set and how a block of memory might be bound to it using the
default C data type for each SQL data type. Each "X" represents a single byte of memory. (This example shows
only the data buffers that are bound to the columns. This is done for simplicity. In actual code, the
length/indicator buffers must also be aligned.)
Assuming the bound addresses are stored in the Address array, the application uses the following expressions to
access the memory bound to each column:
(SQLCHAR *) Address[0]
(SQLSMALLINT *) Address[1]
(SQLINTEGER *) Address[2]
Notice that the addresses bound to the second and third columns start on odd-numbered bytes and that the
address bound to the third column is not divisible by four, which is the size of an SDWORD. On some machines,
this will not be a problem; on others, it will cause a slight performance penalty; on still others, it will cause a fatal
run-time error. A better solution would be to align each bound address on its natural alignment boundary.
Assuming this is 1 for a UCHAR, 2 for an SWORD, and 4 for an SDWORD, this would give the result shown in the
following illustration, where an "X" represents a byte of memory that is used and an "O" represents a byte of
memory that is unused.
While this solution does not use all of the application's memory, it does not encounter any alignment problems.
Unfortunately, it takes a fair amount of code to implement this solution, as each column must be aligned
individually according to its type. A simpler solution is to align all columns on the size of the largest alignment
boundary, which is 4 in the example shown in the following illustration.
Although this solution leaves larger holes, the code to implement it is relatively simple and fast. In most cases,
this offsets the penalty paid in unused memory. For an example that uses this method, see Using SQLBindCol.
Unicode
4/27/2022 • 2 minutes to read • Edit Online
The ODBC 3.5 (or higher) Driver Manager supports both ANSI and Unicode versions of all functions that accept
pointers to character strings or SQLPOINTER in their arguments. The Unicode functions are implemented as
functions (with a suffix of W), not as macros. The ANSI functions (which can be called with or without a suffix of
A) are identical to the current ODBC API functions.
Remarks
For Unicode functions that always return or take strings or length arguments, the arguments are passed as
count-of-characters. For functions that return length information for server data, the display size and precision
are described in number of characters. When a length (transfer size of the data) could refer to string or
nonstring data, the length is described in octet lengths. For example, SQLGetInfoW will still take the length as
count-of-bytes, but SQLExecDirectW will use count-of-characters.
Count-of-characters refers to the number of bytes (octets) for ANSI functions and the number of WCHAR (16-bit
words) for UNICODE functions. In particular, a double-byte character sequence (DBCS) or a multibyte character
sequence (MBCS) can be composed of multiple bytes. A UTF-16 Unicode character sequence can be composed
of multiple WCHARs.
The following is a list of the ODBC API functions that support both Unicode (W) and ANSI (A) versions:
SQLBrowseConnect
SQLColAttribute
SQLColAttributes
SQLColumnPrivileges
SQLColumns
SQLConnect
SQLDataSources
SQLDescribeCol
SQLDriverConnect
SQLDrivers
SQLError
SQLExecDirect
SQLForeignKeys
SQLGetConnectAttr
SQLGetConnectOption
SQLGetCursorName
SQLGetDescField
SQLGetDescRec
SQLGetDiagField
SQLGetDiagRec
SQLGetInfo
SQLGetStmtAttr
SQLGetTypeInfo
SQLNativeSql
SQLPrepare
SQLPrimar yKeys
SQLProcedureColumns
SQLProcedures
SQLSetConnectAttr
SQLSetConnectOption
SQLSetCursorName
SQLSetDescField
SQLSetStmtAttr
SQLSpecialColumns
SQLStatistics
SQLTablePrivileges
SQLTables
The following is a list of the ODBC Installer and ODBC Translator functions that support both Unicode (W) and
ANSI (A) versions:
SQLConfigDataSource
SQLCreateDataSource
SQLDataSourceToDriver
SQLDriverToDataSource
SQLGetAvailableDrivers
SQLGetInstalledDrivers
SQLGetTranslator
SQLInstallDriver
SQLInstallDriverManager
SQLInstallerError
SQLInstallODBC
SQLReadFileDSN
SQLRemoveDSNFromINI
SQLValidDSN
SQLWriteDSNToINI
NOTE
Deprecated functions have Unicode-to-ANSI mapping support because the ODBC 3.x Driver Manager supports
recompiling ODBC 2.x applications with the UNICODE #define .
Whether a driver should be a Unicode driver or an ANSI driver depends entirely on the nature of the data
source. If the data source supports Unicode data, the driver should be a Unicode driver. If the data source only
supports ANSI data, the driver should remain an ANSI driver.
A Unicode driver must export SQLConnectW to be recognized as a Unicode driver by the Driver Manager.
A Unicode driver must accept Unicode functions (with a suffix of W) and store Unicode data. It can also accept
ANSI functions, but is not required to. (The Driver Manager does not pass an ANSI function call with the A suffix
to the driver, but converts it to an ANSI function call without the suffix and then passes it to the driver.)
A Unicode driver must be able to return result sets in either Unicode or ANSI, depending on the application's
binding. If an application binds to SQL_C_CHAR, the Unicode driver must convert SQL_WCHAR data to
SQL_CHAR. The driver manager will map SQL_C_WCHAR to SQL_C_CHAR for ANSI drivers but does no
mapping for Unicode drivers.
NOTE
When determining the driver type, the Driver Manager will call SQLSetConnectAttr and set the SQL_ATTR_ANSI_APP
attribute at connection time. If the application is using ANSI APIs, SQL_ATTR_ANSI_APP will be set to SQL_AA_TRUE, and if
it is using Unicode, it will be set to a value of SQL_AA_FALSE. This attribute is used so that the driver can exhibit different
behavior based on the application type. The attribute cannot be set by the application directly, and it is not supported by
SQLGetConnectAttr . If a driver exhibits the same behavior for both ANSI and Unicode applications, it should return
SQL_ERROR for this attribute. If the driver returns SQL_SUCCESS, the Driver Manager will separate ANSI and Unicode
connections when Connection Pooling is used.
Function Mapping in the Driver Manager
4/27/2022 • 2 minutes to read • Edit Online
The driver manager supports two entry points for functions that take string arguments. The undecorated
function (SQLDriverConnect ) is the ANSI form of the function. The Unicode form is decorated with a W
(SQLDriverConnectW .)
The ODBC header file also supports functions decorated with an A, (SQLDriverConnectA ) for the convenience
of mixed ANSI/Unicode applications. Calls made to the A functions are actually calls into the undecorated entry
point (SQLDriverConnect .)
If the application is compiled with the _UNICODE #define , the ODBC header file will map undecorated function
calls (SQLDriverConnect ) to the Unicode version (SQLDriverConnectW .)
The Driver Manager recognizes a driver as a Unicode driver if SQLConnectW is supported by the driver.
If the driver is a Unicode driver, the Driver Manager makes function calls as follows:
Passes a function without string arguments or parameters directly through to the driver.
Passes Unicode functions (with the W suffix) directly through to the driver.
Converts an ANSI function (with the A suffix) to a Unicode function (with the W suffix) by converting the
string arguments into Unicode characters and passes the Unicode function to the driver.
If the driver is an ANSI driver, the Driver Manager makes function calls as follows:
Passes functions without string arguments or parameters directly through to the driver.
Converts Unicode functions (with the W suffix) to an ANSI function call and passes it to the driver.
Passes an ANSI function directly to the driver.
The Driver Manager is Unicode-enabled internally. As a result, the optimum performance is obtained by a
Unicode application working with a Unicode driver, because the Driver Manager simply passes Unicode
functions through to the driver. When an ANSI application is working with an ANSI driver, the Driver Manager
must convert strings from ANSI to Unicode when processing some functions, such as SQLDriverConnect .
After processing the function, the Driver Manager must then convert the Unicode string back to ANSI before
sending the function to the ANSI driver.
An application should not modify or read its bound parameter buffers when the driver returns
SQL_STILL_EXECUTING or SQL_NEED_DATA. The Driver Manager leaves the buffers bound to ANSI until the
driver returns SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, or SQL_ERROR. A multithreaded application should
not gain access to any bound parameter values that another thread is executing an SQL statement on. The
Driver Manager converts the data from Unicode to ANSI "in place," and the other thread might see ANSI data in
these buffers while the driver is still processing the SQL statement. Applications that bind Unicode data to an
ANSI driver must not bind two different columns to the same address.
Unicode Data
4/27/2022 • 2 minutes to read • Edit Online
SQL Unicode data types are provided to describe data that resides in Unicode natively on the DBMS. A C
Unicode data type is provided to allow an application to bind data to a Unicode buffer. The Driver Manager can
convert data from a Unicode C type (SQL_C_WCHAR) to make it function with an ANSI driver.
An ODBC 3.0 or 2.x application will always bind to the ANSI data types. For optimum performance, an ODBC 3.5
(or higher) application should bind to the ANSI data C type if the SQL column type is ANSI, and should bind to
the Unicode C data type if the SQL column type is Unicode.
The SQL Unicode type indicators are SQL_WCHAR, SQL_WVARCHAR, and SQL_WLONGVARCHAR. SQL_WCHAR
data has a fixed string length, while SQL_WVARCHAR has a variable length with a declared maximum and
SQL_WLONGVARCHAR has a variable length with a maximum that depends on the data source.
The C Unicode type indicator is SQL_C_WCHAR. This is the default for each of the SQL Unicode type indicators.
All of the SQL types can be converted to SQL_C_WCHAR, and SQL_C_WCHAR can be converted to all of the SQL
types. An application can retrieve data in one of three ways:
Retrieve the data as SQL_C_CHAR.
Retrieve the data as SQL_C_WCHAR.
Declare the data as SQL_C_TCHAR. This is a macro that inserts SQL_C_WCHAR if the application is
compiled as a Unicode application or inserts SQL_C_CHAR if it is compiled as an ANSI application.
SQL_C_TCHAR is declared in a function as follows:
When the application is compiled as a Unicode application, the ValueType argument would be changed from
SQL_C_TCHAR to SQL_C_WCHAR. When the application is compiled as an ANSI application, the ValueType
argument would be changed to SQL_C_CHAR.
Unicode drivers must still support ANSI data types, including SQL_CHAR. If an application working with a
Unicode driver binds to SQL_CHAR, the Driver Manager will not map the SQL_CHAR data to SQL_WCHAR. The
Unicode driver must accept the SQL_CHAR data.
The Driver Manager stores driver and DSN names in Unicode and maps them to ANSI as needed. If a Unicode
character cannot be mapped to an ANSI character (as can occur if characters from a code page that is not the
native code page of the computer are used in driver and DSN names), the characters that could not be
converted are represented by a default character supplied by the system.
Translation DLLs
4/27/2022 • 2 minutes to read • Edit Online
The application and data source often store data in different character sets. ODBC provides a generic mechanism
that allows the driver to translate data from one character set to another. It consists of a DLL that implements the
translation functions SQLDriverToDataSource and SQLDataSourceToDriver , which are called by the driver
to translate all data flowing between the data source and driver. This DLL can be written by the application
developer, the driver developer, or a third party.
The translation DLL for a particular data source can be specified in the system information for that data source;
for more information, see Data Source Specification Subkeys. It can also be set at run time with the
SQL_ATTR_TRANSLATE_DLL and SQL_ATTR_TRANSLATE_OPTION connection attributes.
The translation option is a value that can be interpreted only by a particular translation DLL. For example, if the
translation DLL translates between different code pages, the option might give the numbers of the code pages
used by the application and the data source. There is no requirement for a translation DLL to use a translation
option.
After a translation DLL has been specified, the driver loads it and calls it to translate all data flowing between the
application and data source. This includes all SQL statements and character parameters being sent to the data
source, and all character results, character metadata such as column names, and error messages retrieved from
the data source. Connection data is not translated, because the translation DLL is not loaded until after the
application has connected to the data source.
Diagnostic Tools
4/27/2022 • 2 minutes to read • Edit Online
Two facilities can assist with diagnosing problems in ODBC applications. Both are available from the ODBC
Administrator and implemented by the Driver Manager. Tracing provides a means to record to a log file the
sequence of function calls. Visual Studio Analyzer allows the analysis of information about the interaction of
components in a distributed environment.
This section contains the following topics.
Tracing
Visual Studio Analyzer
Tracing
4/27/2022 • 2 minutes to read • Edit Online
The ODBC Driver Manager has a trace facility that allows the sequence of function calls made by an ODBC
application to be recorded and transcribed into a log file. Tracing is performed by a trace DLL that captures calls
between the application and the Driver Manager, and between the Driver Manager and the driver. This method
of tracing replaces the tracing performed by the ODBC 2*.x* Driver Manager and the tracing performed in ODBC
2*.x* by ODBC Spy.
This section contains the following topics.
Trace DLL
Trace File
Enabling Tracing
Dynamic Tracing
Trace DLL
4/27/2022 • 2 minutes to read • Edit Online
The DLL that performs tracing is one of the ODBC core components. The trace DLL is currently provided as a
sample DLL in the ODBC component of the Windows SDK, and was formerly included the Microsoft Data Access
Components (MDAC) SDK. Therefore, the registry entry, interface, and sample code for the trace DLL are
available. This DLL can be replaced by a trace DLL produced by either an ODBC user or a third-party vendor. A
custom trace DLL should be given a different name than the original sample trace DLL. Trace DLLs must be
installed in the system directory, or they will fail to load. The connection strings will not be passed to the trace
DLL by the Driver Manager.
The trace DLL traces input arguments, output arguments, deferred arguments, return codes, and SQLSTATEs.
When tracing is enabled, the Driver Manager calls the trace DLL at two points: once upon function entry (before
argument validation) and again just before the function returns.
When an application calls a function, the Driver Manager calls a trace function in the trace DLL before calling the
function in the driver or processing the call itself. Each ODBC function has a corresponding trace function
(prefixed with Trace) that is identical to the ODBC function with the exception of the name. When the trace
function is called, the trace DLL captures the input arguments and returns a return code. Because the trace DLL is
called before the Driver Manager validates arguments, invalid function calls are traced, so state transition errors
and invalid arguments are logged.
After calling the trace function in the trace DLL, the Driver Manager calls the ODBC function in the driver. It then
calls TraceReturn in the trace DLL. This function takes two arguments: the value returned by the trace DLL for
the trace function, and the return code returned by the driver to the Driver Manager for the ODBC function (or
the value returned by the Driver Manager itself if it processed the function). The function uses the value returned
for the trace function to manipulate captured input argument values. It writes the code returned for the ODBC
function to the log file (or displays it dynamically, if that is enabled). It dereferences the output argument
pointers and logs the output argument values.
Trace File
4/27/2022 • 2 minutes to read • Edit Online
An application specifies the trace file either by setting the TraceFile keyword in the Odbc.ini registry entry or by
calling SQLSetConnectAttr with the SQL_ATTR_TRACEFILE connection attribute. If the file does not exist when
tracing is enabled, the Driver Manager will create the file. Each application should have its own dedicated trace
file to avoid contention. An application can use more than one trace file; an application's setup program can
provide the user with a choice of trace files. If tracing is enabled dynamically, an application can also display
trace results, rather than logging to the trace file.
The trace file provides a log of each ODBC function call with the data types and values of all arguments. It logs
all input functions and logs all returned functions with return codes and error states.
In ODBC 3.x, parameters to connection functions are not provided to the trace DLL.
Enabling Tracing
4/27/2022 • 2 minutes to read • Edit Online
Tracing can be enabled or disabled at any point in an application run. This allows an application to trace any
number of function calls.
The variable ODBCSharedTraceFlag is set to enable tracing dynamically. This variable is shared among all
running copies of the Driver Manager. If any application sets this variable, tracing is enabled for all ODBC
applications currently running. To turn tracing off when dynamic tracing is enabled, an application calls
SQLSetConnectAttr to set SQL_ATTR_TRACE to SQL_TRACE_OFF. This call will turn tracing off for that
application only. Applications that are linked with Odbc32.lib can modify use of this variable. Trace data can be
displayed in a real-time window, instead of the trace file, which must be opened after the ODBC session.
Controls can be added to an application's screen to turn tracing on or off at will.
The trace DLL shipped with ODBC 3*.x* is not thread-safe. It is not guaranteed that the log file is written
correctly if global tracing is enabled (the variable ODBCSharedTraceFlag is set) and more than one application
writes to the trace file at the same time. This condition does not return an error.
Visual Studio Analyzer
4/27/2022 • 2 minutes to read • Edit Online
IMPORTANT
Support for Visual Studio Analyzer was removed beginning in Windows 8 (Visual Studio Analyzer was only included in
older versions of Visual Studio.). For an alternative troubleshooting mechanism, use BID tracing.
Microsoft® Visual Studio™ Analyzer provides a high-level view of the ODBC application. The developer can
evaluate, analyze, and debug the structure, performance, and interactions from the application's perspective,
rather than from a component or code perspective. The information gathered by Visual Studio Analyzer is in the
form of events, which represent some kind of interaction between two components of the application. Events
can be composed of function calls and returns from functions, such as connections, database queries, and
transactions.
This section contains the following topic.
Enabling Visual Studio Analyzer
Enabling Visual Studio Analyzer
4/27/2022 • 2 minutes to read • Edit Online
IMPORTANT
Support for Visual Studio Analyzer was removed beginning in Windows 8 (Visual Studio Analyzer was only included in
older versions of Visual Studio.). For an alternative troubleshooting mechanism, use BID tracing.
Microsoft Visual Studio Analyzer is an application-analysis tool designed to provide a high-level look at an
application's performance across all tiers and systems. It focuses on the interaction between components. Visual
Studio Analyzer can be started and stopped from the ODBC Administrator's Tracing tab.
To view any of the events that ODBC generates, follow these steps:
1. Access the ODBC Data Source Administrator.
2. Click the Tracing tab.
3. Click Star t Visual Studio Analyzer Tracing .
4. Click OK .
Visual Studio Analyzer event-generation continues until Stop Visual Studio Analyzer Tracing is selected.
This section contains the following topic.
Events Generated by the ODBC Driver Manager
Events Generated by the ODBC Driver Manager
4/27/2022 • 2 minutes to read • Edit Online
IMPORTANT
Support for Visual Studio Analyzer was removed beginning in Windows 8 (Visual Studio Analyzer was only included in
older versions of Visual Studio.). For an alternative troubleshooting mechanism, use BID tracing.
Events generated by the ODBC Driver Manager are registered when the Start Visual Studio Analyzer button is
clicked. The tool itself offers system-defined events and the ability to create custom events. For more
information about events, see the Visual Studio Analyzer Reference Guide within the Visual Studio suite of
documentation.
Disconnect Star t Generated when the ODBC Driver Manager calls the driver's
SQLDisconnect function.
Quer ySend Generated when the ODBC Driver Manager calls the driver's
SQLPrepare , SQLExecute , SQLExecDirect functions, as
well as catalog functions such as SQLTables and
SQLColumns .
Quer yResult Generated when the driver returns a result set to the ODBC
Driver Manager for functions involving queries.
NOTE
The ODBC 3.8 Driver Manager neither validates nor enforces these ranges for backward compatibility. A future version of
the Driver Manager might enforce them, however.
O DB C C O N STA N T
F O R DRIVER-
DRIVER- SP EC IF IC DRIVER- SP EC IF IC SP EC IF IC VA L UE
AT T RIB UT E T Y P E O DB C DATA T Y P E RA N GE B A SE RA N GE L IM IT RA N GE B A SE
NOTE
Driver-specific data types, descriptor fields, diagnostic fields, information types, statement attributes, and connection
attributes must be described in the driver documentation. When any of these values is passed to an ODBC function, the
driver must check whether the value is valid. Drivers return SQLSTATE HYC00 (Optional feature not implemented) for
driver-specific values that apply to other drivers.
The base values are defined to facilitate driver development. For example, driver specific diagnostic attributes
can be defined in the following format:
SQL_DRIVER_DIAGNOSTIC_BASE+0, SQL_DRIVER_DIAGNOSTIC_BASE +1
Backward Compatibility and Standards Compliance
4/27/2022 • 2 minutes to read • Edit Online
Backward compatibility is the ability of newer ODBC components to work with old ODBC components. The
following sections discuss how these components are affected by the changes in ODBC 3.x. The information
contained in them primarily addresses the writing of an ODBC 3.x application and how backward compatibility
issues are handled by ODBC drivers. For specific guidelines about how backward compatibility issues affect the
writing of an ODBC 3.x driver, see Appendix G: Driver Guidelines for Backward Compatibility.
This section contains the following topics.
Affected ODBC Components
Types of Changes
Application/Driver Compatibility
New Features
Duplicated Features
Behavioral Changes
Writing ODBC 3.x Applications
Writing ODBC 3.x Drivers
Affected ODBC Components
4/27/2022 • 2 minutes to read • Edit Online
Backward compatibility describes how applications, the Driver Manager, and drivers are affected by the
introduction of a new version of the Driver Manager. This affects applications and driver when either or both of
them remain in the old version. There are, therefore, three types of backward compatibility to consider, as shown
in the following table.
[1] The backward compatibility of drivers is primarily discussed in Appendix G: Driver Guidelines for Backward
Compatibility.
NOTE
A standards-compliant application - for example, an application that has been written in accordance with the Open Group
or ISO CLI standards - is guaranteed to work with an ODBC 3.x driver through the ODBC 3.x Driver Manager. It is
assumed that the functionality that the application is using is available in the driver. It is also assumed that the standards-
compliant application has been compiled with the ODBC 3.x header files.
Types of Changes
4/27/2022 • 2 minutes to read • Edit Online
Three types of changes are made in ODBC 3.x (and any version of ODBC). Each of these affects backward
compatibility differently and is handled in a different way. These changes are described in the following table.
T Y P E O F C H A N GE DESC RIP T IO N
New features These are features that are new to ODBC 3.x, such as out-of-
line binding or descriptors. These are implemented only
when the application and driver, as well as the Driver
Manager, are of version 3.x, so there is no attempt to make
these backward compatible.
Duplicated features These are features that exist in ODBC 2.x and ODBC 3.x but
are implemented in different ways in each. The functions
SQL AllocHandle and SQL AllocStmt are an example.
Backward compatibility issues for these and other duplicated
features are mostly handled by mappings in the Driver
Manager.
Behavioral changes These are features that are handled differently in ODBC 2.x
and ODBC 3.x. A datetime #define is an example. These
features are handled by the ODBC 3.x driver based on an
environment attribute setting. (See Behavioral Changes for
more information.)
Application and Driver Compatibility
4/27/2022 • 2 minutes to read • Edit Online
ODBC applications and driver fall into a number of categories in addition to their version. Some of these
applications are incompatible with some drivers; in other cases, the type of the application or driver may have a
bearing on the backward compatibility issues between them.
This section contains the following topics.
Types of Applications
Types of Drivers
Compatibility Matrix
Types of Applications
4/27/2022 • 2 minutes to read • Edit Online
NOTE
16-bit ODBC drivers will not work directly with the ODBC 3.x Driver Manager. However, it is possible for 16-bit drivers to
work with the 2.0 ODBC Driver Manager, which subsequently thunks up to the 3.x Driver Manager.
Compatibility Matrix
4/27/2022 • 2 minutes to read • Edit Online
The following table describes the compatibility of the types of applications and drivers defined previously in this
section.
A P P L IC AT IO N T Y P E 32- B IT O DB C O DB C 3. X ISO A N D O P EN
GRO UP - C O M P L IA N T
A N D VERSIO N 2. X DRIVER DRIVER O DB C 3. 8 DRIVER DRIVER
Pure 3.8 (or higher) Not compatible [5] Not compatible [5] Compatible Not compatible [4]
application
[1] The application must recompile using ODBC 3.5 (or higher) headers with the UNICODE option (if it is a
Unicode application) and must set ODBCVER to 0x0250.
[2] The application must compile using ODBC 3.5 (or higher)headers and link with the ODBC Driver Manager. It
must also set the header flag ODBC_STD.
[3] This configuration can potentially fail to work because there are features in ODBC 2.x that are not in the
standards, such as bookmarks.
[4] This configuration can potentially fail to work because there are features in ODBC 3.x that are not in the
standards, such as bookmarks.
[5] This configuration can potentially fail because there are features in ODBC 3.8 that are not in ODBC 2.x or 3.x
drivers, such as driver-specific C Data Types in ODBC.
See Also
What's New in ODBC 3.8
New Features
4/27/2022 • 2 minutes to read • Edit Online
The following new functionality has been introduced in ODBC 3.x. An ODBC 3.x application working with an
ODBC 2.x driver will not be able to use this functionality. The ODBC 3.x Driver Manager does not map these
features when working with an ODBC 2.x driver.
Functions that take a descriptor handle as an argument: SQLSetDescField , SQLGetDescField ,
SQLSetDescRec , SQLGetDescRec , and SQLCopyDesc .
The functions SQLSetEnvAttr and SQLGetEnvAttr .
The use of SQL AllocHandle to allocate a descriptor handle. (The use of SQL AllocHandle to allocate
environment, connection, and statement handles is duplicated, not new, functionality.)
The use of SQLGetConnectAttr to get the SQL_ATTR_AUTO_IPD connection attributes. (The use of
SQLSetConnectAttr to set, and SQLGetConnectAttr to get, other connection attributes is duplicated,
not new, functionality.)
The use of SQLSetStmtAttr to set, and SQLGetStmtAttr to get, the following statement attributes. (The
use of SQLSetStmtAttr to set, and SQLGetStmtAttr to get, other statement attributes is duplicated, not
new, functionality.)
SQL_ATTR_APP_ROW_DESC
SQL_ATTR_APP_PARAM_DESC
SQL_ATTR_ENABLE_AUTO_IPD
SQL_ATTR_FETCH_BOOKMARK_PTR
SQL_ATTR_BIND_OFFSET
SQL_ATTR_METADATA_ID
SQL_ATTR_PARAM_BIND_OFFSET_PTR
SQL_ATTR_PARAM_BIND_TYPE
SQL_ATTR_PARAM_OPERATION_PTR
SQL_DESC_PARAM_STATUS_PTR
SQL_ATTR_PARAMS_PROCESSED_PTR
SQL_ATTR_PARAMSET_SIZE
SQL_ATTR_ROW_BIND_OFFSET_PTR
SQL_ATTR_ROW_OPERATION_PTR
SQL_ATTR_ROW_ARRAY_SIZE
The use of SQLGetStmtAttr to get the following statement attributes. (The use of SQLGetStmtAttr to
get other statement attributes is duplicated functionality, not new functionality.)
SQL_ATTR_IMP_ROW_DESC SQL_ATTR_IMP_PARAM_DESC
Use of the interval C data type, the interval SQL data types, the BIGINT C data types, and the
SQL_C_NUMERIC data structure.
Row-wise binding of parameters.
Offset-based bookmark fetches, such as calling SQLFetchScroll with a FetchOrientation argument of
SQL_FETCH_BOOKMARK and specifying an offset other than 0.
SQLFetch returning the row status array, number of rows fetched, fetching multiple rows, intermixing
calls with SQLFetchScroll , and intermixing calls with SQLBulkOperations or SQLSetPos . For more
information, see the next section, Block Cursors, Scrollable Cursors, and Backward Compatibility for
ODBC 3.x Applications.
Named parameters.
Any of the ODBC 3.x-specific SQLGetInfo options. (If an ODBC 3.x application working with an ODBC 2.x
driver calls the SQL_XXX_CURSOR_ATTRIBUTES1 information types, which have replaced several ODBC
2.x information types, some of the information might be reliable, but some might be unreliable. For more
information, see SQLGetInfo.)
Bind offsets.
Updating, refreshing, and deleting by bookmarks (through a call to SQLBulkOperations ).
Calling SQLBulkOperations or SQLSetPos in the S5 state.
The ROW_NUMBER and COLUMN_NUMBER fields in the diagnostic record (which have to be retrieved
by the replacement functions SQLGetDiagField or SQLGetDiagRec ).
Approximate row counts.
Warning information (SQL_ROW_SUCCESS_WITH_INFO from SQLFetchScroll ).
Variable-length bookmarks.
Extended error information for arrays of parameters.
All of the new columns in the result sets returned by the catalog functions.
Use of SQLDescribeCol and SQLColAttribute on column 0.
Use of any ODBC 3.x-specific column attributes in a call to SQLColAttribute .
Use of multiple environment handles.
This section contains the following topic.
Block Cursors, Scrollable Cursors, and Backward Compatibility for ODBC 3.x Applications
Block Cursors, Scrollable Cursors, and Backward
Compatibility for ODBC 3.x Applications
4/27/2022 • 4 minutes to read • Edit Online
The existence of both SQLFetchScroll and SQLExtendedFetch represents the first clear split in ODBC
between the Application Programming Interface (API), which is the set of functions the application calls, and the
Service Provider Interface (SPI), which is the set of functions the driver implements. This split is required to
balance the requirement in ODBC 3.x, which uses SQLFetchScroll , to align with the standards and be
compatible with ODBC 2.x, which uses SQLExtendedFetch .
The ODBC 3.x API, which is the set of functions the application calls, includes SQLFetchScroll and related
statement attributes. The ODBC 3.x SPI, which is the set of functions the driver implements, includes
SQLFetchScroll , SQLExtendedFetch , and related statement attributes. Because ODBC does not formally
enforce this split between the API and the SPI, it is possible for ODBC 3.x applications to call
SQLExtendedFetch and related statement attributes. However, there is no reason for ODBC 3.x applications to
do this. For more information about APIs and SPIs, see the introduction to ODBC Architecture.
For information about how the ODBC 3.x Driver Manager maps calls to ODBC 2.x and ODBC 3.x drivers, and
what functions and statement attributes an ODBC 3.x driver should implement for block and scrollable cursors,
see What the Driver Does in Appendix G: Driver Guidelines for Backward Compatibility.
The following table summarizes what functions and statement attributes an ODBC 3.x application should use
with block and scrollable cursors. It also lists changes between ODBC 2.x and ODBC 3.x in this area that ODBC
3.x applications should be aware of to be compatible with ODBC 2.x drivers.
F UN C T IO N O R
STAT EM EN T AT T RIB UT E C O M M EN T S
STAT EM EN T AT T RIB UT E C O M M EN T S
STAT EM EN T AT T RIB UT E C O M M EN T S
NOTE
ODBC 3.x applications should not use SQLExtendedFetch or the SQL_ROWSET_SIZE statement attribute. Instead, they
should use SQLFetchScroll and the SQL_ATTR_ROW_ARRAY_SIZE statement attribute. ODBC 3.x applications should not
use SQLSetPos with an Operation of SQL_ADD but should use SQLBulkOperations with an Operation of SQL_ADD.
Duplicated Features
4/27/2022 • 2 minutes to read • Edit Online
The following ODBC 2.x functions have been duplicated by ODBC 3.x functions. As a result, the ODBC 2.x
functions are deprecated in ODBC 3.x. The ODBC 3.x functions are referred to as replacement functions.
When an application uses a deprecated ODBC 2.x function and the underlying driver is an ODBC 3.x driver, the
Driver Manager maps the function call to the corresponding replacement function. The only exception to this
rule is SQLExtendedFetch . (See the footnote at the end of the following table.) For more information about
these mappings, see Mapping Deprecated Functions in Appendix G: Driver Guidelines for Backward
Compatibility.
When an application uses a replacement function and the underlying driver is an ODBC 2.x driver, the Driver
Manager maps the function call to the corresponding deprecated function.
O DB C 2. X F UN C T IO N O DB C 3. X F UN C T IO N
SQLColAttributes SQLColAttribute
SQLError SQLGetDiagRec
SQLFreeConnect SQLFreeHandle
SQLFreeEnv SQLFreeHandle
SQLGetConnectOption SQLGetConnectAttr
SQLGetStmtOption SQLGetStmtAttr
SQLSetConnectOption SQLSetConnectAttr
SQLSetParam SQLBindParameter
SQLSetStmtOption SQLSetStmtAttr
SQLTransact SQLEndTran
[1] The function SQLExtendedFetch is duplicated functionality; SQLFetchScroll provides the same
functionality in ODBC 3.x. However, the Driver Manager does not map SQLExtendedFetch to SQLFetchScroll
when going against an ODBC 3.x driver. For more information, see What the Driver Manager Does in Appendix
G: Driver Guidelines for Backward Compatibility. The Driver Manager maps SQLFetchScroll to
SQLExtendedFetch when going against an ODBC 2.x driver.
NOTE
The function SQLBindParam is a special case. SQLBindParam is duplicated functionality. This is not an ODBC 2.x
function, but a function that is present in the Open Group and ISO standards. The functionality provided by this function
is completely subsumed by that of SQLBindParameter . As a result, the Driver Manager maps a call to SQLBindParam
to SQLBindParameter when the underlying driver is an ODBC 3.x driver. However, when the underlying driver is an
ODBC 2.x driver, the Driver Manager does not perform this mapping.
Behavioral Changes
4/27/2022 • 2 minutes to read • Edit Online
Behavioral changes are those changes for which the syntax of the interface remains the same, but the semantics
have changed. For these changes, functionality used in ODBC 2.x behaves differently than the same functionality
in ODBC 3.x.
Whether an application exhibits ODBC 2.x behavior or ODBC 3.x behavior is determined by the
SQL_ATTR_ODBC_VERSION environment attribute. This 32-bit value is set to SQL_OV_ODBC2 to exhibit ODBC
2.x behavior, and SQL_OV_ODBC3 to exhibit ODBC 3.x behavior.
The SQL_ATTR_ODBC_VERSION environment attribute is set by a call to SQLSetEnvAttr . After an application
calls SQL AllocHandle to allocate an environment handle, it must callSQLSetEnvAttr immediately to set the
behavior it exhibits. (As a result, there is a new environment state to describe the environment handle in an
allocated, but versionless, state.) For more information, see Appendix B: ODBC State Transition Tables.
An application states what behavior it exhibits with the SQL_ATTR_ODBC_VERSION environment attribute, but
the attribute has no effect on the application's connection with an ODBC 2.x or ODBC 3.x driver. An ODBC 3.x
application can connect to either an ODBC 2.x or 3.x driver, no matter what the setting of the environment
attribute.
ODBC 3.x applications should never call SQL AllocEnv . As a result, if the Driver Manager receives a call to
SQL AllocEnv , it recognizes the application as an ODBC 2.x application.
The SQL_ATTR_ODBC_VERSION attribute affects three different aspects of an ODBC 3.x driver's behavior:
SQLSTATEs
Data types for date, time, and timestamp
The CatalogName argument in SQLTables accepts search patterns in ODBC 3.x, but not in ODBC 2.x
The setting of the SQL_ATTR_ODBC_VERSION environment attribute does not affect SQLSetParam or
SQLBindParam . SQLColAttribute is also not affected by this bit. Although SQLColAttribute returns
attributes that are affected by the version of ODBC (date type, precision, scale and length), the intended behavior
is determined by the value of the FieldIdentifier argument. When FieldIdentifier is equal to SQL_DESC_TYPE,
SQLColAttribute returns the ODBC 3.x codes for date, time, and timestamp; when FieldIdentifier is equal to
SQL_COLUMN_TYPE, SQLColAttribute returns the ODBC 2.x codes for date, time, and timestamp.
This section contains the following topics.
SQLSTATE Mappings
Datetime Data Type Changes
SQLSTATE Mappings
4/27/2022 • 2 minutes to read • Edit Online
This topic discusses SQLSTATE values for ODBC 2.x and ODBC 3.x. For more information on ODBC 3.x SQLSTATE
values, see Appendix A: ODBC Error Codes.
In ODBC 3.x, HYxxx SQLSTATEs are returned instead of S1xxx, and 42Sxx SQLSTATEs are returned instead of
S00XX. This was done to align with Open Group and ISO standards. In many cases, the mapping is not one-to-
one because the standards have redefined the interpretation of several SQLSTATEs.
When an ODBC 2.x application is upgraded to an ODBC 3.x application, the application has to be changed to
expect ODBC 3.x SQLSTATEs instead of ODBC 2.x SQLSTATEs. The following table lists the ODBC 3.x SQLSTATEs
that each ODBC 2.x SQLSTATE is mapped to.
When the SQL_ATTR_ODBC_VERSION environment attribute is set to SQL_OV_ODBC2, the driver posts ODBC
2.x SQLSTATEs instead of ODBC 3.x SQLSTATEs when SQLGetDiagField or SQLGetDiagRec is called. A specific
mapping can be determined by noting the ODBC 2.x SQLSTATE in column 1 of the following table that
corresponds to the ODBC 3.x SQLSTATE in column 2.
O DB C 2. X SQ L STAT E O DB C 3. X SQ L STAT E C O M M EN T S
01S03 01001
01S04 01001
22003 HY019
22008 22007
22005 22018
24000 07005
37000 42000
70100 HY018
S0001 42S01
S0002 42S02
S0011 42S11
S0012 42S12
S0021 42S21
S0022 42S22
S0023 42S23
O DB C 2. X SQ L STAT E O DB C 3. X SQ L STAT E C O M M EN T S
S1000 HY000
S1001 HY001
S1003 HY003
S1004 HY004
S1008 HY008
S1011 HY011
S1012 HY012
S1090 HY090
S1091 HY091
S1092 HY092
S1096 HY096
O DB C 2. X SQ L STAT E O DB C 3. X SQ L STAT E C O M M EN T S
S1097 HY097
S1098 HY098
S1099 HY099
S1100 HY100
S1101 HY101
S1103 HY103
S1104 HY104
S1105 HY105
S1106 HY106
S1107 HY107
S1108 HY108
S1109 HY109
S1110 HY110
S1111 HY111
S1C00 HYC00
S1T00 HYT00
NOTE
ODBC 3.x SQLSTATE 07008 is mapped to ODBC 2.x SQLSTATE S1000.
Datetime Data Type Changes
4/27/2022 • 2 minutes to read • Edit Online
In ODBC 3.x, the identifiers for date, time, and timestamp SQL data types have changed from SQL_DATE,
SQL_TIME, and SQL_TIMESTAMP (with instances of #define in the header file of 9, 10, and 11) to
SQL_TYPE_DATE, SQL_TYPE_TIME, and SQL_TYPE_TIMESTAMP (with instances of #define in the header file of
91, 92, and 93), respectively. The corresponding C type identifiers have changed from SQL_C_DATE,
SQL_C_TIME, and SQL_C_TIMESTAMP to SQL_C_TYPE_DATE, SQL_C_TYPE_TIME, and SQL_C_TYPE_TIMESTAMP,
respectively.
The column size and decimal digits returned for the SQL datetime data types in ODBC 3.x are the same as the
precision and scale returned for them in ODBC 2.x. These values are different than the values in the
SQL_DESC_PRECISION and SQL_DESC_SCALE descriptor fields. (For more information, see Column Size,
Decimal Digits, Transfer Octet Length, and Display Size.)
These changes affect SQLDescribeCol , SQLDescribeParam , and SQLColAttribute ; SQLBindCol ,
SQLBindParameter , and SQLGetData ; and SQLColumns , SQLGetTypeInfo , SQLProcedureColumns ,
SQLStatistics , and SQLSpecialColumns .
The following table shows how the ODBC 3.x Driver Manager performs mapping of the date, time, and
timestamp C data types entered in the TargetType arguments of SQLBindCol and SQLGetData or in the
ValueType argument of SQLBindParameter .
DATA T Y P E 2. X A P P TO 2. X A P P TO 3. X A P P TO 3. X A P P TO
SQL_C_TYPE_DATE Error (from DM) Error (from DM) SQL_C_DATE (9) No mapping[2]
(91)
SQL_C_TYPE_TIME Error (from DM) Error (from DM) SQL_C_TIME (10) No mapping[2]
(92)
[1] As a result of this, an ODBC 3.x application working with an ODBC 2.x driver can use the date, time, or
timestamp codes returned in the result sets that are returned by the catalog functions.
[2] As a result of this, an ODBC 3.x application working with an ODBC 3.x driver can use the date, time, or
timestamp codes returned in the result sets that are returned by the catalog functions.
The following table shows how the ODBC 3.x Driver Manager performs mapping of the date, time, and
timestamp SQL data types entered in the ParameterType argument of SQLBindParameter or in the DataType
argument of SQLGetTypeInfo .
DATA T Y P E 2. X A P P TO 2. X A P P TO 3. X A P P TO 3. X A P P TO
SQL_TYPE_DATE (91) Error (from DM) Error (from DM) SQL_DATE (9) No mapping[2]
SQL_TYPE_TIME (92) Error (from DM) Error (from DM) SQL_TIME (10) No mapping[2]
[1] As a result of this, an ODBC 3.x application working with an ODBC 2.x driver can use the date, time, or
timestamp codes returned in the result sets that are returned by the catalog functions.
[2] As a result of this, an ODBC 3.x application working with an ODBC 3.x driver can use the date, time, or
timestamp codes returned in the result sets that are returned by the catalog functions.
Writing ODBC 3.x Applications
4/27/2022 • 4 minutes to read • Edit Online
When an ODBC 2.x application is upgraded to ODBC 3.x, it should be written such that it works with both ODBC
2.x and 3.x drivers. The application should incorporate conditional code to take full advantage of the ODBC 3.x
features.
The SQL_ATTR_ODBC_VERSION environment attribute should be set to SQL_OV_ODBC2. This will ensure that
the driver behaves like an ODBC 2.x driver with respect to the changes described in the section Behavioral
Changes.
If the application will use any of the features described in the section New Features, conditional code should be
used to determine whether the driver is an ODBC 3.x or ODBC 2.x driver. The application uses
SQLGetDiagField and SQLGetDiagRec to obtain ODBC 3.x SQLSTATEs while doing error processing on these
conditional code fragments. The following points about the new functionality should be considered:
An application affected by the change in rowset size behavior should be careful not to call SQLFetch
when the array size is greater than 1. These applications should replace calls to SQLExtendedFetch with
calls to SQLSetStmtAttr to set the SQL_ATTR_ARRAY_STATUS_PTR statement attribute and to
SQLFetchScroll , so that they have common code that works with both ODBC 3.x and ODBC 2.x drivers.
Because SQLSetStmtAttr with SQL_ATTR_ROW_ARRAY_SIZE will be mapped to SQLSetStmtAttr with
SQL_ROWSET_SIZE for ODBC 2.x drivers, applications can just set SQL_ATTR_ROW_ARRAY_SIZE for their
multirow fetch operations.
Most applications that are upgrading are not actually affected by changes in SQLSTATE codes. For those
applications that are affected, they can do a mechanical search and replace in most cases using the error
conversion table in the "SQLSTATE Mapping" section to convert ODBC 3.x error codes to ODBC 2.x codes.
Since the ODBC 3.x Driver Manager will perform mapping from ODBC 2.x SQLSTATEs to ODBC 3.x
SQLSTATEs, these application writers need only check for the ODBC 3.x SQLSTATEs and not worry about
including ODBC 2.x SQLSTATEs in conditional code.
If an application makes great use of date, time, and timestamp data types, the application can declare
itself to be an ODBC 2.x application and use its existing code instead of using conditioning code.
The upgrade should also include the following steps:
Call SQLSetEnvAttr before allocating a connection to set the SQL_ATTR_ODBC_VERSION environment
attribute to SQL_OV_ODBC2.
Replace all calls to SQL AllocEnv , SQL AllocConnect , or SQL AllocStmt with calls to SQL AllocHandle
with the appropriate HandleType argument of SQL_HANDLE_ENV, SQL_HANDLE_DBC, or
SQL_HANDLE_STMT.
Replace all calls to SQLFreeEnv or SQLFreeConnect with calls to SQLFreeHandle with the
appropriate HandleType argument of SQL_HANDLE_DBC or SQL_HANDLE_STMT.
Replace all calls to SQLSetConnectOption with calls to SQLSetConnectAttr . If setting an attribute
whose value is a string, set the StringLength argument appropriately. Change Attribute argument from
SQL_XXXX to SQL_ATTR_XXXX.
Replace all calls to SQLGetConnectOption with calls to SQLGetConnectAttr . If getting a string or
binary attribute, set BufferLength to the appropriate value and pass in a StringLength argument. Change
Attribute argument from SQL_XXXX to SQL_ATTR_XXXX.
Replace all calls to SQLSetStmtOption with calls to SQLSetStmtAttr . If setting an attribute whose
value is a string, set the StringLength argument appropriately. Change Attribute argument from
SQL_XXXX to SQL_ATTR_XXXX.
Replace all calls to SQLGetStmtOption with calls to SQLGetStmtAttr . If getting a string or binary
attribute, set BufferLength to the appropriate value and pass in a StringLength argument. Change
Attribute argument from SQL_XXXX to SQL_ATTR_XXXX.
Replace all calls to SQLTransact with calls to SQLEndTran . If the rightmost valid handle in the
SQLTransact call is an environment handle, a HandleType argument of SQL_HANDLE_ENV should be
used in the SQLEndTran call with the appropriate Handle argument. If the rightmost valid handle in your
SQLTransact call is a connection handle, a HandleType argument of SQL_HANDLE_DBC should be used
in the SQLEndTran call with the appropriate Handle argument.
Replace all calls to SQLColAttributes with calls to SQLColAttribute . If the FieldIdentifier argument is
either SQL_COLUMN_PRECISION, SQL_COLUMN_SCALE, or SQL_COLUMN_LENGTH, do not change
anything other than the name of the function. If not, change FieldIdentifier from SQL_COLUMN_XXXX to
SQL_DESC_XXXX. If FieldIdentifier is SQL_DESC_CONCISE_TYPE and the data type is a datetime data type,
change to the corresponding ODBC 3.x data type.
If using block cursors, scrollable cursors, or both, the application does the following:
Sets the rowset size, cursor type, and cursor concurrency using SQLSetStmtAttr .
Calls SQLSetStmtAttr to set SQL_ATTR_ROW_STATUS_PTR to point to an array of status records.
Calls SQLSetStmtAttr to set SQL_ATTR_ROWS_FETCHED_PTR to point to an SQLINTEGER.
Performs the required bindings and executes the SQL statement.
Calls SQLFetchScroll in a loop to fetch rows and move around in the result set.
If it wants to fetch by bookmark, the application calls SQLSetStmtAttr to set
SQL_ATTR_FETCH_BOOKMARK_PTR to a variable that will contain the bookmark for the row that it
wants to fetch, and calls SQLFetchScroll with a FetchOrientation argument of
SQL_FETCH_BOOKMARK.
If using arrays of parameters, the application does the following:
Calls SQLSetStmtAttr to set the SQL_ATTR_PARAMSET_SIZE attribute to the size of the parameter
array.
Calls SQLSetStmtAttr to set SQL_ATTR_ROWS_PROCESSED_PTR to point to an internal
UDWORD variable.
Performs prepare, bind, and execute operations as appropriate.
If execution halts for some reason (such as SQL_NEED_DATA), it can find the "current" row of
parameters by inspecting the location pointed to by SQL_ATTR_ROWS_PROCESSED_PTR.
This section contains the following topics.
Mapping Replacement Functions for Backward Compatibility of Applications
Calling SQLCloseCursor
Calling SQLGetDiagField
Calling SQLSetPos
Cursor Library Operations
Mapping the Cursor Attributes1 Information Types
SQL_NO_DATA
Mapping Replacement Functions for Backward
Compatibility of Applications
4/27/2022 • 14 minutes to read • Edit Online
An ODBC 3.x application working through the ODBC 3.x Driver Manager will work against an ODBC 2.x driver as
long as no new features are used. Both duplicated functionality and behavioral changes do, however, affect the
way that the ODBC 3.x application works on an ODBC 2.x driver. When working with an ODBC 2.x driver, the
Driver Manager maps the following ODBC 3.x functions, which have replaced one or more ODBC 2.x functions,
into the corresponding ODBC 2.x functions.
O DB C 3. X F UN C T IO N O DB C 2. X F UN C T IO N
SQLBulkOperations SQLSetPos
SQLColAttribute SQLColAttributes
SQLEndTran SQLTransact
SQLFetch SQLExtendedFetch
SQLFetchScroll SQLExtendedFetch
SQLGetConnectAttr SQLGetConnectOption
SQLGetDiagRec SQLError
SQLSetConnectAttr SQLSetConnectOption
[1] Other actions might also be taken, depending on the attribute being requested.
SQLAllocHandle
The Driver Manager maps this to SQL AllocEnv , SQL AllocConnect , or SQL AllocStmt , as appropriate. The
following call to SQL AllocHandle :
will result in the Driver Manager performing the following (conceptual, no error checking) mapping:
switch (HandleType) {
case SQL_HANDLE_ENV: return (SQLAllocEnv(OutputHandlePtr));
case SQL_HANDLE_DBC: return (SQLAllocConnect (InputHandle, OutputHandlePtr));
case SQL_HANDLE_STMT: return (SQLAllocStmt (InputHandle, OutputHandlePtr));
default: // return SQL_ERROR, SQLSTATE HY092 ("Invalid attribute/option identifier")
}
SQLBulkOperations
The Driver Manager maps this to SQLSetPos . The following call to SQLBulkOperations :
SQLBulkOperations(hstmt, Operation);
2. If the Operation argument is not SQL_ADD, the driver returns SQLSTATE HY092 (Invalid attribute/option
identifier).
3. If the application attempts to change the SQL_ATTR_ROW_STATUS_PTR between calls to SQLFetch or
SQLFetchScroll and SQLBulkOperations , the Driver Manager will return SQLSTATE HY011 (Attribute
cannot be set now).
4. If the Operation argument is SQL_ADD, the application must call SQLBindCol to bind the data to be
inserted. It cannot call SQLSetDescField or SQLSetDescRec to bind the data to be inserted.
5. If the Operation argument is SQL_ADD and the number of rows to be inserted is not the same as the
current rowset size, SQLSetStmtAttr must be called to set the SQL_ATTR_ROW_ARRAY_SIZE statement
attribute to the number of rows to be inserted before calling SQLBulkOperations . To revert back to the
previous rowset size, the application must set the SQL_ATTR_ROW_ARRAY_SIZE statement attribute
before SQLFetch , SQLFetchScroll , or SQLSetPos is called.
SQLColAttribute
The Driver Manager maps this to SQLColAttributes . The following call to SQLColAttribute :
3. All other FieldIdentifier values are passed through to the driver, with SQLColAttribute mapped to
SQLColAttributes as shown previously.
4. If BufferLength is less than 0, the Driver Manager returns SQL_ERROR with SQLSTATE HY090 (Invalid
string or buffer length). No further rules of this section apply.
5. If FieldIdentifier is SQL_DESC_CONCISE_TYPE and the returned type is a concise datetime data type, the
Driver Manager maps the return values for date, time, and timestamp codes.
6. The Driver Manager performs necessary checks to see whether SQLSTATE HY010 (Function sequence
error) needs to be raised. If so, the Driver Manager returns SQL_ERROR and SQLSTATE HY010 (Function
sequence error). No further rules of this section apply.
SQLEndTran
The Driver Manager maps this to SQLTransact . The following call to SQLEndTran :
will result in the Driver Manager performing the following (conceptual, no error checking) mapping:
switch (HandleType) {
case SQL_HANDLE_ENV:return(SQLTransact(Handle, SQL_NULL_HDBC, CompletionType));
case SQL_HANDLE_DBC:return(SQLTransact(SQL_NULL_HENV, Handle, CompletionType);
default: // return SQL_ERROR, SQLSTATE HY092 ("Invalid attribute/option identifier")
}
SQLFetch
The Driver Manager maps this to SQLExtendedFetch with a FetchOrientation argument of SQL_FETCH_NEXT.
The following call to SQLFetch :
SQLFetch (StatementHandle);
In this call, the pcRow argument is set to the value that the application sets the SQL_ATTR_ROWS_FETCHED_PTR
statement attribute to through a call to SQLSetStmtAttr .
NOTE
When the application calls SQLSetStmtAttr to set SQL_ATTR_ROW_STATUS_PTR to point to a status array, the Driver
Manager caches the pointer. RowStatusArray can be equal to a null pointer.
If the driver does not support SQLExtendedFetch and the cursor library is loaded, the Driver Manager uses the
cursor library's SQLExtendedFetch to map SQLFetch to SQLExtendedFetch . If the driver does not support
SQLExtendedFetch and the cursor library is not loaded, the Driver Manager passes the call to SQLFetch
through to the driver. If the application calls SQLSetStmtAttr to set SQL_ATTR_ROW_STATUS_PTR, the Driver
Manager ensures that the array is populated. If the application calls SQLSetStmtAttr to set
SQL_ATTR_ROWS_FETCHED_PTR, the Driver Manager sets this field to 1.
SQLFetchScroll
The Driver Manager maps this to SQLExtendedFetch . The following call to SQLFetchScroll :
In these calls, the pcRow argument is set to the value that the application sets the
SQL_ATTR_ROWS_FETCHED_PTR statement attribute to through a call to SQLSetStmtAttr .
SQL_ATTR_ROW_ARRAY_SIZE is mapped to SQL_ROWSET_SIZE.
If rc is equal to SQL_SUCCESS or SQL_SUCCESS_WITH_INFO, and if FetchOrientation is equal to
SQL_FETCH_BOOKMARK and FetchOffset is not equal to 0, then the Driver Manager posts a warning,
SQLSTATE 01S10 (Attempt to fetch by a bookmark offset, offset value ignored), and returns
SQL_SUCCESS_WITH_INFO.
SQLFreeHandle
The Driver Manager maps this to SQLFreeEnv , SQLFreeConnect , or SQLFreeStmt as appropriate. The
following call to SQLFreeHandle :
SQLFreeHandle(HandleType, Handle);
will result in the Driver Manager performing the following (conceptual, no error checking) mapping:
switch (HandleType) {
case SQL_HANDLE_ENV: return (SQLFreeEnv(Handle));
case SQL_HANDLE_DBC: return (SQLFreeConnect(Handle));
case SQL_HANDLE_STMT: return (SQLFreeStmt(Handle, SQL_DROP));
default: // return SQL_ERROR, SQLSTATE HY092 ("Invalid attribute/option identifier")
}
SQLGetConnectAttr
The Driver Manager maps this to SQLGetConnectOption . The following call to SQLGetConnectAttr :
SQLGetData
When an ODBC 3.x application working with an ODBC 2.x driver calls SQLGetData with the ColumnNumber
argument equal to 0, the ODBC 3.x Driver Manager maps this to a call to SQLGetStmtOption with the Option
attribute set to SQL_GET_BOOKMARK.
SQLGetStmtAttr
The Driver Manager maps this to SQLGetStmtOption . The following call to SQLGetStmtAttr :
where hstmt, fOption, and pvParam will be set to the values of StatementHandle, Attribute, and ValuePtr,
respectively. The BufferLength and StringLengthPtr are ignored.
SQLSetConnectAttr
The Driver Manager maps this to SQLSetConnectOption . The following call to SQLSetConnectAttr :
SQLSetConnectAttr(ConnectionHandle, Attribute, ValuePtr, StringLength);
where hdbc, fOption, and vParam will be set to the values of ConnectionHandle, Attribute, and ValuePtr,
respectively. StringLengthPtr is ignored.
NOTE
The ability to set statement attributes on the connection level has been deprecated. Statement attributes should never be
set on the connection level by an ODBC 3.x application.
SQLSetStmtAttr
The Driver Manager maps this to SQLSetStmtOption . The following call to SQLSetStmtAttr :
where hstmt, fOption, and vParam will be set to the values of StatementHandle, Attribute, and ValuePtr,
respectively. The StringLength argument is ignored.
If an ODBC 2.x driver supports character-string, driver-specific statement options, an ODBC 3.x
application should call SQLSetStmtOption to set those options.
The Driver Manager later returns a pointer to this variable when the application calls SQLGetStmtAttr to
retrieve SQL_ATTR_PARAMS_PROCESSED_PTR. The Driver Manager cannot change this internal variable until
the statement handle is returned to the prepared or allocated state.
An ODBC 3.x application can call SQLGetStmtAttr to obtain the value of SQL_ATTR_PARAMS_PROCESSED_PTR
even though it has not explicitly set the SQL_DESC_ARRAY_SIZE field in the APD. This situation could arise, for
example, if the application has a generic routine that checks for the current "row" of parameters being processed
when SQLExecute returns SQL_NEED_DATA. This routine is invoked whether or not the SQL_DESC_ARRAY_SIZE
is 1 or is greater than 1. To account for this, the Driver Manager will need to define this internal variable whether
or not the application has called SQLSetStmtAttr to set the SQL_DESC_ARRAY_SIZE field in APD. If
SQL_DESC_ARRAY_SIZE has not been set, the Driver Manager has to make sure that this variable contains the
value 1 prior to returning from SQLExecDirect or SQLExecute .
Error Handling
In ODBC 3.x, calling SQLFetch or SQLFetchScroll populates the SQL_DESC_ARRAY_STATUS_PTR in the IRD,
and the SQL_DIAG_ROW_NUMBER field of a given diagnostic record contains the number of the row in the
rowset that this record pertains to. Using this, the application can correlate an error message with a given row
position.
An ODBC 2.x driver will be unable to provide this functionality. However, it will provide error demarcation with
SQLSTATE 01S01 (Error in row). An ODBC 3.x application that is using SQLFetch or SQLFetchScroll while
going against an ODBC 2.x driver needs to be aware of this fact. Note also that such an application will be
unable to call SQLGetDiagField to actually get the SQL_DIAG_ROW_NUMBER field anyway. An ODBC 3.x
application working with an ODBC 2.x driver will be able to call SQLGetDiagField only with a DiagIdentifier
argument of SQL_DIAG_MESSAGE_TEXT, SQL_DIAG_NATIVE, SQL_DIAG_RETURNCODE, or
SQL_DIAG_SQLSTATE. The ODBC 3.x Driver Manager maintains the diagnostic data structure when working with
an ODBC 2.x driver, but the ODBC 2.x driver returns only these four fields.
When an ODBC 2.x application is working with an ODBC 2.x driver, if an operation can cause multiple errors to
be returned by the Driver Manager, different errors may be returned by the ODBC 3.x Driver Manager than by
the ODBC 2.x Driver Manager.
SQL_DESC_AUTO_UNIQUE_VALUE SQL_FALSE
SQL_DESC_CASE_SENSITIVE SQL_FALSE
SQL_DESC_CONCISE_TYPE SQL_BINARY
SQL_DESC_DATETIME_INTERVAL_CODE 0
SQL_DESC_DISPLAY_SIZE 8
SQL_DESC_FIXED_PREC_SCALE SQL_FALSE
SQL_DESC_LENGTH 0
SQL_DESC_NULLABLE SQL_NO_NULLS
SQL_DESC_OCTET_LENGTH 4
SQL_DESC_PRECISION 4
SQL_DESC_SCALE 0
SQL_DESC_SEARCHABLE SQL_PRED_NONE
SQL_DESC_TYPE SQL_BINARY
SQL_DESC_UNNAMED SQL_UNNAMED
SQL_DESC_UNSIGNED SQL_FALSE
SQL_DESC_UPDATEABLE SQL_ATTR_READ_ONLY
SQLDescribeCol
When an ODBC 3.x application working with an ODBC 2.x driver calls SQLDescribeCol with the
ColumnNumber argument set to 0, the Driver Manager returns the values listed in the following table.
B UF F ER VA L UE
*NameLengthPtr 0
*DataTypePtr SQL_BINARY
*ColumnSizePtr 4
*DecimalDigitsPtr 0
*NullablePtr SQL_NO_NULLS
SQLGetData
When an ODBC 3.x application working with an ODBC 2.x driver makes the following call to SQLGetData to
retrieve a bookmark:
where hstmt and pvParam are set to the values in StatementHandle and TargetValuePtr, respectively. The
bookmark is returned in the buffer pointed to by the pvParam (TargetValuePtr) argument. The value in the buffer
pointed to by the StrLen_or_IndPtr argument in the call to SQLGetData is set to 4.
This mapping is necessary to account for the case in which SQLFetch was called prior to the call to
SQLGetData and the ODBC 2.x driver did not support SQLExtendedFetch . In this case, SQLFetch would be
passed through to the ODBC 2.x driver, in which case bookmark retrieval is not supported.
SQLGetData cannot be called multiple times in an ODBC 2.x driver to retrieve a bookmark in parts, so calling
SQLGetData with the BufferLength argument set to a value less than 4 and the ColumnNumber argument set
to 0 will return SQLSTATE HY090 (Invalid string or buffer length). SQLGetData can, however, be called multiple
times to retrieve the same bookmark.
SQLSetStmtAttr
When an ODBC 3.x application working with an ODBC 2.x driver calls SQLSetStmtAttr to set the
SQL_ATTR_USE_BOOKMARKS attribute to SQL_UB_VARIABLE, the Driver Manager sets the attribute to
SQL_UB_ON in the underlying ODBC 2.x driver.
Calling SQLCloseCursor
4/27/2022 • 2 minutes to read • Edit Online
Because SQLCloseCursor is almost the same as SQLFreeStmt with SQL_CLOSE, the Driver Manager does not
map this function. Replacement functions are mapped so that existing ODBC 2.x applications can easily move to
ODBC 3.x by using the new functions. Such a move makes it easier for such applications to begin using new
ODBC 3.x functionality inside of conditional code in a modular fashion. SQLCloseCursor does not represent
any new functionality. An application does not gain any advantage by moving to SQLCloseCursor from
SQLFreeStmt with SQL_CLOSE.
Calling SQLGetDiagField
4/27/2022 • 2 minutes to read • Edit Online
When an ODBC 3.x application calls SQLGetDiagField in an ODBC 2.x driver, the driver will return
SQL_SUCCESS and the appropriate information in *DiagInfoPtr if the DiagIdentifier argument is
SQL_DIAG_CLASS_ORIGIN, SQL_DIAG_CLASS_SUBCLASS_ORIGIN, SQL_DIAG_CONNECTION_NAME,
SQL_DIAG_MESSAGE_TEXT, SQL_DIAG_NATIVE, SQL_DIAG_NUMBER, SQL_DIAG_RETURNCODE,
SQL_DIAG_SERVER_NAME, or SQL_DIAG_SQLSTATE. All other diagnostic fields will return SQL_ERROR.
Calling SQLSetPos
4/27/2022 • 2 minutes to read • Edit Online
In ODBC 2.x, the pointer to the row status array was an argument to SQLExtendedFetch . The row status array
was later updated by a call to SQLSetPos . Some drivers have relied on the fact that this array does not change
between SQLExtendedFetch and SQLSetPos . In ODBC 3.x, the pointer to the status array is a descriptor field
and therefore the application can easily change it to point to a different array. This can be a problem when an
ODBC 3.x application is working with an ODBC 2.x driver but is calling SQLSetStmtAttr to set the array status
pointer and is calling SQLFetchScroll to fetch data. The Driver Manager maps it as a sequence of calls to
SQLExtendedFetch . In the following code, an error would normally be raised when the Driver Manager maps
the second SQLSetStmtAttr call when working with an ODBC 2.x driver:
The error would be raised if there were no way to change the row status pointer in ODBC 2.x between calls to
SQLExtendedFetch . Instead, the Driver Manager performs the following steps when working with an ODBC 2.x
driver:
1. Initializes an internal Driver Manager flag fSetPosError to TRUE.
2. When an application calls SQLFetchScroll , the Driver Manager sets fSetPosError to FALSE.
3. When the application calls SQLSetStmtAttr to set SQL_ATTR_ROW_STATUS_PTR, the Driver Manager
sets fSetPosError equal toTRUE.
4. When the application calls SQLSetPos , with fSetPosError equal to TRUE, the Driver Manager raises
SQL_ERROR with SQLSTATE HY011 (Attribute cannot be set now) to indicate that the application
attempted to call SQLSetPos after changing the row status pointer but prior to calling SQLFetchScroll .
Cursor Library Operations
4/27/2022 • 2 minutes to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan
to modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
If an application working with an ODBC 2.x driver makes calls to the ODBC 3.x cursor library, the application
might be able to use ODBC 3.x features that are not supported by the ODBC 2.x driver. An application writer
should be careful how these features are used, however. Use of the ODBC 3.x cursor library does not make an
ODBC 2.x driver into an ODBC 3.x driver.
Mapping the Cursor Attributes1 Information Types
4/27/2022 • 2 minutes to read • Edit Online
When an ODBC 3.x application calls SQLGetInfo in an ODBC 2*.x* driver with the
SQL_XXXX_CURSOR_ATTRIBUTES1 information type (for dynamic, forward-only, keyset-driver, or static cursors),
the setting of the bits returned by Driver Manager depends on what the ODBC 2.x driver returns for the
corresponding ODBC 2.x information types. The bits are set as shown in the following table.
B IT IN O DB C 2. X IN F O RM AT IO N
When an ODBC 3.x application calls SQLExecDirect , SQLExecute , or SQLParamData in an ODBC 2.x driver to
execute a searched update or delete statement that does not affect any rows at the data source, the driver
should return SQL_SUCCESS, not SQL_NO_DATA. When an ODBC 2.x or ODBC 3.x application working with an
ODBC 3.x driver calls SQLExecDirect , SQLExecute , or SQLParamData with the same result, the ODBC 3.x
driver should return SQL_NO_DATA.
Writing ODBC 3.x Drivers
4/27/2022 • 2 minutes to read • Edit Online
The following table shows function support in an ODBC 3.x driver and an ODBC application, and the mapping
performed by the Driver Manager when the functions are called against an ODBC 3.x driver.
BY AN BY AN B Y T H E O DB C 3. X
O DB C 3. X O DB C 3. X DRIVER M A N A GER TO
F UN C T IO N DRIVER? A P P L IC AT IO N ? A N O DB C 3. X DRIVER?
BY AN BY AN B Y T H E O DB C 3. X
O DB C 3. X O DB C 3. X DRIVER M A N A GER TO
F UN C T IO N DRIVER? A P P L IC AT IO N ? A N O DB C 3. X DRIVER?
SQLExtendedFetch Yes No No
BY AN BY AN B Y T H E O DB C 3. X
O DB C 3. X O DB C 3. X DRIVER M A N A GER TO
F UN C T IO N DRIVER? A P P L IC AT IO N ? A N O DB C 3. X DRIVER?
SQLParamOptions No No Yes
BY AN BY AN B Y T H E O DB C 3. X
O DB C 3. X O DB C 3. X DRIVER M A N A GER TO
F UN C T IO N DRIVER? A P P L IC AT IO N ? A N O DB C 3. X DRIVER?
SQLSetParam No No Yes
[1] This function is deprecated in ODBC 3.x. ODBC 3.x applications should not use this function. However, an
Open Group or ISO CLI-compliant application can call this function.
[2] ODBC 3.x applications should use SQLBindParameter instead of SQLBindParam . However, an Open
Group or ISO CLI-compliant application can call this function.
[3] Driver writers should note that the ODBC 2.x column attributes SQL_COLUMN_PRECISION,
SQL_COLUMN_SCALE, and SQL_COLUMN_LENGTH must be supported with SQLColAttribute .
[4] SQLCopyDesc is partially implemented by the Driver Manager when a descriptor is being copied across
connections that belong to different drivers. Drivers are required to support SQLCopyDesc across two of their
own connections. Functions such as SQLDrivers , which are implemented solely by the Driver Manager, do not
show up on this list.
[5] Under certain circumstances, drivers may need to support this function. For more information, see this
function's reference page.
[6] The driver can choose to support SQLGetFunctions if the set of functions that the driver supports varies
from connection to connection.
ODBC in Windows
4/27/2022 • 2 minutes to read • Edit Online
The following items apply only to ODBC running in Microsoft® Windows NT®/Windows 2000 and Microsoft
Windows® 95/98 operating systems.
This section contains the following topics.
Standards-Compliant Applications and Drivers
Header Files
Passing CString Objects to ODBC Functions
Creating and Terminating Threads
Standards-Compliant Applications and Drivers
4/27/2022 • 2 minutes to read • Edit Online
A standards-compliant application or driver is one that conforms to the Open Group CAE Specification "Data
Management: SQL Call-Level Interface (CLI)," and the ISO/IEC 9075-3:1995 (E) Call-Level Interface (SQL/CLI).
ODBC 3.x guarantees the following features:
An application written to the Open Group and ISO CLI specifications will work with an ODBC 3.x driver or
a standards-compliant driver when it is compiled with the ODBC 3.x header files and linked with ODBC
3.x libraries, and when it gains access to the driver through the ODBC 3.x Driver Manager.
A driver written to the Open Group and ISO CLI specifications will work with an ODBC 3.x application or a
standards-compliant application when it is compiled with the ODBC 3.x header files and linked with
ODBC 3.x libraries, and when the application gains access to the driver through the ODBC 3.x Driver
Manager.
Standards-compliant applications and drivers are compiled with the ODBC_STD compile flag.
Standards-compliant applications exhibit the following behavior:
If a standards-compliant application calls SQL AllocEnv (which can occur because SQL AllocEnv is a
valid function in the Open Group and ISO CLI), the call is mapped to SQL AllocHandleStd at compile
time. As a result, at run time, the application calls SQL AllocHandleStd . During the course of processing
this call, the Driver Manager sets the SQL_ATTR_ODBC_VERSION environment attribute to
SQL_OV_ODBC3. A call to SQL AllocHandleStd is equivalent to a call to SQL AllocHandle with a
HandleType of SQL_HANDLE_ENV and a call to SQLSetEnvAttr to set SQL_ATTR_ODBC_VERSION to
SQL_OV_ODBC3.
If a standards-compliant application calls SQLBindParam (which can occur because SQLBindParam is
a valid function in the Open Group and ISO CLI), the ODBC 3.x Driver Manager maps the call to the
equivalent call in SQLBindParameter . (See SQLBindParam Mapping in Appendix G: Driver Guidelines
for Backward Compatibility.)
To align with the ISO CLI, the ODBC 3.x header files contain aliases for information types used in calls to
SQLGetInfo . A standards-compliant application can use these aliases instead of the ODBC 3.x
information types. For more information, see the next topic, Header Files.
A standards-compliant application must verify that all features it supports are supported in the driver it
will work with. Setting the SQL_ATTR_CURSOR_SCROLLABLE statement attribute to SQL_SCROLLABLE
and setting the SQL_ATTR_CURSOR_SENSITIVITY statement attribute to SQL_INSENSITIVE or
SQL_SENSITIVE are capabilities that are available as optional features in the standards but are not
included in the ODBC 3.x Core level and therefore might not be supported by all ODBC 3.x drivers. If a
standards-compliant application uses these capabilities, it should verify that the driver that it will work
with supports them.
Header Files
4/27/2022 • 2 minutes to read • Edit Online
The Sql.h header file contains prototypes for the functions and features in the Core ODBC Interface conformance
level. The Sqlext.h header file contains prototypes for the functions and features in the Level 1 and Level 2 API
conformance levels. The Sqltypes.h header file contains type definitions and indicators for the SQL data types.
The header files all contain a #define , ODBCVER, that an application or driver can set to be compiled for
different versions of ODBC.
To align with the ISO CLI and Open Group CLI, the header files contain aliases for the information types used in
calls to SQLGetInfo . In the following table, the column "ODBC name" indicates the ODBC name for the
information type in ODBC API Reference. The column "Alias in header file" indicates the name that is used in the
ISO CLI and the Open Group CLI. The actual numeric value of these manifest names is the same in both ODBC
and the standard CLIs. These aliases enable a standards-compliant application or driver to compile with the
ODBC 3.x header files.
These aliases include expansions of abbreviations in the ODBC names so that the names are more
understandable. "MAX" is expanded to "MAXIMUM", "LEN" to "LENGTH", "MULT" to "MULTIPLE", "OJ" to
"OUTER_JOIN", and "TXN" to "TRANSACTION."
O DB C N A M E A L IA S IN H EA DER F IL E
SQL_MAX_CATALOG_NAME_LEN SQL_MAXIMUM_CATALOG_NAME_LENGTH
SQL_MAX_COLUMN_NAME_LEN SQL_MAXIMUM_COLUMN_NAME_LENGTH
SQL_MAX_COLUMNS_IN_GROUP_BY SQL_MAXIMUM_COLUMNS_IN_GROUP_BY
SQL_MAX_COLUMNS_IN_ORDER_BY SQL_MAXIMUM_COLUMNS_IN_ORDER_BY
SQL_MAX_COLUMNS_IN_SELECT SQL_MAXIMUM_COLUMNS_IN_SELECT
SQL_MAX_COLUMNS_IN_TABLE SQL_MAXIMUM_COLUMNS_IN_TABLE
SQL_MAX_CONCURRENT_ACTIVITIES SQL_MAXIMUM_CONCURRENT_ACTIVITIES
SQL_MAX_CURSOR_NAME_LEN SQL_MAXIMUM_CURSOR_NAME_LENGTH
SQL_MAX_DRIVER_CONNECTIONS SQL_MAXIMUM_DRIVER_CONNECTIONS
SQL_MAX_IDENTIFIER_LEN SQL_MAXIMUM_IDENTIFIER_LENGTH
SQL_MAX_SCHEMA_NAME_LEN SQL_MAXIMUM_SCHEMA_NAME_LENGTH
SQL_MAX_STATEMENT_LEN SQL_MAXIMUM_STATEMENT_LENGTH
SQL_MAX_TABLE_NAME_LEN SQL_MAXIMUM_TABLE_NAME_LENGTH
SQL_MAX_TABLES_IN_SELECT SQL_MAXIMUM_TABLES_IN_SELECT
O DB C N A M E A L IA S IN H EA DER F IL E
SQL_MAX_USER_NAME_LEN SQL_MAXIMUM_USER_NAME_LENGTH
SQL_MULT_RESULT_SETS SQL_MULTIPLE_RESULT_SETS
SQL_OJ_CAPABILITIES SQL_OUTER_JOIN_CAPABILITIES
SQL_TXN_CAPABLE SQL_TRANSACTION_CAPABLE
SQL_TXN_ISOLATION_OPTION SQL_TRANSACTION_ISOLATION_OPTION
CString Class
4/27/2022 • 2 minutes to read • Edit Online
Because objects of the CString class in Microsoft® Visual C++® are signed and string arguments in ODBC
functions are unsigned, applications that pass CString objects to ODBC functions without casting them will
receive compiler warnings.
Creating and Terminating Threads
4/27/2022 • 2 minutes to read • Edit Online
Multithread applications that use ODBC should call the Microsoft® Visual C++® Run-Time Library functions
_beginthread and _endthread (or _beginthreadex and _endthreadex ) to create and terminate threads that
call the ODBC Driver Manager. If applications call the Microsoft Windows NT® functions CreateThread and
EndThread instead, memory leaks will occur because the Driver Manager and some ODBC drivers call C run-
time functions that will not work on a thread created by calling CreateThread . For more information, see the
Microsoft Windows® documentation.
Installing and Configuring the ODBC Software
4/27/2022 • 2 minutes to read • Edit Online
NOTE
Starting with Windows XP and Windows Server 2003, ODBC is included in the Windows operation system. You should
only explicitly install ODBC on earlier versions of Windows.
NOTE
Starting with Windows XP and Windows Server 2003, ODBC is included in the Windows operation system. You should
only explicitly install ODBC on earlier versions of Windows.
This section describes how ODBC components are installed and removed. Because driver developers always
install an ODBC component (their driver), they need to read this section. Application developers need to read
this section only if they will ship ODBC components with their applications. ODBC components include the
Driver Manager, drivers, translators, the installer DLL, the cursor library, and any related files. For the purposes
of this section, ODBC applications are not considered to be ODBC components.
NOTE
This section is specific to Microsoft Windows platforms. How ODBC components are installed on other platforms is
platform-specific.
ODBC components are installed and removed on a component-by-component basis, not a file-by-file basis. For
example, if a translator consists of the translator itself and a number of data files, these files are installed and
removed as a group; they must not be installed and removed on a file-by-file basis. The reason for this is to
make sure that only complete components exist on the system.
For purposes of installing and removing components, the following are defined to be ODBC components:
Core components. The Driver Manager, cursor library, installer DLL, and any other related files make up
the core components and must be installed and removed as a group.
Drivers. Each driver is a separate component.
Translators. Each translator is a separate component.
With the support of Unicode in ODBC 3.5 and later, some consideration must be given to using OLE DB
components with ODBC. The 1.1 version of the OLE DB Provider for ODBC was written to specific Unicode
specifications within ODBC 3.0. Because these specifications changed in ODBC 3.5, it is necessary to have
version 1.5 or later of the provider when using ODBC 3.5 and later. This section contains the following topics.
Installation Components
Usage Counting
Installation Components
4/27/2022 • 2 minutes to read • Edit Online
NOTE
Starting with Windows XP and Windows Server 2003, ODBC is included in the Windows operation system. You should
only explicitly install ODBC on earlier versions of Windows.
The installation process starts when the user runs the setup program. The setup program works in conjunction
with the installer DLL and a driver setup DLL for each driver. Both the setup program and the installer DLL use
the arguments in the SQLInstallDriverEx and SQLInstallTranslatorEx functions to determine which files to
copy or delete for each component. The following illustration shows the relationship between these installation
components.
IMPORTANT
The Odbc.inf file that was used in ODBC 2.x to describe the files required by each ODBC component is not used in ODBC
3.x. Drivers that ship ODBC 3.x components do not need to create an Odbc.inf file. The removal of SQLInstallDriver and
SQLInstallODBC , and the deprecation of SQLInstallTranslator , have rendered Odbc.inf unnecessary. The driver
information that used to be in the Driver Keyword sections of Odbc.inf is now provided in the lpszDriver argument in
SQLInstallDriverEx. The translator information that used to be in the [ODBC Translator] and Translator Specification
sections of Odbc.inf is now provided in the lpszTranslator argument of SQLInstallTranslatorEx. These changes allow the
ODBC Installer to be more portable across platforms.
For more information about these components, see the following topics at the end of this section.
Setup Program
Installer DLL
Driver Setup DLL
Usage Counting
4/27/2022 • 2 minutes to read • Edit Online
NOTE
Starting with Windows XP and Windows Server 2003, ODBC is included in the Windows operation system. You should
only explicitly install ODBC on earlier versions of Windows.
Two types of usage counts are maintained in the registry for each component: a component usage count and
one or more optional file usage counts. The component usage count helps the installer DLL maintain registry
entries. It is stored in the UsageCount value under the ODBC Core, driver, and translator subkeys. For the format
of the UsageCount value and more information about these subkeys, see Registry Entries for ODBC
Components.
When a component is first installed, the installer DLL creates a subkey for it and sets the data for the
UsageCount value in that subkey to 1. When the component is installed again, the installer DLL increments the
usage count. When the component is removed, the installer DLL decrements the usage count. If the usage count
falls to 0, the installer DLL removes the subkey for the component.
Cau t i on
An application should not physically remove Driver Manager files when the component usage count and the file
usage count reach zero.
File usage counts help determine when a file must actually be copied or deleted as opposed to incrementing or
decrementing the usage count. This is important because ODBC components, and therefore the files in ODBC
components, are shared and can be installed or removed by a variety of applications. The application can delete
driver and translator files if the component usage count and the file usage count reach zero. Driver Manager
files should not, however, be deleted when both the component usage count and the file usage count have
reached zero, because these files can be used by other applications that have not incremented the file usage
count.
NOTE
File usage counts are optional in Microsoft® WindowsNT®/Windows2000.
File usage counts are maintained by the setup program after it calls SQLInstallDriverManager ,
SQLInstallDriverEx , SQLInstallTranslatorEx , SQLRemoveDriverManager , SQLRemoveDriver , or
SQLRemoveTranslator .
When a component is first installed, the setup program or installer DLL creates a value under the following key
for each file in that component that is not already on the system:
NOTE
HKEY_LOCAL_MACHINE
SOFTWARE
Microsoft
Windows
CurrentVersion
SharedDlls
It sets the data for those values to 1 and copies the file to the system. When the component is installed again,
the setup program or installer DLL increments the usage counts. When the component is removed, the setup
program or installer DLL decrements the usage counts. If any usage count falls to 0, the setup program or
installer DLL removes the value for the file and, if the component is a driver or a translator, deletes the file.
Driver Manager files should not be deleted.
The format of the file usage count value is shown in the following table.
For example, suppose a driver for Informix uses the Infrmx32.dll and Infrmx32.hlp files, and suppose that this
driver has been installed twice. The values under the SharedDlls subkey for the Informix driver would be as
follows:
Information about data sources is stored in the system registry. Users modify data source information through
an administration program. This can be the ODBC Administrator, the ODBC Control Panel device, or an
administration program written by an application or driver developer.
You can use PowerShell commands to modify data sources. For more information about these PowerShell
commands, see Windows Data Access Components PowerShell Commands.
NOTE
This section is specific to Microsoft Windows® platforms. How data sources are configured on other platforms is
platform-specific.
NOTE
Starting with Windows XP and Windows Server 2003, ODBC is included in the Windows operation system. You should
only explicitly install ODBC on earlier versions of Windows.
Data sources are configured by the installer DLL, which in turn calls driver setup DLLs and translator setup DLLs
as they are needed. The installer DLL is either invoked directly from Control Panel or loaded and called by
another program, known as the administration program. The following illustration shows the relationship
between the configuration components.
For more information about these components, see the following topics at the end of this section.
Setup Program
Installer DLL
Driver Setup DLL
See Also
Installation Components
Installation and Configuration Components
Reference
4/27/2022 • 2 minutes to read • Edit Online
NOTE
Starting with Windows XP and Windows Server 2003, ODBC is included in the Windows operation system. You should
only explicitly install ODBC on earlier versions of Windows.
The following sections provide information about the components used to install and configure ODBC.
Administration Program
Driver Setup DLL
Installer DLL
Setup Program
Translator Setup DLLs
Administration Program
4/27/2022 • 2 minutes to read • Edit Online
NOTE
Starting with Windows XP and Windows Server 2003, ODBC is included in the Windows operation system. You should
only explicitly install ODBC on earlier versions of Windows.
An administration program, the ODBC Administrator, is included with the Windows SDK/MDAC SDK. This
program and can be redistributed by users of the SDK. In addition, developers can write their own
administration programs. Generally, developers write their own administration programs only if they want to
retain complete control over data source configuration, or if they are configuring data sources directly from an
application that is acting as an administration program. For example, a spreadsheet program might allow users
to add and then use data sources at run time.
The administration program first loads the installer DLL. It then calls functions in the installer DLL to perform the
following tasks:
Add, modify, or delete data sources interactively. The administration program can call
SQLManageDataSources , SQLCreateDataSource , or SQLConfigDataSource .
SQLManageDataSources displays a dialog box with which the user can add, modify, or delete data
sources and specify tracing options; this function is called when the installer DLL is invoked directly from
the Control Panel. SQLCreateDataSource displays a dialog box with which the user can only add data
sources. SQLConfigDataSource passes the call directly to the driver setup DLL.
In all cases, the installer DLL calls ConfigDSN in the driver setup DLL to actually add, modify, or delete
the data source. The driver setup DLL might prompt the user for additional information.
Add, modify, or delete data sources silently. The administration program calls
SQLConfigDataSource in the installer DLL and passes it a null window handle, the name of a data
source to add, modify, or delete, and a list of values for the registry. The installer DLL calls ConfigDSN in
the driver setup DLL to actually add, modify, or delete the data source.
Add, modify, or delete a default data source. The default data source is the same as any other data
source, except that its name is Default. It is added, modified, or deleted in the same fashion as any other
data source.
Setup Program
4/27/2022 • 2 minutes to read • Edit Online
NOTE: Starting with Windows XP and Windows Server 2003, ODBC is included in the Windows
operation system . You should only explicitly install ODBC on earlier versions of Windows.
The user runs the setup program to start the setup process. The setup program is written by the application or
driver developer. In addition to installing ODBC components, it can install other software. For example,
application developers might use the same setup program both to install ODBC components and to install their
applications.
Developers can write the setup program from scratch, using the Microsoft® Windows® SDK setup utilities or
setup software from other vendors. This gives those developers complete control over the setup program's look
and feel. The setup program can be written to install additional software, such as an ODBC application. For more
information on the Windows SDK setup utilities, see the Windows SDK documentation.
How much of the installation is actually done by the setup program depends on what functions it calls in the
installer DLL. The installer DLL contains functions to install individual ODBC components. The setup program
simply calls SQLInstallDriverManager , SQLInstallDriverEx , or SQLInstallTranslatorEx in the installer DLL
to retrieve the path of the directory in which the component is to be installed and to add information about the
component to the registry. These functions do not actually copy files; the setup program does this using the
information in the arguments of these functions.
The installer DLL also contains functions to remove ODBC components. The setup program calls
SQLRemoveDriverManager , SQLRemoveDriver , or SQLRemoveTranslator in the installer DLL to
decrement a component's usage count in the registry and, if the component's new usage count falls to 0,
remove all information about the component from the registry. These functions do not actually remove the files
for the component; the setup program does this if the new usage count falls to 0.
Installer DLL
4/27/2022 • 2 minutes to read • Edit Online
NOTE
Starting with Windows XP and Windows Server 2003, ODBC is included in the Windows operation system. You should
only explicitly install ODBC on earlier versions of Windows.
The installer DLL contains functions to install and remove ODBC components, maintain registry information
about those components, and maintain registry information about data sources. It is written by Microsoft and
can be redistributed. For a complete description of the functions in the installer DLL, see Installer DLL API
Reference.
See Also
Registry Entries for ODBC Components
Registry Entries for Data Sources
Driver Setup DLL
4/27/2022 • 2 minutes to read • Edit Online
NOTE
Starting with Windows XP and Windows Server 2003, ODBC is included in the Windows operation system. You should
only explicitly install ODBC on earlier versions of Windows.
The driver setup DLL contains the ConfigDriver and ConfigDSN functions. ConfigDriver performs driver-
specific installation tasks, such as entering driver-specific information into the registry. ConfigDSN maintains
driver-specific information about data sources in the registry. For a complete description of these functions, see
Setup DLL API Reference.
ConfigDSN calls the following functions in the installer DLL to maintain data source information in the registry:
SQLWriteDSNToIni . Add a data source.
SQLRemoveDSNFromIni . Delete a data source.
SQLWritePrivateProfileString . Write a driver-specific value under a data source specification subkey.
SQLGetPrivateProfileString . Read a driver-specific value from a data source specification subkey.
SQLGetTranslator . Prompt the user for a translator name and option. This function calls
ConfigTranslator in the translator setup DLL.
The driver setup DLL is written by the driver developer. It can be part of the driver DLL or a separate DLL.
Translator Setup DLLs
4/27/2022 • 2 minutes to read • Edit Online
NOTE
Starting with Windows XP and Windows Server 2003, ODBC is included in the Windows operation system. You should
only explicitly install ODBC on earlier versions of Windows.
The translator setup DLL contains the ConfigTranslator function, which returns the default option for a
translator. If necessary, it prompts the user for this information. For a complete description of this function, see
Setup DLL API Reference.
The translator setup DLL is written by the translator developer. It can be part of the translator DLL or a separate
DLL.
ODBC Header Files
4/27/2022 • 2 minutes to read • Edit Online
NOTE
Redistribution of ODBC header files is not required. None are considered "Core".
Header Files
Odbcinst.h
Sql.h
Sqlext.h
Sqltypes.h
Sqlucode.h
Msdasql.h
Msdadc.h
Sqlspi.h (used for driver development, see ODBC Service Provider Interface (SPI) Reference for more
information) available beginning in the Windows 8 SDK.
Registry Entries for ODBC Components
4/27/2022 • 2 minutes to read • Edit Online
NOTE
Starting with Windows XP and Windows Server 2003, ODBC is included in the Windows operation system. You should
only explicitly install ODBC on earlier versions of Windows.
The installer DLL maintains information in the registry about each installed ODBC component. On computers
running Microsoft Windows NT and Microsoft Windows 95/98, this information is stored in subkeys under the
following key in the registry:
HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\Odbcinst.ini
Because Odbcinst.ini is a subkey of the HKEY_LOCAL_MACHINE tree, the information about ODBC components
is available to all users of the machine.
This section contains the following topics.
ODBC Core Subkey
ODBC Drivers Subkey
Driver Specification Subkeys
Default Driver Subkey
ODBC Translators Subkey
Translator Specification Subkeys
ODBC Core Subkey
4/27/2022 • 2 minutes to read • Edit Online
The value under the ODBC Core subkey gives the usage count for the core components (Driver Manager, cursor
library, installer DLL, and so on). The format of this value is shown in the following table.
For example, suppose the ODBC Core components have been installed by the setup programs for three different
applications and two different drivers. The value under the ODBC Core subkey would be:
The values under the ODBC Drivers subkey list the installed drivers. The format of these values is shown in the
following table.
The driver-description name is defined by the driver developer. It is usually the name of the DBMS associated
with the driver.
For example, suppose drivers have been installed for formatted text files and SQL Server. The values under the
ODBC Drivers subkey might be:
Each driver listed in the ODBC Drivers subkey has a subkey of its own. This subkey has the same name as the
corresponding value under the ODBC Drivers subkey. The values under this subkey list the full paths of the
driver and driver setup DLLs, the values of the driver keywords returned by SQLDrivers , and the usage count.
The formats of the values are as shown in the following table.
APILevel REG_SZ 0 |1 |2
FileUsage REG_SZ 0 |1 |2
SQLLevel REG_SZ 0 |1 |2
K EY W O RD USA GE
0 = None
1 = Level 1 supported
2 = Level 2 supported
DriverODBCVer A character string with the version of ODBC that the driver
supports. The version is of the form nn.nn, where the first
two digits are the major version and the next two digits are
the minor version. For the version of ODBC described in this
manual, the driver must return "03.00".
When a user selects Open Data File from the File menu,
an application could display the Windows File Open
common dialog box. The list of file types would use the file
extensions specified with the FileExtns keyword for drivers
that specify a FileUsage value of 1 and "Y" as the second
character of the value of the ConnectFunctions keyword.
After the user selects a file, the application would call
SQLDriverConnect with the DRIVER keyword and then
execute a SELECT * FROM table-name statement.
When the user selects Impor t Data from the File menu, an
application could display a list of descriptions for drivers that
specify a FileUsage value of 0 or 2, and "Y" as the second
character of the value of the ConnectFunctions keyword.
After the user selects a driver, the application would call
SQLDriverConnect with the DRIVER keyword and then
display a custom Select Table dialog box.
0 = SQL-92 Entry
1 = FIPS127-2 Transitional
2 = SQL-92 Intermediate
3 = SQL-92 Full
For information about usage counts, see Usage Counting earlier in this section.
Applications should not set the usage count. ODBC will maintain this count.
For example, suppose a driver for formatted text files has a driver DLL named Text.dll, a separate driver setup
DLL named Txtsetup.dll, and has been installed three times. If the driver supports the Level 1 API conformance
level, supports the Minimum SQL grammar conformance level, treats files as tables, and can use files with the
.txt and .csv extensions, the values under the Text subkey might be as follows:
APILevel : REG_SZ : 1
ConnectFunctions : REG_SZ : YYN
Driver : REG_SZ : C:\WINDOWS\SYSTEM32\TEXT.DLL
DriverODBCVer : REG_SZ : 03.00.00
FileExtns : REG_SZ : *.txt,*.csv
FileUsage : REG_SZ : 1
Setup : REG_SZ : C:\WINDOWS\SYSTEM32\TXTSETUP.DLL
SQLLevel : REG_SZ : 0
UsageCount : REG_DWORD : 0x3
Default Driver Subkey
4/27/2022 • 2 minutes to read • Edit Online
The Default subkey contains a single value that describes the driver used by the default data source. The format
of this value is shown in the following table.
The default-driver-description name is the same as the name of the value under the ODBC Drivers subkey that
describes the driver.
For example, if the default data source uses the SQL Server driver, the value under the Default subkey might be:
NOTE
The default driver contained in the Default subkey can refer to either a default user DSN or a default system DSN. If both
a default user DSN and a default system DSN have been created, the default driver is determined by the DSN that was
created last, so it might not be a valid entry for the DSN that was created first.
ODBC Translators Subkey
4/27/2022 • 2 minutes to read • Edit Online
The values under the ODBC Translators subkey list the installed translators. The format of these values is shown
in the following table.
Each translator listed in the ODBC Translators subkey has a subkey of its own. This subkey has the same name as
the corresponding value under the ODBC Translators subkey. The values under this subkey list the full paths of
the translator and translator setup DLLs and the usage count. The formats of the values are as shown in the
following table.
For information about usage counts, see Usage Counting earlier in this section.
Applications should not set the usage count. ODBC will maintain this count.
For example, suppose the Microsoft Code Page Translator has a translation DLL named Mscpxl32.dll, that the
translator setup functions are in the same DLL, and that the translator has been installed three times. The values
under the Microsoft Code Page Translator subkey might be as follows:
NOTE
Starting with Windows XP and Windows Server 2003, ODBC is included in the Windows operation system. You should
only explicitly install ODBC on earlier versions of Windows.
The installer DLL maintains information in the registry about each data source. In Microsoft Windows
NT/Windows 2000 and Microsoft Windows 95/98, this information is stored in subkeys under one of the
following two keys in the registry:
HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\Odbc.ini
HKEY_CURRENT_USER\SOFTWARE\ODBC\Odbc.ini
Which key is used depends on whether the data source is a system data source, which is available to all users, or
a user data source, which is available only to the current user. System data sources are stored on the
HKEY_LOCAL_MACHINE tree, and user data sources are stored on the HKEY_CURRENT_USER tree. In all other
respects, system data sources and user data sources are identical.
This section contains the following topics.
ODBC Data Sources Subkey
Data Source Specification Subkeys
Default Subkey
ODBC Subkey
ODBC Data Sources subkey
4/27/2022 • 2 minutes to read • Edit Online
The values under the ODBC Data Sources subkey list the data sources. The format of these values is shown in the
following table.
The data-source-name value is defined by the administration program (which usually prompts the user for it),
and driver-description is defined by the driver developer (it is usually the name of the DBMS associated with the
driver).
For example, suppose three data sources have been defined: Inventory, which uses SQL Server; Payroll, which
uses dBASE; and Personnel, which uses formatted text files. The values under the ODBC Data Sources subkey
might be as follows:
Each data source listed in the ODBC Data Sources subkey has a subkey of its own. This subkey has the same
name as the corresponding value under the ODBC Data Sources subkey. The values under this subkey must list
the driver DLL and may list a description of the data source. If the driver supports translators, the values may list
the name of a default translator, the default translation DLL, and the default translation option. The values may
also list other information required by the driver to connect to the data source. For example, the driver might
require a server name, database name, or schema name.
The formats of the values are as shown in the following table. Only the Driver value is required.
For example, suppose the SQL Server driver requires the server name and a flag for OEM to ANSI conversion
and defines the Server and OEMTOANSI values for these. Suppose also that the Inventory data source uses the
Microsoft® Code Page Translator to translate between the Windows® Latin 1 (1250) and Multilingual (850)
code pages. The values under the Inventory subkey might be as follows:
The registry may specify a default data source with the Default subkey. This subkey is a special case of a data
source specification subkey and has the same values as any other data source specification subkey. The only
difference is that it is not listed as a value under the ODBC Data Sources subkey.
ODBC Subkey
4/27/2022 • 2 minutes to read • Edit Online
The values under the ODBC subkey specify ODBC tracing options. These options are set through the Tracing tab
of the ODBC Data Source Administrator dialog box displayed by SQLManageDataSources . The ODBC subkey
itself is optional. The format of these values is as shown in the following table.
Trace REG_SZ 0 |1
VA L UE M EA N IN G
For example, suppose that tracing is enabled and the trace file is C:\Odbc.log. The values under the ODBC
subkey would be as follows:
Trace : REG_SZ : 1
TraceFile : REG_SZ : C:\ODBC.LOG
Developing an ODBC Driver
4/27/2022 • 2 minutes to read • Edit Online
This section contains topics that discuss how to develop an ODBC driver.
This section contains the following topics
ODBC Driver Architecture
Upgrading a 3.5 Driver to a 3.8 Driver
Developing Connection-Pool Awareness in an ODBC Driver
Notification of Asynchronous Function Completion
ODBC Driver Architecture
4/27/2022 • 2 minutes to read • Edit Online
Driver writers must be aware that the driver architecture can affect whether an application can use DBMS-
specific SQL.
File-based Drivers
When the driver accesses the physical data directly, the driver acts as both driver and data source. The driver
must process both ODBC calls and SQL statements. Developers of file-based drivers must write their own
database engines.
DBMS-Based Drivers
When a separate database engine is used to access physical data, the driver processes only ODBC calls. It passes
SQL statements to the database engine for processing.
Network Architecture
File and DBMS ODBC configurations can exist on a single network.
Other Driver Architectures
When a driver is required to work with a variety of data sources, it can be used as middleware. Heterogeneous
join engine architecture can make the driver appear as a driver manager. Drivers can also be installed on
servers, where they can be shared by a series of clients.
For more information about driver architecture, see Driver Manager and Driver Architecture in the section on
ODBC Architecture.
More information about driver issues can be found in the locations described in the following table.
ISSUE TO P IC LO C AT IO N
Writing ODBC drivers Writing ODBC 3.x Drivers Programming Considerations, in the
ODBC Programmer's Reference
Driver guidelines for backward Driver Guidelines for Backward Appendix G: Driver Guidelines for
compatibility Compatibility Backward Compatibility, in the ODBC
Programmer's Reference
Connecting to a driver Choosing a Data Source or Driver Connecting to a Data Source or Driver,
in the ODBC Programmer's Reference
Enabling connection pooling ODBC Connection Pooling Connecting to a Data Source or Driver,
in the ODBC Programmer's Reference
See Also
Developing an ODBC Driver
Upgrading a 3.5 Driver to a 3.8 Driver
4/27/2022 • 4 minutes to read • Edit Online
This topic provides guidelines and considerations for upgrading an ODBC 3.5 driver to an ODBC 3.8 driver.
Ve r si o n N u m b e r s
A driver can have customized C data types when it works with a version 3.8 ODBC application. (For more
information, see C Data Types in ODBC.) However, there is no requirement for a 3.8 driver to implement any
driver-specific C types. But the driver should still perform the range check of C types; the Driver Manager will
not do that for 3.8 drivers. To facilitate driver development, the value of the driver specific, C data type can be
defined in the following format:
SQL_DRIVER_C_TYPE_BASE+0, SQL_DRIVER_C_TYPE_BASE+1
D r i v e r- sp e c i fi c D a t a T y p e s, D e sc r i p t o r T y p e s, I n fo r m a t i o n T y p e s, D i a g n o st i c T y p e s, a n d A t t r i b u t e s
When developing a new driver, you should use the driver-specific range for data types, descriptor types,
information types, diagnostic types, and attributes. Driver-specific ranges and their base type values are
discussed in Driver-Specific Data Types, Descriptor Types, Information Types, Diagnostic Types, and Attributes.
Co n n ec t i o n Po o l i n g
For better management of connection pooling, ODBC 3.8 introduces the SQL_ATTR_RESET_CONNECTION
connection attribute in SQLSetConnectAttr . SQL_RESET_CONNECTION_YES is the only valid value for this
attribute. SQL_ATTR_RESET_CONNECTION will be set just before the Driver Manager puts a connection in the
connection pool, allowing the driver to reset the other connection attributes to their default values.
To avoid unnecessary communication with the server, a driver can defer the connection attribute reset until the
next communication with the remote server, after the connection is reused from the pool.
Note that SQL_ATTR_RESET_CONNECTION is only used in communication between the Driver Manager and a
driver. An application cannot set this attribute directly. All version 3.8 drivers should implement this connection
attribute.
St r e a m e d O u t p u t P a r a m e t e r s
ODBC version 3.8 introduces streamed output parameters, a more scalable way to retrieve output parameters.
(For more information, see Retrieving Output Parameters Using SQLGetData.) To support this feature, a driver
should set SQL_GD_OUTPUT_PARAMS in the return value when SQL_GETDATA_EXTENSIONS is the InfoType in a
SQLGetInfo call. Support for an SQL type with streamed output parameters must be implemented in the driver.
The Driver Manager will not generate an error for an invalid SQL type. The SQL types that support streamed
output parameters is defined in the driver.
A driver should return SQL_ERROR if the application used SQLGetData to retrieve a parameter that is not the
same as the parameter returned by SQLParamData .
A sy n c h r o n o u s Ex e c u t i o n fo r C o n n e c t i o n O p e r a t i o n s (P o l l i n g M e t h o d )
ODBC 3.8 supports SQLCancelHandle Function, which is used to cancel both connection and statement
operations. A driver that supports SQLCancelHandle must export the function. A driver should not cancel any
synchronous or asynchronous connection function that is in progress if the application calls SQLCancel or
SQLCancelHandle on a statement handle. Similarly, a driver should not cancel any synchronous or
asynchronous statement function that is in progress if an application calls SQLCancelHandle on the
connection handle. Also, a driver should not cancel the browsing operation (SQLBrowseConnect returns
SQL_NEED_DATA) if the application calls SQLCancelHandle on the connection handle. In these cases, a driver
should return HY010, "function sequence error".
It is not necessary to support both SQLCancelHandle and asynchronous connection operations at the same
time. A driver can support asynchronous connection operations but not SQLCancelHandle , or vice versa.
Su sp e n d e d C o n n e c t i o n s
The ODBC 3.8 Driver Manager can put a connection into suspended state. An application will call
SQLDisconnect to release resources associated with the connection. In this case, a driver should try to release
as many resources as possible without checking the state of the connection. For more information about the
suspended state, see SQLEndTran Function.
D r i v e r- A w a r e C o n n e c t i o n P o o l i n g
ODBC in Windows 8 allows drivers to customize connection pool behavior. For more information, see Driver-
Aware Connection Pooling.
A sy n c h r o n o u s Ex e c u t i o n (N o t i fi c a t i o n M e t h o d )
ODBC 3.8 supports the notification method for asynchronous operations, available beginning on Windows 8.
For more information, see Asynchronous Execution (Notification Method).
See Also
Developing an ODBC Driver
Microsoft-Supplied ODBC Drivers
What's New in ODBC 3.8
Developing Connection-Pool Awareness in an
ODBC Driver
4/27/2022 • 7 minutes to read • Edit Online
This topic discusses the details of developing an ODBC driver that contains information about how the driver
should provide connection pooling services.
F UN C T IO N A DDED F UN C T IO N A L IT Y
SQLGetDiagField
SQLGetDiagRec
NOTE
Deprecated functions such as SQLError and SQLSetConnectOption are not supported for driver-aware connection
pooling.
The Pool ID
The pool ID is a pointer-length driver-specific ID to represent a particular group of connections that can be used
interchangeably. Given a set of connection information, a driver should be able to quickly deduce the
corresponding pool ID.
For example, the pool ID should encode the server name and credential information. However, the database
name is not needed because a driver may be able to reuse a connection and then change the database in less
time than making a new connection.
A driver should define a set of key attributes, which will comprise the pool ID. The value of these key attributes
can come from connection attributes, connection string, and DSN. In case there are any conflicts in these
sources, the existing, driver-specific resolution policy should be used for backward compatibility.
The Driver Manager will use a different pool for different pool IDs. All connections in the same pool are reusable.
The Driver Manager will never reuse a connection with a different pool ID.
Therefore drivers should assign a unique pool ID for every group of connections with the same value in their
defined key attributes. If a driver uses the same pool ID for two connections with different values in their key
attributes, the Driver Manager will still put them into the same pool (the Driver Manager knows nothing about
the driver-specific key attributes). This means that the driver will need to report to the Driver Manager that a
connection with a different set of key attributes is not reusable inside SQLRateConnection Function. This can
decrease performance and this is not recommended.
The Driver Manager will not reuse a connection allocated from another driver environment even if all
connection information matches. The Driver Manager will use a different pool for different environment, even
when connections have the same pool ID. Therefore, the pool ID is local to its driver environment.
The function for getting the pool ID from the driver is SQLGetPoolID Function.
C O M PA RISO N O N C O N N EC T IO N
AT T RIB UT ES B ET W EEN T H E P O O L ED REQ UIRE EXT RA EN L IST M EN T /
C O N N EC T IO N A N D T H E REQ UEST N O EN L IST M EN T / UN EN L IST M EN T UN EN L IST M EN T
Catalog 60 50
(SQL_ATTR_CURRENT_CATALOG) is
different
Sequence Diagram
This sequence diagram shows the basic pooling mechanism described in this topic. It only shows the use of
SQLDriverConnect but the SQLConnect case is similar.
State Diagram
This state diagram shows the connection info token object, described in this topic. The diagram only shows
SQLDriverConnect but the SQLConnect case is similar. Since the Driver Manager may need to handle errors at
any time, the Driver Manager can call SQLFreeHandle for any state.
See Also
Driver-Aware Connection Pooling
ODBC Service Provider Interface (SPI) Reference
Notification of Asynchronous Function Completion
4/27/2022 • 2 minutes to read • Edit Online
In the Windows 8 SDK, ODBC added a mechanism to notify applications when an asynchronous operation
completes, which we will refer to as "notification on completion". (See Asynchronous Execution (Notification
Method) for more information.) This topic discusses some of the issues for driver developers.
See Also
Developing an ODBC Driver
SQLAsyncNotificationCallback Function
4/27/2022 • 2 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 3.8
Standards Compliance: None
Summar y
SQL AsyncNotificationCallback allows a driver to call back to the Driver Manager when there is some
progress for the current asynchronous operation after the driver returns SQL_STILL_EXECUTING.
SQL AsyncNotificationCallback can only called by the driver.
Drivers do not call SQL AsyncNotificationCallback with function name SQL AsyncNotificationCallback .
Instead, the Driver Manager passes a function pointer to a driver as the value for the
SQL_ATTR_ASYNC_DBC_NOTIFICATION_CALLBACK or SQL_ATTR_ASYNC_STMT_NOTIFICATION_CALLBACK
attribute of the corresponding connection handle or statement handle, respectively. Different handles may be
assigned different function pointer values. The type of the function pointer is defined as
SQL_ASYNC_NOTIFICATION_CALLBACK.
SQL AsyncNotificationCallback is thread-safe. A driver can choose to use multiple threads calling
SQL AsyncNotificationCallback on different handles simultaneously.
Syntax
typedef SQLRETURN (SQL_API *SQL_ASYNC_NOTIFICATION_CALLBACK)(
SQLPOINTER pContex,
BOOL fLast);
Arguments
pContex
Pointer to a data structure defined by the Driver Manager. The value is passed to the driver via
SQLSetConnectAttr(SQL_ATTR_ASYNC_DBC_NOTIFICATION_CONTEXT) or
SQLSetStmtAttr(SQL_ATTR_ASYNC_STMT_NOTIFICATION_CONTEXT). The driver does not have access to the
value.
fLast
Used by a driver to indicates that this callback function invocation is the last one for the current asynchronous
operation. The driver will return a return code other than SQL_STILL_EXECUTING when the Driver Manager calls
the function again. The Driver Manager may use this information, for example, to inform the application in
advance that the asynchronous operation will complete.
If Handle is not a valid handle of the type specified by HandleType, SQLCancelHandle returns
SQL_INVALID_HANDLE.
Returns
SQL_SUCCESS or SQL_ERROR.
Diagnostics
SQL AsyncNotificationCallback can return SQL_ERROR for the following two situations (these indicate an
implementation problem in the driver or Driver Manager.
Invalid handle The driver passed in an invalid handle, which failed the
internal Driver Manager validation tests.
See Also
Asynchronous Execution (Polling Method)
ODBC Reference
4/27/2022 • 2 minutes to read • Edit Online
The following topics contain syntax and semantic information for all ODBC functions.
Function Summary
ODBC API Reference
Setup DLL API Reference
Installer DLL API Reference
Translation DLL Function Reference
ODBC Service Provider Interface (SPI) Reference
Function Summary
4/27/2022 • 2 minutes to read • Edit Online
The following sections summarize the functions used by ODBC-enabled applications and related software.
ODBC Function Summary
Setup DLL Function Summary
Installer DLL Function Summary
Translation DLL Function Summary
ODBC Service Provider Interface Summary
ODBC Function Summary
4/27/2022 • 4 minutes to read • Edit Online
The following table lists ODBC functions, grouped by type of task, and includes the conformance designation
and a brief description of the purpose of each function. For more information about conformance designations,
see ODBC and the Standard CLI. For more information about the syntax and semantics for each function, see
ODBC API Reference.
An application can call the SQLGetInfo function to obtain conformance information about a driver. To obtain
information about support for a specific function in a driver, an application can call SQLGetFunctions .
TA SK F UN C T IO N N A M E C O N F O RM A N C E P URP O SE
The following table describes setup DLL functions. For more information about the syntax and semantics for
each function, see Setup DLL API Reference.
TA SK F UN C T IO N N A M E P URP O SE
The following table describes the functions in the installer DLL. For more information about the syntax and
semantics for each function, see Installer DLL API Reference.
TA SK F UN C T IO N N A M E P URP O SE
The following table describes translation DLL functions. For more information about the syntax and semantics
for each function, see Translation DLL Function Reference.
TA SK F UN C T IO N N A M E P URP O SE
The following table describes ODBC Service Provider interface functions. For more information about the syntax
and semantics for each function, see ODBC Service Provider Interface (SPI) Reference.
F UN C T IO N N A M E P URP O SE
SQLSetDriverConnectInfo Sets the connection string into the connection info token for
an application's SQLDriverConnect call.
SQLSetConnectInfo Sets the data source, user ID, and password into the
connection info token for an application's SQLConnect call.
The topics in this section describe each ODBC function in alphabetical order. Each function is defined as a C
programming language function. Descriptions include the following:
Purpose
ODBC version
Standard CLI conformance level
Syntax
Arguments
Return values
Diagnostics
Comments about usage and implementation
Code example
References to related functions
The standard CLI conformance level can be one of the following: ISO 92, Open Group, ODBC, or Deprecated. A
function tagged as ISO 92-conformant also appears in Open Group version 1, because Open Group is a pure
superset of ISO 92. A function tagged as Open Group-compliant also appears in ODBC 3.x, because ODBC 3.x is
a pure superset of Open Group version 1. A function tagged as ODBC-compliant appears in neither standard. A
function tagged as deprecated has been deprecated in ODBC 3.x.
Handling of diagnostic information is described in the SQLGetDiagField function description. The text associated
with SQLSTATE values is included to provide a description of the condition but is not intended to prescribe
specific text.
NOTE
For driver-specific information about ODBC functions, see the section for the driver.
Conformance
Version Introduced: ODBC 1.0 Standards Compliance: Deprecated
Summar y
In ODBC 3.x, the ODBC 2.x function SQL AllocConnect has been replaced by SQL AllocHandle . For more
information, see SQLAllocHandle Function.
NOTE
For more information about what the Driver Manager maps this function to when an ODBC 2.x application is working
with an ODBC 3.x driver, see Mapping Deprecated Functions in Appendix G: Driver Guidelines for Backward Compatibility.
See Also
ODBC API Reference
ODBC Header Files
SQLAllocEnv Function
4/27/2022 • 2 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 1.0 Standards Compliance: Deprecated
Summar y
In ODBC 3.x, the ODBC 2.x function SQL AllocEnv has been replaced by SQL AllocHandle . For more
information, see SQLAllocHandle Function.
NOTE
For more information about what the Driver Manager maps this function to when an ODBC 2.x application is working
with an ODBC 3.x driver, see Mapping Deprecated Functions in Appendix G: Driver Guidelines for Backward Compatibility.
See Also
ODBC API Reference
ODBC Header Files
SQLAllocHandle Function
4/27/2022 • 14 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 3.0 Standards Compliance: ISO 92
Summar y
SQL AllocHandle allocates an environment, connection, statement, or descriptor handle.
NOTE
This function is a generic function for allocating handles that replaces the ODBC 2.0 functions SQL AllocConnect ,
SQL AllocEnv , and SQL AllocStmt . To allow applications calling SQL AllocHandle to work with ODBC 2.x drivers, a call
to SQL AllocHandle is mapped in the Driver Manager to SQL AllocConnect , SQL AllocEnv , or SQL AllocStmt , as
appropriate. For more information, see "Comments." For more information about what the Driver Manager maps this
function to when an ODBC 3.x application is working with an ODBC 2.x driver, see Mapping Replacement Functions for
Backward Compatibility of Applications.
Syntax
SQLRETURN SQLAllocHandle(
SQLSMALLINT HandleType,
SQLHANDLE InputHandle,
SQLHANDLE * OutputHandlePtr);
Arguments
HandleType
[Input] The type of handle to be allocated by SQL AllocHandle . Must be one of the following values:
SQL_HANDLE_DBC
SQL_HANDLE_DBC_INFO_TOKEN
SQL_HANDLE_DESC
SQL_HANDLE_ENV
SQL_HANDLE_STMT
SQL_HANDLE_DBC_INFO_TOKEN handle is used only by the Driver Manager and driver. Applications should not
use this handle type. For more information about SQL_HANDLE_DBC_INFO_TOKEN, see Developing
Connection-Pool Awareness in an ODBC Driver.
InputHandle
[Input] The input handle in whose context the new handle is to be allocated. If HandleType is SQL_HANDLE_ENV,
this is SQL_NULL_HANDLE. If HandleType is SQL_HANDLE_DBC, this must be an environment handle, and if it is
SQL_HANDLE_STMT or SQL_HANDLE_DESC, it must be a connection handle.
OutputHandlePtr
[Output] Pointer to a buffer in which to return the handle to the newly allocated data structure.
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_INVALID_HANDLE, or SQL_ERROR.
When allocating a handle other than an environment handle, if SQL AllocHandle returns SQL_ERROR, it sets
OutputHandlePtr to SQL_NULL_HDBC, SQL_NULL_HSTMT, or SQL_NULL_HDESC, depending on the value of
HandleType, unless the output argument is a null pointer. The application can then obtain additional information
from the diagnostic data structure associated with the handle in the InputHandle argument.
Diagnostics
When SQL AllocHandle returns SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE value can
be obtained by calling SQLGetDiagRec with the appropriate HandleType and Handle set to the value of
InputHandle. SQL_SUCCESS_WITH_INFO (but not SQL_ERROR) can be returned for the OutputHandle argument.
The following table lists the SQLSTATE values typically returned by SQL AllocHandle and explains each one in
the context of this function; the notation "(DM)" precedes the descriptions of SQLSTATEs returned by the Driver
Manager. The return code associated with each SQLSTATE value is SQL_ERROR, unless noted otherwise.
HY001 Memory allocation error (DM) The Driver Manager was unable
to allocate memory for the specified
handle.
HY014 Limit on the number of handles The driver-defined limit for the number
exceeded of handles that can be allocated for the
type of handle indicated by the
HandleType argument has been
reached.
IM001 Driver does not support this function (DM) The HandleType argument was
SQL_HANDLE_STMT, and the driver
was not a valid ODBC driver.
Comments
SQL AllocHandle is used to allocate handles for environments, connections, statements, and descriptors, as
described in the following sections. For general information about handles, see Handles.
More than one environment, connection, or statement handle can be allocated by an application at a time if
multiple allocations are supported by the driver. In ODBC, no limit is defined on the number of environment,
connection, statement, or descriptor handles that can be allocated at any one time. Drivers may impose a limit
on the number of a certain type of handle that can be allocated at a time; for more information, see the driver
documentation.
If the application calls SQL AllocHandle with *OutputHandlePtr set to an environment, connection, statement,
or descriptor handle that already exists, the driver overwrites the information associated with the handle, unless
the application is using connection pooling (see "Allocating an Environment Attribute for Connection Pooling"
later in this section). The Driver Manager does not check to see whether the handle entered in *OutputHandlePtr
is already being used, nor does it check the previous contents of a handle before overwriting them.
NOTE
It is incorrect ODBC application programming to call SQL AllocHandle two times with the same application variable
defined for *OutputHandlePtr without calling SQLFreeHandle to free the handle before reallocating it. Overwriting
ODBC handles in such a manner could lead to inconsistent behavior or errors on the part of ODBC drivers.
On operating systems that support multiple threads, applications can use the same environment, connection,
statement, or descriptor handle on different threads. Drivers must therefore support safe, multithread access to
this information; one way to achieve this, for example, is by using a critical section or a semaphore. For more
information about threading, see Multithreading.
SQL AllocHandle does not set the SQL_ATTR_ODBC_VERSION environment attribute when it is called to
allocate an environment handle; the environment attribute must be set by the application, or SQLSTATE HY010
(Function sequence error) will be returned when SQL AllocHandle is called to allocate a connection handle.
For standards-compliant applications, SQL AllocHandle is mapped to SQL AllocHandleStd at compile time.
The difference between these two functions is that SQL AllocHandleStd sets the SQL_ATTR_ODBC_VERSION
environment attribute to SQL_OV_ODBC3 when it is called with the HandleType argument set to
SQL_HANDLE_ENV. This is done because standards-compliant applications are always ODBC 3.x applications.
Moreover, the standards do not require the application version to be registered. This is the only difference
between these two functions; otherwise, they are identical. SQL AllocHandleStd is mapped to
SQL AllocHandle inside the driver manager. Therefore, third-party drivers do not have to implement
SQL AllocHandleStd .
ODBC 3.8 applications should use:
SQL AllocHandle and not SQL AllocHandleStd to allocate an environment handle.
SQLSetEnvAttr to set the SQL_ATTR_ODBC_VERSION environment attribute to SQL_OV_ODBC3_80.
Code Example
See Sample ODBC Program, SQLBrowseConnect Function, SQLConnect Function, and SQLSetCursorName
Function.
Related Functions
F O R IN F O RM AT IO N A B O UT SEE
See Also
ODBC API Reference
ODBC Header Files
SQLAllocStmt Function
4/27/2022 • 2 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 1.0 Standards Compliance: Deprecated
Summar y
In ODBC 3.x, the ODBC 2.x function SQL AllocStmt has been replaced by SQL AllocHandle . For more
information, see SQLAllocHandle Function.
NOTE
For more information about what the Driver Manager maps this function to when an ODBC 2.x application is working
with an ODBC 3.x driver, see Mapping Deprecated Functions in Appendix G: Driver Guidelines for Backward Compatibility.
See Also
ODBC API Reference
ODBC Header Files
SQLBindCol Function
4/27/2022 • 20 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 1.0 Standards Compliance: ISO 92
Summar y
SQLBindCol binds application data buffers to columns in the result set.
Syntax
SQLRETURN SQLBindCol(
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLSMALLINT TargetType,
SQLPOINTER TargetValuePtr,
SQLLEN BufferLength,
SQLLEN * StrLen_or_IndPtr);
Arguments
StatementHandle
[Input] Statement handle.
ColumnNumber
[Input] Number of the result set column to bind. Columns are numbered in increasing column order starting at
0, where column 0 is the bookmark column. If bookmarks are not used - that is, the
SQL_ATTR_USE_BOOKMARKS statement attribute is set to SQL_UB_OFF - then column numbers start at 1.
TargetType
[Input] The identifier of the C data type of the *TargetValuePtr buffer. When it is retrieving data from the data
source with SQLFetch , SQLFetchScroll , SQLBulkOperations , or SQLSetPos , the driver converts the data to
this type; when it sends data to the data source with SQLBulkOperations or SQLSetPos , the driver converts
the data from this type. For a list of valid C data types and type identifiers, see the C Data Types section in
Appendix D: Data Types.
If the TargetType argument is an interval data type, the default interval leading precision (2) and the default
interval seconds precision (6), as set in the SQL_DESC_DATETIME_INTERVAL_PRECISION and
SQL_DESC_PRECISION fields of the ARD, respectively, are used for the data. If the TargetType argument is
SQL_C_NUMERIC, the default precision (driver-defined) and default scale (0), as set in the
SQL_DESC_PRECISION and SQL_DESC_SCALE fields of the ARD, are used for the data. If any default precision or
scale is not appropriate, the application should explicitly set the appropriate descriptor field by a call to
SQLSetDescField or SQLSetDescRec .
You can also specify an extended C data type. For more information, see C Data Types in ODBC.
TargetValuePtr
[Deferred Input/Output] Pointer to the data buffer to bind to the column. SQLFetch and SQLFetchScroll
return data in this buffer. SQLBulkOperations returns data in this buffer when Operation is
SQL_FETCH_BY_BOOKMARK; it retrieves data from this buffer when Operation is SQL_ADD or
SQL_UPDATE_BY_BOOKMARK. SQLSetPos returns data in this buffer when Operation is SQL_REFRESH; it
retrieves data from this buffer when Operation is SQL_UPDATE.
If TargetValuePtr is a null pointer, the driver unbinds the data buffer for the column. An application can unbind all
columns by calling SQLFreeStmt with the SQL_UNBIND option. An application can unbind the data buffer for a
column but still have a length/indicator buffer bound for the column, if the TargetValuePtr argument in the call
to SQLBindCol is a null pointer but the StrLen_or_IndPtr argument is a valid value.
BufferLength
[Input] Length of the *TargetValuePtr buffer in bytes.
The driver uses BufferLength to avoid writing past the end of the *TargetValuePtr buffer when it returns
variable-length data, such as character or binary data. Notice that the driver counts the null-termination
character when it returns character data to *TargetValuePtr. *TargetValuePtr must therefore contain space for the
null-termination character or the driver will truncate the data.
When the driver returns fixed-length data, such as an integer or a date structure, the driver ignores BufferLength
and assumes the buffer is large enough to hold the data. Therefore, it is important for the application to allocate
a large enough buffer for fixed-length data or the driver will write past the end of the buffer.
SQLBindCol returns SQLSTATE HY090 (Invalid string or buffer length) when BufferLength is less than 0 but not
when BufferLength is 0. However, if TargetType specifies a character type, an application should not set
BufferLength to 0, because ISO CLI-compliant drivers return SQLSTATE HY090 (Invalid string or buffer length) in
that case.
StrLen_or_IndPtr
[Deferred Input/Output] Pointer to the length/indicator buffer to bind to the column. SQLFetch and
SQLFetchScroll return a value in this buffer. SQLBulkOperations retrieves a value from this buffer when
Operation is SQL_ADD, SQL_UPDATE_BY_BOOKMARK, or SQL_DELETE_BY_BOOKMARK. SQLBulkOperations
returns a value in this buffer when Operation is SQL_FETCH_BY_BOOKMARK. SQLSetPos returns a value in this
buffer when Operation is SQL_REFRESH; it retrieves a value from this buffer when Operation is SQL_UPDATE.
SQLFetch , SQLFetchScroll , SQLBulkOperations , and SQLSetPos can return the following values in the
length/indicator buffer:
The length of the data available to return
SQL_NO_TOTAL
SQL_NULL_DATA
The application can put the following values in the length/indicator buffer for use with SQLBulkOperations or
SQLSetPos :
The length of the data being sent
SQL_NTS
SQL_NULL_DATA
SQL_DATA_AT_EXEC
The result of the SQL_LEN_DATA_AT_EXEC macro
SQL_COLUMN_IGNORE
If the indicator buffer and the length buffer are separate buffers, the indicator buffer can return only
SQL_NULL_DATA, whereas the length buffer can return all other values.
For more information, see SQLBulkOperations Function, SQLFetch Function, SQLSetPos Function, and Using
Length/Indicator Values.
If StrLen_or_IndPtr is a null pointer, no length or indicator value is used. This is an error when fetching data and
the data is NULL.
See ODBC 64-Bit Information, if your application will run on a 64-bit operating system.
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
Diagnostics
When SQLBindCol returns SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE value can be
obtained by calling SQLGetDiagRec with a HandleType of SQL_HANDLE_STMT and a Handle of
StatementHandle. The following table lists the SQLSTATE values typically returned by SQLBindCol and explains
each one in the context of this function; the notation "(DM)" precedes the descriptions of SQLSTATEs returned by
the Driver Manager. The return code associated with each SQLSTATE value is SQL_ERROR, unless noted
otherwise.
07006 Restricted data type attribute violation (DM) The ColumnNumber argument
was 0, and the TargetType argument
was not SQL_C_BOOKMARK or
SQL_C_VARBOOKMARK.
07009 Invalid descriptor index The value specified for the argument
ColumnNumber exceeded the
maximum number of columns in the
result set.
HY003 Invalid application buffer type The argument TargetType was neither
a valid data type nor SQL_C_DEFAULT.
SQ L STAT E ERRO R DESC RIP T IO N
HY090 Invalid string or buffer length (DM) The value specified for the
argument BufferLength was less than
0.
HYC00 Optional feature not implemented The driver or data source does not
support the conversion specified by
the combination of the TargetType
argument and the driver-specific SQL
data type of the corresponding
column.
SQL_C_NUMERIC SQL_C_SBIGINT
SQL_C_UBIGINT
IM001 Driver does not support this function (DM) The driver associated with the
StatementHandle does not support
the function.
Comments
SQLBindCol is used to associate, or bind, columns in the result set to data buffers and length/indicator buffers
in the application. When the application calls SQLFetch , SQLFetchScroll , or SQLSetPos to fetch data, the
driver returns the data for the bound columns in the specified buffers; for more information, see SQLFetch
Function. When the application calls SQLBulkOperations to update or insert a row or SQLSetPos to update a
row, the driver retrieves the data for the bound columns from the specified buffers; for more information, see
SQLBulkOperations Function or SQLSetPos Function. For more information about binding, see Retrieving
Results (Basic).
Notice that columns do not have to be bound to retrieve data from them. An application can also call
SQLGetData to retrieve data from columns. Although it is possible to bind some columns in a row and call
SQLGetData for others, this is subject to some restrictions. For more information, see SQLGetData.
NOTE
The statement attribute SQL_ATTR_USE_BOOKMARKS should always be set before binding a column to column 0. This is
not required but is strongly recommended.
Binding Columns
To bind a column, an application calls SQLBindCol and passes the column number, type, address, and length of
a data buffer, and the address of a length/indicator buffer. For information about how these addresses are used,
see "Buffer Addresses," later in this section. For more information about binding columns, see Using
SQLBindCol.
The use of these buffers is deferred; that is, the application binds them in SQLBindCol but the driver accesses
them from other functions - namely SQLBulkOperations , SQLFetch , SQLFetchScroll , or SQLSetPos . It is
the application's responsibility to make sure that the pointers specified in SQLBindCol remain valid as long as
the binding remains in effect. If the application allows these pointers to become invalid - for example, it frees a
buffer - and then calls a function that expects them to be valid, the consequences are undefined. For more
information, see Deferred Buffers.
The binding remains in effect until it is replaced by a new binding, the column is unbound, or the statement is
freed.
Unbinding Columns
To unbind a single column, an application calls SQLBindCol with ColumnNumber set to the number of that
column and TargetValuePtr set to a null pointer. If ColumnNumber refers to an unbound column, SQLBindCol
still returns SQL_SUCCESS.
To unbind all columns, an application calls SQLFreeStmt with fOption set to SQL_UNBIND. This can also be
accomplished by setting the SQL_DESC_COUNT field of the ARD to zero.
Rebinding Columns
An application can perform either of two operations to change a binding:
Call SQLBindCol to specify a new binding for a column that is already bound. The driver overwrites the
old binding with the new one.
Specify an offset to be added to the buffer address that was specified by the binding call to SQLBindCol .
For more information, see the next section, "Binding Offsets."
Binding Offsets
A binding offset is a value that is added to the addresses of the data and length/indicator buffers (as specified in
the TargetValuePtr and StrLen_or_IndPtr argument) before they are dereferenced. When offsets are used, the
bindings are a "template" of how the application's buffers are laid out, and the application can move this
"template" to different areas of memory by changing the offset. Because the same offset is added to each
address in each binding, the relative offsets between buffers for different columns must be the same within each
set of buffers. This is always true when row-wise binding is used; the application must carefully lay out its
buffers for this to be true when column-wise binding is used.
Using a binding offset has basically the same effect as rebinding a column by calling SQLBindCol . The
difference is that a new call to SQLBindCol specifies new addresses for the data buffer and length/indicator
buffer, whereas use of a binding offset does not change the addresses but just adds an offset to them. The
application can specify a new offset whenever it wants, and this offset is always added to the originally bound
addresses. In particular, if the offset is set to 0 or if the statement attribute is set to a null pointer, the driver uses
the originally bound addresses.
To specify a binding offset, the application sets the SQL_ATTR_ROW_BIND_OFFSET_PTR statement attribute to
the address of an SQLINTEGER buffer. Before the application calls a function that uses bindings, it puts an offset
in bytes in this buffer. To determine the address of the buffer to use, the driver adds the offset to the address in
the binding. The sum of the address and the offset must be a valid address, but the address to which the offset is
added does not have to be valid. For more information about how binding offsets are used, see "Buffer
Addresses," later in this section.
Binding Arrays
If the rowset size (the value of the SQL_ATTR_ROW_ARRAY_SIZE statement attribute) is greater than 1, the
application binds arrays of buffers instead of single buffers. For more information, see Block Cursors.
The application can bind arrays in two ways:
Bind an array to each column. This is referred to as column-wise binding because each data structure
(array) contains data for a single column.
Define a structure to hold the data for a whole row and bind an array of these structures. This is referred
to as row-wise binding because each data structure contains the data for a single row.
Each array of buffers must have at least as many elements as the size of the rowset.
NOTE
An application must verify that alignment is valid. For more information about alignment considerations, see Alignment.
Column-Wise Binding
In column-wise binding, the application binds separate data and length/indicator arrays to each column.
To use column-wise binding, the application first sets the SQL_ATTR_ROW_BIND_TYPE statement attribute to
SQL_BIND_BY_COLUMN. (This is the default.) For each column to be bound, the application performs the
following steps:
1. Allocates a data buffer array.
2. Allocates an array of length/indicator buffers.
NOTE
If the application writes directly to descriptors when column-wise binding is used, separate arrays can be used for
length and indicator data.
Row-Wise Binding
In row-wise binding, the application defines a structure that contains data and length/indicator buffers for each
column to be bound.
To use row-wise binding, the application performs the following steps:
1. Defines a structure to hold a single row of data (including both data and length/indicator buffers) and
allocates an array of these structures.
NOTE
If the application writes directly to descriptors when row-wise binding is used, separate fields can be used for
length and indicator data.
2. Sets the SQL_ATTR_ROW_BIND_TYPE statement attribute to the size of the structure that contains a single
row of data or to the size of an instance of a buffer into which the results columns will be bound. The
length must include space for all the bound columns, and any padding of the structure or buffer, to make
sure that when the address of a bound column is incremented with the specified length, the result will
point to the beginning of the same column in the next row. When using the sizeof operator in ANSI C, this
behavior is guaranteed.
3. Calls SQLBindCol with the following arguments for each column to be bound:
TargetType is the type of the data buffer member to be bound to the column.
TargetValuePtr is the address of the data buffer member in the first array element.
BufferLength is the size of the data buffer member.
StrLen_or_IndPtr is the address of the length/indicator member to be bound.
For more information about how this information is used, see "Buffer Addresses," later in this section. For more
information about column-wise binding, see Row-Wise Binding.
Buffer Addresses
The buffer address is the actual address of the data or length/indicator buffer. The driver calculates the buffer
address just before it writes to the buffers (such as during fetch time). It is calculated from the following formula,
which uses the addresses specified in the TargetValuePtr and StrLen_or_IndPtr arguments, the binding offset,
and the row number:
Bound Address + Binding Offset + ((Row Number - 1) x Element Size)
where the formula's variables are defined as described in the following table.
Bound Address For data buffers, the address specified with the
TargetValuePtr argument in SQLBindCol.
Binding Offset If row-wise binding is used, the value stored at the address
specified with the SQL_ATTR_ROW_BIND_OFFSET_PTR
statement attribute.
Row Number The 1-based number of the row in the rowset. For single-
row fetches, which are the default, this is 1.
Calling SQLBindCol for one statement can affect other statements. This occurs when the ARD associated with
the statement is explicitly allocated and is also associated with other statements. Because SQLBindCol modifies
the descriptor, the modifications apply to all statements with which this descriptor is associated. If this is not the
required behavior, the application should dissociate this descriptor from the other statements before it calls
SQLBindCol .
Argument Mappings
Conceptually, SQLBindCol performs the following steps in sequence:
1. Calls SQLGetStmtAttr to obtain the ARD handle.
2. Calls SQLGetDescField to get this descriptor's SQL_DESC_COUNT field, and if the value in the
ColumnNumber argument exceeds the value of SQL_DESC_COUNT, calls SQLSetDescField to increase
the value of SQL_DESC_COUNT to ColumnNumber.
3. Calls SQLSetDescField multiple times to assign values to the following fields of the ARD:
Sets SQL_DESC_TYPE and SQL_DESC_CONCISE_TYPE to the value of TargetType, except that if
TargetType is one of the concise identifiers of a datetime or interval subtype, it sets
SQL_DESC_TYPE to SQL_DATETIME or SQL_INTERVAL, respectively; sets
SQL_DESC_CONCISE_TYPE to the concise identifier; and sets
SQL_DESC_DATETIME_INTERVAL_CODE to the corresponding datetime or interval subcode.
Sets one or more of SQL_DESC_LENGTH, SQL_DESC_PRECISION, SQL_DESC_SCALE, and
SQL_DESC_DATETIME_INTERVAL_PRECISION, as appropriate for TargetType.
Sets the SQL_DESC_OCTET_LENGTH field to the value of BufferLength.
Sets the SQL_DESC_DATA_PTR field to the value of TargetValuePtr.
Sets the SQL_DESC_INDICATOR_PTR field to the value of StrLen_or_IndPtr. (See the following
paragraph.)
Sets the SQL_DESC_OCTET_LENGTH_PTR field to the value of StrLen_or_IndPtr. (See the following
paragraph.)
The variable that the StrLen_or_IndPtr argument refers to is used for both indicator and length information. If a
fetch encounters a null value for the column, it stores SQL_NULL_DATA in this variable; otherwise, it stores the
data length in this variable. Passing a null pointer as StrLen_or_IndPtr keeps the fetch operation from returning
the data length but makes the fetch fail if it encounters a null value and has no way to return SQL_NULL_DATA.
If the call to SQLBindCol fails, the content of the descriptor fields that it would have set in the ARD are
undefined and the value of the SQL_DESC_COUNT field of the ARD is unchanged.
Code Example
In the following example, an application executes a SELECT statement on the Customers table to return a result
set of the customer IDs, names, and phone numbers, sorted by name. It then calls SQLBindCol to bind the
columns of data to local buffers. Finally, the application fetches each row of data with SQLFetch and prints each
customer's name, ID, and phone number.
For more code examples, see SQLBulkOperations Function, SQLColumns Function, SQLFetchScroll Function, and
SQLSetPos Function.
// SQLBindCol_ref.cpp
// compile with: odbc32.lib
#include <windows.h>
#include <windows.h>
#include <stdio.h>
#define UNICODE
#include <sqlext.h>
#define NAME_LEN 50
#define PHONE_LEN 60
void show_error() {
printf("error\n");
}
int main() {
SQLHENV henv;
SQLHDBC hdbc;
SQLHSTMT hstmt = 0;
SQLRETURN retcode;
SQLWCHAR szName[NAME_LEN], szPhone[PHONE_LEN], sCustID[NAME_LEN];
SQLLEN cbName = 0, cbCustID = 0, cbPhone = 0;
// Fetch and print each row of data. On an error, display a message and exit.
for (int i=0 ; ; i++) {
retcode = SQLFetch(hstmt);
if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO)
show_error();
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
//replace wprintf with printf
//%S with %ls
//warning C4477: 'wprintf' : format string '%S' requires an argument of type 'char
*'
//but variadic argument 2 has type 'SQLWCHAR *'
//wprintf(L"%d: %S %S %S\n", i + 1, sCustID, szName, szPhone);
printf("%d: %ls %ls %ls\n", i + 1, sCustID, szName, szPhone);
}
else
break;
}
}
}
// Process data
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
SQLCancel(hstmt);
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
}
SQLDisconnect(hdbc);
}
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
}
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
}
Related Functions
F O R IN F O RM AT IO N A B O UT SEE
See Also
ODBC API Reference
ODBC Header Files
SQLBindParameter Function
4/27/2022 • 40 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 2.0 Standards Compliance: ODBC
Summar y
SQLBindParameter binds a buffer to a parameter marker in an SQL statement. SQLBindParameter supports
binding to a Unicode C data type, even if the underlying driver does not support Unicode data.
NOTE
This function replaces the ODBC 1.0 function SQLSetParam . For more information, see "Comments."
Syntax
SQLRETURN SQLBindParameter(
SQLHSTMT StatementHandle,
SQLUSMALLINT ParameterNumber,
SQLSMALLINT InputOutputType,
SQLSMALLINT ValueType,
SQLSMALLINT ParameterType,
SQLULEN ColumnSize,
SQLSMALLINT DecimalDigits,
SQLPOINTER ParameterValuePtr,
SQLLEN BufferLength,
SQLLEN * StrLen_or_IndPtr);
Arguments
StatementHandle
[Input] Statement handle.
ParameterNumber
[Input] Parameter number, ordered sequentially in increasing parameter order, starting at 1.
InputOutputType
[Input] The type of the parameter. For more information, see "InputOutputType Argument" in "Comments."
ValueType
[Input] The C data type of the parameter. For more information, see "ValueType Argument" in "Comments."
ParameterType
[Input] The SQL data type of the parameter. For more information, see "ParameterType Argument" in
"Comments."
ColumnSize
[Input] The size of the column or expression of the corresponding parameter marker. For more information, see
"ColumnSize Argument" in "Comments."
If your application will run on a 64-bit Windows operating system, see ODBC 64-Bit Information.
DecimalDigits
[Input] The decimal digits of the column or expression of the corresponding parameter marker. For more
information about column size, see Column Size, Decimal Digits, Transfer Octet Length, and Display Size.
ParameterValuePtr
[Deferred Input] A pointer to a buffer for the parameter's data. For more information, see "ParameterValuePtr
Argument" in "Comments."
BufferLength
[Input/Output] Length of the ParameterValuePtr buffer in bytes. For more information, see "BufferLength
Argument" in "Comments."
See ODBC 64-Bit Information, if your application will run on a 64-bit operating system.
StrLen_or_IndPtr
[Deferred Input] A pointer to a buffer for the parameter's length. For more information, see "StrLen_or_IndPtr
Argument" in "Comments."
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
Diagnostics
When SQLBindParameter returns SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE value
can be obtained by calling SQLGetDiagRec with a HandleType of SQL_HANDLE_STMT and a Handle of
StatementHandle. The following table lists the SQLSTATE values typically returned by SQLBindParameter and
explains each one in the context of this function; the notation "(DM)" precedes the descriptions of SQLSTATEs
returned by the Driver Manager. The return code associated with each SQLSTATE value is SQL_ERROR, unless
noted otherwise.
07006 Restricted data type attribute violation The data type identified by the
ValueType argument cannot be
converted to the data type identified
by the ParameterType argument.
Notice that this error may be returned
by SQLExecDirect , SQLExecute , or
SQLPutData at execution time,
instead of by SQLBindParameter .
07009 Invalid descriptor index (DM) The value specified for the
argument ParameterNumber was less
than 1.
HY003 Invalid application buffer type The value specified by the argument
ValueType was not a valid C data type
or SQL_C_DEFAULT.
HY004 Invalid SQL data type The value specified for the argument
ParameterType was neither a valid
ODBC SQL data type identifier nor a
driver-specific SQL data type identifier
supported by the driver.
HY090 Invalid string or buffer length (DM) The value in BufferLength was
less than 0. (See the description of the
SQL_DESC_DATA_PTR field in
SQLSetDescField .)
HY104 Invalid precision or scale value The value specified for the argument
ColumnSize or DecimalDigits was
outside the range of values supported
by the data source for a column of the
SQL data type specified by the
ParameterType argument.
HY105 Invalid parameter type (DM) The value specified for the
argument InputOutputType was
invalid. (See "Comments.")
HYC00 Optional feature not implemented The driver or data source does not
support the conversion specified by
the combination of the value specified
for the argument ValueType and the
driver-specific value specified for the
argument ParameterType.
SQL_C_NUMERIC SQL_C_SBIGINT
SQL_C_UBIGINT
IM001 Driver does not support this function (DM) The driver associated with the
StatementHandle does not support
the function.
Comments
An application calls SQLBindParameter to bind each parameter marker in an SQL statement. Bindings remain
in effect until the application calls SQLBindParameter again, calls SQLFreeStmt with the
SQL_RESET_PARAMS option, or calls SQLSetDescField to set the SQL_DESC_COUNT header field of the APD to
0.
For more information about parameters, see Statement Parameters. For more information about parameter data
types and parameter markers, see Parameter Data Types and Parameter Markers in Appendix C: SQL Grammar.
ParameterNumber Argument
If ParameterNumber in the call to SQLBindParameter is greater than the value of SQL_DESC_COUNT,
SQLSetDescField is called to increase the value of SQL_DESC_COUNT to ParameterNumber.
InputOutputType Argument
The InputOutputType argument specifies the type of the parameter. This argument sets the
SQL_DESC_PARAMETER_TYPE field of the IPD. All parameters in SQL statements that do not call procedures,
such as INSERT statements, are input parameters. Parameters in procedure calls can be input, input/output, or
output parameters. (An application calls SQLProcedureColumns to determine the type of a parameter in a
procedure call; parameters whose type cannot be determined are assumed to be input parameters.)
The InputOutputType argument is one of the following values:
SQL_PARAM_INPUT. The parameter marks a parameter in an SQL statement that does not call a
procedure, such as an INSERT statement, or it marks an input parameter in a procedure. For example, the
parameters in INSERT INTO Employee VALUES (?, ?, ?) are input parameters, whereas the
parameters in {call AddEmp(?, ?, ?)} can be, but are not necessarily, input parameters.
When the statement is executed, the driver sends data for the parameter to the data source; the
*ParameterValuePtr buffer must contain a valid input value, or the *StrLen_or_IndPtr buffer must contain
SQL_NULL_DATA, SQL_DATA_AT_EXEC, or the result of the SQL_LEN_DATA_AT_EXEC macro.
If an application cannot determine the type of a parameter in a procedure call, it sets InputOutputType to
SQL_PARAM_INPUT; if the data source returns a value for the parameter, the driver discards it.
SQL_PARAM_INPUT_OUTPUT. The parameter marks an input/output parameter in a procedure. For
example, the parameter in {call GetEmpDept(?)} is an input/output parameter that accepts an
employee's name and returns the name of the employee's department.
When the statement is executed, the driver sends data for the parameter to the data source; the
*ParameterValuePtr buffer must contain a valid input value, or the *StrLen_or_IndPtr buffer must contain
SQL_NULL_DATA, SQL_DATA_AT_EXEC, or the result of the SQL_LEN_DATA_AT_EXEC macro. After the
statement is executed, the driver returns data for the parameter to the application; if the data source does
not return a value for an input/output parameter, the driver sets the *StrLen_or_IndPtr buffer to
SQL_NULL_DATA.
NOTE
When an ODBC 1.0 application calls SQLSetParam in an ODBC 2.0 driver, the Driver Manager converts this to a
call to SQLBindParameter in which the InputOutputType argument is set to SQL_PARAM_INPUT_OUTPUT.
SQL_PARAM_OUTPUT. The parameter marks the return value of a procedure or an output parameter in a
procedure; in either case, these are known as output parameters. For example, the parameter in {?=call
GetNextEmpID} is an output parameter that returns the next employee ID.
After the statement is executed, the driver returns data for the parameter to the application, unless the
ParameterValuePtr and StrLen_or_IndPtr arguments are both null pointers, in which case the driver
discards the output value. If the data source does not return a value for an output parameter, the driver
sets the *StrLen_or_IndPtr buffer to SQL_NULL_DATA.
SQL_PARAM_INPUT_OUTPUT_STREAM. Indicates that an input/output parameter should be streamed.
SQLGetData can read parameter values in parts. BufferLength is ignored because the buffer length will
be determined at the call of SQLGetData . The value of the StrLen_or_IndPtr buffer must contain
SQL_NULL_DATA, SQL_DEFAULT_PARAM, SQL_DATA_AT_EXEC, or the result of the
SQL_LEN_DATA_AT_EXEC macro. A parameter must be bound as a data-at-execution (DAE) parameter at
input if it will be streamed at output. ParameterValuePtr can be any non-null pointer value that will be
returned by SQLParamData as the user-defined token whose value was passed with ParameterValuePtr
for both input and output. For more information, see Retrieving Output Parameters Using SQLGetData.
SQL_PARAM_OUTPUT_STREAM. Same as SQL_PARAM_INPUT_OUTPUT_STREAM, for an output
parameter. *StrLen_or_IndPtr is ignored at input.
The following table lists different combinations of InputOutputType and *StrLen_or_IndPtr:
REM A RK O N
IN P UTO UT P UT T Y P E * ST RL EN _O R_IN DP T R O UTC O M E PA RA M ET ERVA L UEP T R
NOTE
The driver must decide which SQL types are allowed when an application binds an output or input-output parameter as
streamed. The driver manager will not generate an error for an invalid SQL type.
ValueType Argument
The ValueType argument specifies the C data type of the parameter. This argument sets the SQL_DESC_TYPE,
SQL_DESC_CONCISE_TYPE, and SQL_DESC_DATETIME_INTERVAL_CODE fields of the APD. This must be one of
the values in the C Data Types section of Appendix D: Data Types.
If the ValueType argument is one of the interval data types, the SQL_DESC_TYPE field of the ParameterNumber
record of the APD is set to SQL_INTERVAL, the SQL_DESC_CONCISE_TYPE field of the APD is set to the concise
interval data type, and the SQL_DESC_DATETIME_INTERVAL_CODE field of the ParameterNumber record is set
to a subcode for the specific interval data type. (See Appendix D: Data Types.) The default interval leading
precision (2) and default interval seconds precision (6), as set in the
SQL_DESC_DATETIME_INTERVAL_PRECISION and SQL_DESC_PRECISION fields of the APD, respectively, are
used for the data. If either default precision is not appropriate, the application should explicitly set the descriptor
field by a call to SQLSetDescField or SQLSetDescRec .
If the ValueType argument is one of the datetime data types, the SQL_DESC_TYPE field of the ParameterNumber
record of the APD is set to SQL_DATETIME, the SQL_DESC_CONCISE_TYPE field of the ParameterNumber record
of the APD is set to the concise datetime C data type, and the SQL_DESC_DATETIME_INTERVAL_CODE field of the
ParameterNumber record is set to a subcode for the specific datetime data type. (See Appendix D: Data Types.)
If the ValueType argument is an SQL_C_NUMERIC data type, the default precision (which is driver-defined) and
the default scale (0), as set in the SQL_DESC_PRECISION and SQL_DESC_SCALE fields of the APD, are used for
the data. If the default precision or scale is not appropriate, the application should explicitly set the descriptor
field by a call to SQLSetDescField or SQLSetDescRec .
SQL_C_DEFAULT specifies that the parameter value be transferred from the default C data type for the SQL data
type specified with ParameterType.
You can also specify an extended C data type. For more information, see C Data Types in ODBC.
For more information, see Default C Data Types, Converting Data from C to SQL Data Types, and Converting
Data from SQL to C Data Types in Appendix D: Data Types.
ParameterType Argument
This must be one of the values listed in the SQL Data Types section of Appendix D: Data Types, or it must be a
driver-specific value. This argument sets the SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE, and
SQL_DESC_DATETIME_INTERVAL_CODE fields of the IPD.
If the ParameterType argument is one of the datetime identifiers, the SQL_DESC_TYPE field of the IPD is set to
SQL_DATETIME, the SQL_DESC_CONCISE_TYPE field of the IPD is set to the concise datetime SQL data type, and
the SQL_DESC_DATETIME_INTERVAL_CODE field is set to the appropriate datetime subcode value.
If ParameterType is one of the interval identifiers, the SQL_DESC_TYPE field of the IPD is set to SQL_INTERVAL,
the SQL_DESC_CONCISE_TYPE field of the IPD is set to the concise SQL interval data type, and the
SQL_DESC_DATETIME_INTERVAL_CODE field of the IPD is set to the appropriate interval subcode. The
SQL_DESC_DATETIME_INTERVAL_PRECISION field of the IPD is set to the interval leading precision, and the
SQL_DESC_PRECISION field is set to the interval seconds precision, if applicable. If the default value of
SQL_DESC_DATETIME_INTERVAL_PRECISION or SQL_DESC_PRECISION is not appropriate, the application
should explicitly set it by calling SQLSetDescField . For more information about any of these fields, see
SQLSetDescField.
If the ValueType argument is a SQL_NUMERIC data type, the default precision (which is driver-defined) and the
default scale (0), as set in the SQL_DESC_PRECISION and SQL_DESC_SCALE fields of the IPD, are used for the
data. If the default precision or scale is not appropriate, the application should explicitly set the descriptor field
by a call to SQLSetDescField or SQLSetDescRec .
For information about how data is converted, see Converting Data from C to SQL Data Types and Converting
Data from SQL to C Data Types in Appendix D: Data Types.
ColumnSize Argument
The ColumnSize argument specifies the size of the column or expression that corresponds to the parameter
marker, the length of that data, or both. This argument sets different fields of the IPD, depending on the SQL data
type (the ParameterType argument). The following rules apply to this mapping:
If ParameterType is SQL_CHAR, SQL_VARCHAR, SQL_LONGVARCHAR, SQL_BINARY, SQL_VARBINARY,
SQL_LONGVARBINARY, or one of the concise SQL datetime or interval data types, the
SQL_DESC_LENGTH field of the IPD is set to the value of ColumnSize. (For more information, see the
Column Size, Decimal Digits, Transfer Octet Length, and Display Size section in Appendix D: Data Types.)
If ParameterType is SQL_DECIMAL, SQL_NUMERIC, SQL_FLOAT, SQL_REAL, or SQL_DOUBLE, the
SQL_DESC_PRECISION field of the IPD is set to the value of ColumnSize.
For other data types, the ColumnSize argument is ignored.
For more information, see "Passing Parameter Values" and SQL_DATA_AT_EXEC in "StrLen_or_IndPtr Argument."
DecimalDigits Argument
If ParameterType is SQL_TYPE_TIME, SQL_TYPE_TIMESTAMP, SQL_INTERVAL_SECOND,
SQL_INTERVAL_DAY_TO_SECOND, SQL_INTERVAL_HOUR_TO_SECOND, or
SQL_INTERVAL_MINUTE_TO_SECOND, the SQL_DESC_PRECISION field of the IPD is set to DecimalDigits. If
ParameterType is SQL_NUMERIC or SQL_DECIMAL, the SQL_DESC_SCALE field of the IPD is set to
DecimalDigits. For all other data types, the DecimalDigits argument is ignored.
ParameterValuePtr Argument
The ParameterValuePtr argument points to a buffer that, when SQLExecute or SQLExecDirect is called,
contains the actual data for the parameter. The data must be in the form specified by the ValueType argument.
This argument sets the SQL_DESC_DATA_PTR field of the APD. An application can set the ParameterValuePtr
argument to a null pointer, as long as *StrLen_or_IndPtr is SQL_NULL_DATA or SQL_DATA_AT_EXEC. (This applies
only to input or input/output parameters.)
If *StrLen_or_IndPtr is the result of the SQL_LEN_DATA_AT_EXEC(length) macro or SQL_DATA_AT_EXEC, then
ParameterValuePtr is an application-defined pointer value that is associated with the parameter. It is returned to
the application through SQLParamData . For example, ParameterValuePtr might be a non-zero token such as a
parameter number, a pointer to data, or a pointer to a structure that the application used to bind input
parameters. However, note that if the parameter is an input/output parameter, ParameterValuePtr must be a
pointer to a buffer where the output value will be stored. If the value in the SQL_ATTR_PARAMSET_SIZE
statement attribute is greater than 1, the application can use the value pointed to by the
SQL_ATTR_PARAMS_PROCESSED_PTR statement attribute together with the ParameterValuePtr argument. For
example, ParameterValuePtr might point to an array of values and the application might use the value pointed to
by SQL_ATTR_PARAMS_PROCESSED_PTR to retrieve the correct value from the array. For more information, see
"Passing Parameter Values" later in this section.
If the InputOutputType argument is SQL_PARAM_INPUT_OUTPUT or SQL_PARAM_OUTPUT, ParameterValuePtr
points to a buffer in which the driver returns the output value. If the procedure returns one or more result sets,
the *ParameterValuePtr buffer is not guaranteed to be set until all result sets/row counts have been processed. If
the buffer is not set until processing is complete, the output parameters and return values are unavailable until
SQLMoreResults returns SQL_NO_DATA. Calling SQLCloseCursor or SQLFreeStmt with an Option of
SQL_CLOSE will cause these values to be discarded.
If the value in the SQL_ATTR_PARAMSET_SIZE statement attribute is greater than 1, ParameterValuePtr points to
an array. A single SQL statement processes the complete array of input values for an input or input/output
parameter and returns an array of output values for an input/output or output parameter.
BufferLength Argument
For character and binary C data, the BufferLength argument specifies the length of the *ParameterValuePtr
buffer (if it is a single element) or the length of an element in the *ParameterValuePtr array (if the value in the
SQL_ATTR_PARAMSET_SIZE statement attribute is greater than 1). This argument sets the
SQL_DESC_OCTET_LENGTH record field of the APD. If the application specifies multiple values, BufferLength is
used to determine the location of values in the *ParameterValuePtr array, both on input and on output. For
input/output and output parameters, it is used to determine whether to truncate character and binary C data on
output:
For character C data, if the number of bytes available to return is greater than or equal to BufferLength,
the data in *ParameterValuePtr is truncated to BufferLength less the length of a null-termination
character and is null-terminated by the driver.
For binary C data, if the number of bytes available to return is greater than BufferLength, the data in
*ParameterValuePtr is truncated to BufferLength bytes.
For all other types of C data, the BufferLength argument is ignored. The length of the *ParameterValuePtr buffer
(if it is a single element) or the length of an element in the *ParameterValuePtr array (if the application calls
SQLSetStmtAttr with an Attribute argument of SQL_ATTR_PARAMSET_SIZE to specify multiple values for each
parameter) is assumed to be the length of the C data type.
For streamed output or streamed input/output parameters, the BufferLength argument is ignored because the
buffer length is specified in SQLGetData .
NOTE
When an ODBC 1.0 application calls SQLSetParam in an ODBC 3.x driver, the Driver Manager converts this to a call to
SQLBindParameter in which the BufferLength argument is always SQL_SETPARAM_VALUE_MAX. Because the Driver
Manager returns an error if an ODBC 3.x application sets BufferLength to SQL_SETPARAM_VALUE_MAX, an ODBC 3.x
driver can use this to determine when it is called by an ODBC 1.0 application.
NOTE
In SQLSetParam , the way in which an application specifies the length of the *ParameterValuePtr buffer so that the driver
can return character or binary data, and the way in which an application sends an array of character or binary parameter
values to the driver, are driver-defined.
StrLen_or_IndPtr Argument
The StrLen_or_IndPtr argument points to a buffer that, when SQLExecute or SQLExecDirect is called, contains
one of the following. (This argument sets the SQL_DESC_OCTET_LENGTH_PTR and SQL_DESC_INDICATOR_PTR
record fields of the application parameter pointers.)
The length of the parameter value stored in *ParameterValuePtr. This is ignored except for character or
binary C data.
SQL_NTS. The parameter value is a null-terminated string.
SQL_NULL_DATA. The parameter value is NULL.
SQL_DEFAULT_PARAM. A procedure is to use the default value of a parameter, instead of a value retrieved
from the application. This value is valid only in a procedure called in ODBC canonical syntax, and then
only if the InputOutputType argument is SQL_PARAM_INPUT, SQL_PARAM_INPUT_OUTPUT, or
SQL_PARAM_INPUT_OUTPUT_STREAM. When *StrLen_or_IndPtr is SQL_DEFAULT_PARAM, the ValueType,
ParameterType, ColumnSize, DecimalDigits, BufferLength, and ParameterValuePtr arguments are ignored
for input parameters and are used only to define the output parameter value for input/output
parameters.
The result of the SQL_LEN_DATA_AT_EXEC(length) macro. The data for the parameter will be sent with
SQLPutData . If the ParameterType argument is SQL_LONGVARBINARY, SQL_LONGVARCHAR, or a long,
data source-specific data type, and the driver returns "Y" for the SQL_NEED_LONG_DATA_LEN
information type in SQLGetInfo , length is the number of bytes of data to be sent for the parameter;
otherwise, length must be a nonnegative value and is ignored. For more information, see "Passing
Parameter Values," later in this section.
For example, to specify that 10,000 bytes of data will be sent with SQLPutData in one or more calls, for
an SQL_LONGVARCHAR parameter, an application sets *StrLen_or_IndPtr to
SQL_LEN_DATA_AT_EXEC(10000).
SQL_DATA_AT_EXEC. The data for the parameter will be sent with SQLPutData . This value is used by
ODBC 1.0 applications when they call ODBC 3.x drivers. For more information, see "Passing Parameter
Values," later in this section.
If StrLen_or_IndPtr is a null pointer, the driver assumes that all input parameter values are non-NULL and that
character and binary data is null-terminated. If InputOutputType is SQL_PARAM_OUTPUT or
SQL_PARAM_OUTPUT_STREAM and ParameterValuePtr and StrLen_or_IndPtr are both null pointers, the driver
discards the output value.
NOTE
Application developers are strongly discouraged from specifying a null pointer for StrLen_or_IndPtr when the data type of
the parameter is SQL_C_BINARY. To make sure that a driver does not unexpectedly truncate SQL_C_BINARY data,
StrLen_or_IndPtr should contain a pointer to a valid length value.
NOTE
Although data-at-execution parameters resemble data-at-execution columns, the value returned by
SQLParamData is different for each. Data-at-execution parameters are parameters in an SQL statement for
which data will be sent with SQLPutData when the statement is executed with SQLExecDirect or SQLExecute .
They are bound with SQLBindParameter . The value returned by SQLParamData is a pointer value passed to
SQLBindParameter in the ParameterValuePtr argument. Data-at-execution columns are columns in a rowset for
which data will be sent with SQLPutData when a row is updated or added with SQLBulkOperations or
updated with SQLSetPos . They are bound with SQLBindCol. The value returned by SQLParamData is the
address of the row in the *TargetValuePtr buffer (set by a call to SQLBindCol) that is being processed.
5. Calls SQLPutData one or more times to send data for the parameter. More than one call is needed if the
data value is larger than the *ParameterValuePtr buffer specified in SQLPutData ; multiple calls to
SQLPutData for the same parameter are allowed only when sending character C data to a column with a
character, binary, or data source-specific data type or when sending binary C data to a column with a
character, binary, or data source-specific data type.
6. Calls SQLParamData again to signal that all data has been sent for the parameter.
If there are more data-at-execution parameters, SQLParamData returns SQL_NEED_DATA and the
application-defined value for the next data-at-execution parameter to be processed. The
application repeats steps 4 and 5.
If there are no more data-at-execution parameters, the process is complete. If the statement was
successfully executed, SQLParamData returns SQL_SUCCESS or SQL_SUCCESS_WITH_INFO; if
the execution failed, it returns SQL_ERROR. At this point, SQLParamData can return any
SQLSTATE that can be returned by the function that is used to execute the statement
(SQLExecDirect or SQLExecute ).
Output values for any input/output or output parameters are available in the *ParameterValuePtr
and *StrLen_or_IndPtr buffers after the application retrieves all result sets generated by the
statement.
Calling SQLExecute or SQLExecDirect puts the statement in an SQL_NEED_DATA state. At this point, the
application can call only SQLCancel , SQLGetDiagField , SQLGetDiagRec , SQLGetFunctions ,
SQLParamData , or SQLPutData with the statement or the connection handle associated with the statement. If
it calls any other function with the statement or the connection associated with the statement, the function
returns SQLSTATE HY010 (Function sequence error). The statement leaves the SQL_NEED_DATA state when
SQLParamData or SQLPutData returns an error, SQLParamData returns SQL_SUCCESS or
SQL_SUCCESS_WITH_INFO, or the statement is canceled.
If the application calls SQLCancel while the driver still needs data for data-at-execution parameters, the driver
cancels statement execution; the application can then call SQLExecute or SQLExecDirect again.
NOTE
If the application writes directly to descriptors when column-wise binding is used, separate arrays can be used for
length and indicator data.
NOTE
If the application writes directly to descriptors when row-wise binding is used, separate fields can be used for
length and indicator data.
2. Sets the SQL_ATTR_PARAM_BIND_TYPE statement attribute to the size of the structure that contains a
single set of parameters or to the size of an instance of a buffer into which the parameters will be bound.
The length must include space for all the bound parameters, and any padding of the structure or buffer, to
make sure that when the address of a bound parameter is incremented with the specified length, the
result will point to the beginning of the same parameter in the next row. When you use the sizeof
operator in ANSI C, this behavior is guaranteed.
3. Calls SQLBindParameter with the following arguments for each parameter to be bound:
ValueType is the type of the parameter buffer member to be bound to the column.
ParameterType is the SQL type of the parameter.
ParameterValuePtr is the address of the parameter buffer member in the first array element.
BufferLength is the size of the parameter buffer member.
StrLen_or_IndPtr is the address of the length/indicator member to be bound.
For more information about how this information is used, see "ParameterValuePtr Argument," later in this
section. For more information about row-wise binding of parameters, see the Binding Arrays of Parameters.
Error Information
If a driver does not implement parameter arrays as batches (the SQL_PARAM_ARRAY_ROW_COUNTS option is
equal to SQL_PARC_NO_BATCH), error situations are handled as if one statement were executed. If the driver
does implement parameter arrays as batches, an application can use the SQL_DESC_ARRAY_STATUS_PTR header
field of the IPD to determine which parameter of an SQL statement or which parameter in an array of
parameters caused SQLExecDirect or SQLExecute to return an error. This field contains status information for
each row of parameter values. If the field indicates that an error has occurred, fields in the diagnostic data
structure will indicate the row and parameter number of the parameter that failed. The number of elements in
the array will be defined by the SQL_DESC_ARRAY_SIZE header field in the APD, which can be set by the
SQL_ATTR_PARAMSET_SIZE statement attribute.
NOTE
The SQL_DESC_ARRAY_STATUS_PTR header field in the APD is used to ignore parameters. For more information about
ignoring parameters, see the next section, "Ignoring a Set of Parameters."
When SQLExecute or SQLExecDirect returns SQL_ERROR, the elements in the array pointed to by the
SQL_DESC_ARRAY_STATUS_PTR field in the IPD will contain SQL_PARAM_ERROR, SQL_PARAM_SUCCESS,
SQL_PARAM_SUCCESS_WITH_INFO, SQL_PARAM_UNUSED, or SQL_PARAM_DIAG_UNAVAILABLE.
For each element in this array, the diagnostic data structure contains one or more status records. The
SQL_DIAG_ROW_NUMBER field of the structure indicates the row number of the parameter values that caused
the error. If it is possible to determine the particular parameter in a row of parameters that caused the error, the
parameter number will be entered in the SQL_DIAG_COLUMN_NUMBER field.
SQL_PARAM_UNUSED is entered when a parameter has not been used because an error occurred in an earlier
parameter that forced SQLExecute or SQLExecDirect to abort. For example, if there are 50 parameters and an
error occurred while executing the fortieth set of parameters that caused SQLExecute or SQLExecDirect to
abort, then SQL_PARAM_UNUSED is entered in the status array for parameters 41 through 50.
SQL_PARAM_DIAG_UNAVAILABLE is entered when the driver treats arrays of parameters as a monolithic unit, so
it does not generate this individual parameter level of error information.
Some errors in the processing of a single set of parameters cause processing of the subsequent sets of
parameters in the array to stop. Other errors do not affect the processing of subsequent parameters. Which
errors will stop processing is driver-defined. If processing is not stopped, all parameters in the array are
processed, SQL_SUCCESS_WITH_INFO is returned as a result of the error, and the buffer defined by
SQL_ATTR_PARAMS_PROCESSED_PTR is set to the total number of sets of parameters processed (as defined by
the SQL_ATTR_PARAMSET_SIZE statement attribute), which includes error sets.
Cau t i on
ODBC behavior when an error occurs in the processing of an array of parameters is different in ODBC 3.x than it
was in ODBC 2.x. In ODBC 2.x, the function returned SQL_ERROR and processing ceased. The buffer pointed to
by the pirow argument of SQLParamOptions contained the number of the error row. In ODBC 3.x, the function
returns SQL_SUCCESS_WITH_INFO and processing may either stop or continue. If it continues, the buffer
specified by SQL_ATTR_PARAMS_PROCESSED_PTR will be set to the value of all parameters processed, including
those that resulted in an error. This change in behavior may cause problems for existing applications.
When SQLExecute or SQLExecDirect returns before completing the processing of all parameter sets in a
parameter array, such as when SQL_ERROR or SQL_NEED_DATA is returned, the status array contains statuses
for those parameters that have already been processed. The location pointed to by the
SQL_DESC_ROWS_PROCESSED_PTR field in the IPD contains the row number in the parameter array that
caused the SQL_ERROR or SQL_NEED_DATA error code. When an array of parameters is sent to a SELECT
statement, the availability of status array values is driver-defined; they may be available after the statement has
been executed or as result sets are fetched.
Rebinding Parameters
An application can perform either of two operations to change a binding:
Call SQLBindParameter to specify a new binding for a column that is already bound. The driver
overwrites the old binding with the new one.
Specify an offset to be added to the buffer address that was specified by the binding call to
SQLBindParameter . For more information, see the next section, "Rebinding with Offsets."
Descriptors
How a parameter is bound is determined by fields of the APDs and IPDs. The arguments in SQLBindParameter
are used to set those descriptor fields. The fields can also be set by the SQLSetDescField functions, although
SQLBindParameter is more efficient to use because the application does not have to obtain a descriptor
handle to call SQLBindParameter .
Cau t i on
Calling SQLBindParameter for one statement can affect other statements. This occurs when the ARD
associated with the statement is explicitly allocated and is also associated with other statements. Because
SQLBindParameter modifies the fields of the APD, the modifications apply to all statements with which this
descriptor is associated. If this is not the required behavior, the application should dissociate this descriptor from
the other statements before it calls SQLBindParameter .
Conceptually, SQLBindParameter performs the following steps in sequence:
1. Calls SQLGetStmtAttr to obtain the APD handle.
2. Calls SQLGetDescField to get the APD's SQL_DESC_COUNT field, and if the value of the ColumnNumber
argument exceeds the value of SQL_DESC_COUNT, calls SQLSetDescField to increase the value of
SQL_DESC_COUNT to ColumnNumber.
3. Calls SQLSetDescField multiple times to assign values to the following fields of the APD:
Sets SQL_DESC_TYPE and SQL_DESC_CONCISE_TYPE to the value of ValueType, except that if
ValueType is one of the concise identifiers of a datetime or interval subtype, it sets
SQL_DESC_TYPE to SQL_DATETIME or SQL_INTERVAL, respectively, sets
SQL_DESC_CONCISE_TYPE to the concise identifier, and sets
SQL_DESC_DATETIME_INTERVAL_CODE to the corresponding datetime or interval subcode.
Sets the SQL_DESC_OCTET_LENGTH field to the value of BufferLength.
Sets the SQL_DESC_DATA_PTR field to the value of ParameterValue.
Sets the SQL_DESC_OCTET_LENGTH_PTR field to the value of StrLen_or_Ind.
Sets the SQL_DESC_INDICATOR_PTR field also to the value of StrLen_or_Ind.
The StrLen_or_Ind parameter specifies both the indicator information and the length for the parameter
value.
4. Calls SQLGetStmtAttr to obtain the IPD handle.
5. Calls SQLGetDescField to get the IPD's SQL_DESC_COUNT field, and if the value of the ColumnNumber
argument exceeds the value of SQL_DESC_COUNT, calls SQLSetDescField to increase the value of
SQL_DESC_COUNT to ColumnNumber.
6. Calls SQLSetDescField multiple times to assign values to the following fields of the IPD:
Sets SQL_DESC_TYPE and SQL_DESC_CONCISE_TYPE to the value of ParameterType, except that if
ParameterType is one of the concise identifiers of a datetime or interval subtype, it sets
SQL_DESC_TYPE to SQL_DATETIME or SQL_INTERVAL, respectively, sets
SQL_DESC_CONCISE_TYPE to the concise identifier, and sets
SQL_DESC_DATETIME_INTERVAL_CODE to the corresponding datetime or interval subcode.
Sets one or more of SQL_DESC_LENGTH, SQL_DESC_PRECISION, and
SQL_DESC_DATETIME_INTERVAL_PRECISION, as appropriate for ParameterType.
Sets SQL_DESC_SCALE to the value of DecimalDigits.
If the call to SQLBindParameter fails, the content of the descriptor fields that it would have set in the APD are
undefined, and the SQL_DESC_COUNT field of the APD is unchanged. In addition, the SQL_DESC_LENGTH,
SQL_DESC_PRECISION, SQL_DESC_SCALE, and SQL_DESC_TYPE fields of the appropriate record in the IPD are
undefined and the SQL_DESC_COUNT field of the IPD is unchanged.
C A L L B Y O DB C 1. 0 A P P L IC AT IO N C A L L TO O DB C 3. X DRIVER
Examples
A. Use SQLBindParameter Function
In the following example, an application prepares an SQL statement to insert data into the ORDERS table. For
each parameter in the statement, the application calls SQLBindParameter to specify the ODBC C data type and
the SQL data type of the parameter, and to bind a buffer to each parameter. For each row of data, the application
assigns data values to each parameter and calls SQLExecute to execute the statement.
The following sample assumes that you have an ODBC data source on your computer called Northwind that is
associated with the Northwind database.
For more code examples, see SQLBulkOperations Function, SQLProcedures Function, SQLPutData Function, and
SQLSetPos Function.
// SQLBindParameter_Function.cpp
// compile with: ODBC32.lib
#include <windows.h>
#include <sqltypes.h>
#include <sqlext.h>
#define EMPLOYEE_ID_LEN 10
SQLCHAR szEmployeeID[EMPLOYEE_ID_LEN];
SQL_DATE_STRUCT dsOrderDate;
SQLINTEGER cbCustID = 0, cbOrderDate = 0, cbEmployeeID = SQL_NTS;
int main() {
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);
retcode = SQLExecute(hstmt);
}
int main() {
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);
retcode = SQLExecute(hstmt);
}
Related Functions
F O R IN F O RM AT IO N A B O UT SEE
Conformance
Version Introduced: ODBC 1.0 Standards Compliance: ODBC
Summar y
SQLBrowseConnect supports an iterative method of discovering and enumerating the attributes and attribute
values required to connect to a data source. Each call to SQLBrowseConnect returns successive levels of
attributes and attribute values. When all levels have been enumerated, a connection to the data source is
completed and a complete connection string is returned by SQLBrowseConnect . A return code of
SQL_SUCCESS or SQL_SUCCESS_WITH_INFO indicates that all connection information has been specified and
the application is now connected to the data source.
Syntax
SQLRETURN SQLBrowseConnect(
SQLHDBC ConnectionHandle,
SQLCHAR * InConnectionString,
SQLSMALLINT StringLength1,
SQLCHAR * OutConnectionString,
SQLSMALLINT BufferLength,
SQLSMALLINT * StringLength2Ptr);
Arguments
ConnectionHandle
[Input] Connection handle.
InConnectionString
[Input] Browse request connection string (see "InConnectionString Argument" in "Comments").
StringLength1
[Input] Length of *InConnectionString in characters.
OutConnectionString
[Output] Pointer to a character buffer in which to return the browse result connection string (see
"OutConnectionString Argument" in "Comments").
If OutConnectionString is NULL, StringLength2Ptr will still return the total number of characters (excluding the
null-termination character for character data) available to return in the buffer pointed to by
OutConnectionString.
BufferLength
[Input] Length, in characters, of the *OutConnectionString buffer.
StringLength2Ptr
[Output] The total number of characters (excluding null-termination) available to return in
*OutConnectionString. If the number of characters available to return is greater than or equal to BufferLength,
the connection string in *OutConnectionString is truncated to BufferLength minus the length of a null-
termination character.
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_ERROR, SQL_INVALID_HANDLE, or
SQL_STILL_EXECUTING.
Diagnostics
When SQLBrowseConnect returns SQL_ERROR, SQL_SUCCESS_WITH_INFO, or SQL_NEED_DATA, an
associated SQLSTATE value can be obtained by calling SQLGetDiagRec with a HandleType of
SQL_HANDLE_STMT and a Handle of ConnectionHandle. The following table lists the SQLSTATE values
commonly returned by SQLBrowseConnect and explains each one in the context of this function; the notation
"(DM)" precedes the descriptions of SQLSTATEs returned by the Driver Manager. The return code associated with
each SQLSTATE value is SQL_ERROR, unless noted otherwise.
08001 Client unable to establish connection The driver was unable to establish a
connection with the data source.
08004 Server rejected the connection The data source rejected the
establishment of the connection for
implementation-defined reasons.
SQ L STAT E ERRO R DESC RIP T IO N
HY001 Memory allocation error (DM) The Driver Manager was unable
to allocate memory required to
support execution or completion of
the function.
HY090 Invalid string or buffer length (DM) The value specified for argument
StringLength1 was less than 0 and was
not equal to SQL_NTS.
HY114 Driver does not support connection (DM) The application enabled the
level asynchronous function execution asynchronous operation on the
connection handle before making the
connection. However, the driver does
not support asynchronous operation
on connection handle.
IM001 Driver does not support this function (DM) The driver corresponding to the
specified data source name does not
support the function.
IM002 Data source not found and no default (DM) The data source name specified
driver specified in the browse request connection
string (InConnectionString) was not
found in the system information, nor
was there a default driver specification.
IM003 Specified driver could not be loaded (DM) The driver listed in the data
source specification in the system
information or specified by the
DRIVER keyword was not found or
could not be loaded for some other
reason.
IM009 Unable to load translation DLL The driver was unable to load the
translation DLL that was specified for
the data source or for the connection.
IM010 Data source name too long (DM) The attribute value for the DSN
keyword was longer than
SQL_MAX_DSN_LENGTH characters.
IM011 Driver name too long (DM) The attribute value for the
DRIVER keyword was longer than 255
characters.
IM012 DRIVER keyword syntax error (DM) The keyword-value pair for the
DRIVER keyword contained a syntax
error.
IM014 The specified DSN contains an (DM) 32-bit application uses a DSN
architecture mismatch between the connecting to a 64-bit driver; or vice
Driver and Application versa.
IM018 SQLCompleteAsync has not been If the previous function call on the
called to complete the previous handle returns SQL_STILL_EXECUTING
asynchronous operation on this and if notification mode is enabled,
handle. SQLCompleteAsync must be called
on the handle to do post-processing
and complete the operation.
S1118 Driver does not support asynchronous When the driver does not support
notification asynchronous notification, you cannot
set SQL_ATTR_ASYNC_DBC_EVENT or
SQL_ATTR_ASYNC_DBC_RETCODE_PTR.
InConnectionString Argument
A browse request connection string has the following syntax:
connection-string ::= attribute[ ; ] | attribute ; connection-string;
attribute ::= attribute-keyword = attribute-value | DRIVER= [ { ]attribute-value[ } ]
attribute-keyword ::= DSN | UID | PWD | driver-defined-attribute-keyword
attribute-value ::= character-string
driver-defined-attribute-keyword ::= identifier
where character-string has zero or more characters; identifier has one or more characters; attribute-keyword is
not case-sensitive; attribute-value may be case-sensitive; and the value of the DSN keyword does not consist
solely of blanks. Because of connection string and initialization file grammar, keywords and attribute values that
contain the characters []{}(),;?*=!@ should be avoided. Because of the grammar in the system information,
keywords and data source names cannot contain the backslash (\) character. For an ODBC 2.x driver, braces are
required around the attribute value for the DRIVER keyword.
If any keywords are repeated in the browse request connection string, the driver uses the value associated with
the first occurrence of the keyword. If the DSN and DRIVER keywords are included in the same browse request
connection string, the Driver Manager and driver use whichever keyword appears first.
For information about how an application chooses a data source or driver, see Choosing a Data Source or Driver.
OutConnectionString Argument
The browse result connection string is a list of connection attributes. A connection attribute consists of an
attribute keyword and a corresponding attribute value. The browse result connection string has the following
syntax:
connection-string ::= attribute[ ; ] | attribute ; connection-string
attribute ::= [ * ]attribute-keyword = attribute-value
attribute-keyword ::= ODBC-attribute-keyword | driver-defined-attribute-keyword
ODBC-attribute-keyword = { UID | PWD }[ : localized-identifier] driver-defined-attribute-keyword ::= identifier[
: localized-identifier ] attribute-value ::= { attribute-value-list } | ? (The braces are literal; they are returned
by the driver.)
attribute-value-list ::= character-string [ : localized-character string] | character-string [ : localized-character
string] , attribute-value-list
where character-string and localized-character string have zero or more characters; identifier and localized-
identifier have one or more characters; attribute-keyword is not case-sensitive; and attribute-value may be case-
sensitive. Because of connection string and initialization file grammar, keywords, localized identifiers, and
attribute values that contain the characters []{}(),;?*=!@ should be avoided. Because of the grammar in the
system information, keywords and data source names cannot contain the backslash (\) character.
The browse result connection string syntax is used according to the following semantic rules:
If an asterisk (*) precedes an attribute-keyword, the attribute is optional and can be omitted in the next
call to SQLBrowseConnect .
The attribute keywords UID and PWD have the same meaning as defined in SQLDriverConnect .
A driver-defined-attribute-keyword names the kind of attribute for which an attribute value may be
supplied. For example, it might be SERVER , DATABASE , HOST , or DBMS .
ODBC-attribute-keywords and driver-defined-attribute-keywords include a localized or user-friendly
version of the keyword. This might be used by applications as a label in a dialog box. However, UID ,
PWD , or the identifier alone must be used when passing a browse request string to the driver.
The {attribute-value-list} is an enumeration of actual values valid for the corresponding attribute-
keyword. Note that the braces ({}) do not indicate a list of choices; they are returned by the driver. For
example, it might be a list of server names or a list of database names.
If the attribute-value is a single question mark (?), a single value corresponds to the attribute-keyword.
For example, UID=JohnS; PWD=Sesame.
Each call to SQLBrowseConnect returns only the information required to satisfy the next level of the
connection process. The driver associates state information with the connection handle so that the
context can always be determined on each call.
Using SQLBrowseConnect
SQLBrowseConnect requires an allocated connection. The Driver Manager loads the driver that was specified
in or that corresponds to the data source name specified in the initial browse request connection string; for
information about when this occurs, see the "Comments" section in SQLConnect Function. The driver may
establish a connection with the data source during the browsing process. If SQLBrowseConnect returns
SQL_ERROR, outstanding connections are terminated and the connection is returned to an unconnected state.
NOTE
SQLBrowseConnect does not support connection pooling. If SQLBrowseConnect is called while connection pooling is
enabled, SQLSTATE HY000 (General error) will be returned.
When SQLBrowseConnect is called for the first time on a connection, the browse request connection string
must contain the DSN keyword or the DRIVER keyword. If the browse request connection string contains the
DSN keyword, the Driver Manager locates a corresponding data source specification in the system information:
If the Driver Manager finds the corresponding data source specification, it loads the associated driver
DLL; the driver can retrieve information about the data source from the system information.
If the Driver Manager cannot find the corresponding data source specification, it locates the default data
source specification and loads the associated driver DLL; the driver can retrieve information about the
default data source from the system information. "DEFAULT" is passed to the driver for the DSN.
If the Driver Manager cannot find the corresponding data source specification and there is no default data
source specification, it returns SQL_ERROR with SQLSTATE IM002 (Data source not found and no default
driver specified).
If the browse request connection string contains the DRIVER keyword, the Driver Manager loads the specified
driver; it does not attempt to locate a data source in the system information. Because the DRIVER keyword does
not use information from the system information, the driver must define enough keywords so that a driver can
connect to a data source using only the information in the browse request connection strings.
On each call to SQLBrowseConnect , the application specifies the connection attribute values in the browse
request connection string. The driver returns successive levels of attributes and attribute values in the browse
result connection string; it returns SQL_NEED_DATA as long as there are connection attributes that have not yet
been enumerated in the browse request connection string. The application uses the contents of the browse
result connection string to build the browse request connection string for the next call to SQLBrowseConnect .
All mandatory attributes (those not preceded by an asterisk in the OutConnectionString argument) must be
included in the next call to SQLBrowseConnect . Note that the application cannot use the contents of previous
browse result connection strings when building the current browse request connection string; that is, it cannot
specify different values for attributes set in previous levels.
When all levels of connection and their associated attributes have been enumerated, the driver returns
SQL_SUCCESS, the connection to the data source is complete, and a complete connection string is returned to
the application. The connection string is suitable to use, in conjunction with SQLDriverConnect , with the
SQL_DRIVER_NOPROMPT option to establish another connection. The complete connection string cannot be
used in another call to SQLBrowseConnect , however; if SQLBrowseConnect were called again, the entire
sequence of calls would have to be repeated.
SQLBrowseConnect also returns SQL_NEED_DATA if there are recoverable, nonfatal errors during the browse
process; for example, an invalid password or attribute keyword supplied by the application. When
SQL_NEED_DATA is returned and the browse result connection string is unchanged, an error has occurred and
the application can call SQLGetDiagRec to return the SQLSTATE for browse-time errors. This permits the
application to correct the attribute and continue the browse.
An application can terminate the browse process at any time by calling SQLDisconnect . The driver will
terminate any outstanding connections and return the connection to an unconnected state.
If asynchronous operations are enabled on the connection handle, SQLBrowseConnect might also return
SQL_STILL_EXECUTING. When it returns SQL_NEED_DATA, an application must use SQLDisconnect to cancel
the browse process. If SQLBrowseConnect returns SQL_STILL_EXECUTING, an application should use
SQLCancelHandle to cancel the operation in progress. Calling SQLCancelHandle after the function returns
SQL_NEED_DATA has no effect.
For more information, see Connecting with SQLBrowseConnect.
If a driver supports SQLBrowseConnect , the driver keyword section in the system information for the driver
must contain the ConnectFunctions keyword with the third character set to "Y."
Code Example
NOTE
If you are connecting to a data source provider that supports Windows authentication, you should specify
Trusted_Connection=yes instead of user ID and password information in the connection string.
In the following example, an application calls SQLBrowseConnect repeatedly. Each time SQLBrowseConnect
returns SQL_NEED_DATA, it passes back information about the data it needs in *OutConnectionString. The
application passes OutConnectionString to its routine GetUserInput (not shown). GetUserInput parses the
information, builds and displays a dialog box, and returns the information entered by the user in
*InConnectionString. The application passes the user's information to the driver in the next call to
SQLBrowseConnect . After the application has provided all necessary information for the driver to connect to
the data source, SQLBrowseConnect returns SQL_SUCCESS and the application proceeds.
For a more detailed example of connecting to a SQL Server driver by calling SQLBrowseConnect , see SQL
Server Browsing Example.
For example, to connect to the data source Sales, the following actions might occur. First, the application passes
the following string to SQLBrowseConnect :
"DSN=Sales"
The Driver Manager loads the driver associated with the data source Sales. It then calls the driver's
SQLBrowseConnect function with the same arguments it received from the application. The driver returns the
following string in *OutConnectionString:
"HOST:Server={red,blue,green};UID:ID=?;PWD:Password=?"
The application passes this string to its GetUserInput routine, which builds a dialog box that asks the user to
select the red, blue, or green server and to enter a user ID and password. The routine passes the following user-
specified information back in *InConnectionString, which the application passes to SQLBrowseConnect :
"HOST=red;UID=Smith;PWD=Sesame"
SQLBrowseConnect uses this information to connect to the red server as Smith with the password Sesame,
and then returns the following string in *OutConnectionString:
"*DATABASE:Database={SalesEmployees,SalesGoals,SalesOrders}"
The application passes this string to its GetUserInput routine, which builds a dialog box that asks the user to
select a database. The user selects empdata and the application calls SQLBrowseConnect a final time with this
string:
"DATABASE=SalesOrders"
This is the final piece of information the driver needs to connect to the data source; SQLBrowseConnect
returns SQL_SUCCESS, and *OutConnectionString contains the completed connection string:
// SQLBrowseConnect_Function.cpp
// compile with: odbc32.lib
#include <windows.h>
#include <sqltypes.h>
#include <sqlext.h>
int main() {
// Allocate the environment handle.
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
Related Functions
F O R IN F O RM AT IO N A B O UT SEE
See Also
ODBC API Reference
ODBC Header Files
SQLBulkOperations Function
4/27/2022 • 24 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 3.0 Standards Compliance: ODBC
Summar y
SQLBulkOperations performs bulk insertions and bulk bookmark operations, including update, delete, and
fetch by bookmark.
Syntax
SQLRETURN SQLBulkOperations(
SQLHSTMT StatementHandle,
SQLUSMALLINT Operation);
Arguments
StatementHandle
[Input] Statement handle.
Operation
[Input] Operation to perform:
SQL_ADD SQL_UPDATE_BY_BOOKMARK SQL_DELETE_BY_BOOKMARK SQL_FETCH_BY_BOOKMARK
For more information, see "Comments."
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, or
SQL_INVALID_HANDLE.
Diagnostics
When SQLBulkOperations returns SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE value
can be obtained by calling SQLGetDiagRec with a HandleType of SQL_HANDLE_STMT and a Handle of
StatementHandle. The following table lists the SQLSTATE values typically returned by SQLBulkOperations and
explains each one in the context of this function; the notation "(DM)" precedes the descriptions of SQLSTATEs
returned by the Driver Manager. The return code associated with each SQLSTATE value is SQL_ERROR, unless
noted otherwise.
For all those SQLSTATEs that can return SQL_SUCCESS_WITH_INFO or SQL_ERROR (except 01xxx SQLSTATEs),
SQL_SUCCESS_WITH_INFO is returned if an error occurs on one or more, but not all, rows of a multirow
operation, and SQL_ERROR is returned if an error occurs on a single-row operation.
(Function returns
SQL_SUCCESS_WITH_INFO.)
07006 Restricted data type attribute violation The Operation argument was
SQL_FETCH_BY_BOOKMARK, and the
data value of a column in the result set
could not be converted to the data
type specified by the TargetType
argument in the call to SQLBindCol.
21S02 Degree of derived table does not The argument Operation was
match column list SQL_UPDATE_BY_BOOKMARK; and no
columns were updatable because all
columns were either unbound or read-
only, or the value in the bound
length/indicator buffer was
SQL_COLUMN_IGNORE.
22018 Invalid character value for cast The Operation argument was
specification SQL_FETCH_BY_BOOKMARK; the C
type was an exact or approximate
numeric, a datetime, or an interval
data type; the SQL type of the column
was a character data type; and the
value in the column was not a valid
literal of the bound C type.
42000 Syntax error or access violation The driver was unable to lock the row
as needed to perform the operation
requested in the Operation argument.
SQ L STAT E ERRO R DESC RIP T IO N
HY011 Attribute cannot be set now (DM) The driver was an ODBC 2.x
driver, and the
SQL_ATTR_ROW_STATUS_PTR
statement attribute was set between
calls to SQLFetch or SQLFetchScroll
and SQLBulkOperations .
HY092 Invalid attribute identifier (DM) The value specified for the
Operation argument was invalid.
HYC00 Optional feature not implemented The driver or data source does not
support the operation requested in
the Operation argument.
IM001 Driver does not support this function (DM) The driver associated with the
StatementHandle does not support
the function.
IM018 SQLCompleteAsync has not been If the previous function call on the
called to complete the previous handle returns SQL_STILL_EXECUTING
asynchronous operation on this and if notification mode is enabled,
handle. SQLCompleteAsync must be called
on the handle to do post-processing
and complete the operation.
Comments
Cau t i on
For information about what statement states SQLBulkOperations can be called in and what it must do for
compatibility with ODBC 2.x applications, see the Block Cursors, Scrollable Cursors, and Backward Compatibility
section in Appendix G: Driver Guidelines for Backward Compatibility.
An application uses SQLBulkOperations to perform the following operations on the base table or view that
corresponds to the current query:
Add new rows.
Update a set of rows where each row is identified by a bookmark.
Delete a set of rows where each row is identified by a bookmark.
Fetch a set of rows where each row is identified by a bookmark.
After a call to SQLBulkOperations , the block cursor position is undefined. The application has to call
SQLFetchScroll to set the cursor position. An application should call SQLFetchScroll only with a
FetchOrientation argument of SQL_FETCH_FIRST, SQL_FETCH_LAST, SQL_FETCH_ABSOLUTE, or
SQL_FETCH_BOOKMARK. The cursor position is undefined if the application calls SQLFetch or SQLFetchScroll
with a FetchOrientation argument of SQL_FETCH_PRIOR, SQL_FETCH_NEXT, or SQL_FETCH_RELATIVE.
A column can be ignored in bulk operations performed by a call to SQLBulkOperations by setting the column
length/indicator buffer specified in the call to SQLBindCol , to SQL_COLUMN_IGNORE.
It is not necessary for the application to set the SQL_ATTR_ROW_OPERATION_PTR statement attribute when it
calls SQLBulkOperations because rows cannot be ignored when performing bulk operations with this
function.
The buffer pointed to by the SQL_ATTR_ROWS_FETCHED_PTR statement attribute contains the number of rows
affected by a call to SQLBulkOperations .
When the Operation argument is SQL_ADD or SQL_UPDATE_BY_BOOKMARK and the select-list of the query
specification associated with the cursor contains more than one reference to the same column, it is driver-
defined whether an error is generated or the driver ignores the duplicated references and performs the
requested operations.
For more information about how to use SQLBulkOperations , see Updating Data with SQLBulkOperations.
NOTE
The size of the array pointed to by the SQL_ATTR_ROW_STATUS_PTR statement attribute should either be equal to
SQL_ATTR_ROW_ARRAY_SIZE or SQL_ATTR_ROW_STATUS_PTR should be a null pointer.
NOTE
The size of the array pointed to by the SQL_ATTR_ROW_STATUS_PTR statement attribute should be equal to
SQL_ATTR_ROW_ARRAY_SIZE or SQL_ATTR_ROW_STATUS_PTR should be a null pointer.
NOTE
If the application has set the SQL_ATTR_ROW_STATUS_PTR statement attribute, it can inspect this array to see the
result of the operation.
NOTE
The size of the array pointed to by the SQL_ATTR_ROW_STATUS_PTR statement attribute should be equal to
SQL_ATTR_ROW_ARRAY_SIZE or SQL_ATTR_ROW_STATUS_PTR should be a null pointer.
NOTE
The size of the array pointed to by the SQL_ATTR_ROW_STATUS_PTR statement attribute should be equal to
SQL_ATTR_ROW_ARRAY_SIZE or SQL_ATTR_ROW_STATUS_PTR should be a null pointer.
NOTE
Although data-at-execution parameters resemble data-at-execution columns, the value returned by
SQLParamData is different for each.
Data-at-execution columns are columns in a rowset for which data will be sent with SQLPutData when a
row is updated or inserted with SQLBulkOperations . They are bound with SQLBindCol . The value
returned by SQLParamData is the address of the row in the *TargetValuePtr buffer that is being
processed.
4. The application calls SQLPutData one or more times to send data for the column. More than one call is
needed if all the data value cannot be returned in the *TargetValuePtr buffer specified in SQLPutData ;
multiple calls to SQLPutData for the same column are allowed only when sending character C data to a
column with a character, binary, or data source-specific data type or when sending binary C data to a
column with a character, binary, or data source-specific data type.
5. The application calls SQLParamData again to signal that all data has been sent for the column.
If there are more data-at-execution columns, SQLParamData returns SQL_NEED_DATA and the
address of the TargetValuePtr buffer for the next data-at-execution column to be processed. The
application repeats steps 4 and 5.
If there are no more data-at-execution columns, the process is complete. If the statement was
executed successfully, SQLParamData returns SQL_SUCCESS or SQL_SUCCESS_WITH_INFO; if
the execution failed, it returns SQL_ERROR. At this point, SQLParamData can return any
SQLSTATE that can be returned by SQLBulkOperations .
If the operation is canceled or an error occurs in SQLParamData or SQLPutData after SQLBulkOperations
returns SQL_NEED_DATA and before data is sent for all data-at-execution columns, the application can call only
SQLCancel , SQLGetDiagField , SQLGetDiagRec , SQLGetFunctions , SQLParamData , or SQLPutData for
the statement or the connection associated with the statement. If it calls any other function for the statement or
the connection associated with the statement, the function returns SQL_ERROR and SQLSTATE HY010 (Function
sequence error).
If the application calls SQLCancel while the driver still needs data for data-at-execution columns, the driver
cancels the operation. The application can then call SQLBulkOperations again; canceling does not affect the
cursor state or the current cursor position.
Code Example
The following example fetches 10 rows of data at a time from the Customers table. It then prompts the user for
an action to take. To reduce network traffic, the example buffer updates, deletes, and inserts locally in the bound
arrays, but at offsets past the rowset data. When the user chooses to send updates, deletes, and inserts to the
data source, the code sets the binding offset appropriately and calls SQLBulkOperations . For simplicity, the
user cannot buffer more than 10 updates, deletes, or inserts.
// SQLBulkOperations_Function.cpp
// compile with: ODBC32.lib
#include <windows.h>
#include <sqlext.h>
#include "stdio.h"
// Define structure for customer data (assume 10 byte maximum bookmark size).
typedef struct tagCustStruct {
SQLCHAR Bookmark[10];
SQLINTEGER BookmarkLen;
SQLUINTEGER CustomerID;
SQLINTEGER CustIDInd;
SQLCHAR CompanyName[51];
SQLINTEGER NameLenOrInd;
SQLCHAR Address[51];
SQLINTEGER AddressLenOrInd;
SQLCHAR Phone[11];
SQLINTEGER PhoneLenOrInd;
} CustStruct;
// Allocate 40 of these structures. Elements 0-9 are for the current rowset,
// elements 10-19 are for the buffered updates, elements 20-29 are for
// the buffered inserts, and elements 30-39 are for the buffered deletes.
CustStruct CustArray[40];
SQLUSMALLINT RowStatusArray[10], Action, RowNum, NumUpdates = 0, NumInserts = 0,
NumDeletes = 0;
SQLLEN BindOffset = 0;
SQLRETURN retcode;
SQLHENV henv = NULL;
SQLHDBC hdbc = NULL;
SQLHSTMT hstmt = NULL;
int main() {
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);
// Bind arrays to the bookmark, CustomerID, CompanyName, Address, and Phone columns.
retcode = SQLBindCol(hstmt, 0, SQL_C_VARBOOKMARK, CustArray[0].Bookmark, sizeof(CustArray[0].Bookmark),
&CustArray[0].BookmarkLen);
retcode = SQLBindCol(hstmt, 1, SQL_C_ULONG, &CustArray[0].CustomerID, 0, &CustArray[0].CustIDInd);
retcode = SQLBindCol(hstmt, 2, SQL_C_CHAR, CustArray[0].CompanyName, sizeof(CustArray[0].CompanyName),
&CustArray[0].NameLenOrInd);
retcode = SQLBindCol(hstmt, 3, SQL_C_CHAR, CustArray[0].Address, sizeof(CustArray[0].Address),
&CustArray[0].AddressLenOrInd);
retcode = SQLBindCol(hstmt, 4, SQL_C_CHAR, CustArray[0].Phone, sizeof(CustArray[0].Phone),
&CustArray[0].PhoneLenOrInd);
// Call GetAction to get an action and a row number from the user.
// while (GetAction(&Action, &RowNum)) {
Action = SQL_FETCH_NEXT;
RowNum = 2;
switch (Action) {
case SQL_FETCH_NEXT:
case SQL_FETCH_PRIOR:
case SQL_FETCH_FIRST:
case SQL_FETCH_LAST:
case SQL_FETCH_ABSOLUTE:
case SQL_FETCH_RELATIVE:
// Fetch and display the requested data.
SQLFetchScroll(hstmt, Action, RowNum);
// DisplayCustData(CustArray, 10);
break;
case UPDATE_ROW:
// Check if we have reached the maximum number of buffered updates.
if (NumUpdates < 10) {
// Get the new customer data and place it in the next available element of
// the buffered updates section of CustArray, copy the bookmark of the row
// being updated to the same element, and increment the update counter.
// Checking to see we have not already buffered an update for this
// row not shown.
// GetNewCustData(CustArray, UPDATE_OFFSET + NumUpdates);
memcpy(CustArray[UPDATE_OFFSET + NumUpdates].Bookmark,
CustArray[RowNum - 1].Bookmark,
CustArray[RowNum - 1].BookmarkLen);
CustArray[UPDATE_OFFSET + NumUpdates].BookmarkLen =
CustArray[RowNum - 1].BookmarkLen;
NumUpdates++;
} else {
printf("Buffers full. Send buffered changes to the data source.");
}
}
break;
case DELETE_ROW:
// Check if we have reached the maximum number of buffered deletes.
if (NumDeletes < 10) {
// Copy the bookmark of the row being deleted to the next available element
// of the buffered deletes section of CustArray and increment the delete
// counter. Checking to see we have not already buffered an update for
// this row not shown.
memcpy(CustArray[DELETE_OFFSET + NumDeletes].Bookmark,
CustArray[RowNum - 1].Bookmark,
CustArray[RowNum - 1].BookmarkLen);
CustArray[DELETE_OFFSET + NumDeletes].BookmarkLen =
CustArray[RowNum - 1].BookmarkLen;
NumDeletes++;
} else
printf("Buffers full. Send buffered changes to the data source.");
break;
case ADD_ROW:
// reached maximum number of buffered inserts?
if (NumInserts < 10) {
// Get the new customer data and place it in the next available element of
// the buffered inserts section of CustArray and increment insert counter.
// GetNewCustData(CustArray, INSERT_OFFSET + NumInserts);
NumInserts++;
} else
printf("Buffers full. Send buffered changes to the data source.");
break;
case SEND_TO_DATA_SOURCE:
// If there are any buffered updates, inserts, or deletes, set the array size
// to that number, set the binding offset to use the data in the buffered
// update, insert, or delete part of CustArray, and call SQLBulkOperations to
// do the updates, inserts, or deletes. Because we will never have more than
// 10 updates, inserts, or deletes, we can use the same row status array.
if (NumUpdates) {
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)NumUpdates, 0);
BindOffset = UPDATE_OFFSET * sizeof(CustStruct);
SQLBulkOperations(hstmt, SQL_UPDATE_BY_BOOKMARK);
NumUpdates = 0;
}
if (NumInserts) {
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)NumInserts, 0);
BindOffset = INSERT_OFFSET * sizeof(CustStruct);
SQLBulkOperations(hstmt, SQL_ADD);
NumInserts = 0;
}
if (NumDeletes) {
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)NumDeletes, 0);
BindOffset = DELETE_OFFSET * sizeof(CustStruct);
SQLBulkOperations(hstmt, SQL_DELETE_BY_BOOKMARK);
NumDeletes = 0;
}
// If there were any updates, inserts, or deletes, reset the binding offset
// and array size to their original values.
if (NumUpdates || NumInserts || NumDeletes) {
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)10, 0);
BindOffset = 0;
}
break;
}
// }
Related Functions
F O R IN F O RM AT IO N A B O UT SEE
See Also
ODBC API Reference
ODBC Header Files
SQLCancel Function
4/27/2022 • 5 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 1.0 Standards Compliance: ISO 92
Summar y
SQLCancel cancels the processing on a statement.
To cancel processing on a connection or statement, use SQLCancelHandle Function.
Syntax
SQLRETURN SQLCancel(
SQLHSTMT StatementHandle);
Arguments
StatementHandle
[Input] Statement handle.
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
Diagnostics
When SQLCancel returns SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE value can be
obtained by calling SQLGetDiagRec with a HandleType of SQL_HANDLE_STMT and a Handle of
StatementHandle. The following table lists the SQLSTATE values commonly returned by SQLCancel and
explains each one in the context of this function; the notation "(DM)" precedes the descriptions of SQLSTATEs
returned by the Driver Manager. The return code associated with each SQLSTATE value is SQL_ERROR, unless
noted otherwise.
HY018 Server declined cancel request The server declined the cancel request.
IM001 Driver does not support this function (DM) The driver associated with the
StatementHandle does not support
the function.
Comments
SQLCancel can cancel the following types of processing on a statement:
A function running asynchronously on the statement.
A function on a statement that needs data.
A function running on the statement on another thread.
In ODBC 2.x, if an application calls SQLCancel when no processing is being done on the statement, SQLCancel
has the same effect as SQLFreeStmt with the SQL_CLOSE option; this behavior is defined only for
completeness and applications should call SQLFreeStmt or SQLCloseCursor to close cursors.
When SQLCancel is called to cancel a function running asynchronously in a statement or a function on a
statement that needs data, diagnostic records posted by the function being canceled are cleared, and
SQLCancel posts its own diagnostic records; when SQLCancel is called to cancel a function running on a
statement on another thread, however, it does not clear the diagnostic records of the being canceled function
and does not post its own diagnostic records.
NOTE
In ODBC 3.5, a call to SQLCancel when no processing is being done on the statement is not treated as SQLFreeStmt
with the SQL_CLOSE option, but has is no effect at all. To close a cursor, an application should call SQLCloseCursor , not
SQLCancel.
See Also
ODBC API Reference
ODBC Header Files
SQLCancelHandle Function
4/27/2022 • 5 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 3.8 Standards Compliance: None
It is expected that most ODBC 3.8 (and later) drivers will implement this function. If a driver does not, a call to
SQLCancelHandle with a connection handle in the Handle parameter will return SQL_ERROR with a SQLSTATE
of IM001 and message 'Driver does not support this function'' A call to SQLCancelHandle with a statement
handle as the Handle parameter will be mapped to a call to SQLCancel by the Driver Manager and can be
processed if the driver implements SQLCancel . An application can use SQLGetFunctions to determine if a
driver supports SQLCancelHandle .
Summar y
SQLCancelHandle cancels the processing on a connection or statement. The Driver Manager maps a call to
SQLCancelHandle to a call to SQLCancel when HandleType is SQL_HANDLE_STMT.
Syntax
SQLRETURN SQLCancelHandle(
SQLSMALLINT HandleType,
SQLHANDLE Handle);
Arguments
HandleType
[Input] The type of the handle on which to cacel processing. Valid values are SQL_HANDLE_DBC or
SQL_HANDLE_STMT.
Handle
[Input] The handle on which to cancel processing.
If Handle is not a valid handle of the type specified by HandleType, SQLCancelHandle returns
SQL_INVALID_HANDLE.
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
Diagnostics
When SQLCancelHandle returns SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE value
can be obtained by calling SQLGetDiagRec with a HandleType of SQL_HANDLE_STMT and a statement handle
Handle or a HandleType of SQL_HANDLE_DBC and a connection handle Handle.
The following table lists the SQLSTATE values commonly returned by SQLCancelHandle and explains each one
in the context of this function; the notation "(DM)" precedes the descriptions of SQLSTATEs returned by the
Driver Manager. The return code associated with each SQLSTATE value is SQL_ERROR, unless noted otherwise.
SQ L STAT E ERRO R DESC RIP T IO N
IM001 Driver does not support this function (DM) The driver associated with the
Handle does not support the function.
If SQLCancelHandle is called with HandleType set to SQL_HANDLE_STMT, it can return any SQLSTATE that can
be returned by the function SQLCancel .
Comments
This function is similar to SQLCancel but may take either a connection or statement handle as a parameter
rather than only a statement handle. The Driver Manager maps a call to SQLCancelHandle to a call to
SQLCancel when HandleType is SQL_HANDLE_STMT. This allows applications to use SQLCancelHandle to
cancel statement operations even if the driver does not implement SQLCancelHandle .
For more information about cancelling a statement operation, see SQLCancel Function.
If there are no operations in progress on Handle the call to SQLCancelHandle has no effect.
SQLCancelHandle on a connection handle can cancel the following types of processing:
A function running asynchronously on the connection.
A function running on the connection handle on another thread.
When SQLCancelHandle is called to cancel a function running asynchronously in a connection, diagnostic
records posted by SQLCancelHandle are appended to those returned by the operation being canceled;
SQLCancelHandle does not return diagnostic records, however, when canceling a function running on a
connection on another thread.
Using SQLCancelHandle to cancel SQLEndTran may put the connection in suspended state. For more
information on suspended state, see SQLEndTran Function.
NOTE
For information about how to use SQLCancelHandle in an application that will be deployed on a Windows operating
system older than Windows 7, see Compatibility Matrix.
Related Functions
F O R IN F O RM AT IO N A B O UT SEE
See Also
ODBC API Reference
ODBC Header Files
Asynchronous Execution (Polling Method)
SQLCloseCursor Function
4/27/2022 • 2 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 3.0 Standards Compliance: ISO 92
Summar y
SQLCloseCursor closes a cursor that has been opened on a statement and discards pending results.
Syntax
SQLRETURN SQLCloseCursor(
SQLHSTMT StatementHandle);
Arguments
StatementHandle
[Input] Statement handle.
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
Diagnostics
When SQLCloseCursor returns SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE value may
be obtained by calling SQLGetDiagRec with a HandleType of SQL_HANDLE_STMT and a Handle of
StatementHandle. The following table lists the SQLSTATE values commonly returned by SQLCloseCursor and
explains each one in the context of this function; the notation "(DM)" precedes the descriptions of SQLSTATEs
returned by the Driver Manager. The return code associated with each SQLSTATE value is SQL_ERROR, unless
noted otherwise.
IM001 Driver does not support this function (DM) The driver associated with the
StatementHandle does not support
the function.
Comments
SQLCloseCursor returns SQLSTATE 24000 (Invalid cursor state) if no cursor is open. Calling SQLCloseCursor
is equivalent to calling SQLFreeStmt with the SQL_CLOSE option, with the exception that SQLFreeStmt with
SQL_CLOSE has no effect on the application if no cursor is open on the statement, while SQLCloseCursor
returns SQLSTATE 24000 (Invalid cursor state).
NOTE
If an ODBC 3.x application working with an ODBC 2.x driver calls SQLCloseCursor when no cursor is open, SQLSTATE
24000 (Invalid cursor state) is not returned, because the Driver Manager maps SQLCloseCursor to SQLFreeStmt with
SQL_CLOSE.
Code Example
See SQLBrowseConnect Function and SQLConnect Function.
Related Functions
F O R IN F O RM AT IO N A B O UT SEE
See Also
ODBC API Reference
ODBC Header Files
SQLColAttribute Function
4/27/2022 • 20 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 3.0 Standards Compliance: ISO 92
Summar y
SQLColAttribute returns descriptor information for a column in a result set. Descriptor information is returned
as a character string, a descriptor-dependent value, or an integer value.
NOTE
For more information about what the Driver Manager maps this function to when an ODBC 3.x application is working
with an ODBC 2.x driver, see Mapping Replacement Functions for Backward Compatibility of Applications.
Syntax
SQLRETURN SQLColAttribute (
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLUSMALLINT FieldIdentifier,
SQLPOINTER CharacterAttributePtr,
SQLSMALLINT BufferLength,
SQLSMALLINT * StringLengthPtr,
SQLLEN * NumericAttributePtr);
Arguments
StatementHandle
[Input] Statement handle.
ColumnNumber
[Input] The number of the record in the IRD from which the field value is to be retrieved. This argument
corresponds to the column number of result data, ordered sequentially in increasing column order, starting at 1.
Columns can be described in any order.
Column 0 can be specified in this argument, but all values except SQL_DESC_TYPE and
SQL_DESC_OCTET_LENGTH will return undefined values.
FieldIdentifier
[Input] The descriptor handle. This handle defines which field in the IRD should be queried (for example,
SQL_COLUMN_TABLE_NAME).
CharacterAttributePtr
[Output] Pointer to a buffer in which to return the value in the FieldIdentifier field of the ColumnNumber row of
the IRD, if the field is a character string. Otherwise, the field is unused.
If CharacterAttributePtr is NULL, StringLengthPtr will still return the total number of bytes (excluding the null-
termination character for character data) available to return in the buffer pointed to by CharacterAttributePtr.
BufferLength
[Input] If FieldIdentifier is an ODBC-defined field and CharacterAttributePtr points to a character string or binary
buffer, this argument should be the length of *CharacterAttributePtr. If FieldIdentifier is an ODBC-defined field
and *CharacterAttributePtr is an integer, this field is ignored. If the *CharacterAttributePtr is a Unicode string
(when calling SQLColAttributeW ), the BufferLength argument must be an even number. If FieldIdentifier is a
driver-defined field, the application indicates the nature of the field to the Driver Manager by setting the
BufferLength argument. BufferLength can have the following values:
If CharacterAttributePtr is a pointer to a pointer, BufferLength should have the value SQL_IS_POINTER.
If CharacterAttributePtr is a pointer to a character string, the BufferLength is the length of the buffer.
If CharacterAttributePtr is a pointer to a binary buffer, the application places the result of the
SQL_LEN_BINARY_ATTR(length) macro in BufferLength. This places a negative value in BufferLength.
If CharacterAttributePtr is a pointer to a fixed-length data type, BufferLength must be one of the
following: SQL_IS_INTEGER, SQL_IS_UINTEGER, SQL_IS_SMALLINT, or SQL_IS_USMALLINT.
StringLengthPtr
[Output] Pointer to a buffer in which to return the total number of bytes (excluding the null-termination byte for
character data) available to return in *CharacterAttributePtr.
For character data, if the number of bytes available to return is greater than or equal to BufferLength, the
descriptor information in *CharacterAttributePtr is truncated to BufferLength minus the length of a null-
termination character and is null-terminated by the driver.
For all other types of data, the value of BufferLength is ignored and the driver assumes the size of
*CharacterAttributePtr is 32 bits.
NumericAttributePtr
[Output] Pointer to an integer buffer in which to return the value in the FieldIdentifier field of the
ColumnNumber row of the IRD, if the field is a numeric descriptor type, such as SQL_DESC_COLUMN_LENGTH.
Otherwise, the field is unused. Please note that some drivers may only write the lower 32-bit or 16-bit of a
buffer and leave the higher-order bit unchanged. Therefore, applications should initialize the value to 0 before
calling this function.
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
Diagnostics
When SQLColAttribute returns either SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE
value may be obtained by calling SQLGetDiagRec with a HandleType of SQL_HANDLE_STMT and a Handle of
StatementHandle. The following table lists the SQLSTATE values commonly returned by SQLColAttribute and
explains each one in the context of this function; the notation "(DM)" precedes the descriptions of SQLSTATEs
returned by the Driver Manager. The return code associated with each SQLSTATE value is SQL_ERROR, unless
noted otherwise.
07005 Prepared statement not a cursor- The statement associated with the
specification StatementHandle did not return a
result set and FieldIdentifier was not
SQL_DESC_COUNT. There were no
columns to describe.
HY091 Invalid descriptor field identifier The value specified for the argument
FieldIdentifier was not one of the
defined values and was not an
implementation-defined value.
HYC00 Driver not capable The value specified for the argument
FieldIdentifier was not supported by
the driver.
SQ L STAT E ERRO R DESC RIP T IO N
IM001 Driver does not support this function (DM) The driver associated with the
StatementHandle does not support
the function.
IM018 SQLCompleteAsync has not been If the previous function call on the
called to complete the previous handle returns SQL_STILL_EXECUTING
asynchronous operation on this and if notification mode is enabled,
handle. SQLCompleteAsync must be called
on the handle to do post-processing
and complete the operation.
When called after SQLPrepare and before SQLExecute , SQLColAttribute can return any SQLSTATE that can
be returned by SQLPrepare or SQLExecute , depending on when the data source evaluates the SQL statement
associated with the StatementHandle.
For performance reasons, an application should not call SQLColAttribute before executing a statement.
Comments
For information about how applications use the information returned by SQLColAttribute , see Result Set
Metadata.
SQLColAttribute returns information either in *NumericAttributePtr or in *CharacterAttributePtr. Integer
information is returned in *NumericAttributePtr as a SQLLEN value; all other formats of information are
returned in *CharacterAttributePtr. When information is returned in *NumericAttributePtr, the driver ignores
CharacterAttributePtr, BufferLength, and StringLengthPtr. When information is returned in
*CharacterAttributePtr, the driver ignores NumericAttributePtr.
SQLColAttribute returns values from the descriptor fields of the IRD. The function is called with a statement
handle rather than a descriptor handle. The values returned by SQLColAttribute for the FieldIdentifier values
listed later in this section can also be retrieved by calling SQLGetDescField with the appropriate IRD handle.
The currently defined descriptor fields, the version of ODBC in which they were introduced, and the arguments
in which information is returned for them are shown later in this section; more descriptor types may be defined
by drivers to take advantage of different data sources.
An ODBC 3.x driver must return a value for each of the descriptor fields. If a descriptor field does not apply to a
driver or data source and unless otherwise stated, the driver returns 0 in *StringLengthPtr or an empty string in
*CharacterAttributePtr.
Backward Compatibility
The ODBC 3.x function SQLColAttribute replaces the deprecated ODBC 2.x function SQLColAttributes . When
mapping SQLColAttributes to SQLColAttribute (when an ODBC 2.x application is working with an ODBC 3.x
driver), or mapping SQLColAttribute to SQLColAttributes (when an ODBC 3.x application is working with an
ODBC 2.x driver), the Driver Manager either passes the value of FieldIdentifier through, maps it to a new value,
or returns an error, as follows:
NOTE
The prefix used in FieldIdentifier values in ODBC 3.x has been changed from that used in ODBC 2.x. The new prefix is
"SQL_DESC"; the old prefix was "SQL_COLUMN".
If the #define value of the ODBC 2.x FieldIdentifier is the same as the #define value of the ODBC 3.x
FieldIdentifier, the value in the function call is just passed through.
The #define values of the ODBC 2.x FieldIdentifiers SQL_COLUMN_LENGTH, SQL_COLUMN_PRECISION,
and SQL_COLUMN_SCALE are different from the #define values of the ODBC 3.x FieldIdentifiers
SQL_DESC_PRECISION, SQL_DESC_SCALE, and SQL_DESC_LENGTH. An ODBC 2.x driver need only
support the ODBC 2.x values. An ODBC 3.x driver must support both "SQL_COLUMN" and "SQL_DESC"
values for these three FieldIdentifiers. These values are different because precision, scale, and length are
defined differently in ODBC 3.x than they were in ODBC 2.x. For more information, see Column Size,
Decimal Digits, Transfer Octet Length, and Display Size.
If the #define value of the ODBC 2.x FieldIdentifier is different from the #define value of the ODBC 3.x
FieldIdentifier, as occurs with the COUNT, NAME, and NULLABLE values, the value in the function call is
mapped to the corresponding value. For example, SQL_COLUMN_COUNT is mapped to
SQL_DESC_COUNT, and SQL_DESC_COUNT is mapped to SQL_COLUMN_COUNT, depending on the
direction of the mapping.
If FieldIdentifier is a new value in ODBC 3.x, for which there was no corresponding value in ODBC 2.x, it
will not be mapped when an ODBC 3.x application uses it in a call to SQLColAttribute in an ODBC 2.x
driver, and the call will return SQLSTATE HY091 (Invalid descriptor field identifier).
The following table lists the descriptor types returned by SQLColAttribute . The type for NumericAttributePtr
values is SQLLEN * .
IN F O RM AT IO N
SQL_DESC_LABEL (ODBC 2.0) CharacterAttributePtr The column label or title. For example,
a column named EmpName might be
labeled Employee Name or might be
labeled with an alias.
SQL_DESC_TABLE_NAME (ODBC 2.0) CharacterAttributePtr The name of the table that contains
the column. The returned value is
implementation-defined if the column
is an expression or if the column is
part of a view.
SQL_DESC_TYPE (ODBC 3.0) NumericAttributePtr A numeric value that specifies the SQL
data type.
SQL_ATTR_READONLY
SQL_ATTR_WRITE
SQL_ATTR_READWRITE_UNKNOWN
Related Functions
F O R IN F O RM AT IO N A B O UT SEE
Example
The following sample code does not free handles and connections. See SQLFreeHandle Function, Sample ODBC
Program, and SQLFreeStmt Function for code samples to free handles and statements.
// SQLColAttibute.cpp
// compile with: user32.lib odbc32.lib
#define UNICODE
#include <windows.h>
#include <sqlext.h>
#include <strsafe.h>
struct DataBinding {
SQLSMALLINT TargetType;
SQLSMALLINT TargetType;
SQLPOINTER TargetValuePtr;
SQLINTEGER BufferLength;
SQLLEN StrLen_or_Ind;
};
int main() {
int bufferSize = 1024, i, count = 1, numCols = 5;
wchar_t firstTableName[1024], * dbName = (wchar_t *)malloc( sizeof(wchar_t)*bufferSize ), * userName =
(wchar_t *)malloc( sizeof(wchar_t)*bufferSize );
HWND desktopHandle = GetDesktopWindow(); // desktop's window handle
SQLWCHAR connStrbuffer[1024];
SQLSMALLINT connStrBufferLen, bufferLen;
SQLRETURN retCode;
// connect to database
retCode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
retCode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLCHAR *)(void*)SQL_OV_ODBC3, -1);
retCode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
retCode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
retCode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)10, 0);
retCode = SQLDriverConnect(hdbc, desktopHandle, L"Driver={SQL Server}", SQL_NTS, connStrbuffer, 1025,
&connStrBufferLen, SQL_DRIVER_PROMPT);
retCode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
// Set up the binding. This can be used even if the statement is closed by closeStatementHandle
for ( i = 0 ; i < numCols ; i++ )
retCode = SQLBindCol(hstmt, (SQLUSMALLINT)i + 1, catalogResult[i].TargetType,
catalogResult[i].TargetValuePtr, catalogResult[i].BufferLength, &(catalogResult[i].StrLen_or_Ind));
retCode = SQLTables( hstmt, (SQLWCHAR*)SQL_ALL_CATALOGS, SQL_NTS, L"", SQL_NTS, L"", SQL_NTS, L"",
SQL_NTS );
retCode = SQLFreeStmt(hstmt, SQL_CLOSE);
retCode = SQLTables( hstmt, dbName, SQL_NTS, userName, SQL_NTS, L"%", SQL_NTS, L"TABLE", SQL_NTS );
wprintf( L"Select all data from the first table (%s)\n", firstTableName );
StringCchPrintfW( selectAllQuery, bufferSize, L"SELECT * FROM %s", firstTableName );
See Also
ODBC API Reference
ODBC Header Files
Sample ODBC Program
SQLColAttributes Function
4/27/2022 • 2 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 1.0 Standards Compliance: Deprecated
Summar y
In ODBC 3.x, the ODBC 2.0 function SQLColAttributes has been replaced by SQLColAttribute . For more
information, see SQLColAttribute Function.
NOTE
For more information about what the Driver Manager maps this function to when an ODBC 2.x application is working
with an ODBC 3.x driver, see Mapping Deprecated Functions in Appendix G: Driver Guidelines for Backward Compatibility.
See ODBC 64-Bit Information, if your application will run on a 64-bit operating system.
See Also
ODBC API Reference
ODBC Header Files
SQLColumnPrivileges Function
4/27/2022 • 9 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 1.0 Standards Compliance: ODBC
Summar y
SQLColumnPrivileges returns a list of columns and associated privileges for the specified table. The driver
returns the information as a result set on the specified StatementHandle.
Syntax
SQLRETURN SQLColumnPrivileges(
SQLHSTMT StatementHandle,
SQLCHAR * CatalogName,
SQLSMALLINT NameLength1,
SQLCHAR * SchemaName,
SQLSMALLINT NameLength2,
SQLCHAR * TableName,
SQLSMALLINT NameLength3,
SQLCHAR * ColumnName,
SQLSMALLINT NameLength4);
Arguments
StatementHandle
[Input] Statement handle.
CatalogName
[Input] Catalog name. If a driver supports names for some catalogs but not for others,such as when the driver
retrieves data from different DBMSs, an empty string ("") denotes those catalogs that do not have names.
CatalogName cannot contain a string search pattern.
If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, CatalogName is treated as an identifier
and its case is not significant. If it is SQL_FALSE, CatalogName is an ordinary argument; it is treated literally, and
its case is significant. For more information, see Arguments in Catalog Functions.
NameLength1
[Input] Length in characters of *CatalogName.
SchemaName
[Input] Schema name. If a driver supports schemas for some tables but not for others, such as when the driver
retrieves data from different DBMSs, an empty string ("") denotes those tables that do not have schemas.
SchemaName cannot contain a string search pattern.
If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, SchemaName is treated as an identifier. If
it is SQL_FALSE, SchemaName is an ordinary argument; it is treated literally, and its case is significant.
NameLength2
[Input] Length in characters of *SchemaName.
TableName
[Input] Table name. This argument cannot be a null pointer. TableName cannot contain a string search pattern.
If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, TableName is treated as an identifier and
its case is not significant. If it is SQL_FALSE, TableName is an ordinary argument; it is treated literally, and its case
is significant.
NameLength3
[Input] Length in characters of *TableName.
ColumnName
[Input] String search pattern for column names.
If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, ColumnName is treated as an identifier
and its case is not significant. If it is SQL_FALSE, ColumnName is a pattern value argument; it is treated literally,
and its case is significant.
NameLength4
[Input] Length in characters of *ColumnName.
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
Diagnostics
When SQLColumnPrivileges returns SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE
value may be obtained by calling SQLGetDiagRec with a HandleType of SQL_HANDLE_STMT and a Handle of
StatementHandle. The following table lists the SQLSTATE values commonly returned by SQLColumnPrivileges
and explains each one in the context of this function; the notation "(DM)" precedes the descriptions of
SQLSTATEs returned by the Driver Manager. The return code associated with each SQLSTATE value is
SQL_ERROR, unless noted otherwise.
HY009 Invalid use of null pointer The TableName argument was a null
pointer.
The SQL_ATTR_METADATA_ID
statement attribute was set to
SQL_TRUE, the CatalogName
argument was a null pointer, and the
SQL_CATALOG_NAME InfoType returns
that catalog names are supported.
HY090 Invalid string or buffer length (DM) The value of one of the name
length arguments was less than 0 but
not equal to SQL_NTS.
HYC00 Optional feature not implemented A catalog name was specified, and the
driver or data source does not support
catalogs.
The SQL_ATTR_USE_BOOKMARKS
statement attribute was set to
SQL_UB_VARIABLE, and the
SQL_ATTR_CURSOR_TYPE statement
attribute was set to a cursor type for
which the driver does not support
bookmarks.
IM001 Driver does not support this function (DM) The driver associated with the
StatementHandle does not support
the function.
IM018 SQLCompleteAsync has not been If the previous function call on the
called to complete the previous handle returns SQL_STILL_EXECUTING
asynchronous operation on this and if notification mode is enabled,
handle. SQLCompleteAsync must be called
on the handle to do post-processing
and complete the operation.
Comments
SQLColumnPrivileges returns the results as a standard result set, ordered by TABLE_CAT, TABLE_SCHEM,
TABLE_NAME, COLUMN_NAME, and PRIVILEGE.
NOTE
SQLColumnPrivileges might not return privileges for all columns. For example, a driver might not return information
about privileges for pseudo-columns, such as Oracle ROWID. Applications can use any valid column, regardless of whether
it is returned by SQLColumnPrivileges .
The lengths of VARCHAR columns are not shown in the table; the actual lengths depend on the data source. To
determine the actual lengths of the CATALOG_NAME, SCHEMA_NAME, TABLE_NAME, and COLUMN_NAME
columns, an application can call SQLGetInfo with the SQL_MAX_CATALOG_NAME_LEN,
SQL_MAX_SCHEMA_NAME_LEN, SQL_MAX_TABLE_NAME_LEN, and SQL_MAX_COLUMN_NAME_LEN options.
NOTE
For more information about the general use, arguments, and returned data of ODBC catalog functions, see Catalog
Functions.
The following columns have been renamed for ODBC 3.x. The column name changes do not affect backward
compatibility because applications bind by column number.
O DB C 2. 0 C O L UM N O DB C 3. X C O L UM N
TABLE_QUALIFIER TABLE_CAT
TABLE_OWNER TABLE_SCHEM
The following table lists the columns in the result set. Additional columns beyond column 8 (IS_GRANTABLE) can
be defined by the driver. An application should gain access to driver-specific columns by counting down from
the end of the result set rather than specifying an explicit ordinal position. For more information, see Data
Returned by Catalog Functions.
C O L UM N N A M E C O L UM N N UM B ER DATA T Y P E C O M M EN T S
GRANTEE (ODBC 1.0) 6 Varchar not NULL Name of the user to whom
the privilege was granted.
A privilege is either
grantable or not grantable,
but not both. The result set
returned by
SQLColumnPrivileges will
never contain two rows for
which all columns except
the IS_GRANTABLE column
contain the same value.
Code Example
For a code example of a similar function, see SQLColumns Function.
Related Functions
F O R IN F O RM AT IO N A B O UT SEE
See Also
ODBC API Reference
ODBC Header Files
SQLColumns Function
4/27/2022 • 16 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 1.0 Standards Compliance: Open Group
Summar y
SQLColumns returns the list of column names in specified tables. The driver returns this information as a result
set on the specified StatementHandle.
Syntax
SQLRETURN SQLColumns(
SQLHSTMT StatementHandle,
SQLCHAR * CatalogName,
SQLSMALLINT NameLength1,
SQLCHAR * SchemaName,
SQLSMALLINT NameLength2,
SQLCHAR * TableName,
SQLSMALLINT NameLength3,
SQLCHAR * ColumnName,
SQLSMALLINT NameLength4);
Arguments
StatementHandle
[Input] Statement handle.
CatalogName
[Input] Catalog name. If a driver supports catalogs for some tables but not for others, such as when the driver
retrieves data from different DBMSs, an empty string ("") indicates those tables that do not have catalogs.
CatalogName cannot contain a string search pattern.
NOTE
If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, CatalogName is treated as an identifier and its
case is not significant. If it is SQL_FALSE, CatalogName is an ordinary argument; it is treated literally, and its case is
significant. For more information, see Arguments in Catalog Functions.
NameLength1
[Input] Length in characters of *CatalogName.
SchemaName
[Input] String search pattern for schema names. If a driver supports schemas for some tables but not for others,
such as when the driver retrieves data from different DBMSs, an empty string ("") indicates those tables that do
not have schemas.
NOTE
If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, SchemaName is treated as an identifier and its
case is not significant. If it is SQL_FALSE, SchemaName is a pattern value argument; it is treated literally, and its case is
significant.
NameLength2
[Input] Length in characters of *SchemaName.
TableName
[Input] String search pattern for table names.
NOTE
If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, TableName is treated as an identifier and its case
is not significant. If it is SQL_FALSE, TableName is a pattern value argument; it is treated literally, and its case is significant.
NameLength3
[Input] Length in characters of *TableName.
ColumnName
[Input] String search pattern for column names.
NOTE
If the SQL_ATTR_METADATA_ID statement attribute is set to SQL_TRUE, ColumnName is treated as an identifier and its
case is not significant. If it is SQL_FALSE, ColumnName is a pattern value argument; it is treated literally, and its case is
significant.
NameLength4
[Input] Length in characters of *ColumnName.
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
Diagnostics
When SQLColumns returns SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE value can be
obtained by calling SQLGetDiagRec with a HandleType of SQL_HANDLE_STMT and a Handle of
StatementHandle. The following table lists the SQLSTATE values typically returned by SQLColumns and
explains each one in the context of this function; the notation "(DM)" precedes the descriptions of SQLSTATEs
returned by the Driver Manager. The return code associated with each SQLSTATE value is SQL_ERROR, unless
noted otherwise.
HY090 Invalid string or buffer length (DM) The value of one of the name
length arguments was less than 0 but
not equal to SQL_NTS.
HYC00 Optional feature not implemented A catalog name was specified, and the
driver or data source does not support
catalogs.
The SQL_ATTR_USE_BOOKMARKS
statement attribute was set to
SQL_UB_VARIABLE, and the
SQL_ATTR_CURSOR_TYPE statement
attribute was set to a cursor type for
which the driver does not support
bookmarks.
IM001 Driver does not support this function (DM) The driver associated with the
StatementHandle does not support
the function.
IM018 SQLCompleteAsync has not been If the previous function call on the
called to complete the previous handle returns SQL_STILL_EXECUTING
asynchronous operation on this and if notification mode is enabled,
handle. SQLCompleteAsync must be called
on the handle to do post-processing
and complete the operation.
Comments
This function typically is used before statement execution to retrieve information about columns for a table or
tables from the data source's catalog. SQLColumns can be used to retrieve data for all types of items returned
by SQLTables . In addition to base tables, this may include (but is not limited to) views, synonyms, system tables,
and so on. By contrast, the functions SQLColAttribute and SQLDescribeCol describe the columns in a result
set and the function SQLNumResultCols returns the number of columns in a result set. For more information,
see Uses of Catalog Data.
NOTE
For more information about the general use, arguments, and returned data of ODBC catalog functions, see Catalog
Functions.
SQLColumns returns the results as a standard result set, ordered by TABLE_CAT, TABLE_SCHEM, TABLE_NAME,
and ORDINAL_POSITION.
NOTE
When an application works with an ODBC 2.x driver, no ORDINAL_POSITION column is returned in the result set. As a
result, when working with ODBC 2.x drivers, the order of the columns in the column list returned by SQLColumns is not
necessarily the same as the order of the columns returned when the application performs a SELECT statement on all
columns in that table.
NOTE
SQLColumns might not return all columns. For example, a driver might not return information about pseudo-columns,
such as Oracle ROWID. Applications can use any valid column, whether it is returned by SQLColumns .
Some columns that can be returned by SQLStatistics are not returned by SQLColumns . For example, SQLColumns
does not return the columns in an index created over an expression or filter, such as SALARY + BENEFITS or DEPT = 0012.
The lengths of VARCHAR columns are not shown in the table; the actual lengths depend on the data source. To
determine the actual lengths of the TABLE_CAT, TABLE_SCHEM, TABLE_NAME, and COLUMN_NAME columns, an
application can call SQLGetInfo with the SQL_MAX_CATALOG_NAME_LEN, SQL_MAX_SCHEMA_NAME_LEN,
SQL_MAX_TABLE_NAME_LEN, and SQL_MAX_COLUMN_NAME_LEN options.
The following columns have been renamed for ODBC 3.x. The column name changes do not affect backward
compatibility because applications bind by column number.
O DB C 2. 0 C O L UM N O DB C 3. X C O L UM N
TABLE_QUALIFIER TABLE_CAT
O DB C 2. 0 C O L UM N O DB C 3. X C O L UM N
TABLE_OWNER TABLE_SCHEM
PRECISION COLUMN_SIZE
LENGTH BUFFER_LENGTH
SCALE DECIMAL_DIGITS
RADIX NUM_PREC_RADIX
The following columns have been added to the result set returned by SQLColumns for ODBC 3.x:
CHAR_OCTET_LENGTH
COLUMN_DEF
IS_NULLABLE
ORDINAL_POSITION
SQL_DATA_TYPE
SQL_DATETIME_SUB
The following table lists the columns in the result set. Additional columns beyond column 18 (IS_NULLABLE) can
be defined by the driver. An application should gain access to driver-specific columns by counting down from
the end of the result set instead of specifying an explicit ordinal position. For more information, see Data
Returned by Catalog Functions.
C O L UM N
C O L UM N N A M E N UM B ER DATA T Y P E C O M M EN T S
C O L UM N N A M E N UM B ER DATA T Y P E C O M M EN T S
DATA_TYPE (ODBC 1.0) 5 Smallint not NULL SQL data type. This can be
an ODBC SQL data type or
a driver-specific SQL data
type. For datetime and
interval data types, this
column returns the concise
data type (such as
SQL_TYPE_DATE or
SQL_INTERVAL_YEAR_TO_M
ONTH, instead of the
nonconcise data type such
as SQL_DATETIME or
SQL_INTERVAL). For a list of
valid ODBC SQL data types,
see SQL Data Types in
Appendix D: Data Types. For
information about driver-
specific SQL data types, see
the driver's documentation.
C O L UM N N A M E N UM B ER DATA T Y P E C O M M EN T S
C O L UM N N A M E N UM B ER DATA T Y P E C O M M EN T S
C O L UM N N A M E N UM B ER DATA T Y P E C O M M EN T S
If it is 2, the values in
COLUMN_SIZE and
DECIMAL_DIGITS give the
number of bits allowed in
the column. For example, a
FLOAT column could return
a RADIX of 2, a
COLUMN_SIZE of 53, and a
DECIMAL_DIGITS of NULL.
C O L UM N N A M E N UM B ER DATA T Y P E C O M M EN T S
SQL_NULLABLE if the
column accepts NULL
values.
SQL_NULLABLE_UNKNOW
N if it is not known whether
the column accepts NULL
values.
C O L UM N N A M E N UM B ER DATA T Y P E C O M M EN T S
C O L UM N N A M E N UM B ER DATA T Y P E C O M M EN T S
Code Example
In the following example, an application declares buffers for the result set returned by SQLColumns . It calls
SQLColumns to return a result set that describes each column in the EMPLOYEE table. It then calls
SQLBindCol to bind the columns in the result set to the buffers. Finally, the application fetches each row of data
with SQLFetch and processes it.
// SQLColumns_Function.cpp
// compile with: ODBC32.lib
#include <windows.h>
#include <sqlext.h>
#define STR_LEN 128 + 1
#define REM_LEN 254 + 1
SQLINTEGER ColumnSize;
SQLINTEGER BufferLength;
SQLINTEGER CharOctetLength;
SQLINTEGER OrdinalPosition;
SQLSMALLINT DataType;
SQLSMALLINT DecimalDigits;
SQLSMALLINT DecimalDigits;
SQLSMALLINT NumPrecRadix;
SQLSMALLINT Nullable;
SQLSMALLINT SQLDataType;
SQLSMALLINT DatetimeSubtypeCode;
int main() {
SQLHENV henv;
SQLHDBC hdbc;
SQLHSTMT hstmt = 0;
SQLRETURN retcode;
Related Functions
F O R IN F O RM AT IO N A B O UT SEE
See Also
ODBC API Reference
ODBC Header Files
SQLCompleteAsync Function
4/27/2022 • 2 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 3.8 Standards Compliance: None
Summar y
SQLCompleteAsync can be used to determine when an asynchronous function is complete using either
notification- or polling-based processing. For more information about asynchronous operations, see
Asynchronous Execution.
SQLCompleteAsync is only implemented in the ODBC Driver Manager.
In notification based asynchronous processing mode, SQLCompleteAsync must be called after the Driver
Manager raises the event object used for notification. SQLCompleteAsync completes the asynchronous
processing and the asynchronous function will generate a return code.
In polling based asynchronous processing mode, SQLCompleteAsync is an alternative to calling the original
asynchronous function, without needing to specify the arguments in the original asynchronous function call.
SQLCompleteAsync can be used regardless whether the ODBC Cursor Library is enabled.
Syntax
SQLRETURN SQLCompleteAsync(
SQLSMALLINT HandleType,
SQLHANDLE Handle,
RETCODE * AsyncRetCodePtr);
Arguments
HandleType
[Input] The type of the handle on which to complete asynchronous processing. Valid values are
SQL_HANDLE_DBC or SQL_HANDLE_STMT.
Handle
[Input] The handle on which to complete asynchronous processing. If Handle is not a valid handle of the type
specified by HandleType, SQLCompleteAsync returns SQL_INVALID_HANDLE.
If Handle is not a valid handle of the type specified by HandleType, SQLCompleteAsync returns
SQL_INVALID_HANDLE.
AsyncRetCodePtr
[Output] Pointer to a buffer that will contain the return code of the asynchronous API. If AsyncRetCodePtr is
NULL, SQLCompleteAsync returns SQL_ERROR.
Returns
SQL_SUCCESS, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE.
Diagnostics
If SQLCompleteAsync returns SQL_SUCCESS, an application should get the return code of the asynchronous
function from the buffer pointed to by AsyncRetCodePtr. The associated SQLSTATE, if any, can be obtained by
calling SQLGetDiagRec with a HandleType of SQL_HANDLE_STMT and a statement handle or a HandleType of
SQL_HANDLE_DBC and a connection handle. Those diagnostic records are associated with the asynchronous
function, not this SQLCompleteAsync function.
SQLCompleteAsync returns a code other than SQL_SUCCESS to indicate that SQLCompleteAsync is not
called correctly. SQLCompleteAsync will not post any diagnostic record in this case. Possible return codes are:
SQL_INVALID_HANDLE: The handle indicated by HandleType and Handle is not a valid handle.
SQL_ERROR: AsyncRetCodePtr is NULL or asynchronous processing is not enabled on the handle.
SQL_NO_DATA: In notification mode, an asynchronous operation is not in progress or the Driver Manager
has not notified the application. In polling mode, an asynchronous operation is not in progress.
Comments
In polling based asynchronous processing mode, AsyncRetCodePtr might be SQL_STILL_EXECUTING when
SQLCompleteAsync returns SQL_SUCCESS. Application should keep polling until AsyncRetCodePtr is not
SQL_STILL_EXECUTING. In notification based asynchronous processing mode, AsyncRetCodePtr will never be
SQL_STILL_EXECUTING.
See Also
Asynchronous Execution (Polling Method)
SQLConnect Function
4/27/2022 • 14 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 1.0 Standards Compliance: ISO 92
Summar y
SQLConnect establishes connections to a driver and a data source. The connection handle references storage
of all information about the connection to the data source, including status, transaction state, and error
information.
Syntax
SQLRETURN SQLConnect(
SQLHDBC ConnectionHandle,
SQLCHAR * ServerName,
SQLSMALLINT NameLength1,
SQLCHAR * UserName,
SQLSMALLINT NameLength2,
SQLCHAR * Authentication,
SQLSMALLINT NameLength3);
Arguments
ConnectionHandle
[Input] Connection handle.
ServerName
[Input] Data source name. The data might be located on the same computer as the program, or on another
computer somewhere on a network. For information about how an application chooses a data source, see
Choosing a Data Source or Driver.
NameLength1
[Input] Length of *ServerName in characters.
UserName
[Input] User identifier.
NameLength2
[Input] Length of *UserName in characters.
Authentication
[Input] Authentication string (typically the password).
NameLength3
[Input] Length of *Authentication in characters.
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.
Diagnostics
When SQLConnect returns SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE value can be
obtained by calling SQLGetDiagRec with a HandleType of SQL_HANDLE_DBC and a Handle of
ConnectionHandle. The following table lists the SQLSTATE values typically returned by SQLConnect and
explains each one in the context of this function; the notation "(DM)" precedes the descriptions of SQLSTATEs
returned by the Driver Manager. The return code associated with each SQLSTATE value is SQL_ERROR, unless
noted otherwise.
01S02 Option value changed The driver did not support the
specified value of the ValuePtr
argument in SQLSetConnectAttr
and substituted a similar value.
(Function returns
SQL_SUCCESS_WITH_INFO.)
08001 Client unable to establish connection The driver was unable to establish a
connection with the data source.
08004 Server rejected the connection The data source rejected the
establishment of the connection for
implementation-defined reasons.
28000 Invalid authorization specification The value specified for the argument
UserName or the value specified for
the argument Authentication violated
restrictions defined by the data source.
HY001 Memory allocation error (DM) The Driver Manager was unable
to allocate memory that is required to
support execution or completion of
the function.
SQ L STAT E ERRO R DESC RIP T IO N
HY090 Invalid string or buffer length (DM) The value specified for argument
NameLength1, NameLength2, or
NameLength3 was less than 0 but not
equal to SQL_NTS.
HY114 Driver does not support connection (DM) The application enabled the
level asynchronous function execution asynchronous operation on the
connection handle before making the
connection. However, the driver does
not support asynchronous operations
on the connection handle.
IM001 Driver does not support this function (DM) The driver specified by the data
source name does not support the
function.
IM002 Data source not found and no default (DM) The data source name specified
driver specified in the argument ServerName was not
found in the system information, nor
was there a default driver specification.
IM003 Specified driver could not be (DM) The driver listed in the data
connected to source specification in system
information was not found or could
not be connected to for some other
reason.
IM009 Unable to connect to translation DLL The driver was unable to connect to
the translation DLL that was specified
for the data source.
IM010 Data source name too long (DM) *ServerName was longer than
SQL_MAX_DSN_LENGTH characters.
IM014 The specified DSN contains an (DM) 32-bit application uses a DSN
architecture mismatch between the connecting to a 64-bit driver; or vice
Driver and Application versa.
IM018 SQLCompleteAsync has not been If the previous function call on the
called to complete the previous handle returns SQL_STILL_EXECUTING
asynchronous operation on this and if notification mode is enabled,
handle. SQLCompleteAsync must be called
on the handle to do post-processing
and complete the operation.
S1118 Driver does not support asynchronous When the driver does not support
notification asynchronous notification, you cannot
set SQL_ATTR_ASYNC_DBC_EVENT or
SQL_ATTR_ASYNC_DBC_RETCODE_PTR.
Comments
For information about why an application uses SQLConnect , see Connecting with SQLConnect.
The Driver Manager does not connect to a driver until the application calls a function (SQLConnect ,
SQLDriverConnect , or SQLBrowseConnect ) to connect to the driver. Until that point, the Driver Manager
works with its own handles and manages connection information. When the application calls a connection
function, the Driver Manager checks whether a driver is currently connected to for the specified
ConnectionHandle:
If a driver is not connected to, the Driver Manager connects to the driver and calls SQL AllocHandle with
a HandleType of SQL_HANDLE_ENV, SQL AllocHandle with a HandleType of SQL_HANDLE_DBC,
SQLSetConnectAttr (if the application specified any connection attributes), and the connection function
in the driver. The Driver Manager returns SQLSTATE IM006 (Driver's SQLSetConnectOption failed) and
SQL_SUCCESS_WITH_INFO for the connection function if the driver returned an error for
SQLSetConnectAttr . For more information, see Connecting to a Data Source or Driver.
If the specified driver is already connected to on the ConnectionHandle, the Driver Manager calls only the
connection function in the driver. In this case, the driver must make sure that all connection attributes for
the ConnectionHandle maintain their current settings.
If a different driver is connected to, the Driver Manager calls SQLFreeHandle with a HandleType of
SQL_HANDLE_DBC, and then, if no other driver is connected to in that environment, it calls
SQLFreeHandle with a HandleType of SQL_HANDLE_ENV in the connected driver and then disconnects
that driver. It then performs the same operations as when a driver is not connected to.
The driver then allocates handles and initializes itself.
When the application calls SQLDisconnect , the Driver Manager calls SQLDisconnect in the driver. However, it
does not disconnect the driver. This keeps the driver in memory for applications that repeatedly connect to and
disconnect from a data source. When the application calls SQLFreeHandle with a HandleType of
SQL_HANDLE_DBC, the Driver Manager calls SQLFreeHandle with a HandleType of SQL_HANDLE_DBC and
then SQLFreeHandle with a HandleType of SQL_HANDLE_ENV in the driver, and then disconnects the driver.
An ODBC application can establish more than one connection.
int main() {
SQLHENV henv;
SQLHDBC hdbc;
SQLHSTMT hstmt;
SQLRETURN retcode;
// Process data
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
}
SQLDisconnect(hdbc);
}
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
}
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
}
Related Functions
F O R IN F O RM AT IO N A B O UT SEE
See Also
ODBC API Reference
ODBC Header Files
SQLCopyDesc Function
4/27/2022 • 9 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 3.0 Standards Compliance: ISO 92
Summar y
SQLCopyDesc copies descriptor information from one descriptor handle to another.
Syntax
SQLRETURN SQLCopyDesc(
SQLHDESC SourceDescHandle,
SQLHDESC TargetDescHandle);
Arguments
SourceDescHandle
[Input] Source descriptor handle.
TargetDescHandle
[Input] Target descriptor handle. The TargetDescHandle argument can be a handle to an application descriptor or
an IPD. TargetDescHandle cannot be set to a handle to an IRD, or SQLCopyDesc will return SQLSTATE HY016
(Cannot modify an implementation row descriptor).
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
Diagnostics
When SQLCopyDesc returns SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE value can be
obtained by calling SQLGetDiagRec with a HandleType of SQL_HANDLE_DESC and a Handle of
TargetDescHandle. If an invalid SourceDescHandle was passed in the call, SQL_INVALID_HANDLE will be
returned but no SQLSTATE will be returned. The following table lists the SQLSTATE values commonly returned by
SQLCopyDesc and explains each one in the context of this function; the notation "(DM)" precedes the
descriptions of SQLSTATEs returned by the Driver Manager. The return code associated with each SQLSTATE
value is SQL_ERROR, unless noted otherwise.
When an error is returned, the call to SQLCopyDesc is immediately aborted, and the contents of the fields in
the TargetDescHandle descriptor are undefined.
Because SQLCopyDesc may be implemented by calling SQLGetDescField and SQLSetDescField ,
SQLCopyDesc may return SQLSTATEs returned by SQLGetDescField or SQLSetDescField .
HY001 Memory allocation error The driver was unable to allocate the
memory required to support execution
or completion of the function.
IM001 Driver does not support this function (DM) The driver associated with the
SourceDescHandle or
TargetDescHandle does not support
the function.
Comments
A call to SQLCopyDesc copies the fields of the source descriptor handle to the target descriptor handle. Fields
can be copied only to an application descriptor or an IPD, but not to an IRD. Fields can be copied from either an
application or an implementation descriptor.
Fields can be copied from an IRD only if the statement handle is in the prepared or executed state; otherwise, the
function returns SQLSTATE HY007 (Associated statement is not prepared).
Fields can be copied from an IPD whether or not a statement has been prepared. If an SQL statement with
dynamic parameters has been prepared and automatic population of the IPD is supported and enabled, then the
IPD is populated by the driver. When SQLCopyDesc is called with the IPD as the SourceDescHandle, the
populated fields are copied. If the IPD is not populated by the driver, the contents of the fields originally in the
IPD are copied.
All fields of the descriptor, except SQL_DESC_ALLOC_TYPE (which specifies whether the descriptor handle was
automatically or explicitly allocated), are copied, whether or not the field is defined for the destination descriptor.
Copied fields overwrite the existing fields.
The driver copies all descriptor fields if the SourceDescHandle and TargetDescHandle arguments are associated
with the same driver, even if the drivers are on two different connections or environments. If the
SourceDescHandle and TargetDescHandle arguments are associated with different drivers, the Driver Manager
copies ODBC-defined fields, but does not copy driver-defined fields or fields that are not defined by ODBC for
the type of descriptor.
The call to SQLCopyDesc is aborted immediately if an error occurs.
When the SQL_DESC_DATA_PTR field is copied, a consistency check is performed on the target descriptor. If the
consistency check fails, SQLSTATE HY021 (Inconsistent descriptor information) is returned and the call to
SQLCopyDesc is immediately aborted. For more information on consistency checks, see "Consistency Checks"
in SQLSetDescRec Function.
Descriptor handles can be copied across connections even if the connections are under different environments.
If the Driver Manager detects that the source and the destination descriptor handles do not belong to the same
connection and the two connections belong to separate drivers, it implements SQLCopyDesc by performing a
field-by-field copy using SQLGetDescField and SQLSetDescField .
When SQLCopyDesc is called with a SourceDescHandle on one driver and a TargetDescHandle on another
driver, the error queue of the SourceDescHandle is cleared. This occurs because SQLCopyDesc in this case is
implemented by calls to SQLGetDescField and SQLSetDescField .
NOTE
An application might be able to associate an explicitly allocated descriptor handle with a StatementHandle, rather than
calling SQLCopyDesc to copy fields from one descriptor to another. An explicitly allocated descriptor can be associated
with another StatementHandle on the same ConnectionHandle by setting the SQL_ATTR_APP_ROW_DESC or
SQL_ATTR_APP_PARAM_DESC statement attribute to the handle of the explicitly allocated descriptor. When this is done,
SQLCopyDesc does not have to be called to copy descriptor field values from one descriptor to another. A descriptor
handle cannot be associated with a StatementHandle on another ConnectionHandle, however; to use the same descriptor
field values on StatementHandles on different ConnectionHandles, SQLCopyDesc has to be called.
For a description of the fields in a descriptor header or record, see SQLSetDescField Function. For more
information on descriptors, see Descriptors.
// Bind
SQLBindCol(hstmt0, 1, SQL_C_SLONG, rget[0].sPartID, 0,
&rget[0].cbPartID);
SQLBindCol(hstmt0, 2, SQL_C_CHAR, &rget[0].szDescription, DESC_LEN,
&rget[0].cbDescription);
SQLBindCol(hstmt0, 3, SQL_C_FLOAT, rget[0].sPrice,
0, &rget[0].cbPrice);
Related Functions
F O R IN F O RM AT IO N A B O UT SEE
See Also
ODBC API Reference
ODBC Header Files
SQLDataSources Function
4/27/2022 • 4 minutes to read • Edit Online
Conformance
Version Introduced: ODBC 1.0 Standards Compliance: ISO 92
Summar y
SQLDataSources returns information about a data source. This function is implemented only by the Driver
Manager.
Syntax
SQLRETURN SQLDataSources(
SQLHENV EnvironmentHandle,
SQLUSMALLINT Direction,
SQLCHAR * ServerName,
SQLSMALLINT BufferLength1,
SQLSMALLINT * NameLength1Ptr,
SQLCHAR * Description,
SQLSMALLINT BufferLength2,
SQLSMALLINT * NameLength2Ptr);
Arguments
EnvironmentHandle
[Input] Environment handle.
Direction
[Input] Determines which data source the Driver Manager returns information about. Can be:
SQL_FETCH_NEXT (to fetch the next data source name in the list), SQL_FETCH_FIRST (to fetch from the beginning
of the list), SQL_FETCH_FIRST_USER (to fetch the first user DSN), or SQL_FETCH_FIRST_SYSTEM (to fetch the first
system DSN).
When Direction is set to SQL_FETCH_FIRST, subsequent calls to SQLDataSources with Direction set to
SQL_FETCH_NEXT return both user and system DSNs. When Direction is set to SQL_FETCH_FIRST_USER, all
subsequent calls to SQLDataSources with Direction set to SQL_FETCH_NEXT return only user DSNs. When
Direction is set to SQL_FETCH_FIRST_SYSTEM, all subsequent calls to SQLDataSources with Direction set to
SQL_FETCH_NEXT return only system DSNs.
ServerName
[Output] Pointer to a buffer in which to return the data source name.
If ServerName is NULL, NameLength1Ptr will still return the total number of characters (excluding the null-
termination character for character data) available to return in the buffer pointed to by ServerName.
BufferLength1
[Input] Length of the *ServerName buffer, in characters; this does not need to be longer than
SQL_MAX_DSN_LENGTH plus the null-termination character.
NameLength1Ptr
[Output] Pointer to a buffer in which to return the total number of characters (excluding the null-termination
character) available to return in *ServerName. If the number of characters available to return is greater than or
equal to BufferLength1, the data source name in *ServerName is truncated to BufferLength1 minus the length
of a null-termination character.
Description
[Output] Pointer to a buffer in which to return the description of the driver associated with the data source. For
example, dBASE or SQL Server.
If Description is NULL, NameLength2Ptr will still return the total number of characters (excluding the null-
termination character for character data) available to return in the buffer pointed to by Description.
BufferLength2
[Input] Length in characters of the *Description buffer.
NameLength2Ptr
[Output] Pointer to a buffer in which to return the total number of characters (excluding the null-termination
character) available to return in *Description. If the number of characters available to return is greater than or
equal to BufferLength2, the driver description in *Description is truncated to BufferLength2 minus the length of
a null-termination character.
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, or SQL_INVALID_HANDLE.
Diagnostics
When SQLDataSources returns either SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE
value can be obtained by calling SQLGetDiagRec with a HandleType of SQL_HANDLE_ENV and a Handle of
EnvironmentHandle. The following table lists the SQLSTATE values typically returned by SQLDataSources and
explains each one in the context of this function; the notation "(DM)" precedes the descriptions of SQLSTATEs
returned by the Driver Manager. The return code associated with each SQLSTATE value is SQL_ERROR, unless
noted otherwise.
01004 String data, right truncated (DM) The buffer *ServerName was not
large enough to return the complete
data source name. Therefore, the name
was truncated. The length of the entire
data source name is returned in
*NameLength1Ptr. (Function returns
SQL_SUCCESS_WITH_INFO.)
HY001 Memory allocation error (DM) The Driver Manager was unable
to allocate memory that is required to
support execution or completion of
the function.
HY090 Invalid string or buffer length (DM) The value specified for argument
BufferLength1 was less than 0.
HY103 Invalid retrieval code (DM) The value specified for the
argument Direction was not equal to
SQL_FETCH_FIRST,
SQL_FETCH_FIRST_USER,
SQL_FETCH_FIRST_SYSTEM, or
SQL_FETCH_NEXT.