📜  SQL Server 中的确定性和非确定性函数(1)

📅  最后修改于: 2023-12-03 15:05:17.753000             🧑  作者: Mango

SQL Server中的确定性和非确定性函数

在SQL Server中,函数可以被分类为确定性或非确定性。这些分类基于函数的行为及其是否始终返回相同的结果。在应用程序中使用函数时,了解函数分类非常重要,因为它们可以影响性能和查询的正确性。

确定性函数

确定性函数是指始终返回相同输出的函数。无论何时调用该函数,它都将返回相同的输出。这意味着可预测和可重复的函数。

例如,LEN()函数是一个确定性函数,因为给定相同的输入,它总是返回相同的输出。以下是一个LEN()函数的的示例:

SELECT LEN('MyString') AS Result;
-- Result: 8

在上面的示例中,给定字符串"MyString",函数LEN()将始终返回相同的输出值8。

非确定性函数

非确定性函数是指它可能返回不同的输出值,即使在相同的输入条件下也是如此。这通常发生在依赖于运行时环境或外部资源的函数(例如随机数或系统值)中。

例如,GETDATE()函数是一个非确定性函数,因为它基于系统时间。以下是一个GETDATE()函数的示例:

SELECT GETDATE() AS Result;
-- Result: 2021-08-31 19:19:27.903

在上面的示例中,每次调用函数时,它都将返回当前系统时间。由于系统时间每次都会发生更改,因此函数将返回不同的输出。

影响性能和查询正确性

使用非确定性函数可能会导致查询的结果不可重复,这可能导致出现问题。确定性函数允许查询结果是可预测和可重复的。函数的分类可以影响查询优化和执行计划。由于非确定性函数依赖于外部资源,因此它们通常会增加查询的成本,从而降低性能。

可以通过在函数名前添加注解来修改函数的确定性属性。这可以改变函数的约束和行为。注解包括DETERMINISTIC(确定性)和NOT DETERMINISTIC(非确定性)。

例如,以下是一个将非确定性函数RAND()转换为确定性函数的示例:

CREATE FUNCTION dbo.deterministic_rand()
RETURNS float
WITH SCHEMABINDING
AS
BEGIN
    RETURN RAND();
END
GO

EXEC sp_addextendedproperty 
    @name = N'IsDeterministic', 
    @value = N'True',
    @level0type = N'SCHEMA', 
    @level0name = N'dbo', 
    @level1type = N'FUNCTION', 
    @level1name = N'deterministic_rand';
GO

在上面的示例中,新函数名为deterministic_rand(),并使用创建函数语句中的WITH SCHEMABINDING子句。此语句强制函数是确定性的,并保护函数以不允许潜在的更改。

结论

SQL Server中的函数可以被分类为确定性或非确定性。确定性函数始终返回相同输出,而非确定性函数则可能基于运行时环境或外部资源而更改输出。使用确定性函数有助于确保查询结果是可预测和可重复的,这可以提高性能和避免问题。