다음을 통해 공유


사용자 정의 함수

대부분의 데이터베이스에는 사용자 고유의 함수를 정의하는 데 사용할 수 있는 SQL의 절차적 방언이 있습니다. 그러나 SQLite는 앱에서 In-Process로 실행됩니다. SQL의 새 방언을 학습하는 대신 앱의 프로그래밍 언어만 사용할 수 있습니다.

스칼라 함수

스칼라 함수는 쿼리의 각 행에 대해 단일 스칼라 값을 반환합니다. 새 스칼라 함수를 정의하고 CreateFunction을(를) 사용하여 기본 함수를 재정의합니다.

인수에 대해 지원되는 매개 변수 및 반환 형식 목록은 데이터 형식을 func 참조하세요.

인수를 state 지정하면 함수의 모든 호출에 해당 값이 전달됩니다. 닫기를 방지하려면 이 방법을 사용합니다.

쿼리를 컴파일할 때 SQLite가 추가 최적화를 사용할 수 있도록 함수가 결정적인지 여부를 지정 isDeterministic 합니다.

다음 예제에서는 스칼라 함수를 추가하여 실린더의 반경을 계산하는 방법을 보여줍니다.

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
";

운영자

다음 SQLite 연산자는 해당 스칼라 함수에 의해 구현됩니다. 앱에서 이러한 스칼라 함수를 정의하면 이러한 연산자의 동작이 재정의됩니다.

오퍼레이터 기능
X GLOB Y glob(Y, X)
Without specific context, it is challenging to determine the exact translation. However, if we assume "X likes Y" is meant, an appropriate translation could be "X가 Y를 좋아한다". If "X is like Y" is intended, then "X는 Y와 같다" would be suitable. like(Y, X)
X LIKE Y ESCAPE Z like(Y, X, Z)
X 일치 Y 매치(Y, X)
X REGEXP(정규 표현식) Y regexp(Y, X)

다음 예제에서는 regexp 함수를 정의하여 해당 연산자를 사용하도록 설정하는 방법을 보여 줍니다. SQLite는 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();

집계 함수

집계 함수는 쿼리의 모든 행에 대해 집계된 단일 값을 반환합니다. 를 사용하여 CreateAggregate집계 함수를 정의하고 재정의합니다.

인수는 seed 컨텍스트의 초기 상태를 지정합니다. 또한 닫기를 방지하려면 이 방법을 사용합니다.

인수는 func 행당 한 번씩 호출됩니다. 컨텍스트를 사용하여 최종 결과를 누적합니다. 컨텍스트를 반환합니다. 이 패턴을 사용하면 컨텍스트가 값 형식이거나 불변일 수 있습니다.

지정하지 resultSelector 않으면 컨텍스트의 최종 상태가 결과로 사용됩니다. 이렇게 하면 각 행 수를 증가시키고 반환하기만 하면 되는 합계 및 개수와 같은 함수의 정의를 간소화할 수 있습니다.

모든 행을 반복한 후 컨텍스트에서 최종 결과를 계산하도록 지정 resultSelector 합니다.

데이터 형식을 참조하여 func 인수에 지원되는 매개 변수 유형 및 resultSelector의 반환 유형 목록을 확인하세요.

함수가 결정적이면 쿼리를 컴파일할 때 SQLite가 추가 최적화를 사용하도록 허용하도록 지정 isDeterministic 합니다.

다음 예제에서는 열의 표준 편차를 계산하는 집계 함수를 정의합니다.

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();

오류

사용자 정의 함수가 예외를 throw하면 메시지가 SQLite로 반환됩니다. 그러면 SQLite에서 오류가 발생하며 Microsoft.Data.Sqlite는 SqliteException을 throw합니다. 자세한 내용은 데이터베이스 오류를 참조하세요.

기본적으로 오류 SQLite 오류 코드는 SQLITE_ERROR(또는 1)입니다. 함수에서 원하는 SqliteException을(를) 지정하고 SqliteErrorCode을(를) 던져서 변경할 수 있습니다.

디버깅

SQLite는 구현을 직접 호출합니다. 이렇게 하면 SQLite가 쿼리를 평가하는 동안 트리거되는 중단점을 추가할 수 있습니다. 전체 .NET 디버깅 환경을 사용하여 사용자 정의 함수를 만들 수 있습니다.

참고하십시오