能否在Visual Studio数据库(SSDT)项目中免括号/引号使用SQLCMD变量?
在SSDT项目里直接用无包裹SQLCMD变量的解决办法
问题说明
你已经知道在Visual Studio的SSDT(SQL Server Data Tools)项目里,SQLCMD变量用单引号或者方括号包裹就能正常使用,比如这个例子:
:setvar StringFilter "One" DECLARE @tbl TABLE ( ID INT, StrValue VARCHAR(50) ); INSERT INTO @tbl (ID, StrValue) VALUES (1, 'One'), (2, 'Two'), (3, 'Three'); SELECT ID, StrValue FROM @tbl WHERE StrValue = '$(StringFilter)';
但碰到设置排序规则的场景时,你想直接调用不加包裹的SQLCMD变量,比如这样写:
:setvar Collation "Latin1_General_CI_AS" DECLARE @tbl TABLE ( ID INT, StrValue VARCHAR(50) ); INSERT INTO @tbl (ID, StrValue) VALUES (1, 'One'), (2, 'Two'), (3, 'Three'); SELECT ID, StrValue COLLATE $(Collation) FROM @tbl;
这段代码在SSMS里能正常运行,但在SSDT项目编译时会报语法错误。而且只有在部署后脚本里这么写才可行,放到存储过程、触发器这些需要编译的对象里就不行,你想知道有没有设置能允许这种用法。
可行方案
开启SQLCMD变量的延迟验证
SSDT默认会在编译阶段严格校验所有SQL语法,像排序规则这种场景里的无包裹SQLCMD变量,会被当成未解析的语法直接报错。你可以调整项目设置来解决:
- 右键你的SSDT项目,选择属性
- 先进入SQLCMD变量选项卡,确认
Collation变量已经正确定义 - 切换到生成选项卡,找到验证区域,勾选延迟验证(Delay Validation)
- 这个设置会让SSDT在编译时跳过对依赖SQLCMD变量的部分语法校验,只在部署阶段结合变量的实际值做最终验证
其他规避方式
如果开启延迟验证后还是有问题,还可以试试这些办法:
- 对于存储过程这类编译对象,用脚本变量替换的方式处理排序规则变量,或者部署时用SQLCMD模式执行脚本
- 也可以在项目里创建一个包含固定排序规则的视图或函数,然后在对象里引用,但这种方式灵活性较差,不如直接用变量方便
注意事项
- 延迟验证可能会掩盖一些真实的语法错误,建议开发完成后关闭延迟验证,做一次全量校验
- 一定要确保所有SQLCMD变量在项目属性里都设置了默认值,避免部署时因变量缺失导致失败
内容的提问来源于stack exchange,提问作者Simon Elms
相关产品推荐
相关产品推荐

