int sqlite3_create_function( sqlite3 *db, const char *zFunctionName, int nArg, int eTextRep, void *pApp, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); int sqlite3_create_function16( sqlite3 *db, const void *zFunctionName, int nArg, int eTextRep, void *pApp, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); int sqlite3_create_function_v2( sqlite3 *db, const char *zFunctionName, int nArg, int eTextRep, void *pApp, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*), void(*xDestroy)(void*) ); int sqlite3_create_window_function( sqlite3 *db, const char *zFunctionName, int nArg, int eTextRep, void *pApp, void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*), void (*xValue)(sqlite3_context*), void (*xInverse)(sqlite3_context*,int,sqlite3_value**), void(*xDestroy)(void*) );
这些函数(统称为“函数创建例程”)用于添加 SQL 函数或聚合函数,或重新定义现有 SQL 函数或聚合函数的行为。三个“sqlite3_create_function*”例程之间的唯一区别是第二个参数(要创建的函数的名称)所期望的文本编码以及应用程序数据指针是否存在析构回调函数。函数 sqlite3_create_window_function() 类似,但允许用户提供 聚合窗口函数所需的额外回调函数。
第一个参数是 数据库连接,SQL 函数将添加到该连接中。如果应用程序使用多个数据库连接,则必须分别将应用程序定义的 SQL 函数添加到每个数据库连接中。
第二个参数是要创建或重新定义的 SQL 函数的名称。名称的长度在 UTF-8 表示中(不包括零终止符)限制为 255 个字节。请注意,名称长度限制以 UTF-8 字节为单位,而不是字符或 UTF-16 字节。尝试创建名称更长的函数将导致返回 SQLITE_MISUSE。
第三个参数 (nArg) 是 SQL 函数或聚合函数接受的参数数量。如果此参数为 -1,则 SQL 函数或聚合函数可以接受 0 到由 sqlite3_limit(SQLITE_LIMIT_FUNCTION_ARG) 设置的限制之间的任意数量的参数。如果第三个参数小于 -1 或大于 127,则行为未定义。
第四个参数 eTextRep 指定此 SQL 函数对其参数首选的 文本编码。如果函数实现对输入调用 sqlite3_value_text16le(),则应用程序应将此参数设置为 SQLITE_UTF16LE;如果实现对输入调用 sqlite3_value_text16be(),则应设置为 SQLITE_UTF16BE;如果使用 sqlite3_value_text16(),则应设置为 SQLITE_UTF16;否则应设置为 SQLITE_UTF8。可以使用不同的首选文本编码和每个编码的不同实现多次注册相同的 SQL 函数。当存在同一函数的多个实现时,SQLite 将选择涉及最少数据转换的实现。
第四个参数可以选择与 SQLITE_DETERMINISTIC 进行按位或运算,以表明在单个 SQL 语句中,给定相同的输入,函数将始终返回相同的结果。大多数 SQL 函数都是确定性的。内置的 random() SQL 函数就是一个非确定性函数的示例。SQLite 查询规划器能够对确定性函数执行其他优化,因此建议在可能的情况下使用 SQLITE_DETERMINISTIC 标志。
第四个参数还可以选择包含 SQLITE_DIRECTONLY 标志,如果存在此标志,则会阻止从视图、触发器、CHECK 约束、生成列表达式、索引表达式或部分索引的 WHERE 子句中调用该函数。
为了获得最佳安全性,建议对于所有不需要在触发器、视图、CHECK 约束或数据库模式的其他元素中使用的应用程序定义的 SQL 函数使用 SQLITE_DIRECTONLY 标志。对于具有副作用或揭示内部应用程序状态的 SQL 函数,尤其建议使用此标志。如果没有此标志,攻击者可能会修改数据库文件的模式以包含由攻击者选择的参数的函数调用,然后在打开和读取数据库文件时,应用程序将执行这些调用。
第五个参数是一个任意指针。函数的实现可以使用 sqlite3_user_data() 访问此指针。
传递给三个“sqlite3_create_function*”函数的第六、第七和第八个参数 xFunc、xStep 和 xFinal 是指向实现 SQL 函数或聚合函数的 C 语言函数的指针。标量 SQL 函数只需要实现 xFunc 回调函数;必须将 NULL 指针作为 xStep 和 xFinal 参数传递。聚合 SQL 函数需要实现 xStep 和 xFinal,并且必须为 xFunc 传递 NULL 指针。要删除现有的 SQL 函数或聚合函数,请为所有三个函数回调传递 NULL 指针。
传递给 sqlite3_create_window_function 的第六、第七、第八和第九个参数(xStep、xFinal、xValue 和 xInverse)是指向实现新函数的 C 语言回调函数的指针。xStep 和 xFinal 都必须为非 NULL。xValue 和 xInverse 可以都为 NULL,在这种情况下将创建一个常规聚合函数;或者都必须为非 NULL,在这种情况下,新函数可以用作聚合函数或聚合窗口函数。有关聚合窗口函数实现的更多详细信息,请点击此处。
如果 sqlite3_create_function_v2() 或 sqlite3_create_window_function() 的最后一个参数不是 NULL,则它是应用程序数据指针的析构函数。当函数被删除时(通过重载或数据库连接关闭时),将调用析构函数。如果对 sqlite3_create_function_v2() 的调用失败,也会调用析构函数。当调用析构函数回调时,它将传递一个参数,该参数是作为 sqlite3_create_function_v2() 的第五个参数的应用程序数据指针的副本。
允许注册同一函数的多个实现,这些实现具有相同的名称,但参数数量或首选文本编码不同。SQLite 将使用最符合 SQL 函数使用方式的实现。具有非负 nArg 参数的函数实现比具有负 nArg 参数的函数实现更匹配。首选文本编码与数据库编码匹配的函数比编码不同的函数更匹配。UTF16le 和 UTF16be 之间编码差异的函数比 UTF8 和 UTF16 之间编码差异的函数更匹配。
内置函数可以通过新的应用程序定义的函数进行重载。
应用程序定义的函数允许调用其他 SQLite 接口。但是,此类调用不得关闭数据库连接,也不得完成或重置正在运行的准备好的语句。