PSQL 函数不能转义引号
Posted
技术标签:
【中文标题】PSQL 函数不能转义引号【英文标题】:PSQL function cannot escaping quotes 【发布时间】:2018-05-08 06:04:51 【问题描述】:我有如下查询。分析和比较不同服务器上同一张表的行数。它按预期工作,但如果有任何大小写混合的表名,例如:'stg.my_table_OTHER',则会遇到问题。
如果我添加像 stg."my_table_OTHER" 这样的引号,它会起作用。但它似乎不适用于功能。已经尝试使用 '\"stg.my_table_OTHER\"' 逃脱,但仍然没有运气。
请在我的查询下方找到。
问候, 里安
CREATE OR REPLACE FUNCTION dwh.sync_update_analyze(schemaname varchar, tablename varchar)
RETURNS integer AS $body$
DECLARE
passedSrc boolean;
passedTgt boolean;
rowcount bigint;
tgtcount bigint;
query text;
BEGIN
SELECT EXISTS (
SELECT 1
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = $1
AND c.relname = $2
AND c.relkind = 'r' -- only tables
) into passedSrc;
passedTgt = ops.runcmd('psql -h 666.66.6.666 -Atc "SELECT EXISTS ( SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = ''' || schemaname || ''' AND c.relname = ''' || tablename || ''' AND c.relkind = ''r'');"');
IF passedSrc = 't' and passedTgt = 't' THEN
query = ops.runcmd('psql -h 666.66.6.666 -Atc "ANALYZE ' || schemaname || '.' || tablename || ';"');
tgtcount = ops.runcmd('psql -h 666.66.6.666 -Atc "select count(*) from ' || schemaname || '.' || tablename || ';"');
EXECUTE '(select count(1) from ' || quote_ident($1) || '.' || quote_ident($2) || ')' INTO rowcount;
query := 'UPDATE dwh.table_list_2018 SET
move_data_to_dca = ''D'',
row_count = '|| rowcount || ',
target_cnt = '|| tgtcount ||'
WHERE schema = ''' || $1 || ''' and table_name = ''' || $2 || '''';
EXECUTE query;
ELSE
query := 'UPDATE dwh.table_list_2018 SET
move_data_to_dca = ''D'',
purge_table = ''Y'',
backup_location = ''table maybe purge on source or relation doesnt exists''
WHERE schema = ''' || $1 || ''' and table_name = ''' || $2 || '''';
EXECUTE query;
END IF;
return 0;
EXCEPTION WHEN OTHERS THEN
query := 'UPDATE dwh.table_list_2018 SET
move_data_to_dca = ''D'',
purge_table = ''Y'',
backup_location = ''table maybe purge on source or relation doesnt exists''
WHERE schema = ''' || $1 || ''' and table_name = ''' || $2 || '''';
EXECUTE query;
RETURN 1;
END
$body$ LANGUAGE plpgsql;
在这部分抛出错误
tgtcount = ops.runcmd('psql -h 666.66.6.666 -Atc "select count(*) from ' || schemaname || '.' || tablename || ';"');
当我编辑到
tgtcount = ops.runcmd('psql -h 666.66.6.666 -Atc "select count(*) from ' || schemaname || '.\"' || tablename || '\";"');
它抛出
HINT: Use the escape string syntax for escapes, e.g., E'\r\n'
INT: Use the escape string syntax for escapes, e.g., E'\r\n'.
QUERY: SELECT ops.runcmd('psql -h 666.66.6.666 -Atc "select count(*) from ' || $1 || '.\"' || $2 || '\";"')
CONTEXT: SQL statement in PL/PgSQL function "sync_update_analyze1" near line 26
WARNING: nonstandard use of escape in a string literal
仅供参考。我正在使用
"PostgreSQL 8.2.15 (Greenplum Database 4.3.18.0 build 1) on x86_64-unknown-linux-gnu, compiled by GCC gcc (GCC) 4.4.2 compiled on Nov 22 2017 18:54:31"
【问题讨论】:
【参考方案1】:我对greenplum一无所知,但如果它的行为类似于PostgreSQL,我会尝试这样:
tgtcount := ops.runcmd(
'psql -h 666.66.6.666 -Atc ''select count(*) from '
|| quote_ident(schemaname) || '.'
|| quote_ident(tablename) || ';'''
);
这样,您在 SQL 语句中使用单引号,这样就不会与 quote_ident
可能添加的双引号发生冲突。
【讨论】:
嗨,阿尔贝。感谢您的回复。我试过了,是的,它确实放了双引号,但它降低了大小写。并且仍然抛出错误预期的表不存在。 嗯,它在 PostgreSQL 中工作。考虑一下DO
声明:DO $$DECLARE s text := 'Schema'; t text := 'Table'; BEGIN RAISE NOTICE '%', 'psql -h 666.66.6.666 -Atc ''select count(*) from ' || quote_ident(s) || '.' || quote_ident(t) || ';'''; END;$$;
结果是:NOTICE: psql -h 666.66.6.666 -Atc 'select count(*) from "Schema"."Table";'
不知道你那边出了什么问题,但是我不知道ops.runcms
到底做了什么。
赋值给变量和 quote_ident 就可以了。现在可以了。谢谢大哥!
@ryanfauzi:如果你有答案,请考虑accepting it。以上是关于PSQL 函数不能转义引号的主要内容,如果未能解决你的问题,请参考以下文章