Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A következőkre vonatkozik: SQL Server 2019 (15.x) és újabb verziók
Ez az oktatóanyag bemutatja, hogyan hozhat létre olyan Java-osztályt az SQL Server nyelvkiterjesztéseinek használatával, amelyek két oszlopot (azonosítót és szöveget) kapnak az SQL Servertől, valamint egy regex regex kifejezést bemeneti paraméterként. Az osztály két oszlopot ad vissza az SQL Servernek (azonosító és szöveg).
A Java-osztálynak küldött szövegoszlop adott szövege esetén a kód ellenőrzi, hogy a megadott reguláris kifejezés teljesül-e, és az eredeti azonosítóval együtt adja vissza a szöveget.
Ez a mintakód egy reguláris kifejezést használ, amely ellenőrzi, hogy egy szöveg tartalmazza-e a szót Java vagy javaa szót.
Előfeltételek
Adatbázismotor-példány az SQL Server 2019 (15.x) és újabb verzióiban, bővíthetőségi keretrendszerrel és Java programozási bővítménysel Windowson vagy Linuxon. További információ: SQL Server Language Extensions. A kódolási követelményekkel kapcsolatos további információkért tekintse meg a Java-futtatókörnyezet meghívását az SQL Server Language Extensionsben.
Adatbázis-ügyfél. Az SQL Server egy példányához bármilyen ismerős SQL Server-ügyféleszközzel csatlakozhat, például sqlcmd, SQL Server Management Studio (SSMS) vagy a Visual Studio Code MSSQL-bővítményével.
Java SE Development Kit (JDK) 8 vagy JRE 8 Windows vagy Linux rendszeren.
A
mssql-java-lang-extension.jarfájl a Microsoft SQL Serverhez készült Java-bővíthetőségi SDK-ból származik.
Ehhez az oktatóanyaghoz elegendő a parancssorból történő fordítás javac használatával.
Mintaadatok létrehozása
Először hozzon létre egy új adatbázist, és töltse fel a testdata táblát ID és text oszlopokkal.
CREATE DATABASE javatest;
GO
USE javatest;
GO
CREATE TABLE testdata
(
[id] INT NOT NULL,
[text] NVARCHAR (100) NOT NULL
);
GO
-- Insert data into test table
INSERT INTO testdata ([id], [text]) VALUES (1, 'This sentence contains java');
INSERT INTO testdata ([id], [text]) VALUES (2, 'This sentence does not');
INSERT INTO testdata ([id], [text]) VALUES (3, 'I love Java!');
GO
A főosztály létrehozása
Ebben a lépésben hozzon létre egy osztályfájlt, RegexSample.java és másolja a következő Java-kódot a fájlba.
Ez a főosztály importálja az SDK-t, ami azt jelenti, hogy az 1. lépésben letöltött jar-fájlt ebből az osztályból kell felderíteni.
package pkg;
import com.microsoft.sqlserver.javalangextension.PrimitiveDataset;
import com.microsoft.sqlserver.javalangextension.AbstractSqlServerExtensionExecutor;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.regex.*;
public class RegexSample extends AbstractSqlServerExtensionExecutor {
private Pattern expr;
public RegexSample() {
// Setup the expected extension version, and class to use for input and output dataset
executorExtensionVersion = SQLSERVER_JAVA_LANG_EXTENSION_V1;
executorInputDatasetClassName = PrimitiveDataset.class.getName();
executorOutputDatasetClassName = PrimitiveDataset.class.getName();
}
public PrimitiveDataset execute(PrimitiveDataset input, LinkedHashMap<String, Object> params) {
// Validate the input parameters and input column schema
validateInput(input, params);
int[] inIds = input.getIntColumn(0);
String[] inValues = input.getStringColumn(1);
int rowCount = inValues.length;
String regexExpr = (String)params.get("regexExpr");
expr = Pattern.compile(regexExpr);
System.out.println("regex expression: " + regexExpr);
// Lists to store the output data
LinkedList<Integer> outIds = new LinkedList<Integer>();
LinkedList<String> outValues = new LinkedList<String>();
// Evaluate each row
for(int i = 0; i < rowCount; i++) {
if (check(inValues[i])) {
outIds.add(inIds[i]);
outValues.add(inValues[i]);
}
}
int outputRowCount = outValues.size();
int[] idOutputCol = new int[outputRowCount];
String[] valueOutputCol = new String[outputRowCount];
// Convert the list of output columns to arrays
outValues.toArray(valueOutputCol);
ListIterator<Integer> it = outIds.listIterator(0);
int rowId = 0;
System.out.println("Output data:");
while (it.hasNext()) {
idOutputCol[rowId] = it.next().intValue();
System.out.println("ID: " + idOutputCol[rowId] + " Value: " + valueOutputCol[rowId]);
rowId++;
}
// Construct the output dataset
PrimitiveDataset output = new PrimitiveDataset();
output.addColumnMetadata(0, "ID", java.sql.Types.INTEGER, 0, 0);
output.addColumnMetadata(1, "Text", java.sql.Types.NVARCHAR, 0, 0);
output.addIntColumn(0, idOutputCol, null);
output.addStringColumn(1, valueOutputCol);
return output;
}
private void validateInput(PrimitiveDataset input, LinkedHashMap<String, Object> params) {
// Check for the regex expression input parameter
if (params.get("regexExpr") == null) {
throw new IllegalArgumentException("Input parameter 'regexExpr' is not found");
}
// The expected input schema should be at least 2 columns, (INTEGER, STRING)
if (input.getColumnCount() < 2) {
throw new IllegalArgumentException("Unexpected input schema, schema should be an (INTEGER, NVARCHAR or VARCHAR)");
}
// Check that the input column types are expected
if (input.getColumnType(0) != java.sql.Types.INTEGER &&
(input.getColumnType(1) != java.sql.Types.VARCHAR && input.getColumnType(1) == java.sql.Types.NVARCHAR )) {
throw new IllegalArgumentException("Unexpected input schema, schema should be an (INTEGER, NVARCHAR or VARCHAR)");
}
}
private boolean check(String text) {
Matcher m = expr.matcher(text);
return m.find();
}
}
.jar-fájl fordítása és létrehozása
Csomagolja be az osztályokat és függőségeket egy .jar fájlba. A legtöbb Java IDE (például az Eclipse vagy az IntelliJ) támogatja a .jar fájlok generálását a projekt összeállításakor vagy fordításakor. Nevezze el a .jar fájlt regex.jar.
Ha nem Java IDE-t használ, manuálisan is létrehozhat egy .jar fájlt. További információ: Java-.jar-fájl létrehozása osztályfájlokból.
Megjegyzés:
Ez az oktatóanyag csomagokat használ. Az package pkg; osztály tetején lévő sor biztosítja, hogy a lefordított kód egy úgynevezett pkgalmappába legyen mentve. IDE használata esetén a program automatikusan ebbe a mappába menti a lefordított kódot. Ha a(z) javac használatával manuálisan fordítja le az osztályokat, a lefordított kódot a pkg könyvtárba kell helyeznie.
Külső nyelv létrehozása
Létre kell hoznia egy külső nyelvet az adatbázisban. A külső nyelv egy adatbázis-hatókörű objektum, ami azt jelenti, hogy minden olyan adatbázishoz létre kell hozni külső nyelveket, mint a Java.
Külső nyelv létrehozása Windows rendszeren
Ha Windowst használ, az alábbi lépéseket követve hozzon létre egy külső nyelvet a Java számára.
Hozzon létre egy .zip kiterjesztést tartalmazó fájlt.
A Windows SQL Server telepítésének részeként a Java-bővítményfájl
.zipa következő helyen van telepítve:[SQL Server install path]\MSSQL\Binn\java-lang-extension.zip. Ez a zip-fájl tartalmazza ajavaextension.dll.Hozzon létre egy külső nyelvű Java-t a .zip fájlból:
CREATE EXTERNAL LANGUAGE Java FROM (CONTENT = N'[SQL Server install path]\MSSQL\Binn\java-lang-extension.zip', FILE_NAME = 'javaextension.dll', ENVIRONMENT_VARIABLES = N'{"JRE_HOME":"<path to JRE>"}' ); GO
Külső nyelv létrehozása Linuxon
A telepítés részeként a bővítményfájl .tar.gz a következő elérési úton lesz mentve: /opt/mssql-extensibility/lib/java-lang-extension.tar.gz.
Külső nyelvű Java létrehozásához futtassa a következő T-SQL-utasítást Linuxon:
CREATE EXTERNAL LANGUAGE Java
FROM (CONTENT = N'/opt/mssql-extensibility/lib/java-lang-extension.tar.gz', file_name = 'javaextension.so',
ENVIRONMENT_VARIABLES = N'{"JRE_HOME":"<path to JRE>"}' );
GO
Külső nyelv végrehajtásának engedélyei
A Java-kód végrehajtásához a felhasználónak külső szkriptvégrehajtást kell biztosítani az adott nyelven.
További információért lásd CREATE EXTERNAL LANGUAGE.
Külső kódtárak létrehozása
A .jar fájlokhoz külső függvénytár létrehozásához használja a(z) CREATE EXTERNAL LIBRARY elemet. Az SQL Server hozzáfér a .jar fájlokhoz, és nem kell külön engedélyeket beállítania a classpath.
Ebben a mintában két külső kódtárat hoz létre. Egyet az SDK-hoz, egyet pedig a RegEx Java-kódhoz.
Az SDK jar-fájl
mssql-java-lang-extension.jaraz SQL Server 2019 (15.x) és újabb verzióinak részeként van telepítve Windows és Linux rendszeren is.Alapértelmezett telepítési útvonal Windows rendszeren:
<instance installation home directory>\MSSQL\Binn\mssql-java-lang-extension.jarAlapértelmezett telepítési útvonal Linuxon:
/opt/mssql/lib/mssql-java-lang-extension.jar
A kód nyílt forráskódú is, és megtalálható az SQL Server Language Extensions GitHub-adattárban. További információ: Microsoft Extensibility SDK for Java for SQL Server.
Hozzon létre egy külső kódtárat az SDK-hoz.
CREATE EXTERNAL LIBRARY sdk FROM (CONTENT = '<OS specific path from above>/mssql-java-lang-extension.jar') WITH (LANGUAGE = 'Java'); GOHozzon létre egy külső kódtárat a RegEx-kódhoz.
CREATE EXTERNAL LIBRARY regex FROM (CONTENT = '<path>/regex.jar') WITH (LANGUAGE = 'Java'); GO
Engedélyek beállítása
Megjegyzés:
Hagyja ki ezt a lépést, ha az előző lépésben külső kódtárakat használ. A javasolt módszer egy külső tár létrehozása a .jar fájlból.
Ha nem szeretne külső kódtárakat használni, be kell állítania a szükséges engedélyeket. A szkript végrehajtása csak akkor sikeres, ha a folyamatidentitások hozzáférnek a kódhoz. Az engedélyek beállításáról a telepítési útmutatóban talál további információt.
Linux rendszeren
Adjon olvasási/végrehajtási engedélyeket a classpathon a mssql_satellite felhasználó számára.
Windows rendszeren
Adjon "Olvasási és végrehajtási" engedélyeket az SQLRUserGroupnak és az Összes alkalmazáscsomag SID-jének a lefordított Java-kódot tartalmazó mappában.
A teljes fának rendelkeznie kell engedélyekkel a gyökér szülőtől az utolsó almappáig.
- Kattintson a jobb gombbal a mappára (például ) és
C:\myJavaCodeválassza a Tulajdonságok>biztonsága lehetőséget. - Válassza a Szerkesztés lehetőséget.
- Válassza a Hozzáadás lehetőséget.
- Felhasználók , számítógépek, szolgáltatásfiókok vagy csoportok kiválasztásakor:
- Válassza az Objektumtípusok lehetőséget , és győződjön meg arról , hogy a beépített biztonsági alapelvek és csoportok ki vannak választva.
- Válassza a Helyek lehetőséget a helyi számítógép nevének kiválasztásához a lista tetején.
- Írja be az SQLRUserGroup nevet, ellenőrizze a nevet, és kattintson az OK gombra a csoport hozzáadásához.
- Írja be a(z) ÖSSZES ALKALMAZÁSCSOMAG elemet, ellenőrizze a nevet, majd a hozzáadáshoz kattintson az OK gombra. Ha a név nem oldódik fel, térjen vissza a Locations lépéshez. A SID a gép helyi azonosítója.
Győződjön meg arról, hogy mindkét biztonsági identitás olvasási és végrehajtási engedélyekkel rendelkezik a mappán és az pkg almappán.
A Java-osztály meghívása
Hozzon létre egy tárolt eljárást, amely meghívja sp_execute_external_script a Java-kódot az SQL Serverről. A script paraméterben adja meg, hogy melyik package.class-t szeretné meghívni. Az alábbi kódban az osztály egy hívott pkg csomaghoz és egy osztályfájlhoz RegexSample.javatartozik.
Megjegyzés:
A kód nem határozza meg, hogy melyik metódust kell meghívni. Alapértelmezés szerint meghívják a execute metódust. Ez azt jelenti, hogy követnie kell az SDK-felületet, és végre kell hajtania egy végrehajtási metódust a Java-osztályban, ha meg szeretné hívni az osztályt az SQL Serverről.
A tárolt eljárás egy bemeneti lekérdezést (bemeneti adatkészletet) és egy reguláris kifejezést használ, és visszaadja azokat a sorokat, amelyek teljesítették az adott reguláris kifejezést. Egy reguláris kifejezést [Jj]ava használ, amely ellenőrzi, hogy egy szöveg tartalmazza-e a Java vagy java szót.
CREATE OR ALTER PROCEDURE [dbo].[java_regex] (
@expr NVARCHAR (200),
@query NVARCHAR (400)
)
AS
BEGIN
--Call the Java program by giving the package.className in @script
--The method invoked in the Java code is always the "execute" method
EXECUTE sp_execute_external_script
@language = N'Java',
@script = N'pkg.RegexSample',
@input_data_1 = @query,
@params = N'@regexExpr nvarchar(200)',
@regexExpr = @expr
WITH RESULT SETS
(
(ID INT, TEXT NVARCHAR (100))
);
END
GO
--Now execute the above stored procedure and provide the regular expression and an input query
EXECUTE [dbo].[java_regex] N'[Jj]ava', N'SELECT id, text FROM testdata';
GO
Results
A hívás végrehajtása után egy két sort tartalmazó eredményhalmazt kell kapnia.
Ha hibaüzenet jelenik meg
Az osztályok lefordításakor az
pkgalmappának tartalmaznia kell mind a három osztály lefordított kódját.Ha nem használ külső függvénytárakat, ellenőrizze a jogosultságokat minden mappán, a
rootmappától apkgalmappáig, hogy a külső folyamatot futtató biztonsági azonosítók rendelkezzenek a kód olvasásához és végrehajtásához szükséges engedélyekkel.