Получение необработанной строки запроса SQL из подготовленных операторов PDO

Убедитесь, что файл json настроен на копирование в каталог, как описано в этого блога . В противном случае при сборке или отладке файл конфигурации не будет включен. Убедитесь, что вы изменили его в свойствах.

Причина, по которой вы не можете получить доступ к вашей конфигурации, заключается в том, что IConfigurationRoot не ссылается на зависимость для ConfigurationBuilder. Чтобы убедиться, что ваш контент конфигурации будет загружен, нужно будет сделать что-то вроде этого:

public static class ConfigurationProvider
{
     public static IConfiguration BuildConfiguration => new ConfigurationBuilder()
          .SetBasePath(Directory.GetCurrentDirectory())
          .AddJsonFile("appsettings.json", true, true)
          .Build();
}

Выше будет построена наша конфигурация, теперь мы должны использовать конфигурацию.

public static class ServiceProvider
{
     public static IServiceProvider BuildServiceProvider(IServiceCollection services) => services
          .BuildDependencies()
          .BuildServiceProvider();
}

Как только мы определили нашего провайдера, мы можем сделать следующее, чтобы мы могли передать наш IConfiguration вокруг приложения для доступа к объектам.

var serviceCollection = new ServiceCollection()
     .AddSingleton(configuration => ConfigurationProvider.BuildConfiguration());

var serviceProvider = ServiceProvider.BuildServiceProvider(serviceCollection);

Тогда внутри другого класса у вас будет следующее:

public class SampleContext : ISampleRepository
{
     private readonly string dbConection;

     public SampleContext(IConfiguration configuration) => configuration.GetConnectionString("dbConnection");

     ...
 }

Тогда наш appsettings.json будет выглядеть так:

{
  "ConnectionStrings": {
    "dbConnection": "..."
  }
}

Выше приведено правильный формат для объекта JSON. Если у вас есть вложенный объект вдоль этих линий:

{
     "Sample" : {
          "Api" : {
               "SampleGet" : "..."
          }
     }
}

Тогда ваш C # будет:

configuration.GetSection("Sample:Api")["SampleGet"];

Вышеуказанное основано на предположении, что ваша конфигурация и использование не совпадают последовательная область, т. е. непосредственно в вашей главной. Также вы должны использовать appsettings.json, так как это по умолчанию, меньше дополнительной проводки, если я правильно помню. Ваш JSON также должен быть правильно отформатирован.

Но это определенно сработает, если вам понадобится дополнительная помощь, дайте мне знать, и я могу выслать вам несколько примеров приложений ядра консоли, чтобы продемонстрировать их использование.

125
задан Mike 25 February 2013 в 23:17
поделиться

4 ответа

Я предполагаю, что Вы подразумеваете желание заключительного SQL-запроса со значениями параметров, интерполированными в него. Я понимаю, что это было бы полезно для отладки, но это не подготовленная работа операторов пути. Параметры не объединены с подготовленным оператором на клиентском, таким образом, PDO никогда не должен иметь доступа к строке запроса, объединенной с ее параметрами.

SQL-оператор отправляется на сервер базы данных, когда Вы действительно готовитесь (), и параметры отправляются отдельно, когда Вы действительно выполняетесь (). Журнал общего запроса MySQL действительно показывает заключительный SQL со значениями, интерполированными после выполнения (). Ниже выборка от моего журнала общего запроса. Я выполнил запросы от mysql CLI, не от PDO, но принцип является тем же.

081016 16:51:28 2 Query       prepare s1 from 'select * from foo where i = ?'
                2 Prepare     [2] select * from foo where i = ?
081016 16:51:39 2 Query       set @a =1
081016 16:51:47 2 Query       execute s1 using @a
                2 Execute     [2] select * from foo where i = 1

Можно также получить то, что Вы хотите при установке атрибута PDO PDO:: ATTR_EMULATE_PREPARES. В этом режиме PDO интерполируют параметры в SQL-запрос, и отправляет целый запрос, когда Вы выполняетесь (). Это не истинный подготовленный запрос. Вы обойдете преимущества подготовленных запросов путем интерполяции переменных в строку SQL, прежде чем выполнятся ().


Комментарий ре от @afilina:

Нет, текстовый SQL-запрос не объединен с параметрами во время выполнения. Таким образом, нет ничего, чтобы PDO показал Вам.

Внутренне, если Вы используете PDO:: ATTR_EMULATE_PREPARES, PDO делает копию из SQL-запроса и интерполирует значения параметров в него прежде, чем сделать готовить, и выполниться. Но PDO не выставляет этот измененный SQL-запрос.

Объект PDOStatement имеет $queryString свойства, но это установлено только в конструкторе для PDOStatement, и он не обновляется, когда запрос переписывается с параметрами.

Это был бы разумный запрос новых функций для PDO, чтобы попросить, чтобы они выставили переписанный запрос. Но даже который не дал бы Вам "полный" запрос, если Вы не используете PDO:: ATTR_EMULATE_PREPARES.

Поэтому я показываю обходное решение выше использования журнала общего запроса сервера MySQL, потому что в этом случае даже подготовленный запрос с заполнителями параметра переписывается на сервере со значениями параметров, заделанными в строку запроса. Но это только сделано во время входа, не во время выполнения запросов.

107
ответ дан 24 November 2019 в 00:59
поделиться

Упомянутое свойство $queryString, вероятно, только возвратится, запрос передал в без параметров, замененных их значениями. В .NET у меня есть часть выгоды моего исполнителя запроса, делают простую поисковую замену на параметрах с их значениями, которая была предоставлена так, чтобы журнал ошибок мог показать фактические значения, которые использовались для запроса. Необходимо смочь перечислить параметры в PHP и заменить параметры их присвоенным значением.

1
ответ дан 24 November 2019 в 00:59
поделиться

PDOStatement имеет $queryString общественной собственности. Это должно быть тем, что Вы хотите.

У меня есть просто уведомление, что PDOStatement имеет недокументированный метод debugDumpParams (), на который можно также хотеть посмотреть.

8
ответ дан 24 November 2019 в 00:59
поделиться
/**
 * Replaces any parameter placeholders in a query with the value of that
 * parameter. Useful for debugging. Assumes anonymous parameters from 
 * $params are are in the same order as specified in $query
 *
 * @param string $query The sql query with parameter placeholders
 * @param array $params The array of substitution parameters
 * @return string The interpolated query
 */
public static function interpolateQuery($query, $params) {
    $keys = array();

    # build a regular expression for each parameter
    foreach ($params as $key => $value) {
        if (is_string($key)) {
            $keys[] = '/:'.$key.'/';
        } else {
            $keys[] = '/[?]/';
        }
    }

    $query = preg_replace($keys, $params, $query, 1, $count);

    #trigger_error('replaced '.$count.' keys');

    return $query;
}
106
ответ дан 24 November 2019 в 00:59
поделиться
Другие вопросы по тегам:

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