Почему SQL Server SHOWPLAN_XML через DbCommand(параметризованный) не возвращает результаты?

Я хочу собрать план запросов через C# для улучшения развития.

Мой подход заключается в использовании DbCommand а также SET SHOWPLAN_XML ON

Но...

  • Non-parameterized query вернет план запроса в сборе.
  • Parameterized query ничего не вернет!

И SQL Server 2008 R2, и LocalDB(2012) имеют одинаковую проблему.

Как я могу получить план параметризованного запроса?

Знаете ли вы, почему мой параметризованный запрос не планируется?


[Пример: шаги для воспроизведения]

1. Создать таблицу.

СОЗДАТЬ СТОЛ Банан (
  BananaId             int IDENTITY(100,1),
  Название nvarchar(512),);
ИДТИ

ALTER TABLE Банан
    ADD CONSTRAINT Banana_PK ПЕРВИЧНЫЙ КЛЮЧ (BananaId);
ИДТИ

2. Выполнять запросы

  • Непараметрический запрос

    Это будет план возврата:

    using (var conn = new SqlConnection( {Connection Strings} )) {
        conn.Open();
        DbCommand command = conn.CreateCommand();
    
        command.CommandText = "SET SHOWPLAN_XML ON;";
        command.CommandType = CommandType.Text;
        command.ExecuteNonQuery();
    
        command.CommandText = "SELECT BananaId, Title FROM Banana Where BananaId = 999";
        var plan = (string)command.ExecuteScalar();
    
        command.CommandText = "SET SHOWPLAN_XML OFF;";
        command.ExecuteNonQuery();
    
        Debug.WriteLine(plan); // <ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" ...
    }
    
  • Праметрический запрос

    Это не план реагирования:

    using (var conn = new SqlConnection( {Connection Strings} )) {
        conn.Open();
        DbCommand command = conn.CreateCommand();
    
        command.CommandText = "SET SHOWPLAN_XML ON;";
        command.CommandType = CommandType.Text;
        command.ExecuteNonQuery();
    
        command.CommandText = "SELECT BananaId, Title FROM Banana Where BananaId = @BananaId";
        var parameter = command.CreateParameter();
        parameter.ParameterName = "@BananaId";
        parameter.Value = 999;
        command.Parameters.Add(parameter);
        var plan = (string)command.ExecuteScalar();
    
        command.CommandText = "SET SHOWPLAN_XML OFF;";
        command.ExecuteNonQuery();
    
        Debug.WriteLine(plan); // (null)
    }
    

2 ответа

Вместо того, чтобы создавать SqlParameters, создайте кучу операторов T-SQL DECLARE и добавьте префикс к вашему запросу. Тогда план будет работать как положено.

DECLARE @BananaId INT
SELECT BananaId, Title FROM Banana Where BananaId = @BananaId

Наконец я нашел уродливый и ограниченный ответ.
Почему угры? Потому что он должен выполнять SQL!

Итак... Я должен исключить "NON SELECT" SQL, чтобы избежать дублирования данных.

Я мог бы получить QueryPlan при следовании в то же время.

  1. использование SET STATISTICS XML ON(OFF)
  2. использование ExecuteReader()
Другие вопросы по тегам