【问题标题】:C# alter stored procedure programmaticallyC# 以编程方式更改存储过程
【发布时间】:2018-06-06 14:38:56
【问题描述】:

我有以下 C# 代码应该允许我修改(更改)我的存储过程:

SqlConnection sqlCon = new SqlConnection(ConfigurationManager.ConnectionStrings["sqlConnection"].ConnectionString);
ServerConnection srvCon = new ServerConnection(sqlCon);

sqlCon.Open();

Server srv = new Server(srvCon);
Database db = srv.Databases[sqlCon.Database];
StoredProcedure sp = new StoredProcedure(db, "spRDLDataFetcher");

sp.TextMode = false;
sp.AnsiNullsStatus = false;
sp.QuotedIdentifierStatus = false;
sp.TextBody = "SELECT blah FROM MyTable WHERE ID=1";
sp.Alter();

但是,sp.Alter()call 会引发此错误:

Microsoft.SqlServer.Management.Smo.FailedOperationException:'StoredProcedure 'dbo.spRDLDataFetcher' 的更改失败。 '

内部异常:InvalidSmoOperationException:您无法对处于Creating 状态的对象执行Alter 操作。

为了让它改变(更新)该存储过程,我缺少什么?

【问题讨论】:

  • 放弃 SMO 可以节省大量时间和麻烦,只需使用 SqlClient 发送一个完整的“ALTER PROCEDURE”批处理。
  • idownvotedbecau.se/noresearch。我敢肯定,对于之前的 750 多个问题,您已经听过一两次:您尝试过什么? Google 的第一个命中建议调用 Refresh() 来同步 SQL 和 SMO 对象的状态(即告诉 SMO 它实际上是一个现有的 SP)。
  • 你不是说sp = db.StoredProcedures["spRLDataFetcher"]吗?我相信另一种选择是在new 之后立即调用sp.Refresh(),这样SMO 就会意识到它已经存在。 (尽管我在这里完全同意@David 的观点——每次我使用 SMO 时,最终都会遇到比其价值更多的麻烦,即使对于它名义上应该擅长的任务也是如此。)
  • 无法执行@DavidBrowne-Microsoft 的建议,因为我只是在 SP 中更改了一些内容。我正在用数据替换 cmets (--something)。上面的 textBody= 只是一个示例,并不是我将要更改的真实 SP。
  • 即使以编程方式替换存储过程主体,SELECT [definition] FROM sys.sql_modules WHERE object_id = OBJECT_ID('myprocedure') 也可以。给文字打补丁,把第一个CREATE换成ALTER,发回去。但是 SMO 在所需的代码行数方面做得稍微好一些。

标签: c# sql sql-server stored-procedures sql-server-2014


【解决方案1】:

好的,所以我发现了它为什么不更新它。似乎,无论出于何种原因,在我覆盖 textBody 之前,它都需要 sp.Refresh(); First

SqlConnection sqlCon = new SqlConnection(ConfigurationManager.ConnectionStrings["sqlConnection"].ConnectionString);
ServerConnection srvCon = new ServerConnection(sqlCon);

sqlCon.Open();

Server srv = new Server(srvCon);
Database db = srv.Databases[sqlCon.Database];
StoredProcedure sp = new StoredProcedure(db, "spRDLDataFetcher");

sp.TextMode = false;
sp.AnsiNullsStatus = false;
sp.QuotedIdentifierStatus = true;
sp.ImplementationType = ImplementationType.TransactSql;
sp.Schema = "dbo";

sp.Refresh(); //What was needed to make work
string orgSPText = sp.TextBody;

sp.TextBody = "SELECT blah FROM MyTable WHERE ID=1";
sp.Recompile = true;
sp.Alter();

sp.Recompile = true; 确实是不需要的。没有它它也能工作,但我喜欢把它放在那里只是为了好玩和咯咯笑。

【讨论】:

  • 这不是“开玩笑”,它在存储过程中添加了WITH RECOMPILE。这可能是一件好事,坏事或无关紧要的事情,但它在运行时会产生影响,所以不要因为可以就扔掉它。 (它与 SMO 更改存储过程的操作无关;特别是,它不会指示数据库在那个时刻重新编译该过程,因为这将在新过程首次执行时发生。)
  • 感谢@JeroenMostert 提供的知识
猜你喜欢
  • 2019-03-28
  • 2013-08-30
  • 1970-01-01
  • 2019-11-28
  • 2013-02-15
  • 1970-01-01
  • 2019-04-10
  • 2015-08-16
  • 2012-10-04
相关资源
最近更新 更多