sys.objects 是 SQL Server 中存储数据库对象元数据的系统视图,包含用户表(U)、视图(V)、存储过程(P)、函数(FN/IF/TF)等类型,其 type 字段标识对象类型,is_deterministic 属性需联查 sys.sql_modules 判断函数确定性。

查 pg_proc 或 sys.objects 看函数属性
PostgreSQL 和 SQL Server 都把函数的确定性标记(provolatile 或 xtype + 属性)存进系统表,直接查就能知道它能不能用在视图里。
PostgreSQL 中运行:
SELECT proname, provolatile, prosrc
FROM pg_proc
WHERE proname IN ('now', 'uuid_generate_v4', 'format_phone');
provolatile 值为 v(volatile)或 s(stable)的函数,只要没显式标成 i(immutable),就大概率不能安全用于视图定义;尤其是 v,基本一用就报错。
SQL Server 中查自定义函数是否 deterministic:
SELECT name, is_deterministic
FROM sys.sql_modules m
JOIN sys.objects o ON m.object_id = o.object_id
WHERE o.type IN ('FN', 'IF', 'TF') AND o.name = 'your_function_name';
注意:is_deterministic = 0 表示该函数被声明为非确定性,哪怕它实际只做加法——SQL Server 信的是元数据,不是行为。
用 CREATE VIEW ... AS SELECT 测试是否能建成功
最直白的办法:把疑似含非确定性函数的 SELECT 语句单独拎出来,套上 CREATE VIEW v_test AS 尝试创建。数据库会在语法解析阶段就拦截,不等到执行。
- MySQL 8.0+ 会直接报
ERROR 1351 (HY000): View's SELECT contains a function that is not allowed,并列出具体函数名 - PostgreSQL 报
ERROR: cannot use function xxx in view definition,且明确提示需 IMMUTABLE/STABLE - SQL Server 在创建含
GETDATE()的索引视图时,错误是Cannot create index on view 'xxx' because it contains the nondeterministic function 'GETDATE',但普通视图不会拦,得靠后续建索引才发现问题
关键点:普通视图创建成功 ≠ 安全。SQL Server 普通视图允许 GETDATE(),但一旦你后续想加唯一聚集索引,就会卡在这儿。
检查视图定义文本里有没有高危函数关键词
有些函数一眼就能识别为非确定性,不用查系统表也能快速筛查。人工扫视图定义 SQL 时,重点盯这些词:
-
NOW()、GETDATE()、SYSDATETIME()、CURRENT_TIMESTAMP -
NEWID()、NEWSEQUENTIALID()、UUID()、uuid_generate_v4() -
RAND()(未带 seed)、CRYPT_GEN_RANDOM() -
SESSION_USER、CURRENT_USER(部分场景下被视为 non-deterministic)
注意:ROW_NUMBER() 本身不是函数,但它的 OVER 子句若含 ORDER BY NEWID(),整条表达式就变成非确定性了——这种嵌套陷阱容易漏看。
为什么光看函数名还不够
函数是否“真非确定性”,还取决于它怎么被声明和使用。比如:
- MySQL 中
RAND(42)是确定性的,但RAND()不带参数就是非确定性;视图里写前者能过,后者直接失败 - PostgreSQL 中用户函数若没显式声明
IMMUTABLE,默认是VOLATILE,哪怕函数体只有一行RETURN $1 + 1 -
CONVERT(datetime, '2020-01-01', 120)是确定性的,但CONVERT(varchar, getdate(), 120)不是——类型转换方向和源是否稳定,共同决定结果
真正麻烦的地方在于:非确定性可能藏在嵌套调用里。比如视图调用函数 A,A 内部又调用了函数 B(B 被标为 STABLE),那整个视图就继承了 STABLE 属性——在 PostgreSQL 里勉强可用,但在 MySQL 里仍会被拒,因为 MySQL 不认 STABLE 这个概念。

















