Как я могу получить список параметров из хранимой процедуры в SQL Server

Как указал Роквелл, проблема здесь была связана с расположением сценариев. Переместите их в заголовок, чтобы они загружались до того, как зависимые скрипты устранили проблему.

15
задан Matt Hamilton 29 August 2008 в 01:36
поделиться

8 ответов

Можно использовать SqlCommandBuilder. DeriveParameters () (см. SqlCommandBuilder. DeriveParameters - Получают информацию Параметра для Хранимой процедуры - Учебные руководства ADO.NET ) или существует этот путь , который не так изящен.

9
ответ дан 1 December 2019 в 01:39
поделиться

Вы хотите 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";

   // ....
}
15
ответ дан 1 December 2019 в 01:39
поделиться

Хотя не точно, что Вы хотите, вот некоторый пример кода, который использует SqlConnection. GetSchema () метод для возврата всех хранимых процедур, связанных с базой данных, и затем впоследствии всех названий параметра и типов для каждой хранимой процедуры. Пример ниже просто загружает это в переменные. Обратите внимание, что это также возвращает все "системные" хранимые процедуры, которые не могли бы быть желательными.

Steve

    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();
                }
            }
        }
    }
5
ответ дан 1 December 2019 в 01:39
поделиться

Можно использовать объект SqlCommandBuilder и назвать метод DeriveParameters.

В основном необходимо передать его команда, которая является установкой для вызова сохраненного proc, и это поразит DB, чтобы обнаружить параметры и создать соответствующие параметры в свойстве Parameters РЕДАКТИРОВАНИЯ SqlCommand

: Вы слишком быстры!!

2
ответ дан 1 December 2019 в 01:39
поделиться
SqlCommandBuilder.DeriveParameters(command)

Этот оператор делает то, к чему я нуждаюсь в нем.

Вот полный пример кода для способа, которым я решил эту проблему.

Public Sub GetLogEntriesForApplication(ByVal settings As FilterSettings,
                              Optional ByVal RowGovernor As Integer = -1)

    Dim command As New SqlCommand("GetApplicationActions", 
        New SqlConnection(m_environment.LoggingDatabaseConnectionString))
    Dim adapter As New SqlDataAdapter(command)

    Using command.Connection

        With command

            .Connection.Open()
            .CommandType = CommandType.StoredProcedure

            SqlCommandBuilder.DeriveParameters(command)

            With .Parameters

                If settings.FilterOnLoggingLevel Then
                    If .Contains("@loggingLevel") Then
                        .Item("@loggingLevel").Value = settings.LoggingLevel
                    End If
                End If

                If settings.FilterOnApplicationID Then
                    If .Contains("@applicationID") Then
                        .Item("@applicationID").Value = settings.ApplicationID
                    End If
                End If

                If settings.FilterOnCreatedDate Then
                    If .Contains("@startDate") Then
                        .Item("@startDate").Value = settings.CreatedDate.Ticks
                    End If
                End If

                If settings.FilterOnEndDate Then
                    If .Contains("@endDate") Then
                        .Item("@endDate").Value = settings.EndDate.Ticks
                    End If
                End If

                If settings.FilterOnSuccess Then
                    If .Contains("@success") Then
                        .Item("@success").Value = settings.Success
                    End If
                End If

                If settings.FilterOnProcess Then
                    If settings.Process > -1 Then
                        If .Contains("@process") Then
                            .Item("@process").Value = settings.Process
                        End If
                    End If
                End If

                If RowGovernor > -1 Then
                    If .Contains("@topRows") Then
                        .Item("@topRows").Value = RowGovernor
                    End If
                End If

            End With

        End With

        adapter.TableMappings.Clear()
        adapter.TableMappings.Add("Table", "ApplicationActions")
        adapter.TableMappings.Add("Table1", "Milestones")

        LogEntries.Clear()
        Milestones.Clear()
        adapter.Fill(m_logEntryData)

    End Using

End Sub
2
ответ дан 1 December 2019 в 01:39
поделиться

Все эти решения ADO.NET, просит библиотека кода запрашивать метаданные базы данных от Вашего имени. Если Вы собираетесь получить тот удар производительности во всяком случае, возможно, необходимо просто записать некоторым функциям помощника тот вызов

Select count(*) from information_schema.parameters 
where ...(proc name =.. param name=...) (pseudo-code)

Или, возможно, даже генерируйте свои параметры на основе списка параметрического усилителя, который Вы возвращаете. Эта техника будет работать с несколькими версиями MS SQL и иногда другие базы данных ANSI SQL.

0
ответ дан 1 December 2019 в 01:39
поделиться

У Mark есть лучшая реализация DeriveParameters. Как он сказал, удостоверьтесь Вы кэш как в это учебное руководство .

Однако, я думаю, что это - опасный способ решить Вашу исходную проблему базы данных sproc управление версиями. Если Вы собираетесь изменить подпись процедуры путем добавления или удаления параметров, необходимо выполнить одно из следующих действий:

  • Код назад совместимым способом при помощи значений по умолчанию (для новых параметрических усилителей) или путем простого игнорирования параметрического усилителя (для удаленных параметрических усилителей). Это гарантирует, что Ваш клиентский код может всегда называть любую версию Вашей хранимой процедуры.
  • Явно присваивают версию процедуре по имени (таким образом, у Вас будут my_proc и my_proc_v2). Это гарантирует, чтобы Ваш клиентский код и sprocs остались в синхронизации.

Доверие DeriveParameters для проверки, какую версию sproc Вы используете, походит на неправильный инструмент для задания, по моему скромному мнению.

1
ответ дан 1 December 2019 в 01:39
поделиться

I have been using DeriveParameters with .NET 1.1 and 2.0 since a couple of years now, and worked like a charm every time.

Now I'm working on my first assignment with .NET 3.5, and just found and ugly surprise: DeriveParameters is creating all parameters with SqlDbType "Variant", instead proper SqlDbTypes. This is creating a SqlException when trying to execute SPs with numeric parameters, because SQL Server 2005 says that sql-variant types cant be implictily converted to int (or smallint, or numeric) values.

I just tested the same code with .NET CF 2.0 and SQL Server 2000, and worked as expected, assigning the correct SqlDbType to each parameters.

I had tested .NET 2.0 apps against SQL Server 2005 Databases, so is not a SQL Server related issue, so it has to be something related with .NET 3.5

Any ideas?

0
ответ дан 1 December 2019 в 01:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: