我认为这不是确定性的,因为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
答案 0 :(得分: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的返回值更“硬编码”。
更好的是,只需将此信息放在某个配置表中即可。
答案 1 :(得分: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()
作为函数来确定数据库名称
答案 2 :(得分:1)
根据定义,确定性函数是一个函数,其返回值由其批量值唯一标识。
现在,鉴于DB_NAME()
的参数(没有参数),你能告诉它会返回什么内容吗?
答案 3 :(得分:1)
在严格意义上的确定性中,结果不是基于输入参数,而是基于不在您控制范围内的外部对象的状态。
名称可以更改等,
Alter Database Modify Name = new_name
在2005年,当我针对默认模式尝试时,SQL不会阻止正在创建的函数。 如果你遇到一种情况,它拒绝接受基于非确定性的函数,你必须解决它(带有风险等),它周围的路径是创建一个使用该函数的视图,然后从中选择函数内的视图。