以编程方式检索与 SQL Server Management Studio gui 返回的源相同的 SQL Server 存储过程源?

发布于 2024-07-12 10:14:16 字数 984 浏览 4 评论 0原文

有没有关于如何以编程方式从 SQL Server 2005 获取完全相同的存储过程源的指示,就像在 SQL Server Management Studio 中右键单击该存储过程并选择修改一样?

我正在尝试使用 SMO,但存在一些文本差异。 该过程始终具有 CREATE,而不是 ALTER,并且标头中存在一些差异,例如我以编程方式获取的版本中缺少 GO。 我可以解决这些问题,但也许有更好的方法?

同样,我在 SQL Server 2005 中使用 SMSE。 通过 Visual Studio 8 2008 使用 SMO。

更新:获得了一些答案,讲述了如何检索存储过程的基础知识。 我正在寻找的是检索与 GUI 生成的文本相同(或几乎相同)的文本。

示例:对于 sp_mysp,在 Management Studio 中右键单击,选择修改。 这会生成:

    USE [MY_DB]  
    GO  
    /****** Object:  StoredProcedure [dbo].[sp_mysp]    Script Date: 01/21/2009 17:43:18 ******/  
    SET ANSI_NULLS ON  
    GO  
    SET QUOTED_IDENTIFIER ON  
    GO  
    -- =============================================
    -- Author:      
    -- Create date: 
    -- Description: 
    -- =============================================
    ALTER PROCEDURE [dbo].[sp_mysp]

我想以编程方式获得相同的东西(请注意标头中的 GO,以及它是一个 ALTER PROCEDURE 的事实。理想情况下,我希望通过对检索到的源进行最少的编程修复来获得此结果。

我我们很乐意只得到脚本日期细节上的不同内容。

Any pointers on how I can programmatically get exactly the identical stored procedure source from SQL Server 2005, as when I right-click on that stored procedure in SQL Server Management Studio and select modify?

I'm trying using SMO, but there are some textual differences. The procedure always has CREATE, not ALTER, and there are some differences in the header, such as missing GOs in the version I'm getting programmatically. I can fix these up, but perhaps there is a better way?

Again, I'm in SQL Server 2005, using SMSE. Using SMO via Visual Studio 8 2008.

Update: Gotten some answers that tell the basics of how to retrieve the stored procedure. What I'm looking for is retrieving the text identical (or nearly identical) to what the GUI generates.

Example: for sp_mysp, right-click in Management Studio, select modify. This generates:

    USE [MY_DB]  
    GO  
    /****** Object:  StoredProcedure [dbo].[sp_mysp]    Script Date: 01/21/2009 17:43:18 ******/  
    SET ANSI_NULLS ON  
    GO  
    SET QUOTED_IDENTIFIER ON  
    GO  
    -- =============================================
    -- Author:      
    -- Create date: 
    -- Description: 
    -- =============================================
    ALTER PROCEDURE [dbo].[sp_mysp]

I'd like to programmatically get the same thing (notice the GOs in the header, and the fact that it's an ALTER PROCEDURE. Ideally, I'd like to get this with minimal programmatic fixing up of the source retrieved.

I'd be happy to only get something that differed in the Script Date details . . .

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

淡写薰衣草的香 2024-07-19 10:14:16
EXEC sp_helptext 'your procedure name';

这避免了 INFORMATION_SCHEMA 方法的问题,其中存储过程如果太长就会被切断。

更新:大卫写道,这与他的存储过程不同......也许是因为它将行作为“记录”返回以保留格式? 如果您想以更“自然”的格式查看结果,可以先使用 Ctrl-T(以文本形式输出),它应该按照您输入的内容准确地打印出来。 如果您在代码中执行此操作,则执行 foreach 以完全相同的方式将结果组合在一起是很简单的。

更新2:这将为源提供“CREATE PROCEDURE”而不是“ALTER PROCEDURE”,但我知道没有办法让它使用“ALTER”来代替。 不过,这是一件微不足道的事情,不是吗?

更新 3:请参阅评论,了解有关如何在源代码控制系统中维护 SQL DDL(数据库结构)的更多见解。 这确实是这个问题的关键。

EXEC sp_helptext 'your procedure name';

This avoids the problem with INFORMATION_SCHEMA approach wherein the stored procedure gets cut off if it is too long.

Update: David writes that this isn't identical to his sproc...perhaps because it returns the lines as 'records' to preserve formatting? If you want to see the results in a more 'natural' format, you can use Ctrl-T first (output as text) and it should print it out exactly as you've entered it. If you are doing this in code, it is trivial to do a foreach to put together your results in exactly the same way.

Update 2: This will provide the source with a "CREATE PROCEDURE" rather than an "ALTER PROCEDURE" but I know of no way to make it use "ALTER" instead. Kind of a trivial thing, though, isn't it?

Update 3: See the comments for some more insight on how to maintain your SQL DDL (database structure) in a source control system. That is really the key to this question.

素手挽清风 2024-07-19 10:14:16

您必须手动对其进行编码,SQL Profiler 会显示以下内容。

SMSE 在生成语句时执行相当长的查询字符串。

以下查询(或类似的查询)用于提取文本:

SELECT
NULL AS [Text],
ISNULL(smsp.definition, ssmsp.definition) AS [Definition]
FROM
sys.all_objects AS sp
LEFT OUTER JOIN sys.sql_modules AS smsp ON smsp.object_id = sp.object_id
LEFT OUTER JOIN sys.system_sql_modules AS ssmsp ON ssmsp.object_id = sp.object_id
WHERE
(sp.type = N'P' OR sp.type = N'RF' OR sp.type='PC')and(sp.name=N'#test___________________________________________________________________________________________________________________00003EE1' and SCHEMA_NAME(sp.schema_id)=N'dbo')

它返回纯 CREATE,然后在代码中的某处用 ALTER 替换。

SET ANSI NULL 内容以及 GO 语句和日期都在此前面。

使用 sp_helptext,它更简单......

You will have to hand code it, SQL Profiler reveals the following.

SMSE executes quite a long string of queries when it generates the statement.

The following query (or something along its lines) is used to extract the text:

SELECT
NULL AS [Text],
ISNULL(smsp.definition, ssmsp.definition) AS [Definition]
FROM
sys.all_objects AS sp
LEFT OUTER JOIN sys.sql_modules AS smsp ON smsp.object_id = sp.object_id
LEFT OUTER JOIN sys.system_sql_modules AS ssmsp ON ssmsp.object_id = sp.object_id
WHERE
(sp.type = N'P' OR sp.type = N'RF' OR sp.type='PC')and(sp.name=N'#test___________________________________________________________________________________________________________________00003EE1' and SCHEMA_NAME(sp.schema_id)=N'dbo')

It returns the pure CREATE which is then substituted with ALTER in code somewhere.

The SET ANSI NULL stuff and the GO statements and dates are all prepended to this.

Go with sp_helptext, its simpler ...

椵侞 2024-07-19 10:14:16

你说的是程序化吧? 我希望C#没问题。 我知道您说过您尝试过 SMO,但它并没有完全满足您的要求,因此这可能不太适合您的请求,但它会以编程方式读出合法的 SQL 语句,您可以运行这些语句来重新创建存储过程。 如果它没有您想要的 GO 语句,您可能可以假设 StringCollection 中的每个字符串都可以有一个 GO在它之后。 您可能不会得到带有日期和时间的评论,但在我听起来类似的项目(必须单独备份所有内容的大部署工具)中,这做得相当好。 如果您有想要使用的先前基础,并且仍然有原始数据库可以运行它,那么我会考虑放弃最初的工作并重新标准化此输出。

using System.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
…
string connectionString = … /* some connection string */;
ServerConnection sc = new ServerConnection(connectionString);
Server s = new Server(connection);
Database db = new Database(s, … /* database name */);
StoredProcedure sp = new StoredProcedure(db, … /* stored procedure name */);
StringCollection statements = sp.Script;

You said programmatically, right? I hope C# is ok. I know you said that you tried SMO and it didn't quite do what you wanted, so this probably won't be perfect for your request, but it will programmatically read out legit SQL statements that you could run to recreate the stored procedure. If it doesn't have the GO statements that you want, you can probably assume that each of the strings in the StringCollection could have a GO after it. You may not get that comment with the date and time in it, but in my similar sounding project (big-ass deployment tool that has to back up everything individually), this has done rather nicely. If you have a prior base that you wanted to work from, and you still have the original database to run this on, I'd consider tossing the initial effort and restandardizing on this output.

using System.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
…
string connectionString = … /* some connection string */;
ServerConnection sc = new ServerConnection(connectionString);
Server s = new Server(connection);
Database db = new Database(s, … /* database name */);
StoredProcedure sp = new StoredProcedure(db, … /* stored procedure name */);
StringCollection statements = sp.Script;
故人如初 2024-07-19 10:14:16

使用以下 select 语句来获取整个定义:

select ROUTINE_DEFINITION 
  from INFORMATION_SCHEMA.ROUTINES 
 where ROUTINE_NAME = 'someprocname'

我猜 SSMS 和其他工具会读出此内容并在必要时进行更改,例如将 CREATE 更改为 ALTER。 据我所知,SQL 不存储过程的其他表示形式。

Use the following select statement to get the whole definition:

select ROUTINE_DEFINITION 
  from INFORMATION_SCHEMA.ROUTINES 
 where ROUTINE_NAME = 'someprocname'

I guess that SSMS and other tools read this out and make changes where necessary, such as changing CREATE to ALTER. As far as I know, SQL stores not other representations of the procedure.

尝蛊 2024-07-19 10:14:16

我同意马克的观点。 我将输出设置为文本模式,然后 sp_HelpText 'sproc'。 我将其绑定到 Crtl-F1 以使其变得简单。

I agree with Mark. I set the output to text mode and then sp_HelpText 'sproc'. I have this binded to Crtl-F1 to make it easy.

辞别 2024-07-19 10:14:16

数据库发布向导可以转储架构(和其他对象)从命令行。

The Databse Publishing Wizard can dump the schema (and other objects) from the command line.

半世晨晓 2024-07-19 10:14:16

我只是想指出,您最好使用拖放,而不是使用查找和替换来更改创建过程来更改过程,您可以将其放在顶部,并且它确实需要文本搜索。

IF exists (SELECT * FROM sys.objects 
        WHERE object_id = OBJECT_ID(N'sp_name')
            and type in ('P','V') --procedure or view
        )
    DROP sp_name
GO

如果你确定它在那里,我想你也可以把它扔掉,但我不建议这样做。 不要忘记 go,因为 create procedure 必须是批处理中的第一个也是唯一一个语句。

或者懒惰的方法:

IF OBJECT_ID(N'sp_name') is not null
    DROP sp_name
GO

I just want to note that instead of using find and replace to change create procedure to alter procedure, you are just as well to use a drop, you can put it right at the top and it does require text searching.

IF exists (SELECT * FROM sys.objects 
        WHERE object_id = OBJECT_ID(N'sp_name')
            and type in ('P','V') --procedure or view
        )
    DROP sp_name
GO

If you are sure it's there, I guess you could just drop it too, but I wouldn't recommend that. Don't forget the go, since create procedure must be the first and only statement in a batch.

Or the lazy approach:

IF OBJECT_ID(N'sp_name') is not null
    DROP sp_name
GO
万劫不复 2024-07-19 10:14:16

我通过 链接看到一篇文章< /a>.
有四种方法,我只是在这里做了一个简短的总结,以帮助其他程序员。

  1. 执行 sp_helptext 'sp_name';

  2. 选择 OBJECT_ID('sp_name')

  3. 选择 OBJECT_DEFINITION(
    OBJECT_ID('sp_name')
    ) AS [定义];

  4. 从sys.sql_modules中选择*,其中object_id = object_id('sp_name');

I saw a article via link.
There are four methods, I just did a short summary here for helping other programmers.

  1. EXEC sp_helptext 'sp_name';

  2. SELECT OBJECT_ID('sp_name')

  3. SELECT OBJECT_DEFINITION(
    OBJECT_ID('sp_name')
    ) AS [Definition];

  4. SELECT * FROM sys.sql_modules WHERE object_id = object_id('sp_name');

擦肩而过的背影 2024-07-19 10:14:16

要更改存储过程,以下是 C# 代码:

SqlConnection con = new SqlConnection("your connection string");
con.Open();
cmd.CommandType = System.Data.CommandType.Text;
string sql = File.ReadAllText(YUOR_SP_SCRIPT_FILENAME);
cmd.CommandText = sql;   
cmd.Connection = con;
cmd.ExecuteNonQuery();
con.Close();

注意事项:

  1. 确保连接字符串中的 USER 有权更改 SP
  2. 从存储过程中删除所有 GO,SET ANSI_NULLS XX,SET QUOTED_IDENTIFIER 语句脚本文件。 (如果不这样做,SqlCommand 将抛出错误)。

To alter a stored procedure, here's the C# code:

SqlConnection con = new SqlConnection("your connection string");
con.Open();
cmd.CommandType = System.Data.CommandType.Text;
string sql = File.ReadAllText(YUOR_SP_SCRIPT_FILENAME);
cmd.CommandText = sql;   
cmd.Connection = con;
cmd.ExecuteNonQuery();
con.Close();

Things to note:

  1. Make sure the USER in the connection string have the right to alter SP
  2. Remove all the GO,SET ANSI_NULLS XX,SET QUOTED_IDENTIFIER statements from the script file. (If you don't, the SqlCommand will throw an error).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文