In my previous comment, there was an error in the code which was causing the issue.
Removing the surrounding quotes from from_unixtime()'s return value solved the issue, and so UDFs _do work_ from within DELETEs and INSERTs! Yay!
<?php
// SQLite UDF
// Mimic MySQL FROM_UNIXTIME
function from_unixtime($unixtime)
{
return date('Y-m-d H:i:s', $unixtime); // no surrouding quotes
}
?>
sqlite_create_function
SQLiteDatabase->createFunction
(PHP 5, PECL pdo_sqlite:0.2-0.3 sqlite:1.0-1.0.3)
sqlite_create_function -- SQLiteDatabase->createFunction — SQLステートメントで使用するために"通常の"ユーザ定義関数を登録する
説明
オブジェクト指向言語型スタイル (メソッド):
sqlite_create_function() により、SQLiteにPHP関数 をUDF (ユーザ定義関数)として登録することが可能で す。この関数は、SQLステートメントの中からコールできます。
UDFは、SELECTおよびUPDATEステートメント、そして、トリガーの中のよう に関数をコールできる全てのSQLステートメントで使用可能です。
パラメータ
- dbhandle
-
SQLite データベースリソース。手続きに従って、 sqlite_open() から返されます。 このパラメータは、 オブジェクト指向言語型メソッドを使用する場合は不要です。
- function_name
-
SQL ステートメントで使用する関数名
- callback
-
定義された SQL 関数を処理するためのコールバック関数
注意: コールバック関数は SQLite で有効な型 (例えば スカラー型) を返す必要があります
- num_args
-
コールバック関数が規定の引数の数を受け入れるかどうかを決定するため SQLite パーサに渡すヒント
注意: (MySQL のような)他のデータベースエクステンションとの互換性のため、 2 種類の構文がサポートされています。 推奨されるのは最初の構文で、dbhandle パラメータを 関数の最初のパラメータとするものです。
返り値
値を返しません。
例
例1 sqlite_create_function() の例
<?php
function md5_and_reverse($string)
{
return strrev(md5($string));
}
if ($dbhandle = sqlite_open('mysqlitedb', 0666, $sqliteerror)) {
sqlite_create_function($dbhandle, 'md5rev', 'md5_and_reverse', 1);
$sql = 'SELECT md5rev(filename) FROM files';
$rows = sqlite_array_query($dbhandle, $sql);
} else {
echo 'Error opening sqlite db: ' . $sqliteerror;
exit;
}
?>
この例では、文字列のMD5サムを計算し、順番を反転する関数が記述されています。 このSQLステートメントが実行された場合、 関数により変換されたファイル名の値を返します。 $rows により返されるデータには、 処理結果が含まれています。
この技術の美しいところは、データのクエリーを実行した後で foreach() ループにより結果を処理する必要がないことです。
PHP は、データベースが最初にオープンされる際に php という名前の特別な関数を登録します。 このphp関数は、事前に登録することなしにあらゆるPHP関数をコールする ために使用可能です。
例2 PHP 関数の使用例
<?php
$rows = sqlite_array_query($dbhandle, "SELECT php('md5', filename) from files");
?>
この例は、データベースの各 filename カラムにつ いて md5() をコールし、その結果を $rows に返します。
注意: 性能上の理由から、PHPはUDFとの間で送受信されるバイナリデータを自動 的にエンコード/デコードしません。この方法でバイナリデータを処理す る必要がある場合、パラメータを手動でエンコード/デコードし、 値を返すようにする必要があります。 詳細については、sqlite_udf_encode_binary() およびsqlite_udf_decode_binary()を参照して下さ い。
適用するアプリケーションの主要な要求が高い性能でない限り、バイナリ データの処理を行うためにUDFを使用することは推奨されません。
SQLiteのネーティブSQL関数をオーバーライドするために sqlite_create_function()および sqlite_create_aggregate()も使用可能です。
sqlite_create_function
20-May-2005 10:27
20-May-2005 09:44
It appears that UDFs created by sqlite_create_function() do not work properly within INSERT or DELETE statements.
A simplified INSERT example:
<?php
// SQLite UDF
// Mimic MySQL FROM_UNIXTIME function
function from_unixtime($unixtime)
{
return "'".date('Y-m-d H:i:s', $unixtime)."'";
}
// -----------------------------------------------------------
// Open the database and create the UDF
$handle = sqlite_open('db.sqlite', 0666);
sqlite_create_function($handle, 'FROM_UNIXTIME', 'from_unixtime', 1);
// Insert a row
$sql = "
INSERT INTO table (name, timestamp)
VALUES ('Foo', FROM_UNIXTIME(".time().");
";
$result = sqlite_exec($handle, $sql);
// Retrieve the row
$sql = "SELECT * FROM table";
$result = sqlite_unbuffered_query($handle, $sql)
$row = sqlite_fetch_all($result, SQLITE_ASSOC);
// Dump
print_r($row);
?>
This will show:
Array
(
[0] => Array
(
[name] => 'Foo'
[timestamp] => -1
)
)
The expected result for timestamp would be something like '2005-05-20 10:00:00'
28-Dec-2004 01:52
The function can be a method of a class:
<?php
class sqlite_function {
function md5($value)
{
return md5($value);
}
}
$dbhandle = sqlite_open('SQLiteDB');
sqlite_create_function($dbhandle, 'md5', array('sqlite_function', 'md5'), 1);
// From now on, you can use md5 function inside your SQL statements
?>
It works fine :)
