-
See Also
- ExternalEvaluate
- StartExternalSession
- DatabaseReference
-
- External Evaluation Systems
- SQL
- Related Guides
- Tech Notes
"SQL-JDBC" (External Evaluation System)
Listing of Supported Databases »Details
- To configure a database for use with JDBC in ExternalEvaluate, see details for each specific database in the listing of supported databases.
ExternalEvaluate Usage
- ExternalEvaluate["SQL-JDBC",code] executes a string of SQL in a database connection and returns the result as a Wolfram Language expression.
- ExternalEvaluate["SQL-JDBC"form,code] executes the SQL string and returns the result in the specified form. Possible specifications for form are "Dataset", "Rows", "NamedRows", "Columns" and "NamedColumns".
- The possible settings for Evaluator in ExternalEvaluate[{"SQL-JDBC","Evaluator"Evaluator},…] include:
-
"path"or File["path"] path to an SQLite database URL["url"] a connection specified in the form "backend://user:password@host:port/name" DatabaseReference[…] an SQL database connection SQLConnection[…] an SQL-JDBC database connection
Data Types
- SQL data types are mapped to appropriate Wolfram Language expressions.
- Dates and times are typically converted to DateObject and TimeObject.
- Binary data is converted to ByteArray.
Examples
open all close allBasic Examples (2)
Specify a reference to the demo database:
db = DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]]Evaluate a query in SQL and return the result:
ExternalEvaluate[{"SQL-JDBC", "Evaluator" -> db}, "SELECT * FROM offices"]To use SQL in an external language cell, you need to register a default database:
db = DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]]RegisterExternalEvaluator["SQL-JDBC", db]Type > and select SQL-JDBC from the drop-down menu to get an SQL-JDBC code cell:
Scope (5)
db = DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]]session = StartExternalSession[{"SQL-JDBC", "Evaluator" -> db}]Evaluate a query that is returning all tables:
ExternalEvaluate[session, "SELECT name FROM sqlite_master WHERE name NOT LIKE 'sqlite_%'"]Query a certain table using limit:
ExternalEvaluate[session, "SELECT * FROM offices limit 4"]Rename columns using AS statement:
ExternalEvaluate[session, "SELECT officeCode AS id, addressLine1 || ' - ' || addressLine2 AS address FROM offices"]DeleteObject[session]ExternalEvaluate also accepts DatabaseLink`SQLConnection:
Needs["DatabaseLink`"];db = SQLConnection[JDBC["SQLite", FindFile["ExampleData/ecommerce-database.sqlite"]]];ExternalEvaluate[db, "SELECT * FROM offices"]Any JDBC driver supported by DatabaseLink` can be used:
ExternalEvaluate[SQLConnection[JDBC["PostgreSQL", "localhost/template1"]], "SELECT * FROM generate_series(3, 6)"]By default, ExternalEvaluate returns data using Dataset:
db = DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]]ExternalEvaluate[{"SQL-JDBC", "Evaluator" -> db}, "SELECT officeCode AS pk, phone FROM offices"]"ReturnType" can be used to return data in a different form:
ExternalEvaluate[{"SQL-JDBC", "Evaluator" -> db, "ReturnType" -> "Rows"}, "SELECT officeCode AS pk, phone FROM offices"]ExternalEvaluate[{"SQL-JDBC", "Evaluator" -> db, "ReturnType" -> "NamedRows"}, "SELECT officeCode AS pk, phone FROM offices"]ExternalEvaluate[{"SQL-JDBC", "Evaluator" -> db, "ReturnType" -> "Columns"}, "SELECT officeCode AS pk, phone FROM offices"]ExternalEvaluate[{"SQL-JDBC", "Evaluator" -> db, "ReturnType" -> "NamedColumns"}, "SELECT officeCode AS pk, phone FROM offices"]Start a session to a local PostgreSQL database (to evaluate this input, you would need to have an appropriate PostgreSQL database instance running):
db = DatabaseReference[URL["postgres://localhost/template1"]]When supported, ExternalEvaluate will return Wolfram Language expressions instead of strings:
ExternalEvaluate[{"SQL-JDBC", "Evaluator" -> db}, "SELECT NOW() AS now, NOW()::date AS date, interval '1 day' AS interval, '1.23'::decimal AS decimal"]String templates can be used to insert Wolfram Language expressions into SQL code:
db = DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]];x = 3;
y = 2;The expression x^2+y^2 is evaluated in the Wolfram Language, and the result is converted and inserted into the SQL code string:
ExternalEvaluate[{"SQL-JDBC", "Evaluator" -> db}, "SELECT <* x^2 + y^2 *> AS value"]Manually provide arguments to the template by using an Association:
ExternalEvaluate[{"SQL-JDBC", "Evaluator" -> db}, <|
"Command" -> "SELECT city, addressLine1, country FROM offices WHERE country = `1`",
"TemplateArguments" -> {"USA"}
|>]ExternalEvaluate[{"SQL-JDBC", "Evaluator" -> db}, <|
"Command" -> "SELECT officeCode, city, addressLine1 FROM offices WHERE officeCode < `n`",
"TemplateArguments" -> <|"n" -> 4|>
|>]Parameters are automatically normalized according to the database back end that is currently in use. Expressions like Integer, ByteArray, String, DateObject and TimeObject can be used if the back end supports them:
ExternalEvaluate[{"SQL-JDBC", "Evaluator" -> DatabaseReference["postgresql://localhost/template1"]}, <|
"Command" -> "SELECT `` AS number, NOW() AS now",
"TemplateArguments" -> {1}
|>]Applications (2)
Operations that are doing side effects on the database typically return Null:
ExternalEvaluate[
{"SQL-JDBC", DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]]}, {
"CREATE TEMPORARY TABLE t(x INTEGER PRIMARY KEY ASC, y, z);",
"INSERT INTO t(x, y, z) VALUES (1, 2, 3)"
}]For some back ends, it is possible to insert data and specify a return value:
ExternalEvaluate[
{"SQL-JDBC", DatabaseReference["postgresql://localhost/template1"]}, {
"CREATE TEMPORARY TABLE test_data(
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL
)",
"INSERT INTO test_data(name) VALUES ('john') RETURNING(\"id\") as pk",
"SELECT id, name FROM test_data"
}]It is possible to keep a connection open in order to perform a rollback later. Start a new database connection:
session = StartExternalSession[{"SQL-JDBC", DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]]}]ExternalEvaluate[session, {
"CREATE TEMPORARY TABLE t(id SERIAL PRIMARY KEY, y INTEGER, z INTEGER)",
"INSERT INTO t(id, y, z) VALUES (1, 2, 3)",
"INSERT INTO t(id, y, z) VALUES (3, 4, 6)",
"INSERT INTO t(id, y, z) VALUES (4, 5, 6)"
}];ExternalEvaluate[session, "SELECT * from t"]Start a transaction block and delete some data:
ExternalEvaluate[session, "BEGIN"];ExternalEvaluate[session, "DELETE FROM t WHERE id=4"];Check that the row has been deleted during the transaction:
ExternalEvaluate[session, "SELECT * from t"]Perform the rollback and run the query again:
ExternalEvaluate[session, "ROLLBACK"];ExternalEvaluate[session, "SELECT * from t"]DeleteObject[session]Possible Issues (2)
Usually a database returns dates using the server time zone:
db = DatabaseReference[URL["postgres://localhost/template1"]];ExternalEvaluate[{"SQL-JDBC", "Evaluator" -> db, "ReturnType" -> "Rows"}, "SELECT NOW()"]Change the query to return a column at a particular time zone:
ExternalEvaluate[{"SQL-JDBC", "Evaluator" -> db, "ReturnType" -> "Rows"}, "SELECT NOW() at time zone 'UTC'"]Or "SessionEpilog" can be used to set a default time zone:
ExternalEvaluate[<|"Evaluator" -> db, "System" -> "SQL-JDBC", "SessionProlog" -> "SET TIME ZONE 'UTC'", "ReturnType" -> "Rows"|>, "SELECT NOW()"]ExternalEvaluate will always maintain a new connection internally, even if an already opened connection is provided:
Needs["DatabaseLink`"];conn = OpenSQLConnection[JDBC["SQLite", FindFile["ExampleData/ecommerce-database.sqlite"]]]SQLConnections[]StartExternalSession will create a JDBC connection:
session = StartExternalSession[conn]SQLConnections[]After deleting the ExternalSessionObject, the connection will be closed automatically:
DeleteObject[session];SQLConnections[]Close all pending connections:
DatabaseLink`CloseSQLConnection[DatabaseLink`SQLConnections[]]Tech Notes
Related Guides
History
Introduced in 2020 (12.2)