以编程方式获取所有存储过程的简单方法
Posted
技术标签:
【中文标题】以编程方式获取所有存储过程的简单方法【英文标题】:Simple way to programmatically get all stored procedures 【发布时间】:2010-09-15 05:19:51 【问题描述】:有没有办法使用 C# 从 SQL Server 2005 Express 数据库中获取存储过程?我想以您可以使用 SQL Server Management Studio 编写脚本的方式导出所有这些数据,而无需安装 GUI。
我看到了一些通过 PowerShell 执行操作的参考,但最终我真正想要的是 C# 控制台应用程序。
澄清......
我想编写存储过程的脚本。 Select * from sys.procedures
的列表很有帮助,但最后我需要编写每个脚本。
【问题讨论】:
【参考方案1】:This blog post 建议对你的数据库运行这个:
select * from sys.procedures
【讨论】:
【参考方案2】:您可以编写 C# 代码在您的数据库上运行以下查询。
Select * from sys.procedures
【讨论】:
【参考方案3】:只需从 SYS.PROCEDURES 读取 SELECT NAME 的输出,然后为每个存储过程调用 EXEC sp_HelpText SPNAME,您将获得每行一行文本的记录集。
【讨论】:
SELECT NAME from SYS.PROCEDURES 返回系统存储过程,而不是用户定义的存储过程。如果您从 SSMS 运行此语句,那么是的,您将获得所有存储过程。正如我所说,通过 c# 代码运行此语句将仅返回系统存储过程。【参考方案4】:我认为这就是您真正想要的:
select SPECIFIC_NAME,ROUTINE_DEFINITION from information_schema.routines
里面还有很多其他有用的专栏...
【讨论】:
INFORMATION_SCHEMA(在 SQL 2005 中)中的 ROUTINE_DEFINITION 不幸地因长 SP 而被截断。我将为此追踪我的代码并将其发布在另一个答案中。【参考方案5】:您可以为此使用 SMO。首先,将这些程序集的引用添加到您的项目中:
Microsoft.SqlServer.ConnectionInfo Microsoft.SqlServer.Smo Microsoft.SqlServer.SmoEnum它们位于 GAC 中(浏览到 C:\WINDOWS\assembly 文件夹)。
使用以下代码作为脚本存储过程的示例:
using System;
using System.Collections.Generic;
using System.Data;
using Microsoft.SqlServer.Management.Smo;
class Program
static void Main(string[] args)
Server server = new Server(@".\SQLEXPRESS");
Database db = server.Databases["Northwind"];
List<SqlSmoObject> list = new List<SqlSmoObject>();
DataTable dataTable = db.EnumObjects(DatabaseObjectTypes.StoredProcedure);
foreach (DataRow row in dataTable.Rows)
string sSchema = (string)row["Schema"];
if (sSchema == "sys" || sSchema == "INFORMATION_SCHEMA")
continue;
StoredProcedure sp = (StoredProcedure)server.GetSmoObject(
new Urn((string)row["Urn"]));
if (!sp.IsSystemObject)
list.Add(sp);
Scripter scripter = new Scripter();
scripter.Server = server;
scripter.Options.IncludeHeaders = true;
scripter.Options.SchemaQualify = true;
scripter.Options.ToFileOnly = true;
scripter.Options.FileName = @"C:\StoredProcedures.sql";
scripter.Script(list.ToArray());
另请参阅:SQL Server: SMO Scripting Basics。
【讨论】:
也可以在 C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies 中找到所需的参考资料 我还必须参考 Microsoft.SqlServer.Management.Sdk.Sfc 从 Sql Server 2008R2 开始,URN class 已移至程序集 Microsoft.SqlServer.Management.Sdk.Sfc 中的命名空间 Microsoft.SqlServer.Management.Sdk.Sfc。【参考方案6】:;WITH ROUTINES AS (
-- CANNOT use INFORMATION_SCHEMA.ROUTINES because of 4000 character limit
SELECT o.type_desc AS ROUTINE_TYPE
,o.[name] AS ROUTINE_NAME
,m.definition AS ROUTINE_DEFINITION
FROM sys.sql_modules AS m
INNER JOIN sys.objects AS o
ON m.object_id = o.object_id
)
SELECT *
FROM ROUTINES
【讨论】:
【参考方案7】:你可以使用:
DataTable dtProcs = sqlConn.GetSchema("Procedures", new string[] databaseName );
DataTable dtProcParams = sqlConn.GetSchema("ProcedureParameters", new string[] databaseName );
如果需要,您还可以获得各种其他架构信息,例如表、索引等。
您可以获取有关 GetSchema() here 的信息和有关 SQL Server 架构集合 here 的信息
编辑:抱歉,这对实际编写信息没有帮助,但我想这是有用的信息。
【讨论】:
【参考方案8】:begin
--select column_name from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='Products'
--Declare the Table variable
DECLARE @GeneratedStoredProcedures TABLE
(
Number INT IDENTITY(1,1), --Auto incrementing Identity column
name VARCHAR(300) --The string value
)
--Decalre a variable to remember the position of the current delimiter
DECLARE @CurrentDelimiterPositionVar INT
declare @sqlCode varchar(max)
--Decalre a variable to remember the number of rows in the table
DECLARE @Count INT
--Populate the TABLE variable using some logic
INSERT INTO @GeneratedStoredProcedures SELECT name FROM sys.procedures where name like 'procGen_%'
--Initialize the looper variable
SET @CurrentDelimiterPositionVar = 1
--Determine the number of rows in the Table
SELECT @Count=max(Number) from @GeneratedStoredProcedures
--A variable to hold the currently selected value from the table
DECLARE @CurrentValue varchar(300);
--Loop through until all row processing is done
WHILE @CurrentDelimiterPositionVar <= @Count
BEGIN
--Load current value from the Table
SELECT @CurrentValue = name FROM @GeneratedStoredProcedures WHERE Number = @CurrentDelimiterPositionVar
--Process the current value
--print @CurrentValue
set @sqlCode = 'drop procedure ' + @CurrentValue
print @sqlCode
--exec (@sqlCode)
--Increment loop counter
SET @CurrentDelimiterPositionVar = @CurrentDelimiterPositionVar + 1;
END
end
【讨论】:
【参考方案9】:如果您在 sqlmetal.exe(从数据库生成代码的 LINQ-to-SQL 的独立部分)上打开一罐反射器,您可以看到它用于获取所有存储的列表的 SQL 语句程序和功能。 SQL 与the one in this answer 相似但不完全相同。
【讨论】:
【参考方案10】:public static void GenerateTableScript()
Server databaseServer = default(Server);//DataBase Server Name
databaseServer = new Server("yourDatabase Server Name");
string strFileName = @"C:\Images\Your FileName_" + DateTime.Today.ToString("yyyyMMdd") + ".sql"; //20120720`enter code here
if (System.IO.File.Exists(strFileName))
System.IO.File.Delete(strFileName);
List<SqlSmoObject> list = new List<SqlSmoObject>();
Scripter scripter = new Scripter(databaseServer);
Database dbUltimateSurvey = databaseServer.Databases["YourDataBaseName"];//DataBase Name
//Table scripting Writing
DataTable dataTable1 = dbUltimateSurvey.EnumObjects(DatabaseObjectTypes.Table);
foreach (DataRow drTable in dataTable1.Rows)
//string strTableSchema = (string)drTable["Schema"];
//if (strTableSchema == "dbo")
// continue;
Table dbTable = (Table)databaseServer.GetSmoObject(new Urn((string)drTable["Urn"]));
if (!dbTable.IsSystemObject)
if (dbTable.Name.Contains("SASTool_"))
list.Add(dbTable);
scripter.Server = databaseServer;
scripter.Options.IncludeHeaders = true;
scripter.Options.SchemaQualify = true;
scripter.Options.ToFileOnly = true;
scripter.Options.FileName = strFileName;
scripter.Options.DriAll = true;
scripter.Options.AppendToFile = true;
scripter.Script(list.ToArray());//Table Script completed
//Store Procedures scripting Writing
list = new List<SqlSmoObject>();
DataTable dataTable = dbUltimateSurvey.EnumObjects(DatabaseObjectTypes.StoredProcedure);
foreach (DataRow row in dataTable.Rows)
string sSchema = (string)row["Schema"];
if (sSchema == "sys" || sSchema == "INFORMATION_SCHEMA")
continue;
StoredProcedure sp = (StoredProcedure)databaseServer.GetSmoObject(
new Urn((string)row["Urn"]));
if (!sp.IsSystemObject)
if (sp.Name.Contains("custom_"))
list.Add(sp);
scripter.Server = databaseServer;
scripter.Options.IncludeHeaders = true;
scripter.Options.SchemaQualify = true;
scripter.Options.ToFileOnly = true;
scripter.Options.FileName = strFileName;
scripter.Options.DriAll = true;
scripter.Options.AppendToFile = true;
scripter.Script(list.ToArray()); // Stored procedure Script completed
【讨论】:
【参考方案11】:假设你有一个名为 sqlCon 的 SqlConnection
对象,最简单的方法是调用 sqlCon.GetSchema("Procedures")
【讨论】:
【参考方案12】:这是我刚刚在MSSQL中测试并使用的SQL
SELECT NAME from SYS.PROCEDURES
order by name
如果您需要查找特定名称或子字符串/文本
SELECT NAME from SYS.PROCEDURES
where name like '%<TEXT_TO_LOOK_FOR>%'
order by name
替换为例如:
SELECT NAME from SYS.PROCEDURES
where name like '%CUSTOMER%'
order by name
然后打电话
EXEC sp_HelpText SPNAME
对于每个存储过程,您将获得每行一行文本的记录集
【讨论】:
以上是关于以编程方式获取所有存储过程的简单方法的主要内容,如果未能解决你的问题,请参考以下文章