Fungsi yang ditentukan pengguna

Sebagian besar database memiliki dialek prosedural SQL yang dapat Anda gunakan untuk menentukan fungsi Anda sendiri. Namun, SQLite berjalan dalam satu proses dengan aplikasi Anda. Alih-alih harus mempelajari dialek baru SQL, Anda hanya dapat menggunakan bahasa pemrograman aplikasi Anda.

Fungsi skalar

Fungsi skalar mengembalikan nilai skalar tunggal untuk setiap baris dalam kueri. Tentukan fungsi skalar baru dan ambil alih fungsi bawaan menggunakan CreateFunction.

Lihat Jenis data untuk daftar parameter yang didukung dan jenis pengembalian untuk func argumen.

Menentukan state argumen akan meneruskan nilai tersebut ke dalam setiap pemanggilan fungsi. Gunakan ini untuk menghindari penutupan.

Tentukan isDeterministic apakah fungsi Anda deterministik untuk memungkinkan SQLite menggunakan pengoptimalan tambahan saat mengkompilasi kueri.

Contoh berikut menunjukkan cara menambahkan fungsi skalar untuk menghitung radius silinder.

connection.CreateFunction(
    "volume",
    (double radius, double height)
        => Math.PI * Math.Pow(radius, 2) * height);

var command = connection.CreateCommand();
command.CommandText =
@"
    SELECT name,
           volume(radius, height) AS volume
    FROM cylinder
    ORDER BY volume DESC
";

Para Operator

Operator SQLite berikut diimplementasikan oleh fungsi skalar yang sesuai. Menentukan fungsi skalar ini di aplikasi Anda akan mengambil alih perilaku operator ini.

Pengoperasi Fungsi
X GLOB Y glob(Y, X)
X SEPERTI Y seperti(Y, X)
X SEPERTI Y MENGGUNAKAN ESCAPE Z seperti(Y, X, Z)
X SESUAI DENGAN Y cocokkan(Y, X)
X REGEXP Y regexp(Y, X)

Contoh berikut menunjukkan cara menentukan fungsi regexp untuk mengaktifkan operator yang sesuai. SQLite tidak menyertakan implementasi default fungsi regexp.

connection.CreateFunction(
    "regexp",
    (string pattern, string input)
        => Regex.IsMatch(input, pattern));

var command = connection.CreateCommand();
command.CommandText =
@"
    SELECT count()
    FROM user
    WHERE bio REGEXP '\w\. {2,}\w'
";
var count = command.ExecuteScalar();

Fungsi agregat

Fungsi agregat mengembalikan nilai agregat tunggal untuk semua baris dalam kueri. Tentukan dan ambil alih fungsi agregat menggunakan CreateAggregate.

Argumen seed menentukan status awal konteks. Gunakan ini untuk menghindari penutupan juga.

Argumen func dipanggil sekali per baris. Gunakan konteks untuk mengakumulasi hasil akhir. Mengembalikan konteks. Pola ini memungkinkan konteks menjadi jenis nilai atau tidak dapat diubah.

Jika resultSelector tidak ditentukan, status akhir konteks digunakan sebagai hasilnya. Ini dapat menyederhanakan definisi fungsi seperti jumlah dan hitungan yang hanya perlu menaikkan angka setiap baris dan mengembalikannya.

Tentukan resultSelector untuk menghitung hasil akhir dari konteks setelah melakukan iterasi melalui semua baris.

Lihat Jenis data untuk daftar jenis parameter yang didukung untuk func argumen dan jenis pengembalian untuk resultSelector.

Jika fungsi Anda deterministik, tentukan isDeterministic untuk mengizinkan SQLite menggunakan pengoptimalan tambahan saat mengkompilasi kueri.

Contoh berikut mendefinisikan fungsi agregat untuk menghitung simpangan standar dari sebuah kolom.

connection.CreateAggregate(
    "stdev",

    // A tuple to maintain context between rows
    (Count: 0, Sum: 0.0, SumOfSquares: 0.0),

    // This is called for each row
    ((int Count, double Sum, double SumOfSquares) context, double value) =>
    {
        context.Count++;
        context.Sum += value;
        context.SumOfSquares += value * value;

        return context;
    },

    // This is called to get the final result
    context =>
    {
        var variance = context.SumOfSquares - context.Sum * context.Sum / context.Count;

        return Math.Sqrt(variance / context.Count);
    });

var command = connection.CreateCommand();
command.CommandText =
@"
    SELECT stdev(gpa)
    FROM student
";
var stdDev = command.ExecuteScalar();

Kesalahan

Jika fungsi yang ditentukan pengguna melemparkan pengecualian, pesan dikembalikan ke SQLite. SQLite kemudian akan menimbulkan kesalahan dan Microsoft.Data.Sqlite akan melemparkan SqliteException. Untuk informasi selengkapnya, lihat Kesalahan database.

Secara standar, kode kesalahan SQLite akan menjadi SQLITE_ERROR (atau 1). Namun, Anda dapat mengubahnya dengan menambahkan SqliteException dalam fungsi Anda dan menentukan SqliteErrorCode yang diinginkan.

Pemecahan Masalah

SQLite memanggil implementasi Anda secara langsung. Ini memungkinkan Anda menambahkan titik henti yang memicu saat SQLite sedang mengevaluasi kueri. Pengalaman debugging .NET yang lengkap tersedia untuk membantu Anda membuat fungsi yang Anda tentukan.

Lihat juga