сообщение bind предоставляет 3 параметра, но для подготовленного оператора требуется 0 [Node js, pg]

Я хочу передать параметры моему запросу pg следующим образом:

    await client.query("DO\n" +
    "$do$\n" +
    "DECLARE\n" +
    "  _db TEXT := $1;\n" +
    "  _user TEXT := $2;\n" +
    "  _password TEXT := $3;\n" +
    "BEGIN\n" +
    "  CREATE EXTENSION IF NOT EXISTS dblink; -- enable extension \n" +
    "  IF EXISTS (SELECT 1 FROM pg_database WHERE datname = _db) THEN\n" +
    "    RAISE NOTICE 'Database already exists';\n" +
    "  ELSE\n" +
    "    PERFORM dblink_connect('host=localhost user=' || _user || ' password=' || _password || ' dbname=' || current_database());\n" +
    "    PERFORM dblink_exec('CREATE DATABASE ' || _db);\n" +
    "  END IF;\n" +
    "END\n" +
    "$do$", [process.env.database, process.env.user, process.env.password]);

Но я получаю bind message supplies 3 parameters, but prepared statement "" requires 0. Если я не передаю массив параметров, я получаю ошибку there is no parameter $1.

Итак, как я могу передать параметры моему запросу?


person GorgeousPuree    schedule 18.10.2020    source источник
comment
Прочтите это DO и посмотрите, что там говорится о параметрах.   -  person Adrian Klaver    schedule 18.10.2020
comment
Спасибо за комментарий, Адриан. Но, честно говоря, я несколько раз перечитывал эту страницу и до сих пор не понимаю причины такого поведения. Документацию Postgre трудно понять... Похоже на что-то со знаком доллара. Может быть, мне нужно углубиться в DO и долларовые котировки. Я заменил долларовые параметры строковой интерполяцией и оставил ее.   -  person GorgeousPuree    schedule 18.10.2020
comment
Проблема в том, что DO не принимает параметры. $* скрыты внутри DO, ваш [process.env.database, process.env.user, process.env.password] не имеет к ним доступа, отсюда и сообщение об ошибке. Вам понадобится что-то вроде правильной функции (db, user, pwd), в которую вы могли бы передать параметры. Не очень хорошо знаю pg, но не могли бы вы построить db TEXT := $1;\n" как db TEXT := process.env.database ;\n"?   -  person Adrian Klaver    schedule 18.10.2020
comment
О, теперь я вижу, большое спасибо за разъяснение. Ну вроде, я сделал это с помощью интерполяции строк вот так: _db TEXT := '${process.env.database}'; Вы можете написать ответ, что DO не принимает параметров, и я отмечу его как правильный.   -  person GorgeousPuree    schedule 18.10.2020
comment
Я бы упустил, если бы не упомянул, что важно убедиться, что значения, передаваемые таким образом, должны быть правильно проверены заранее.   -  person Adrian Klaver    schedule 18.10.2020


Ответы (1)