SQLite C 接口

创建或重新定义 SQL 函数

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 标志,如果存在,该标志将阻止从 VIEW、TRIGGER、CHECK 约束、生成的列表达式、索引表达式或部分索引的 WHERE 子句中调用该函数。

为获得最佳安全性,建议将SQLITE_DIRECTONLY标志用于不需要在触发器、视图、CHECK 约束或数据库模式的其他元素内部使用的所有应用程序定义的 SQL 函数。对于具有副作用或揭示内部应用程序状态的 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 接口。但是,此类调用不得关闭数据库连接,也不得完成或重置运行函数的准备语句。

另请参阅 对象常量函数的列表。