-
参见
- 函 数
- ExternalEvaluate
- StartExternalSession
- DatabaseReference
-
- 数据库连接
- SQLite
- MicrosoftSQL
- MySQL
- Oracle
- PostgreSQL
-
- 外部计算系统
- SQL-JDBC
- 相关指南
"SQL" (外部计算系统)
支持的数据库列表 »更多信息
- 想获取使用 ExternalEvaluate 配置数据库的说明,请参阅支持的数据库列表中每个特定数据库的详细信息.
ExternalEvaluate 用法
- ExternalEvaluate["SQL",code] 在数据库连接中执行 SQL 字符串并以 Wolfram 语言表达式的形式返回结果.
- ExternalEvaluate["SQL"returntype,code] 执行 SQL 字符串并以指定 returntype 的形式返回结果. returntype 的可能规格包括 "Dataset"、"Tabular"、"Rows"、"NamedRows"、"Columns" 和 "NamedColumns".
- ExternalEvaluate[DatabaseReference[ref],code] 等价于 ExternalEvaluate[{"SQL","Evaluator"DatabaseReference[ref]},code].
- ExternalEvaluate[{"SQL","Evaluator"target},…] 中 target 的可能设置包括:
-
"path"or File["path"] 访问 SQLite 数据库的路径 URL["url"] 以形式 "backend://user:password@host:port/name" 指定的连接 DatabaseReference[…] SQL 数据库连接 SQLConnection[…] SQL-JDBC 数据库连接
数据类型
- SQL 数据类型映射到正确的 Wolfram 语言表达式.
- 日期和时间通常转换为 DateObject 和 TimeObject.
- 二进制数据转换为 ByteArray.
- 每个支持的数据库都有一个完整的支持数据类型列表:SQLite,PostgreSQL,MySQL,MicrosoftSQL 和 Oracle.
范例
打开所有单元 关闭所有单元基本范例 (3)
db = DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]]ExternalEvaluate[db, "SELECT * FROM offices"]若想要在外部语言单元格中使用 SQL,则需要注册一个默认数据库:
db = DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]]RegisterExternalEvaluator["SQL", db]类型 > 并在下拉菜单中选择 SQL 可得到一个 SQL 代码单元格:
用 File 封装运行文件中的代码:
path = Export[CreateFile[], "select 21 as AGE", "String"]ExternalEvaluate[DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]], File[path]
]用 CloudDeploy 部署代码,从 CloudObject 直接运行代码:
cobj = CloudExport["select 21 as AGE", "String"]ExternalEvaluate[DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]], cobj]用 URL 封装直接运行线上的代码:
query = URL["https://exampledata.wolfram.com/script.sql"]ExternalEvaluate[DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]], query
]范围 (20)
db = DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]]session = StartExternalSession[db]ExternalEvaluate[session, "SELECT name FROM sqlite_master WHERE name NOT LIKE 'sqlite_%'"]ExternalEvaluate[session, "SELECT * FROM offices limit 4"]ExternalEvaluate[session, "SELECT officeCode AS id, addressLine1 || ' - ' || addressLine2 AS address FROM offices"]DeleteObject[session]默认情况下, ExternalEvaluate 使用 Dataset 返回数据:
db = DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]]ExternalEvaluate[db, "SELECT officeCode AS pk, phone FROM offices"]ExternalEvaluate[db -> "Rows", "SELECT officeCode AS pk, phone FROM offices"]ExternalEvaluate[db -> "NamedRows", "SELECT officeCode AS pk, phone FROM offices"]ExternalEvaluate[db -> "Columns", "SELECT officeCode AS pk, phone FROM offices"]ExternalEvaluate[db -> "NamedColumns", "SELECT officeCode AS pk, phone FROM offices"]ExternalEvaluate[db -> "Tabular", "SELECT officeCode AS pk, phone FROM offices"]使用 "Columns" 时,如果可能的话数字数据会以打包数组的形式呈现:
data = ExternalEvaluate[db -> "Columns", "SELECT employeeNumber AS id FROM employees limit 5"]Developer`PackedArrayQ[First[data]]开启本地 PostgreSQL 数据库的会话(要执行这个输入,你需要有一个正常运行的 PostgreSQL 数据库实例):
db = DatabaseReference[URL["postgres://localhost/template1"]]在支持的情况下,ExternalEvaluate 会返回 Wolfram 语言表达式而非字符串:
ExternalEvaluate[db, "SELECT NOW() AS now, NOW()::date AS date, interval '1 day' AS interval, '1.23'::decimal AS decimal"]会根据当前使用的数据库后端自动对参数进行规范化. 如果后端支持,可使用如 Integer、ByteArray、String、DateObject 和 TimeObject 这样的表达式:
ExternalEvaluate[DatabaseReference["postgresql://localhost/template1"], <|
"Command" -> "SELECT `` AS kernel_now, NOW() AS db_now",
"TemplateArguments" -> {Now}
|>]字符串模板可用于将 Wolfram 语言表达式插入 SQL 代码:
db = DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]];x = 3;
y = 2;表达式 x^2+y^2 在 Wolfram 语言中计算,得到的结果在被转换后插入到 SQL 代码字符串中:
ExternalEvaluate[db, "SELECT <* x^2 + y^2 *> AS value"]使用 Association 可手动向模板提供参数:
ExternalEvaluate[db, <|
"Command" -> "SELECT city, addressLine1, country FROM offices WHERE country = `1`",
"TemplateArguments" -> {"USA"}
|>]ExternalEvaluate[db, <|
"Command" -> "SELECT officeCode, city, addressLine1 FROM offices WHERE officeCode < `n`",
"TemplateArguments" -> <|"n" -> 4|>
|>]会话的选项 (8)
"ReturnType" (3)
对于 SQL,默认的返回类型为 "Dataset":
db = DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]]ExternalEvaluate[db, "SELECT 2"] === ExternalEvaluate[{db, "ReturnType" -> "Dataset"}, "SELECT 2"]ExternalEvaluate[db, "select officeCode as pk, phone from offices"]ExternalEvaluate[{db, "ReturnType" -> "Rows"}, "select officeCode as pk, phone from offices"]ExternalEvaluate[{db, "ReturnType" -> "NamedRows"}, "select officeCode as pk, phone from offices"]ExternalEvaluate[{db, "ReturnType" -> "Columns"}, "select officeCode as pk, phone from offices"]ExternalEvaluate[{db, "ReturnType" -> "NamedColumns"}, "select officeCode as pk, phone from offices"]无论是何种 "ReturnType",整数、实数和字符串等基本类型都会自动转换:
ExternalEvaluate[DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]], "SELECT 'John' as name, 22 as age, 78.3 as weight"
]可用 connectionreturntype 作为指定 "ReturnType" 的便捷方法:
db = DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]];ExternalEvaluate[db -> "NamedColumns", "select officeCode as pk, phone from offices"]"Evaluator" (1)
ExternalEvaluate[{"SQL", "Evaluator" -> FindFile["ExampleData/ecommerce-database.sqlite"]}, "select 2+2 as result"
]使用字符串或 File 封装时,将打开一个 SQLite 连接:
ExternalEvaluate[{"SQL", "Evaluator" -> File[FindFile["ExampleData/ecommerce-database.sqlite"]]}, "select 2+2 as result"
]也可以用 URL 封装指定 "Evaluator":
ExternalEvaluate[{"SQL", "Evaluator" -> URL["postgres://postgres:postgres@localhost/template1"]}, "SELECT NOW() as now, NOW()::date as date, interval '1 day' as interval, '1.23'::decimal as decimal"
]ExternalEvaluate[{"SQL", "Evaluator" -> DatabaseReference[<|"Backend" -> "postgres", "Name" -> "template1", "Port" -> None, "Host" -> "localhost", "Username" -> "postgres", "Password" -> "postgres"|>]}, "SELECT NOW() as now, NOW()::date as date, interval '1 day' as interval, '1.23'::decimal as decimal"
]"SessionProlog" (1)
"SessionEpilog" (1)
用 "SessionEpilog" 在会话结束时执行一些小操作:
makeLoggerCommand[s_String] := <|"Command" -> "INSERT INTO db_access(unixtime, type) VALUES (``, ``)", "TemplateArguments" :> {UnixTime[], s}|>connection = {
"SQL",
"Evaluator" -> FindFile["ExampleData/ecommerce-database.sqlite"],
"SessionProlog" -> "CREATE TABLE IF NOT EXISTS db_access (id INTEGER PRIMARY KEY AUTOINCREMENT, unixtime INTEGER, type STRING);",
"SessionEpilog" -> makeLoggerCommand["SessionEpilog"]
};ExternalEvaluate[connection, "SELECT 'hello' as msg"]ExternalEvaluate[connection, "SELECT * from db_access where type == 'SessionEpilog'"]"Prolog" (1)
makeLoggerCommand[s_String] := <|"Command" -> "INSERT INTO db_access(unixtime, type) VALUES (``, ``)", "TemplateArguments" :> {UnixTime[], s}|>connection = {
"SQL",
"Evaluator" -> FindFile["ExampleData/ecommerce-database.sqlite"],
"SessionProlog" -> "CREATE TABLE IF NOT EXISTS db_access (id INTEGER PRIMARY KEY AUTOINCREMENT, unixtime INTEGER, type STRING);",
"Prolog" -> makeLoggerCommand["Prolog"]
};ExternalEvaluate[connection, "SELECT * from db_access where type == 'Prolog'"]"Epilog" (1)
makeLoggerCommand[s_String] := <|"Command" -> "INSERT INTO db_access(unixtime, type) VALUES (``, ``)", "TemplateArguments" :> {UnixTime[], s}|>connection = {
"SQL",
"Evaluator" -> FindFile["ExampleData/ecommerce-database.sqlite"],
"SessionProlog" -> "CREATE TABLE IF NOT EXISTS db_access (id INTEGER PRIMARY KEY AUTOINCREMENT, unixtime INTEGER, type STRING);",
"Epilog" -> makeLoggerCommand["Epilog"]
};ExternalEvaluate[connection, "select 'hello' as msg"]ExternalEvaluate[connection, "SELECT * from db_access where type == 'Epilog'"]指令的选项 (8)
"Command" (4)
ExternalEvaluate["SQL", "SELECT 21 as age"]ExternalEvaluate["SQL", <|"Command" -> "SELECT 21 as age"|>]用 File 封装运行文件中的代码:
path = Export[CreateFile[], "select 21 as age", "Text"]ExternalEvaluate["SQL", <|"Command" -> File[path]|>]大多数情况下可以省去 Association:
ExternalEvaluate["SQL", File[path]]用 URL 封装直接运行线上的代码:
query = URL["https://exampledata.wolfram.com/script.sql"]ExternalEvaluate["SQL", <|"Command" -> query|>]大多数情况下可以省去 Association:
ExternalEvaluate["SQL", query]将代码放入 CloudObject:
cloudObj = CloudExport["select 21 as age", "Text", CloudObject["hello-world-sql"]]ExternalEvaluate["SQL", <|"Command" -> cloudObj|>]大多数情况下可以省去 Association:
ExternalEvaluate["SQL", cloudObj]"ReturnType" (1)
默认情况下,使用会话创建期间指定的 "ReturnType" 执行该指令:
ExternalEvaluate[
{"SQL", "ReturnType" -> "Rows"},
"select 21 as age, 'john' as name"
]在指令中指定 "ReturnType" 将覆盖会话的 "ReturnType":
ExternalEvaluate[
{"SQL", "ReturnType" -> "Rows"},
{
<|"Command" -> "select 21 as age, 'john' as name"|>,
<|"Command" -> "select 21 as age, 'john' as name", "ReturnType" -> "NamedColumns"|>
}
]用 "Tabular" 返回 Tabular 对象:
ExternalEvaluate[
{"SQL", "ReturnType" -> "Tabular"},
"select 21 as age, 'john' as name"
]"TemplateArguments" (3)
运行指令时,可内嵌 TemplateExpression:
x = RandomReal[]
ExternalEvaluate["SQL", "SELECT <* x *> as real"]可用 "TemplateArguments" 填充 TemplateSlot:
ExternalEvaluate[
"SQL",
<|"Command" -> "SELECT `1` as real, `2` as integer", "TemplateArguments" -> {RandomReal[], RandomInteger[]}|>
]ExternalEvaluate[
"SQL",
<|"Command" -> "SELECT `` as real", "TemplateArguments" -> RandomReal[]|>
]可以命名模板插槽并使用 Association 将命名参数传递给模板:
ExternalEvaluate[
"SQL",
<|"Command" -> "SELECT `r` as real, `int` as integer", "TemplateArguments" -> <|"r" -> RandomReal[], "int" -> RandomInteger[]|>|>
]应用 (2)
DatabaseReference 可以表示一个内存 SQLite 数据库:
ExternalEvaluate[
DatabaseReference[<|"Backend" -> "sqlite"|>], "SELECT time('now') as now, sqlite_version() AS version"
]所有在内存会话期间进行的操作会在 ExternalEvaluate 调用的最后丢失:
ExternalEvaluate[
DatabaseReference[<|"Backend" -> "sqlite"|>], {
"CREATE TABLE t(x INTEGER PRIMARY KEY ASC, y, z);",
"INSERT INTO t(x, y, z) VALUES (1, 2, 3)",
"INSERT INTO t(x, y, z) VALUES (4, 5, 6)",
"SELECT * FROM t"
}]ExternalEvaluate[
DatabaseReference[<|"Backend" -> "sqlite"|>],
"SELECT * FROM t"
]数据库中有副效应的操作通常返回 Null:
ExternalEvaluate[
DatabaseReference[<|"Backend" -> "sqlite"|>], {
"CREATE TEMPORARY TABLE t(x INTEGER PRIMARY KEY ASC, y, z);",
"INSERT INTO t(x, y, z) VALUES (1, 2, 3)"
}]ExternalEvaluate[
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"
}]可能存在的问题 (1)
db = DatabaseReference[URL["postgres://localhost/template1"]];ExternalEvaluate[db -> "Rows", "SELECT NOW()"]ExternalEvaluate[db -> "Rows", "SELECT NOW() AT TIME ZONE 'UTC'"]ExternalEvaluate[<|"Evaluator" -> db, "System" -> "SQL", "SessionProlog" -> "SET TIME ZONE 'UTC'", "ReturnType" -> "Rows"|>, "SELECT NOW()"]参见
ExternalEvaluate StartExternalSession DatabaseReference
数据库连接: SQLite MicrosoftSQL MySQL Oracle PostgreSQL
外部计算系统: SQL-JDBC
相关指南
-
▪
- 外部已诠释的语言接口 ▪
- 外部语言接口 ▪
- 数据库连接
历史
2020年引入 (12.2)