我正在编写一个脚本,它将自动执行一个特别漫长且烦人的过程。if... return我想通过使用评估门变量(在下面的示例中)来“硬退出”脚本@iHaveSetTheTwoImportantVariablesCorrectly,并在该变量评估为“否”时无条件退出(在打印有用的注释后)。我已经在许多其他脚本中使用了这种技术,没有出现任何问题。
该if... return块根本没有被评估。无论我尝试过什么,都不会被评估。我知道这与后面的代码有关,就好像我删除了之后的所有代码一样,它将被评估。
目的是确保我或其他用户在运行脚本之前已设置变量。
我花了相当长的时间测试不同的东西来尝试使这项工作成功。
检查后的代码if... return包含一些已知的“...不存在...”错误,因为对象尚不存在,但将在执行期间创建,因此不会产生错误。
我使用的是 SSMS 版本 18.10
这是一个经过大量修改的脚本示例,它保留了原始结构和所有相关代码,让您了解它的样子,实际脚本要长得多:
--(multi-line comment block with explanation of script)
set nocount on
declare @variableOne varchar(20) = 'some_text_one'
declare @variableTwo varchar(20) = 'some_text_two'
declare @iHaveSetTheTwoImportantVariablesCorrectly varchar(3) = 'No' --set this to Yes when vars are set correctly
declare @otherVariableOne varchar(10) = 'some text'
declare @otherVariableTwo varchar(10) = 'some other text'
declare @otherVariableThree varchar(10) = 'some more text'
declare @aBitVariable bit = 0
declare @anotherBitVariable bit = 1
if @iHaveSetTheTwoImportantVariablesCorrectly <> 'Yes'
begin
print 'The variable @iHaveSetTheVariablesCorrectly is still set to ''No'', please make sure the vars are set correctly and then change it to ''Yes'''
return
end
use [DatabaseThatExists]
set SomeColumn = 'a value'
where SomeColumn = 'another value'
use [master]
sp_configure 'clr enabled', 1
reconfigure
create asymmetric key AKey
from executable file = 'C:\Path\to\executable.exe'
create login ##UserThatDoesNotExist## from asymmetric key AKey
grant unsafe assembly to ##UserThatDoesNotExist##
use [master]
restore database [SomeDB]
FROM DISK = N'C:\Temp\SomeDB.bak'
WITH FILE = 1, NOUNLOAD,
STATS = 5
use [SomeDB]
--do things
--etc etc etc
Run Code Online (Sandbox Code Playgroud)
该if... return块后面的代码只是正在完成的事情的一个示例,其中一些在执行脚本的早期部分之前会出现错误。
TL;DR -if... return上例中的块未被评估。我发现评估它的唯一情况是删除它之后的所有代码。
如果该IF语句能够执行批处理,则该语句将被正确执行。但它甚至没有编译。
这是因为您USE对不存在的数据库有一个语句。文档说:
USE在编译时和执行时都会执行,并且立即生效。因此,该语句之后批量出现的语句USE都会在指定的数据库中执行。
对不存在的数据库的语句USE将阻止编译,无论IF它周围是否有CREATEorRESTORE语句。
显然,如果您可以将其作为单独的批次执行,那么就这样做。
但是,您不能在单个存储过程中拥有单独的批次。相反,您需要使用动态 SQL。
将要在该数据库上执行的所有代码放入变量中。
restore database [SomeDB]
FROM DISK = N'C:\Temp\SomeDB.bak'
WITH FILE = 1, NOUNLOAD,
STATS = 5;
DECLARE @sp_exec nvarchar(1000) = 'SomeDB.sys.sp_executesql';
DECLARE @sql nvarchar(max) = '
--do things
--etc etc etc
';
EXEC @sp_exec @sql;
Run Code Online (Sandbox Code Playgroud)
如有必要,不要忘记正确参数化。
| 归档时间: |
|
| 查看次数: |
979 次 |
| 最近记录: |