获取 SQLCLR 存储过程的 T-SQL CREATE 语句
我有一个使用 sp_helptext 检索存储过程文本的应用程序。它对我的所有存储过程都非常有效,除了 CLR 存储过程。如果我尝试在 SQLCLR 存储过程上使用 sp_helptext
,则会收到以下错误:
对象“PROC_NAME”没有文本
我知道当我使用“脚本为”时,SSMS 可以做到这一点 - > “创建到”->命令。
但是,当我使用 SQL Server Profiler 跟踪 SSMS“生成脚本”操作时,它给了我一个相当复杂的活动的长得令人畏惧的列表。如果必须的话,我可以费力地完成这个过程,但是有人知道以编程方式获取 CLR 存储过程的代码的直接方法吗?
编辑以澄清
我不想看到程序集中的实际代码;我只是要求一种简单的方法来查看T-SQL代码,如本例所示:
CREATE PROCEDURE [dbo].[MY_PROC]
@PARAM1 [xml],
@PARAM2 [uniqueidentifier],
@PARAM3 [nvarchar](255),
@PARAM4[bit] = False
WITH EXECUTE AS OWNER
AS
EXTERNAL NAME [SomeSolution.SomeProject].[SomeAssembly].[SomeMethod]
GO
换句话说,SQLCLR 函数的“SQL Server 端”。
I have an application that retrieves the text of stored procedures using sp_helptext. It works great on all my stored procedures except for CLR stored procedures. If I try to use sp_helptext
on a SQLCLR stored procedure, I get this error:
There is no text for object 'PROC_NAME'
I know SSMS can do it when I use the "script as" -> "create to" -> command.
But when I trace the SSMS "generate script" action with SQL Server Profiler, it gives me a dauntingly long list of fairly complex activity. I can slog through that if I must, but does anyone know a straightforward way to programmatically get the code of a CLR stored proc?
Edit for clarification
I don't want to see the actual code from the assembly; I'm just asking for an easy way to view the T-SQL code, as in this example:
CREATE PROCEDURE [dbo].[MY_PROC]
@PARAM1 [xml],
@PARAM2 [uniqueidentifier],
@PARAM3 [nvarchar](255),
@PARAM4[bit] = False
WITH EXECUTE AS OWNER
AS
EXTERNAL NAME [SomeSolution.SomeProject].[SomeAssembly].[SomeMethod]
GO
In other words, the "SQL Server side" of the SQLCLR function.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我遇到了同样的困境,并在网上一遍又一遍地搜索任何解决方案来获取 CLR 存储过程的代码。最后必须按照您所说的描述 SSMS“生成脚本”操作的作用,这就是我得到的:
使用此脚本,我制作了一个 Perl 脚本来为我生成代码。我想从这里您可以执行相同的操作或创建自己的存储过程来打印所需的代码。我不是 SQL 程序员,所以我不知道该怎么做,但如果有人对上述查询进行编程,请分享。
I had the same dilemma and searched over and over on the web for any solution to get the code of a CLR stored procedure. Finally had to PROFILE what SSMS "generate script" action did as you said and here is what I got:
With this scripts I made a Perl script to generate the code for me. I guess from here you could do the same or create your own stored procedure to print the desired code. I'm not a SQL programmer so I don't know how to do that, but if someone does the programming of the above queries, please share it.
CLR 存储过程不会包含文本,因为它是 DLL 的链接。您需要获取 DLL 的源代码,
请参阅公共语言运行时 (CLR) 集成例如,编程概念
A CLR stored procedure will not have text as such as it is a link to a DLL. You will need to get the source code to the DLL
See Common Language Runtime (CLR) Integration Programming Concepts for example
简短的回答:不,你不能这样做。 (至少不是以编程方式/轻松地)
CLR 过程是从 .NET 程序集(二进制文件)加载的,并且没有简单的方法来获取此类文件的源代码。不在 SQL Server 内。
但是您可以使用 RedGate Reflector 等工具来反汇编 DLL 并查看/恢复存储过程的源代码。
Short answer: no, you can't do that. (At least not programatically/easily)
CLR procedures are loaded from .NET assemblies (binary files) and there is no simple way to get the source code of such file. Not within SQL Server.
But you can use tools like RedGate Reflector to disassemble DLL and view/recover source code of the stored procedure.
与类似的 T-SQL 对象不同,
CREATE [ STORED PROCEDURE |功能|触发|类型 | SQLCLR 对象的 AGGREGATE ] ...
语句不会按原样存储;它们是通过对象类型以及 sys.assemblies、sys. assembly_modules、sys.parameters、sys.types 的组合派生的 和sys. assembly_types
。如果您尝试使用 T-SQL 或其他非 .NET 语言构建这些
CREATE
语句,那么您需要从这些表中选择适当的数据并将其组合在一起。但是,如果您使用 .NET,则可以使用 SMO 库中的脚本编写器类 (Microsoft.SqlServer.Smo.dll)。它应该能够在 SQL Server 中编写任何内容的脚本。事实上,您可能应该使用它为您的工具编写所有内容的脚本,而不是使用查询。除了在 SSMS 中动态查看存储过程/函数/触发器定义(即快速且简单)之外,您不应该使用
sp_helptext
来提取对象定义。它做了很多不必要的工作,因为自 SQL Server 2000 以来它似乎只进行了少量更新。它的两个主要问题是:\r\n
)换行符,而不是有效的仅 LF 换行符(即\n
)。您可以通过查看该系统存储过程的定义来了解这一点:
相反,您应该使用
OBJECT_DEFINITION()
内置函数(它采用object_id
作为输入)或从包含以下内容的系统目录视图之一进行选择:这些定义:sys.sql_modules
、sys.server_sql_modules
、sys.system_sql_modules
和sys.system_sql_modules
。 p>Unlike similar T-SQL objects, the
CREATE [ STORED PROCEDURE | FUNCTION | TRIGGER | TYPE | AGGREGATE ] ...
statements for SQLCLR objects are not stored as-is; they are derived through the object type and a combination ofsys.assemblies
,sys.assembly_modules
,sys.parameters
,sys.types
, andsys.assembly_types
.If you are trying to construct these
CREATE
statements in T-SQL or some other non-.NET language, then you need to select the appropriate data from those tables and piece it all together. However, if you are using .NET, then you can make use of the Scripter Class in the SMO library ( Microsoft.SqlServer.Smo.dll ). It should be able to script anything in SQL Server. And in fact, you should probably use it to script everything for your tool instead of using queries.Outside of viewing stored procedure / function / trigger definitions on the fly in SSMS (i.e. quick and easy), you should not be using
sp_helptext
to extract object definitions. It does a lot of unnecessary work as it appears to be only minorly updated since SQL Server 2000. The two main issues with it are:\r\n
) newlines, not LF-only newlines (i.e.\n
) which are valid.You can see this by viewing the definition of that system stored procedure:
Instead, you should use either the
OBJECT_DEFINITION()
built-in function (which takes anobject_id
as input) or select from one of the system catalog views that contain these definitions:sys.sql_modules
,sys.server_sql_modules
,sys.system_sql_modules
, andsys.system_sql_modules
.我们遇到了更改未添加到源代码管理中的问题,因此我执行了以下操作来获取更新。
找到我需要的东西。
编写了一个快速控制台程序来获取已更改文件的源。
在我们的例子中,它适用于 assembly_id 为 68541 的记录以及 file_id 均大于 3 的多个文件
cs 文件的源位于名为 content 的列中,文件名位于名为 name 的列中。我将内容转换为字节数组,然后转换为字符串,并使用 filename.txt 将内容写入文本文件。
复制并粘贴更新的代码并推送到源代码管理。
We had an issue of changes not getting added to source control so I did the following to get the updates.
find what I needed.
wrote a quick console program to get the source for the files that were changed.
In our case it was for records having an assembly_id of 68541 and multiple files all having a file_id greater than 3
the source for the cs file is in a column named content and the file name is in a column named name. I converted the content to a byte array then a string and wrote the content to a text file using filename.txt.
copy and past the updated code and push to source control.
实际上,您可以通过检查 sys. assembly_files 目录视图来做到这一点:
Actually, you can do this - by inspecting the
sys.assembly_files
catalog view:要提取程序集,请运行以下命令:
然后使用 Redgate Reflector 或任何 .Net 反编译器(ilspy,...)对其进行反编译
To extract the assambly run this :
Then decompile it with Redgate Reflector or any .Net decompiler (ilspy, ...)
这个问题很老了,但是互联网上没有其他来源,只是说明如何使用 SSMS 脚本。
作为 Alex Castillo,我还对 SSMS 脚本过程进行了分析和逆向工程,然后将其全部合并到一个 T-SQL 查询中以方便使用。这是我得到的:
只需执行查询并将相应输出行中的值复制粘贴到新的查询窗口中并执行。该查询涵盖了很多方面,但不包括用户定义的类型(如果 SQL CLR 例程中有任何类型)。调整起来并不困难,只是我的代码中没有使用 SQL CLR UDT。
我希望有人会觉得它有用。
The question is quite old, but there are no other sources in the internet, just instructions how to use SSMS scripting.
As Alex Castillo, I also profiled and reverse-engineered SSMS scripting procedures and then combined it all in one T-SQL query for convenience. Here is what I got:
One just needs to execute the query and copy-paste value from corresponding output row into a new query window and execute. The query covers quite many aspects, but not, for example, user-defined types, if you have any in your SQL CLR routines. It is not that difficult to adjust, i just do not use SQL CLR UDT in my code.
I hope someone will find it useful.
这非常简单 - 如果您可以访问 SQL Server Management Studio。
右键单击 CLR 存储过程,然后选择 CREATE SCRIPT - 瞧。
快乐的 CLR。
-丹麦语。
Its pretty easy - if you have access to SQL Server Management Studio.
Right click the CLR Stored Procedure and then select CREATE SCRIPT - voilla.
Happy CLRing.
-Danish.