Ошибка субд 42601

Syntax errors are quite common while coding.

But, things go for a toss when it results in website errors.

PostgreSQL error 42601 also occurs due to syntax errors in the database queries.

At Bobcares, we often get requests from PostgreSQL users to fix errors as part of our Server Management Services.

Today, let’s check PostgreSQL error in detail and see how our Support Engineers fix it for the customers.

What causes error 42601 in PostgreSQL?

PostgreSQL is an advanced database engine. It is popular for its extensive features and ability to handle complex database situations.

Applications like Instagram, Facebook, Apple, etc rely on the PostgreSQL database.

But what causes error 42601?

PostgreSQL error codes consist of five characters. The first two characters denote the class of errors. And the remaining three characters indicate a specific condition within that class.

Here, 42 in 42601 represent the class “Syntax Error or Access Rule Violation“.

In short, this error mainly occurs due to the syntax errors in the queries executed. A typical error shows up as:

Here, the syntax error has occurred in position 119 near the value “parents” in the query.

How we fix the error?

Now let’s see how our PostgreSQL engineers resolve this error efficiently.

Recently, one of our customers contacted us with this error. He tried to execute the following code,

CREATE OR REPLACE FUNCTION prc_tst_bulk(sql text)
RETURNS TABLE (name text, rowcount integer) AS
$$
BEGIN
WITH m_ty_person AS (return query execute sql)
select name, count(*) from m_ty_person where name like '%a%' group by name
union
select name, count(*) from m_ty_person where gender = 1 group by name;
END
$$ LANGUAGE plpgsql;

But, this ended up in PostgreSQL error 42601. And he got the following error message,

ERROR: syntax error at or near "return"
LINE 5: WITH m_ty_person AS (return query execute sql)

Our PostgreSQL Engineers checked the issue and found out the syntax error. The statement in Line 5 was a mix of plain and dynamic SQL. In general, the PostgreSQL query should be either fully dynamic or plain. Therefore, we changed the code as,

RETURN QUERY EXECUTE '
WITH m_ty_person AS (' || sql || $x$)
SELECT name, count(*)::int FROM m_ty_person WHERE name LIKE '%a%' GROUP BY name
UNION
SELECT name, count(*)::int FROM m_ty_person WHERE gender = 1 GROUP BY name$x$;

This resolved the error 42601, and the code worked fine.

[Need more assistance to solve PostgreSQL error 42601?- We’ll help you.]

Conclusion

In short, PostgreSQL error 42601 occurs due to the syntax errors in the code. Today, in this write-up, we have discussed how our Support Engineers fixed this error for our customers.

PREVENT YOUR SERVER FROM CRASHING!

Never again lose customers to poor server speed! Let us help you.

Our server experts will monitor & maintain your server 24/7 so that it remains lightning fast and secure.

GET STARTED

var google_conversion_label = «owonCMyG5nEQ0aD71QM»;

Your function would work like this:

CREATE OR REPLACE FUNCTION prc_tst_bulk(sql text)
  RETURNS TABLE (name text, rowcount int)
  LANGUAGE plpgsql AS 
$func$
BEGIN
   RETURN QUERY EXECUTE '
   WITH v_tb_person AS (' || sql || $x$)
   SELECT name, count(*)::int FROM v_tb_person WHERE nome LIKE '%a%' GROUP BY name
   UNION
   SELECT name, count(*)::int FROM v_tb_person WHERE gender = 1 GROUP BY name$x$;
END     
$func$;

Call:

SELECT * FROM prc_tst_bulk($$SELECT a AS name, b AS nome, c AS gender FROM tbl$$)

You cannot mix plain and dynamic SQL the way you tried to do it. The whole statement is either all dynamic or all plain SQL. So I am building one dynamic statement to make this work. You may be interested in the chapter about executing dynamic commands in the manual.

The aggregate function count() returns bigint, but you had rowcount defined as integer, so you need an explicit cast ::int to make this work.

I use dollar quoting to avoid quoting hell.

However, is this supposed to be a honeypot for SQL injection attacks or are you seriously going to use it? For your very private and secure use, it might be ok-ish — though I wouldn’t even trust myself with a function like that. If there is any possible access for untrusted users, such a function is a loaded footgun. It’s impossible to make this secure.

Craig (a sworn enemy of SQL injection) might get a light stroke when he sees what you forged from his answer to your preceding question. :)

The query itself seems rather odd, btw. The two SELECT terms might be merged into one. But that’s beside the point here.

   Лекс

07.02.17 — 17:24

После обновления сервера 1С:Предприятие с 8.2 на 8.3 при работе c программой выскакивает сообщение об ошибке (даже при тестировании базы):

Ошибка СУБД

42601:ERROR: syntax error at near «not»

LINE 1: create table if not exists _tmpRCT (TabID bytea not null pri…

Платформа 8.3.9.2170, PostgreSQL 9.0.3-3.1C(x64), лицензии софтовые

   Artful Den

1 — 07.02.17 — 17:31

Выгрузку базы под 8.2, загрузку под 8.3 пробовали?

   Лекс

2 — 07.02.17 — 17:36

Нет. Базы на постгре висят уже, обновилась только платформа сервера.

   Artful Den

3 — 07.02.17 — 17:38

(2) Так вроде бы ничего не мешает попробовать, поднимите 2 сервера 1с параллельно, если 8.2 не осталось уже.

   Фрэнки

4 — 07.02.17 — 17:54

с какого на какой релиз 1С был переход?

   Фрэнки

5 — 07.02.17 — 17:54

то, что прыгнули на самый последний — это конечно здорово, но с какого спрыгивал — не написал

   Karamzin

6 — 07.02.17 — 18:04

Не исправили видимо. Мы переходили на 8.3.9.2033 — та же фигня была. Пришлось поставить 8.3.8.1747 — минимально нужный для Бухгалтерии 2.0. Все нормально завелось.

   pessimist

7 — 07.02.17 — 18:11

(0) 8.3.9.2170 не поддерживает работу с PostgreSQL 9.0.3-3.1C(x64), если вы используете сборку 1С. В документации это отражено. И наоборот, старые платформы 1С не поддерживают новые сборки PostgreSQL.

Теоретически вероятно можно собрать версию 9.0.3 для работы с платформой  8.3.9. Практически в этом нет смысла.

Выгрузка в dt на старой платформе и загрузка из dt на новой платформе с новым SQL сервером.

Несколько SQL серверов могут жить под одной ОС. Например по портам разнести. Или по интерфейсам.

   Karamzin

8 — 07.02.17 — 18:14

(7) У нас стоит 9.4.2-1.1C, и это нам не помогло.

   Karamzin

9 — 07.02.17 — 18:15

Последняя 1с-кая сборка от 17.06.15. Тогда 8.3.9, наверное, только в мыслях у разработчика была.

   ansh15

10 — 07.02.17 — 18:23

(9) Можно попробовать сборку от Postgres Professional, 9.4.10, или 9.5.5-9.6.1, для эксперимента.

https://postgrespro.ru/products/1c_build

   Karamzin

11 — 07.02.17 — 18:44

(10) Видели. Пока решили не пробовать. Но спасибо за ссылку!

   Лекс

12 — 08.02.17 — 12:59

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

Поэтому решил все снести к чертям и установить заново.

Спасибо    ansh15 за наводку на 9.4.10, поставил сразу его, пока полет нормальный.

   Лекс

13 — 08.02.17 — 13:52

(7)  если не секрет, ссыль можете дать, где в документации указано, что не работает, что-то не нашел

   dmrjan

14 — 08.02.17 — 14:16

Вот тут вроде как подобная тема обсуждается:

http://postgresql.ru.net/node/214401

«В одном из ответов говориться, что до версии 9.1 операторы DELETE, UPDATE, INSERT не могут быть использованы в подзапросах.»

   dmrjan

15 — 08.02.17 — 14:23

(10) Все-таки лучше начинать с 9.6.1, там патчи для 1С доработанные. Все равно разработчики говорят, что «экспериментальная» практически такая же боевая.

   pessimist

16 — 08.02.17 — 16:49

(13)Но у меня сейчас доступа к сайту ИТС нет. Забыли продлить.

Вот что написано в файле Osobennosti_reliza_9.4.2-1.1C.txt, который можно скачать там же где и сборку 9.4.2-1.1C Postgresql:

«Поддержка этой версии в 1С:Предприятии 8.3 реализована в версии 8.3.3 и старше.

Для использования PostgreSQL 9.4.2-1.1C с версиями 1С:Предприятия ниже 8.3.3 необходимо его собрать с установленым значением параметра integer_datetimes=off»

Вероятно что-то похожее есть и в документации на платформу.

Для старых версий платформы (более старые чем 8.3.3) нужно использовать старые версии PostgreSQL,  если не ошибаюсь, 9.0 и более старые. Для новых платформ нужно использовать 9.2 и новее. Про 9.1 просто не помню.

  

ansh15

17 — 09.02.17 — 00:36

(15) Да, нормально работает, потестировал на ней наши базы, проблем не возникало.

I have a table address_all and it is inherited by several address tables. address_history inherits from parent table history_all and keeps current address information. I am creating new table which inherits address_all table and copies information from address_history to new table.

My stored procedure is like this below. I am having some error when I call it. To better explain error I am using line number.

1  CREATE OR REPLACE FUNCTION somefunc()
2  RETURNS void AS
3  $BODY$
4  DECLARE
5   year_id INTEGER;
6   month_id INTEGER;
7   week_id INTEGER;
8   addresstablename text; 
9   backupdays text;
10 BEGIN
11  week_id := EXTRACT(DAY FROM TIMESTAMP 'now()');
12  month_id := EXTRACT(MONTH FROM TIMESTAMP 'now()');
13  year_id := EXTRACT(YEAR FROM TIMESTAMP 'now()');
14  addresstablename := 'address_history_' || week_id || '_' || month_id || '_' || year_id;
15  backupdays:= date_trunc('hour',CURRENT_TIMESTAMP - interval '7 days');
16  EXECUTE 'create table ' || addresstablename || '() INHERITS (address_all)';
17  EXECUTE 'insert into ' || addresstablename || ' select * from address_history where address_timestamp >= ' || backupdays || ''; --AS timestamp without time zone);  
18 END;
19 $BODY$
20 LANGUAGE 'plpgsql' VOLATILE;

When I run:

select somefunc()

I get this error:

ERROR:  syntax error at or near "12"
LINE 1: ...story where address_timestamp >= 2012-07-31 12:00:00-0...
                                                         ^
QUERY:  insert into address_history_7_8_2012 select * from address_history where address_timestamp >= 2012-07-31 12:00:00-04
CONTEXT:  PL/pgSQL function "somefunc" line 14 at EXECUTE statement

 ********** Error **********

ERROR: syntax error at or near "12"
SQL state: 42601
Context: PL/pgSQL function "somefunc" line 14 at EXECUTE statement

Erwin Brandstetter's user avatar

asked Aug 7, 2012 at 16:24

prakashpoudel's user avatar

Try this largely simplified form:

CREATE OR REPLACE FUNCTION somefunc()
  RETURNS void AS
$func$
DECLARE
 addresstablename text := 'address_history_' || to_char(now(), 'FMDD_MM_YYYY');

BEGIN
 EXECUTE 
 'CREATE TABLE ' || addresstablename || '() INHERITS (address_all)';

 EXECUTE
 'INSERT INTO ' || addresstablename || '
  SELECT *
  FROM   address_history
  WHERE  address_timestamp >= $1'
 USING date_trunc('hour', now() - interval '7 days');

END
$func$ LANGUAGE plpgsql;

Major points:

  • You can assign variables in plpgsql at declaration time. Simplifies code.

  • Use to_char() to format your date. Much simpler.

  • now() and CURRENT_TIMESTAMP do the same.

  • Don’t quote 'now()', use now() (without quotes) if you want the current timestamp.

  • Use the USING clause with EXECUTE, so you don’t have to convert the timestamp to text and back — possibly running into quoting issues like you did. Faster, simpler, safer.

  • In LANGUAGE plpgsql, plpgsql is a keyword and should not be quoted.

  • You may want to check if the table already exists with CREATE TABLE IF NOT EXISTS, available since PostgreSQL 9.1.

answered Aug 7, 2012 at 17:05

Erwin Brandstetter's user avatar

Erwin BrandstetterErwin Brandstetter

595k144 gold badges1056 silver badges1215 bronze badges

1

Apparently you need to quote backupdays, or it is not seen as a string from where to parse a timestamp.

answered Aug 7, 2012 at 16:27

LSerni's user avatar

LSerniLSerni

55.3k10 gold badges65 silver badges107 bronze badges

0

You’re building SQL using string manipulation so you have to properly quote everything just like in any other language. There are a few functions that you’ll want to know about:

  • quote_ident: quote an identifier such as a table name.
  • quote_literal: quote a string to use as a string literal.
  • quote_nullable: as quote_literal but properly handles NULLs as well.

Something like this will server you better:

EXECUTE 'create table ' || quote_ident(addresstablename) || ...
EXECUTE 'insert into '  || quote_ident(addresstablename) || ... || quote_literal(backupdays) ...

The quote_ident calls aren’t necessary in your case but they’re a good habit.

answered Aug 7, 2012 at 17:07

mu is too short's user avatar

mu is too shortmu is too short

425k70 gold badges829 silver badges795 bronze badges

5

Добрый вечер. Есть выражение:

$this->insertStmt = $this->connection->getPdo()->prepare("
    INSERT INTO files (
           real_name, 
           virtual_name, 
           album,
           size,
           resolution, 
           duration, 
           comment,
           path,
           user
    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
");

Которое вызывается как обычно:

protected function doInsert(object $object)
{
    $values = [
        $object->getRealName(),
        $object->getVirtualName(),
        $object->getAlbum(),
        $object->getSize(),
        $object->getResolution(),
        $object->getDuration(),
        $object->getComment(),
        $object->getPath(),
        $object->getUser(),
    ];
       
    $this->insertStmt->execute($values);
}

Примерное содержание $values:

array(9) { 
    [0]=> string(15) "BvrK9z6UPxY.jpg" 
    [1]=> string(16) "1265dde1c67abc1c" 
    [2]=> string(23) "По умолчанию" 
    [3]=> int(54973) 
    [4]=> string(7) "720x430" 
    [5]=> NULL 
    [6]=> string(0) "" 
    [7]=> string(108) "files/id5cd487313a93a/По умолчанию/2019-05-10/1265dde1c67abc1c.jpg" 
    [8]=> string(15) "id5cd487313a93a" 
}

Сообщение ошибки:

Type: PDOException
Code: 42601
Message: SQLSTATE[42601]: Syntax error: 7 ОШИБКА: ошибка синтаксиса (примерное положение: "user") LINE 11: user ^

С точки зрения синтаксиса вроде все верно, много раз перепроверил, IDE ни на что не ругается. В чем трабл, господа?

Понравилась статья? Поделить с друзьями:
  • Ошибка субд 1cv8
  • Ошибка субару форестер p0031
  • Ошибка субару трибека р0175
  • Ошибка субару трибека p0306
  • Ошибка субару трибека p0340