我们一直在使用.NET的Sql Server管理对象(SMO)来维护我们的数据库脚本(用作安装和升级脚本)。对于某些存储过程,我们希望具有默认实现,以后可以由客户自行决定。因此,在我们的安装/升级脚本中,我们有类似的东西:
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[STORED_PROC_NAME]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql @statement = N'
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE PROCEDURE [dbo].[STORED_PROC_NAME] @yada varchar(50),....
AS
BEGIN
yada yada yada definition here is within the string passed to executesql
END'
END
注意整个定义如何位于传递给sp_executesql的字符串中。
这很有效,因为如果程序已经存在则不会更改。但是,在过去几天的某个时间点,SMO生成的脚本已更改为以下格式:
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[STORED_PROC_NAME]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql @statement = N'CREATE PROCEDURE [dbo].[STORED_PROC_NAME] AS'
END
GO
ALTER PROCEDURE [dbo].[STORED_PROC_NAME] @yada varchar(50), ...
BEGIN
yada yada yada this definition is now non-dynamic sql
END
从可读性的角度来看,这显然更清晰,因为过程定义不在字符串中,但现在这个脚本将改变已存在的存储过程。改变了什么?生成以下脚本的代码:
Scripter scrp = new Scripter(serv);
scrp.Options.IncludeIfNotExists = true; //important
scrp.Options.NoCollation = true;
scrp.Options.Encoding = Encoding.Unicode;
scrp.Options.Bindings = true;
scrp.Options.ClusteredIndexes = true;
scrp.Options.DriChecks = true;
scrp.Options.DriClustered = true;
scrp.Options.DriDefaults = true;
scrp.Options.DriForeignKeys = false;
scrp.Options.DriIndexes = true;
scrp.Options.DriNonClustered = true;
scrp.Options.DriPrimaryKey = true;
scrp.Options.DriUniqueKeys = true;
scrp.Options.FullTextIndexes = true;
scrp.Options.Indexes = true;
scrp.Options.NonClusteredIndexes = true;
scrp.Options.Triggers = false;
foreach (String s in scrp.Script(new Urn[] { source.StoredProcedures["STORED_PROC_NAME"].Urn }))
{
file.WriteLine(s);
file.WriteLine("GO");
}
答案 0 :(得分:1)
假设您的代码没有更改,我将不得不猜测您引用的库已更改。您现在是否引用了不同版本的SMO库?