我正在VisualParadigm中开发一个简单的数据库架构,并最近浏览了下一段代码摘录。
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'getType') AND type in (N'P', N'PC'))
DROP PROCEDURE getType;
接下来是我的存储过程:
CREATE PROCEDURE getType @typeId int
AS
SELECT * FROM type t WHERE t.type_id = @typeId;
任何人都能解释它的意思/做法(前者)吗?
P.S。:如果你也可以检查任何语法错误,那将是很棒的,因为我对SQL Server和存储过程完全不熟悉。
答案 0 :(得分:2)
IF EXISTS部分首先检查是否存在具有相同名称的存储过程。如果它确实它在创建它之前丢弃它。如果没有此检查,您将收到存储过程已存在的错误。
答案 1 :(得分:1)
如果对象已存在,CREATE PROCEDURE getType...
将失败。通过包含IF EXISTS...
代码,如果该对象首先存在,它将删除该对象,您将消除该错误并运行CREATE...
。
OBJECT_ID(N'getType')
只返回名为N'getType'的对象的数字ID,而AND type in (N'P', N'PC'))
确保该对象是P =存储过程或PC = Assembly(CLR)。< / p>
您可以尝试使用类似的内容,这样您就可以使用ALTER
来保留权限(DROP + CREATE会删除任何内容):
BEGIN TRY EXEC ('CREATE PROCEDURE YourProcedureName AS SELECT ''ERROR'' RETURN 999') END TRY BEGIN CATCH END CATCH
GO
ALTER PROCEDURE YourProcedureName
AS
SELECT 'WORKS!2'
GO
EXEC YourProcedureName
输出:
-------
WORKS!2
(1 row(s) affected)
答案 2 :(得分:1)
添加到Raj的帖子中,没有办法对存储过程进行“upsert”。 Create Procedure语句必须是批处理的第一个语句。因此,以下将不工作:
If Not Exists(Select 1 From sys.procedures Where Name = 'getType')
Create Procedure...
Else
Alter Procedure...
“更新”过程的唯一方法,如果它已经存在则不抛出错误就是删除它并重新创建它。
<强> ADDITION 强>
为了解决您在注释中提出的具体问题,sys.objects是一个目录视图,其中包含所有对象(表,约束,列,索引等数据库中的每个“事物”)的列表,其中的过程是一个他们因此,这是检查过程对象(基于类型上的过滤器)是否存在。 sys.objects表/视图的主键是object_id,它是一个整数。在您的示例中,他们使用OBJECT_ID
函数来查找对象getType
的ID,并确定它是否是一个过程。 (使用If OBJECT_ID(N'getType') is not null
可能是安全的,但是为了防止另一个具有该名称的对象不是一个过程,他们添加了对象类型的检查。)
答案 3 :(得分:0)
看起来这是生成数据库的脚本的一部分。第一个语句查看是否存在名为“getType”的sproc。如果它确实那么它将丢弃它。为什么?因为下一行将创建它。
它可以创建它并确保它与您的过程的当前版本匹配的唯一方法是将create
更改为alter
。这会产生更长的代码,因为它必须列出两次sproc。或者它可以生成动态的sql,它几乎不干净。
答案 4 :(得分:0)
正在执行放弃并重新创建
如果存在名为getType的数据库对象:
WHERE object_id = OBJECT_ID(N'getType')
这是一个存储过程:
AND type in (N'P', N'PC'))
然后在添加存储过程之前删除它:
DROP PROCEDURE getType;
答案 5 :(得分:0)
第一个查询会丢弃过程(如果存在)。第二个创建一个新过程,它接受整数参数并返回结果集。