我有一块看起来有点像这样的SQL
IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = '{FOO}')
BEGIN
EXECUTE ('CREATE DATABASE {FOO}')
ALTER DATABASE {FOO} SET AUTO_CLOSE OFF
END
{FOO}
在运行时被替换为用户可配置数据库的名称。逻辑是,如果数据库已经存在,我不想创建数据库。
如果{FOO}
为tempdb
,则查询运行时会出现故障
无法在数据库'tempdb'中设置选项'AUTO_CLOSE'。
我的问题是为什么我会失败? SELECT * FROM sys.databases WHERE name = 'tempdb'
返回零结果,所以我的整个BEGIN/END
对不应该运行吗?实际上,如果我在开始和结束之间放置print
语句,我看不到任何输出。
我的猜测是,SQL Server正在对SQL进行某种处理,以确保我不会使用tempdb进行处理?我通过使用EXECUTE
来解决问题,但我有点困惑为什么我必须这样做!
答案 0 :(得分:3)
尝试确保两个命令是分开的并且在动态SQL中,然后解析器不会捕获对tempdb的更改:
EXEC sp_executesql N'CREATE DATABASE {FOO};';
EXEC sp_executesql N'ALTER DATABASE {FOO} SET AUTO_CLOSE OFF;';
这与你不能这样做的原因类似:
IF 1 = 1
BEGIN
CREATE TABLE #t1(id INT);
END
ELSE
BEGIN
CREATE TABLE #t1(x NVARCHAR(255));
END
即使您和我知道只有其中一个#t1代码路径会被访问,但SQL Server假定在运行时可以访问这两个路径,因此在分析时会抱怨。