在Bash中执行PostgreSQL语句时的引号处理问题求助
问题解决:PostgreSQL自动创建用户时的语法错误
错误原因
你的SQL语句结构错误:'CREATE USER myuser'是独立的字符串常量,后面直接跟WITH PASSWORD不符合PostgreSQL语法。WITH PASSWORD是CREATE USER的子句,必须包含在要执行的SQL字符串内部。
正确解决方案
方案1:转义单引号(bash环境)
在bash中,用两个连续单引号表示字符串内部的单个单引号,确保完整的CREATE USER语句被包裹在SELECT的返回字符串中:
echo "SELECT 'CREATE USER myuser WITH PASSWORD ''mypassword''' WHERE NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'myuser')\gexec" | psql -h myhost -U admin -d mydb
方案2:使用双引号包裹密码
PostgreSQL支持用双引号包裹密码,配合bash的转义符\处理嵌套:
echo "SELECT 'CREATE USER myuser WITH PASSWORD \"mypassword\"' WHERE NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'myuser')\gexec" | psql -h myhost -U admin -d mydb
方案3:PostgreSQL美元引号(推荐,避免引号嵌套问题)
用PostgreSQL原生的美元引号语法$$...$$定义字符串,内部无需转义单引号,更适合复杂密码场景:
echo "SELECT \$\$CREATE USER myuser WITH PASSWORD 'mypassword'\$\$ WHERE NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'myuser')\gexec" | psql -h myhost -U admin -d mydb
原理说明
三种方案都是让SELECT语句返回完整合法的CREATE USER语句,再通过\gexec命令让psql自动执行返回的SQL,从而实现「不存在则创建」的逻辑。
内容的提问来源于stack exchange,提问作者user45097
相关产品推荐
相关产品推荐

