当语句在if..else语句中时,我遇到使用USE Database; GO
的问题。我的猜测是USE Database; GO
假设在脚本或sql语句的顶部使用。
也许有人可以帮我提出一种不同的方法来解决这个问题,我要做的是,检查特定数据库是否存在,如果它确实从该特定数据库中删除了特定用户访问权限。我想这样做的方式如下......
IF EXISTS(select * from sys.databases where name='MyDB')
BEGIN
USE MyDB
GO
DROP USER [tester]
.
.
.
END
ELSE
PRINT 'MyDB database is not available'
我把sql脚本切成了一个较小的版本所以我不会弄乱这篇文章,所以请注意在DROP USER
EDITED: 我已经尝试了各种方法来检查数据库是否存在,所以每个人都知道 试图
if db_id('MyDB') is not null
or
if object_id('MyDB', 'U')
但是,它总是直接转到use MyDb
,我不知道为什么以及如何解决它。
答案 0 :(得分:1)
以下工作对我来说没问题(给出了所有预期的结果,我也在USE之后用一些select语句进行了测试,当找到DB时工作正常,如果DB超出预期的范围则抛出错误)< / p>
USE master
IF EXISTS(select * from sys.databases where name='SomeDatabase') BEGIN
USE SomeDatabase
print 'Database available'
END ELSE
PRINT 'Database is not available'
您能否进一步解释您的期望和所看到的内容?
更新
这也可行:
USE master
IF EXISTS(select * from sys.databases where name='SomeDatabase') BEGIN
USE SomeDatabase
print 'Database available'
print 'more stuff'
print 'even more stuff'
END ELSE
PRINT 'Database is not available'
然而:
USE master
IF EXISTS(select * from sys.databases where name='SomeDatabase') BEGIN
USE SomeDatabase
print 'Database available'
print 'more stuff'
print 'even more stuff'
END ELSE
PRINT 'Database is not available'
print 'something else when the db is unavail' -- This line will always print regardless
更新:我也可以这样做(仅供参考我在2008年管理工作室运行)
USE master
IF EXISTS(select * from sys.databases where name='JMCExpenseService')
BEGIN
USE SomeDatabase
select * from SomeTableInSomeDatabase
USE AnotherDatabase
SELECT * FROM TableInAnotherDatabase
USE SomeDatabase
select * from SomeOtherTableInSomeDatabase
END
ELSE
PRINT 'MyDB database is not available'
我得到3个带有预期数据的结果集 - 不确定这是否适用于2005年,但我不明白为什么不这样做。你是如何执行查询的?
编辑:
我看到了我的问题 - 如果数据库不存在会死掉,我使用USE SomeDatabase2
来测试它,而实际上我确实有一个叫做这个的数据库。如果DB实际上不存在,这完全会窒息!我想动态SQL是完成这项工作的唯一方法(我厌恶动态SQL)
答案 1 :(得分:1)
如评论中所述,您不能将GO
置于一组彼此依赖的SQL语句的中间,因为:
GO
表示一个已编译批处理的结束和下一个批处理的开始。大多数语句上下文(如IF..ELSE
)不能跨越GO
。和,
GO
甚至不是SQL语句,它是Management Studio / SQLCMD命令,因此在其他任何地方都无法识别。
您的情况是一种常见的需求,但没有一种解决方案。对于您列出的特定情况,使用动态SQL可能是最好的方法:
IF EXISTS(select * from sys.databases where name='MyDB')
BEGIN
EXEC('
USE MyDB
EXEC(''
DROP USER [tester]
.
.
.
'')
')
END
ELSE
PRINT 'MyDB database is not available'
这充分利用了这样一个事实:动态SQL执行每个都构成了自己的批处理,以替换GO
的效果(开始新的批处理)并隔离USE
与编译器的特殊交互。当然,这很奇怪,因为需要在USE..GO
命令之后“双重包装”。
另请注意,由于这种双重包装,其中的任何字符串都必须是四重引用。