使用C#和System.Data.SqlClient,有没有办法在实际执行之前检索属于SQL Server上的存储过程的参数列表?
我有一个"多环境"场景,其中有相同数据库架构的多个版本.环境的示例可以是"开发","分段"和"生产"."开发"将有一个版本的存储过程,"Staging"将有另一个版本.
我想要做的就是在传递一个值并调用存储过程之前验证参数是否存在.避免SqlException而不是必须捕获它对我来说是一个加分.
约书亚
您需要SqlCommandBuilder.DeriveParameters(SqlCommand)方法.请注意,它需要额外的数据库往返,因此它的性能有点显着.您应该考虑缓存结果.
一个示例电话:
using (SqlConnection conn = new SqlConnection(CONNSTRING)) using (SqlCommand cmd = new SqlCommand("StoredProc", conn)) { cmd.CommandType = CommandType.StoredProcedure; SqlCommandBuilder.DeriveParameters(cmd); cmd.Parameters["param1"].Value = "12345"; // .... }
您可以使用SqlCommandBuilder.DeriveParameters()(请参阅SqlCommandBuilder.DeriveParameters - 获取存储过程的参数信息 - ADO.NET教程)或者这种方式不是那么优雅.
虽然它不完全是您想要的,但这里有一些示例代码,它使用SqlConnection.GetSchema()方法返回与数据库关联的所有存储过程,然后返回每个存储过程的所有参数名称和类型.下面的示例只是将其加载到变量中.请注意,这也会返回所有"系统"存储过程,这可能是不可取的.
史蒂夫
public void LoadProcedureInfo() { SqlConnection connection = new SqlConnection(); ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings["ConnectionString"]; connection.ConnectionString = settings.ConnectionString; connection.Open(); DataTable procedureDataTable = connection.GetSchema("Procedures"); DataColumn procedureDataColumn = procedureDataTable.Columns["ROUTINE_NAME"]; if (procedureDataColumn != null) { foreach (DataRow row in procedureDataTable.Rows) { String procedureName = row[procedureDataColumn].ToString(); DataTable parmsDataTable = connection.GetSchema("ProcedureParameters", new string[] { null, null, procedureName }); DataColumn parmNameDataColumn = parmsDataTable.Columns["PARAMETER_NAME"]; DataColumn parmTypeDataColumn = parmsDataTable.Columns["DATA_TYPE"]; foreach (DataRow parmRow in parmsDataTable.Rows) { string parmName = parmRow[parmNameDataColumn].ToString(); string parmType = parmRow[parmTypeDataColumn].ToString(); } } } }