4

我认为这不是确定性的,仅仅是因为DB_NAME()不是确定性的?如果DB_NAME()不是确定性的,为什么它不是确定性的?

ALTER FUNCTION [TheSchema].[udf_IS_PRODUCTION] ()
RETURNS bit
    WITH SCHEMABINDING
AS 
    BEGIN
        RETURN CASE WHEN DB_NAME() = 'PRODUCTION' THEN CONVERT(bit, 1) ELSE CONVERT(bit, 0) END
    END

更新:此版本有效,具有确定性,允许在任何数据库中使用相同的代码并删除数据库名称的硬编码(这也允许我删除另一个关于数据库名称编码的自动系统健康异常)

ALTER FUNCTION [TheSchema].[udf_IS_PRODUCTION] ()
RETURNS bit
    WITH SCHEMABINDING
AS 
    BEGIN
        RETURN (SELECT IS_PRODUCTION FROM TheSchema.IS_PRODUCTION)
    END

仅供参考,这是我用于监控潜在问题的系统健康自我报告系统中的代码片段。

    SELECT  'Non-deterministic Scalar UDF' AS Problem
           ,QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME) AS ROUTINE_NAME
    FROM    INFORMATION_SCHEMA.ROUTINES WITH (NOLOCK)
    WHERE   IS_DETERMINISTIC = 'NO'
            AND ROUTINE_TYPE = 'FUNCTION'
            AND DATA_TYPE <> 'TABLE'
    ORDER BY ROUTINE_SCHEMA
           ,ROUTINE_NAME
4

4 回答 4

5

当然,我可以想出一种使其具有确定性的方法。在您的生产数据库上部署此功能:

ALTER FUNCTION [TheSchema].[udf_IS_PRODUCTION] ()
RETURNS bit
    WITH SCHEMABINDING
AS 
BEGIN
    RETURN CONVERT(bit, 1)
END

并将这个部署到您的测试数据库:

ALTER FUNCTION [TheSchema].[udf_IS_PRODUCTION] ()
RETURNS bit
    WITH SCHEMABINDING
AS 
BEGIN
    RETURN CONVERT(bit, 0)
END

这可能看起来很愚蠢,但 IMO 数据库名称不应该比某些 UDF 的返回值更“硬编码”。

更好的是,只需将此信息放在某个配置表中即可。

于 2010-01-22T16:40:04.237 回答
2

难道你不能重写你的函数而不是在内部确定 DB_NAME() ,而是让它作为参数发送吗?

ALTER FUNCTION [TheSchema].[udf_IS_PRODUCTION] (DatabaseName VARCHAR(255))
RETURNS bit
WITH SCHEMABINDING
AS 
    BEGIN
        RETURN CASE WHEN DatabaseName = 'PRODUCTION' 
                    THEN CONVERT(bit, 1) 
                    ELSE CONVERT(bit, 0) 
               END
    END

不应该是确定性的,对吧?

当你调用它时,你可以DB_NAME()作为一个函数来确定数据库名称

于 2010-01-22T16:45:27.093 回答
1

根据定义,确定性函数是一个函数,其返回值由其参数的值唯一标识。

现在,给定参数DB_NAME()(没有参数),你能说出它会返回什么吗?

于 2010-01-22T16:34:14.987 回答
1

在严格的确定性意义上,结果不是基于输入参数,而是基于不受您控制的外部对象的状态。

名称可以更改等,

Alter Database Modify Name = new_name

在 2005 年,尽管当我针对默认模式尝试它时,SQL 并没有阻止创建该函数。如果您遇到一种情况,它拒绝接受基于非确定性的函数并且您必须解决它(存在风险等),围绕它的路线是创建一个使用该函数的视图,然后从函数内的视图。

于 2010-01-22T16:36:24.720 回答