PostgreSQL执行INSERT插入语句报syntax error at or near错误如何解决
问题根因排查
- 直接语法错误原因:你拼接生成的INSERT语句中,所有字符串类型的字段值没有用单引号包裹。从PostgreSQL日志可以看到最终执行的SQL是:
INSERT INTO authors (id, author_name, author_slug) VALUES (an3cxZh8ZD3tdtqG4wuwPR, Alan Paton, alan-paton);
这里Alan Paton是带空格的字符串,没有单引号包裹的情况下,PostgreSQL会把空格识别为语法分隔符,解析到Paton的时候无法识别语法含义,就抛出了你看到的42601语法错误。同时id、author_slug两个值也属于字符串类类型,同样需要单引号包裹才能正确识别。
- 隐藏风险:你现在直接拼接SQL的写法存在SQL注入漏洞,一旦输入内容包含单引号、特殊字符就会触发语法错误,恶意输入甚至会篡改、删除数据库数据。
- 后续潜在错误:你的authors表id字段定义为UUID类型,当前你用
short.generate()生成的是短字符串,不符合UUID的标准格式,就算补上引号后续也会抛出类型不匹配错误。
修复方案
方案1:保留UUID类型id(推荐)
使用PostgreSQL参数化查询,不用手动处理引号、转义问题,同时避免SQL注入风险:
const insertAuthor = async() => { try { const data = await fs.readFile( path.join( __dirname, '../../data/data.json' ) ); const parsedData = JSON.parse( data.toString() ); // 生成标准UUID,可以用uuid包的v4方法 const authorID = require('uuid').v4(); const authorName = parsedData[ 0 ].author; const authorSlug = slugify( parsedData[ 0 ].author, { strict: true, lower: true } ); // 使用参数化查询,$1 $2 $3为参数占位符 const insertData = ` INSERT INTO authors (id, author_name, author_slug) VALUES ($1, $2, $3); `; // 按占位符顺序传值,pg驱动会自动处理类型、转义 await pool.query( insertData, [authorID, authorName, authorSlug] ); console.log( 'Data inserted successfully!' ); } catch ( e ) { console.log( e ); } };
提前安装uuid包即可使用:npm install uuid
方案2:保留短ID生成逻辑
修改authors表的id字段类型为VARCHAR,适配你生成的短ID长度:
CREATE TABLE authors ( id VARCHAR(32) 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) );
插入逻辑还是使用上面的参数化写法即可正常运行。
内容的提问来源于stack exchange,提问作者s.khan
相关产品推荐
相关产品推荐

