PostgreSQL多表JOIN语句中字符串被识别为列的语法错误排查
多表JOIN中字符串'play'被识别为列名的原因
问题现象
单独对midiport表执行WHERE mp.implementation != 'play'条件时可正常运行,但将该条件放入多表JOIN的SQL语句中时,触发“column 'play' does not exist”的语法错误,数据库将字符串'play'当作列名处理。
涉及的SQL语句
SELECT DISTINCT midiport_id, mp.implementation, d.device_function, mp.serial, mp.dev, mp.subdev, mc.device_id, mc.target, mc.mask, mf.midi_function_id, kd.divn, mc.dev, mc.channel, d.inputs, d.outputs, mc.lo_key, mc.hi_key, mc.program, mc.case_value, mc.num_value, mc.tab_device_id, mf.status, pd.divn, mp.local_port, mp.console_id, mc.controlling_tab_device_id, mc.controlling_tab_default, mp.digit_offset, mp.digit_size FROM midiport mp join console c on c.console_id = mp.console_id and mp.console_id = 652 JOIN midi_input_rules mc USING (midiport_id) JOIN device d ON (d.device_id = mc.device_id) join midi_function mf on mf.name = mc.datasource LEFT OUTER JOIN pipe_division kd ON kd.key_division_id = mc.key_division_id LEFT OUTER JOIN pipe_division pd ON pd.pipe_division_id = mc.pipe_division_id where kd.divn is null or kd.divn = (select min(divn) from pipe_division pdm where mc.key_division_id = pdm.key_division_id) AND mp.implementation != ‘play’ ORDER BY midiport_id, mc.case_value, mc.channel, mc.target, mc.mask;
原因分析
问题出在条件mp.implementation != ‘play’中的引号:这里使用的是中文全角单引号‘’,而非数据库能识别的英文半角单引号''。
数据库的SQL语法规则中,只有英文半角单引号才会被视为字符串常量的边界标记;而中文全角单引号不属于SQL语法的合法引号,会被数据库当作标识符(列名、表名等)的一部分,因此数据库会将‘play’解析为一个名为‘play’的列,自然找不到这个列,从而抛出“column 'play' does not exist”的错误。
至于单独执行时正常,大概率是你在单独测试时使用了正确的英文半角单引号,而复制到多表JOIN语句时不小心输入了全角引号。
解决方法
将条件中的中文全角单引号替换为英文半角单引号,修改后的条件语句为:
AND mp.implementation != 'play'
内容的提问来源于stack exchange,提问作者Cheetaiean
相关产品推荐
相关产品推荐

