- How to call the Java runtime in SQL Server Language Extensions
- Where to place Java classes
- Use Classpath
- Basic principles
- Call Java class
- Set CLASSPATH
- Use external library
- Loopback connection to SQL Server
- Next steps
- Шаг 3. Подтверждение концепции: подключение к SQL с помощью Java
- Шаг 1. Подключение
- Шаг 2. Выполнение запроса
- Шаг 3. Вставка строки
- Шаг 3. Подтверждение концепции: подключение к SQL с помощью Java
- Шаг 1. Подключение
- Шаг 2. Выполнение запроса
- Шаг 3. Вставка строки
- Работа с подключением
- Установка подключения с использованием класса DriverManager
- Установка подключения с использованием класса SQLServerDriver
- Установка подключения с использованием класса SQLServerDataSource
- Установка подключения, предназначенного для конкретного источника данных
- Установка подключения с настраиваемым временем сохранения учетных данных
- Установка подключения с идентификацией на уровне приложения
- Закрытие подключения
How to call the Java runtime in SQL Server Language Extensions
SQL Server Language Extensions uses the sp_execute_external_script system stored procedure as the interface to call the Java runtime.
This how-to article explains implementation details for Java classes and methods that execute on SQL Server.
Where to place Java classes
There are two methods for calling Java classes in SQL Server:
- Place .class or .jar files in your Java classpath.
- Upload compiled classes in a .jar file and other dependencies into the database using the external library DDL.
As a general recommendation, use .jar files and not individual .class files. This is common practice in Java and will make the overall experience easier. See also, How to create a jar file from class files.
Use Classpath
Basic principles
The following are some basic principles when executing Java on SQL Server.
- Compiled custom Java classes must exist in .class files or .jar files in your Java classpath. The CLASSPATH parameter provides the path to the compiled Java files.
- The Java method you are calling must be provided in the script parameter on the stored procedure.
- If the class belongs to a package, the packageName must be provided.
- params is used to pass parameters to a Java class. Calling a method that requires arguments is not supported. Therefore, parameters the only way to pass argument values to your method.
This note restates supported and unsupported operations specific to Java in SQL Server 2019 Release Candidate 1.
Call Java class
The sp_execute_external_script system stored procedure is the interface used to call the Java runtime. The following example shows an sp_execute_external_script using the Java extension, and parameters for specifying path, script, and your custom code.
Note that you don’t need to define which method to call. By default, a method called execute is called. This means that you need to follow the Extensibility SDK for Java in SQL Server and implement an execute method in your Java class.
DECLARE @param1 int SET @param1 = 3 EXEC sp_execute_external_script @language = N'Java' , @script = N'.' , @input_data_1 = N'' , @param1 = @param1
Set CLASSPATH
Once you have compiled your Java class or classes and created a jar file in your Java classpath, you have two options for providing the classpath to the SQL Server Java extension:
- Use external libraries The easiest option is to make SQL Server automatically find your classes by creating external libraries and pointing the library to a jar. Use external libraries for Java
- Register a system environment variable You can create a system environment variable and provide the paths to your jar file that contains the classes. Create a system environment variable called CLASSPATH.
Use external library
In SQL Server 2019 Release Candidate 1, you can use external libraries for the Java language on Windows and Linux. You can compile your classes into a .jar file and upload the .jar file and other dependencies into the database using the CREATE EXTERNAL LIBRARY DDL.
Example of how to upload a .jar file with external library:
CREATE EXTERNAL LIBRARY myJar FROM (CONTENT = '') WITH (LANGUAGE = 'Java'); GO
By creating an external library, SQL Server will automatically have access to the Java classes and you do not need to set any special permissions to the classpath.
Example of calling a method in a class from a package uploaded as an external library:
EXEC sp_execute_external_script @language = N'Java' , @script = N'MyPackage.MyCLass' , @input_data_1 = N'SELECT * FROM MYTABLE' with result sets ((column1 int))
Loopback connection to SQL Server
Use a loopback connection to connect back to SQL Server over JDBC to read or write data from Java executed from sp_execute_external_script . You can use this when using the InputDataSet and OutputDataSet arguments of sp_execute_external_script are not possible. To make a loopback connection in Windows use the following example:
jdbc:sqlserver://localhost:1433;databaseName=Adventureworks;integratedSecurity=true;
To make a loopback connection in Linux the JDBC driver requires three connection properties defined in the following Certificate:
Next steps
Шаг 3. Подтверждение концепции: подключение к SQL с помощью Java
Этот пример следует рассматривать только как подтверждение концепции. Пример кода упрощен для ясности и для него не гарантируется соблюдение рекомендаций корпорации Майкрософт.
Шаг 1. Подключение
Используйте класс подключения для подключения к базе данных SQL.
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class SQLDatabaseConnection < // Connect to your database. // Replace server name, username, and password with your credentials public static void main(String[] args) < String connectionUrl = "jdbc:sqlserver://yourserver.database.windows.net:1433;" + "database=AdventureWorks;" + "user=yourusername@yourserver;" + "password=yourpassword;" + "encrypt=true;" + "trustServerCertificate=false;" + "loginTimeout=30;"; try (Connection connection = DriverManager.getConnection(connectionUrl);) < // Code here. >// Handle any errors that may have occurred. catch (SQLException e) < e.printStackTrace(); >> >
Шаг 2. Выполнение запроса
В этом примере следует подключиться к базе данных SQL Azure, выполнить инструкцию SELECT и вернуть выбранные строки.
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class SQLDatabaseConnection < // Connect to your database. // Replace server name, username, and password with your credentials public static void main(String[] args) < String connectionUrl = "jdbc:sqlserver://yourserver.database.windows.net:1433;" + "database=AdventureWorks;" + "user=yourusername@yourserver;" + "password=yourpassword;" + "encrypt=true;" + "trustServerCertificate=false;" + "loginTimeout=30;"; ResultSet resultSet = null; try (Connection connection = DriverManager.getConnection(connectionUrl); Statement statement = connection.createStatement();) < // Create and execute a SELECT SQL statement. String selectSql = "SELECT TOP 10 Title, FirstName, LastName from SalesLT.Customer"; resultSet = statement.executeQuery(selectSql); // Print results from select statement while (resultSet.next()) < System.out.println(resultSet.getString(2) + " " + resultSet.getString(3)); >> catch (SQLException e) < e.printStackTrace(); >> >
Шаг 3. Вставка строки
В этом примере следует выполнить инструкцию INSERT, передать параметры и извлечь автоматически созданное значение первичного ключа.
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; public class SQLDatabaseConnection < // Connect to your database. // Replace server name, username, and password with your credentials public static void main(String[] args) < String connectionUrl = "jdbc:sqlserver://yourserver.database.windows.net:1433;" + "database=AdventureWorks;" + "user=yourusername@yourserver;" + "password=yourpassword;" + "encrypt=true;" + "trustServerCertificate=false;" + "loginTimeout=30;"; String insertSql = "INSERT INTO SalesLT.Product (Name, ProductNumber, Color, StandardCost, ListPrice, SellStartDate) VALUES " + "('NewBike', 'BikeNew', 'Blue', 50, 120, '2016-01-01');"; ResultSet resultSet = null; try (Connection connection = DriverManager.getConnection(connectionUrl); PreparedStatement prepsInsertProduct = connection.prepareStatement(insertSql, Statement.RETURN_GENERATED_KEYS);) < prepsInsertProduct.execute(); // Retrieve the generated key from the insert. resultSet = prepsInsertProduct.getGeneratedKeys(); // Print the ID of the inserted row. while (resultSet.next()) < System.out.println("Generated: " + resultSet.getString(1)); >> // Handle any errors that may have occurred. catch (Exception e) < e.printStackTrace(); >> >
Шаг 3. Подтверждение концепции: подключение к SQL с помощью Java
Этот пример следует рассматривать только как подтверждение концепции. Пример кода упрощен для ясности и для него не гарантируется соблюдение рекомендаций корпорации Майкрософт.
Шаг 1. Подключение
Используйте класс подключения для подключения к базе данных SQL.
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class SQLDatabaseConnection < // Connect to your database. // Replace server name, username, and password with your credentials public static void main(String[] args) < String connectionUrl = "jdbc:sqlserver://yourserver.database.windows.net:1433;" + "database=AdventureWorks;" + "user=yourusername@yourserver;" + "password=yourpassword;" + "encrypt=true;" + "trustServerCertificate=false;" + "loginTimeout=30;"; try (Connection connection = DriverManager.getConnection(connectionUrl);) < // Code here. >// Handle any errors that may have occurred. catch (SQLException e) < e.printStackTrace(); >> >
Шаг 2. Выполнение запроса
В этом примере следует подключиться к базе данных SQL Azure, выполнить инструкцию SELECT и вернуть выбранные строки.
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class SQLDatabaseConnection < // Connect to your database. // Replace server name, username, and password with your credentials public static void main(String[] args) < String connectionUrl = "jdbc:sqlserver://yourserver.database.windows.net:1433;" + "database=AdventureWorks;" + "user=yourusername@yourserver;" + "password=yourpassword;" + "encrypt=true;" + "trustServerCertificate=false;" + "loginTimeout=30;"; ResultSet resultSet = null; try (Connection connection = DriverManager.getConnection(connectionUrl); Statement statement = connection.createStatement();) < // Create and execute a SELECT SQL statement. String selectSql = "SELECT TOP 10 Title, FirstName, LastName from SalesLT.Customer"; resultSet = statement.executeQuery(selectSql); // Print results from select statement while (resultSet.next()) < System.out.println(resultSet.getString(2) + " " + resultSet.getString(3)); >> catch (SQLException e) < e.printStackTrace(); >> >
Шаг 3. Вставка строки
В этом примере следует выполнить инструкцию INSERT, передать параметры и извлечь автоматически созданное значение первичного ключа.
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; public class SQLDatabaseConnection < // Connect to your database. // Replace server name, username, and password with your credentials public static void main(String[] args) < String connectionUrl = "jdbc:sqlserver://yourserver.database.windows.net:1433;" + "database=AdventureWorks;" + "user=yourusername@yourserver;" + "password=yourpassword;" + "encrypt=true;" + "trustServerCertificate=false;" + "loginTimeout=30;"; String insertSql = "INSERT INTO SalesLT.Product (Name, ProductNumber, Color, StandardCost, ListPrice, SellStartDate) VALUES " + "('NewBike', 'BikeNew', 'Blue', 50, 120, '2016-01-01');"; ResultSet resultSet = null; try (Connection connection = DriverManager.getConnection(connectionUrl); PreparedStatement prepsInsertProduct = connection.prepareStatement(insertSql, Statement.RETURN_GENERATED_KEYS);) < prepsInsertProduct.execute(); // Retrieve the generated key from the insert. resultSet = prepsInsertProduct.getGeneratedKeys(); // Print the ID of the inserted row. while (resultSet.next()) < System.out.println("Generated: " + resultSet.getString(1)); >> // Handle any errors that may have occurred. catch (Exception e) < e.printStackTrace(); >> >
Работа с подключением
В следующих разделах приведены примеры различных способов соединения с базой данных SQL Server с помощью класса SQLServerConnection драйвера Microsoft JDBC Driver для SQL Server.
При возникновении неполадок с соединением с SQL Server с помощью драйвера JDBC см. раздел Профилактика подключений, где можно найти сведения по их устранению.
Установка подключения с использованием класса DriverManager
Простейший способ соединения с базой данных SQL Server — загрузка драйвера JDBC и вызов метода getConnection класса DriverManager:
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); String connectionUrl = "jdbc:sqlserver://localhost;encrypt=true;database=AdventureWorks;integratedSecurity=true;" Connection con = DriverManager.getConnection(connectionUrl);
По этой методике подключение к базе данных будет создано с помощью первого доступного драйвера из списка драйверов, способных успешно подсоединиться к данному URL-адресу.
При использовании библиотеки классов sqljdbc4.jar приложениям не обязательно явно регистрировать или загружать драйвер с помощью метода Class.forName. При вызове метода getConnection класса DriverManager подходящий драйвер выбирается из набора зарегистрированных драйверов JDBC. Дополнительные сведения об использовании JDBC см. в разделе «Использование драйвера JDBC».
Установка подключения с использованием класса SQLServerDriver
Если нужно указать конкретный драйвер из списка драйверов для DriverManager, то можно создать подключение к базе данных с помощью метода connect класса SQLServerDriver:
Driver d = (Driver) Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance(); String connectionUrl = "jdbc:sqlserver://localhost;encrypt=true;database=AdventureWorks;integratedSecurity=true;" Connection con = d.connect(connectionUrl, new Properties());
Установка подключения с использованием класса SQLServerDataSource
При необходимости создать соединение с помощью класса SQLServerDataSource можно использовать различные методы задания класса, после чего вызывается метод getConnection:
SQLServerDataSource ds = new SQLServerDataSource(); ds.setUser("MyUserName"); ds.setPassword("*****"); ds.setServerName("localhost"); ds.setPortNumber(1433); ds.setDatabaseName("AdventureWorks"); Connection con = ds.getConnection();
Установка подключения, предназначенного для конкретного источника данных
Создать подключение к базе данных, целью которого является конкретный источник данных, можно несколькими способами. Каждый способ зависит от свойств, задаваемых с помощью URL-адреса соединения.
Подключиться к экземпляру по умолчанию на удаленном сервере можно следующим образом:
String url = "jdbc:sqlserver://MyServer;encrypt=true;integratedSecurity=true;"
Подключиться к конкретному порту на сервере можно следующим образом:
String url = "jdbc:sqlserver://MyServer:1533;encrypt=true;integratedSecurity=true;"
Подключиться к именованному экземпляру на сервере можно следующим образом:
String url = "jdbc:sqlserver://209.196.43.19;encrypt=true;instanceName=INSTANCE1;integratedSecurity=true;"
Подключиться к конкретной базе данных на сервере можно следующим образом:
String url = "jdbc:sqlserver://172.31.255.255;encrypt=true;database=AdventureWorks;integratedSecurity=true;"
Дополнительные примеры URL-адресов подключений см. в статье о создании URL-адреса подключения.
Установка подключения с настраиваемым временем сохранения учетных данных
Если приходится подстраиваться под нагрузку сервера или сети, можно создать соединение с заданным временем сохранения учетных данных в секундах:
String url = "jdbc:sqlserver://MyServer;encrypt=true;loginTimeout=90;integratedSecurity=true;"
Установка подключения с идентификацией на уровне приложения
Если для работы требуется ведение журнала и профилирование, то необходимо идентифицировать соединение по инициировавшему его приложению:
String url = "jdbc:sqlserver://MyServer;encrypt=true;applicationName=MYAPP.EXE;integratedSecurity=true;"
Закрытие подключения
Подключение к базе данных можно явно закрыть путем вызова метода close класса SQLServerConnection:
Освобождение ресурсов базы данных, используемых объектом SQLServerConnection, или возврат соединения в пул соединений в сценариях с пулами.
Вызов метода close также приведет к откату любой ожидающей выполнения транзакции.