sql server 不支持 constant 关键字,所有“常量”均为变量或函数返回值;推荐用 declare @var = value 初始化模拟,跨过程复用应使用标量udf,字符串须加 n' 前缀确保 unicode 正确性。

SQL Server 里没有 CONSTANT 关键字,别硬套语法
SQL Server 的 T-SQL 不支持像 PL/SQL 那样用 DECLARE pi CONSTANT DECIMAL(10,6) := 3.1415926; 定义真正不可变的常量。所有“常量”本质都是变量或函数返回值,靠约定或封装来模拟不可变性。硬写 CONSTANT 会直接报错:Incorrect syntax near 'CONSTANT'。
用 DECLARE + 不重赋值是最常用、最轻量的做法
在存储过程开头声明一个变量,赋值后就不再修改,语义上当常量用。它不占额外资源,兼容所有 SQL Server 版本(包括 2005+),且调试时容易观察值。
-
DECLARE @TaxRate DECIMAL(5,4) = 0.075;—— 推荐用初始化语法,比SET少一行 - 避免在后续逻辑中对
@TaxRate再执行SET @TaxRate = ...或SELECT @TaxRate = ... - 如果值来自配置表,可用
SELECT @TaxRate = value FROM Config WHERE key = 'TaxRate',但要确保只查一次、且结果唯一 - 注意:这种“常量”作用域仅限当前批处理或存储过程,跨存储过程不共享
跨存储过程复用?优先选标量值用户定义函数(UDF)
比起全局变量,CREATE FUNCTION dbo.GetMaxRetryCount() 更安全、更易测试、无并发风险。SQL Server 2016+ 虽有 sp_addglobalvar,但它依赖 sys.global_variables 视图,该视图未公开文档,且重启服务后丢失,实际生产环境极少使用。
- 定义函数:
CREATE FUNCTION dbo.GetBatchSize() RETURNS INT AS BEGIN RETURN 1000; END; - 调用:
SELECT * FROM Orders WHERE OrderID IN (SELECT TOP (dbo.GetBatchSize()) OrderID FROM Orders) - 函数可被索引视图、计算列引用,而全局变量不能
- 不要在函数里查表或调用非确定性函数(如
GETDATE()),否则可能影响查询优化器选择计划
字符串常量别拼接,用 N' 前缀防隐式转换
在存储过程中硬编码字符串(比如状态码、分类标识),看似简单,但漏掉 N 前缀会导致 Unicode 字符被截断或乱码,尤其当字段是 NVARCHAR 时。
- 错误写法:
WHERE Status = '已完成'—— 可能触发隐式转换,索引失效 - 正确写法:
WHERE Status = N'已完成'—— 明确告知 SQL Server 这是 Unicode 字符串 - 数字、日期常量不用加前缀,但日期建议统一用 ISO 格式:
'2026-07-02',避免语言设置影响解析 - 如果常量值来自参数或变量,确保变量类型与目标列一致,比如
@Status NVARCHAR(20),而不是VARCHAR(20)
真正需要“常量”的地方,往往暴露的是设计问题:值是否该进配置表?逻辑是否该抽成函数?硬编码值越多,后期越难维护。把常量当成临时占位符,而不是长期方案。











