【问题标题】:Getting 'error: syntax error at or near...' in Postgresql insert query在 Postgresql 插入查询中获取“错误:在或附近出现语法错误”
【发布时间】:2021-12-04 23:41:26
【问题描述】:

我是 Postgresql 的新手,每天都在学习新事物。所以我有这个博客项目,我想在其中使用 PostgreSQL 作为数据库。但我有点卡在最基本的插入查询中,这会引发错误。我有三张桌子,postsauthorscategories。我想我可以正确地创建表格,但是当我尝试插入数据时,我得到了这个错误:

error: syntax error at or near 
length: 95,
  severity: 'ERROR',
  code: '42601',
  detail: undefined,
  hint: undefined,
  position: '122',
  internalPosition: undefined,
  internalQuery: undefined,
  where: undefined,
  schema: undefined,
  table: undefined,
  column: undefined,
  dataType: undefined,
  constraint: undefined,
  file: 'scan.l',
  line: '1180',
  routine: 'scanner_yyerror'

现在我不知道问题出在哪里,而且 Postgres 的错误也不是那么具体。

谁能告诉我哪里出错了?

这是表格:

const createInitialTables = `
        CREATE TABLE authors (
             id UUID NOT NULL,
             author_name VARCHAR(100) NOT NULL UNIQUE CHECK (author_name <> ''),
             author_slug VARCHAR(100) NOT NULL UNIQUE CHECK (author_slug <> ''),
             PRIMARY KEY (id)
        );

        CREATE TABLE posts (
             id UUID NOT NULL,
             post VARCHAR(500) NOT NULL CHECK (post<> ''),
             post_slug VARCHAR(500) NOT NULL CHECK (post_slug <> ''),
             author_id UUID NOT NULL,
             PRIMARY KEY (id),
             CONSTRAINT fk_authors FOREIGN KEY(author_id) REFERENCES authors(id)
        );

        CREATE TABLE categories (
             id UUID NOT NULL,
             category_name VARCHAR(50) NOT NULL CHECK (category_name <> ''),
             category_slug VARCHAR(50) NOT NULL CHECK (category_slug <> ''),
             post_id UUID NOT NULL,
             PRIMARY KEY (id),
             CONSTRAINT fk_posts FOREIGN KEY(post_id) REFERENCES posts(id)
        );

`;

这是我进行插入查询的异步函数:

const insertAuthor = async() => {

    try {

        const data       = await fs.readFile( path.join( __dirname + '../../data/data.json' ) );
        const parsedData = JSON.parse( data.toString() );

        const authorID   = short.generate();
        const authorName = parsedData[ 0 ].author;
        const authorSlug = slugify( parsedData[ 0 ].author, {
            strict: true,
            lower: true
        } );

        const insertData = `
            INSERT INTO authors (id, author_name, author_slug) 
            VALUES 
            (${authorID}, ${authorName}, ${authorSlug});
        `;

        await pool.query( insertData );

        console.log( 'Data inserted successfully!' );

    } catch ( e ) {
        console.log( e );
    }
};

insertAuthor();

更新---------------------------------------

这是 Postgres 日志文件的样子:

2021-10-18 01:23:16.885 +06 [5964] ERROR:  syntax error at or near "Paton" at character 122
2021-10-18 01:23:16.885 +06 [5964] STATEMENT:  
                INSERT INTO authors (id, author_name, author_slug) 
                VALUES 
                (an3cxZh8ZD3tdtqG4wuwPR, Alan Paton, alan-paton);

【问题讨论】:

  • Postgres 错误消息往往非常具体。看起来你的司机正在编辑细节。查看 Postgres 日志,它应该包含您需要的信息。如果您不理解它,请将错误消息复制并粘贴为文本以更新您的问题。
  • @AdrianKlaver 我已经用日志文件数据更新了 OP。

标签: sql node.js postgresql express


【解决方案1】:
INSERT INTO authors (id, author_name, author_slug) 
VALUES 
(an3cxZh8ZD3tdtqG4wuwPR, Alan Paton, alan-paton);

您的字符串值没有被引用。应该是……

INSERT INTO authors (id, author_name, author_slug) 
VALUES 
('an3cxZh8ZD3tdtqG4wuwPR', 'Alan Paton', 'alan-paton');

您可以在查询中添加引号,但不要。您所写的查询不安全并且容易受到SQL injection attack 的攻击。 不要在字符串连接的查询中插入值

改为使用parameters

const insertSQL = `
  INSERT INTO authors (id, author_name, author_slug) 
  VALUES ($1, $2, $3);
`;
await pool.query( insertSQL, [authorID, authorName, authorSlug] );

Postgres 将为您处理报价。这样更安全、更安全、更快捷。


请注意,an3cxZh8ZD3tdtqG4wuwPR 不是有效的 UUID。 UUID 是一个 128 位整数,通常表示为 32 个字符的十六进制字符串。

请注意,您可能还想使用autoincrementing primary keys 而不是自己生成 ID。对于 UUID 主键,加载 uuid-ossp package 并将其 UUID 函数用作您的默认值。

create extension "uuid-ossp";

create table authors (
  id uuid primary key default uuid_generate_v4(),

  -- There's no point in arbitrarily limiting the size of your text fields.
  -- They will only use as much space as they need.
  author_name text not null unique check (author_name <> ''),
  author_slug text not null unique check (author_slug <> '')
);

insert into authors (author_name, author_slug) 
values ('Alan Paton', 'alan-paton');

【讨论】:

  • 嘿,伙计,我没有收到此错误:error: invalid input syntax for type uuid: "hWBoUWD521QZoEUyV9KGtF"。我正在使用不同的包来生成 uuid,因为 Postgres 的本机 uuid 太大。我想要一些更短的东西。这会是个问题吗?
  • @s.khan 这不是一个有效的 UUID。是的,这是一个问题。为什么你觉得它太大了?对于这样一个简单的架构,您是否需要 UUID 主键?
  • 能否让原生uuid变短?原生 uuid 会解决这个问题吗?
  • @s.khan UUID 是 128 位。如果您想要更短的内容,则必须使用bytea 声明您自己的二进制列。但为什么呢?
  • @s.khan 您需要某种主键,但您可以只使用简单的整数。 Postgres 有serial data type which automatically increments
【解决方案2】:

在 INSERT 查询中,将字符串值添加到引号中 -

const insertData = `
    INSERT INTO authors (id, author_name, author_slug) 
    VALUES 
    ('${authorID}', '${authorName}', '${authorSlug}');`;  // added the quotes

【讨论】:

  • 虽然正确,但这是不安全的。 en.wikipedia.org/wiki/SQL_injection
  • 我以前试过这个。现在我得到这个错误:error: invalid input syntax for type uuid: "fyk6q6EsAqhwUQsXiEf6B2"
  • @Schwern,完全同意你的看法。应该对数据进行清理和绑定。
  • @Vedant 这可能是因为作者表是帖子表中的外键吗?
  • @s.khan 正如它所说,fyk6q6EsAqhwUQsXiEf6B2 不是有效的 UUID。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-26
  • 1970-01-01
  • 2017-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多