在 Postgresql 插入查询中出现“错误:语法错误位于或接近...”

s.k*_*han 0 sql postgresql node.js express

我对 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'
Run Code Online (Sandbox Code Playgroud)

现在我不知道问题出在哪里,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)
        );

`;
Run Code Online (Sandbox Code Playgroud)

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

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();
Run Code Online (Sandbox Code Playgroud)

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

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);
Run Code Online (Sandbox Code Playgroud)

Sch*_*ern 5

INSERT INTO authors (id, author_name, author_slug) 
VALUES 
(an3cxZh8ZD3tdtqG4wuwPR, Alan Paton, alan-paton);
Run Code Online (Sandbox Code Playgroud)

您的字符串值未加引号。一定是……

INSERT INTO authors (id, author_name, author_slug) 
VALUES 
('an3cxZh8ZD3tdtqG4wuwPR', 'Alan Paton', 'alan-paton');
Run Code Online (Sandbox Code Playgroud)

您可以在查询中添加引号,但不要这样做。您编写的查询不安全并且容易受到SQL 注入攻击不要将值插入到带有字符串连接的查询中

相反,使用参数

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

Postgres 将为您处理引用。这样更安全、更可靠、更快捷。


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

请注意,您可能还想使用自动增量主键,而不是自己生成 ID。对于 UUID 主键,加载uuid-ossp 包并使用其 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');
Run Code Online (Sandbox Code Playgroud)