sql-server - 如果存储过程尚不存在,则创建它,但不要更改也不要删除现有的存储过程
问题描述
我找到了一些示例,其中存储过程被删除或更改以防万一它存在。
但是我如何编写一个严格执行以下操作的 T-SQL 批处理脚本:
- 检查存储过程是否存在:
- 如果它存在,则脚本什么都不做 - 我不想放弃并重写或更改现有程序,因为它可能有其他人所做的更改。此外,脚本不应因错误而中止,因为它可能是较大批量更改的一部分。
- 如果它不存在,那么只有用我的代码创建一个新过程
?
解决方案
创建存储过程时,它可以是批处理中的唯一语句。这意味着像下面这样的事情将失败:
IF NOT EXISTS(SELECT 1 FROM sys.schemas s JOIN sys.procedures p ON s.schema_id = p.schema_id WHERE s.[name] = N'dbo' AND p.[name] = N'YourProcedure') BEGIN
CREATE PROC dbo.YourProcedure @TableName sysname AS
BEGIN
SELECT *
FROM sys.tables t
WHERE t.name = @TableName;
END;
END;
因此,如果要先检查过程是否存在,如果不存在则创建它,则必须使用“动态”SQL(它不是真正的动态,因为其中没有任何动态):
IF NOT EXISTS(SELECT 1 FROM sys.schemas s JOIN sys.procedures p ON s.schema_id = p.schema_id WHERE s.[name] = N'dbo' AND p.[name] = N'YourProcedure') BEGIN
EXEC sys.sp_executesql N'CREATE PROC dbo.YourProcedure @TableName sysname AS
BEGIN
SELECT *
FROM sys.tables t
WHERE t.name = @TableName;
END;';
END;
这意味着在将存储过程的定义中的任何单引号粘贴到动态语句中时,您需要对其进行转义。
推荐阅读
- ios - 如何访问 Project > Build Settings > Other Swift Flags 中定义的值?
- javascript - 如何用玩笑配置`NormalModuleReplacementPlugin`
- android - UncaughtException ExceptionInInitializerError
- c# - 在创建/完成封闭类型之前如何使用嵌套类型构建器?
- azure - 将链代码部署到 Azure 上的 Hyperledger Fabric Consortium
- rest - Yii2 rest api 基本认证
- sql - ORDER BY 可能缺少列
- python - 将函数映射到 Pandas 中的列值的问题
- android - 如何合并两个菜单并对它们进行排序?
- automapper - 如何将 ExpandoObject(或动态)映射到实例上?