我正在尝试解决PostgreSQL函数的问题,该函数每次用用户提供的新信息更新Web应用程序时都会创建(或替换)“视图”。
起初我以为它缺少逗号,并将逗号从', 4)'更改为'.valor,0)的数字),',但这似乎更可能是一个级联问题,但我无法弄清楚。
这是PostgreSQL函数中的代码区域:
CASE
WHEN string_agg(i_v.operador, ' '::text ORDER BY i_v.id_indicador, i_v.ordem) ~~ '%/%'::text THEN (' case when '::text || string_agg(
CASE
WHEN i_v_ant.operador = '/'::text THEN COALESCE(('cast(coalesce(v'::text || v.id_variavel) || '.valor,0) as numeric) '::text, ''::text)
ELSE ''::text
END, ' '::text ORDER BY i_v.id_indicador, i_v.ordem)) || ' = 0 then 0 else '::text
ELSE ''::text
END) || 'round('::text) || string_agg((COALESCE(i_v.aninhamento, ''::text) || COALESCE(('cast(coalesce(v'::text || v.id_variavel) || '.valor,0) as numeric) '::text, ''::text)) || COALESCE(i_v.operador, ''::text), ' '::text ORDER BY i_v.id_indicador, i_v.ordem)) || ',4) '::text) ||
CASE [...]
原始错误消息在强制转换时有一个指针“ ^”,因此我将其应指向的位置加粗了。
错误:\“ cast \” \ nLINE 7或附近的语法错误:... m(round(cast(cast(coalesce(v326.valor,0)as数字)) c ast(coale ...
完全错误(它带有\ r \ n \ t等,因此为了方便可视化而将其替换):
QUERY: insert into sistema.indicador_calculo (id_indicador,data,id_regiao,dimensao,id_territorio,valor) select 350 as id_indicador
,cast(date_trunc( 'year', coalesce(cast(v326.data as date),cast(v326.data as date))) as date) as data
,coalesce(cast(v326.id_regiao as numeric),cast(v326.id_regiao as numeric)) as id_regiao
,coalesce(cast(v326.dimensao as text),cast(v326.dimensao as text)) as dimensao
,8 as id_territorio
, sum( round(cast(coalesce(v326.valor,0) as numeric) cast(coalesce(v326.valor,0) as numeric) ,4) ) as valor
您能提供的任何帮助将不胜感激!
编辑:这是整个CREATE OR REPLACE语句:
CREATE OR REPLACE VIEW sistema.query_indicador AS
SELECT COALESCE(comp.id_indicador_pai, query_indicador.id_indicador) AS id_indicador,
query_indicador.id_territorio,
'insert into sistema.indicador_calculo (id_indicador,data,id_regiao,dimensao,id_territorio,valor) '::text ||
CASE
WHEN comp.id_indicador_pai IS NOT NULL THEN (((((' select '::text || comp.id_indicador_pai) || ',data,id_regiao,'::text) || COALESCE((''''::text || comp.dimensao) || ''''::text, 'dimensao'::text)) || ' ,id_territorio,valor from ('::text) || query_indicador.query) || ') query_indicador '::text
ELSE query_indicador.query
END AS query
FROM sistema.indicador_composicao comp
FULL JOIN ( SELECT i_v.id_indicador,
CASE
WHEN col.cont_terr = 0 AND NOT c_ant.id_territorio IS NULL OR i_v.id_variavel IS NULL THEN c_ant.id_territorio
ELSE c.id_territorio
END AS id_territorio,
(((((((((((((((((((((((((((((((((((((((((' select'::text || '
'::text) || i_v.id_indicador) || ' as id_indicador'::text) || '
'::text) || ','::text) || 'cast(date_trunc( ' ||
CASE
WHEN indic.periodicidade = 'mensal'::text THEN '''month'''::text
WHEN indic.periodicidade = 'anual'::text THEN '''year'''::text
WHEN indic.periodicidade = 'trimestral'::text THEN '''quarter'''::text
ELSE ''::text
END || ', coalesce('::text) || string_agg(('cast(v'::text || v.id_variavel) || '.data as date)'::text, ','::text ORDER BY i_v.id_indicador, i_v.ordem)) || ')) as date) as data'::text) || '
'::text) || ','::text) || 'coalesce('::text) || string_agg(('cast(v'::text || v.id_variavel) || '.id_regiao as numeric)'::text, ','::text ORDER BY i_v.id_indicador, i_v.ordem)) || ') as id_regiao'::text) || '
'::text) || ','::text) || 'coalesce('::text) || string_agg(('cast(v'::text || v.id_variavel) || '.dimensao as text)'::text, ','::text ORDER BY i_v.id_indicador, i_v.ordem)) || ') as dimensao'::text) || '
'::text) || ','::text) ||
CASE
WHEN col.cont_terr = 0 AND NOT c_ant.id_territorio IS NULL OR i_v.id_variavel IS NULL THEN c_ant.id_territorio
ELSE c.id_territorio
END) || ' as id_territorio'::text) || '
'::text) || ','::text) ||
' sum( ' ||
CASE
WHEN string_agg(i_v.operador, ' '::text ORDER BY i_v.id_indicador, i_v.ordem) ~~ '%/%'::text THEN (' case when '::text || string_agg(
CASE
WHEN i_v_ant.operador = '/'::text THEN COALESCE(('cast(coalesce(v'::text || v.id_variavel) || '.valor,0) as numeric) '::text, ''::text)
ELSE ''::text
END, ' '::text ORDER BY i_v.id_indicador, i_v.ordem)) || ' = 0 then 0 else '::text
ELSE ''::text
END) || 'round('::text) || string_agg((COALESCE(i_v.aninhamento, ''::text) || COALESCE(('cast(coalesce(v'::text || v.id_variavel) || '.valor,0) as numeric) '::text, ''::text)) || COALESCE(i_v.operador, ''::text), ' '::text ORDER BY i_v.id_indicador, i_v.ordem)) || ',4) '::text) ||
CASE
WHEN string_agg(i_v.operador, ' '::text ORDER BY i_v.id_indicador, i_v.ordem) ~~ '%/%'::text THEN ' end '::text
ELSE ''::text
END) || ' ) as valor '::text) || '
'::text) || ' from '::text) || '
'::text) || string_agg(((((
CASE
WHEN i_v.rank > 1 AND NOT (v.coluna_data IS NULL AND v.coluna_dimensao IS NULL AND v.distribuicao = true) THEN (('
'::text || v.tipo_cruzamento) || ' join '::text) || '
'::text
WHEN v.coluna_data IS NULL AND v.coluna_dimensao IS NULL AND v.distribuicao = true THEN ' cross join '::text
ELSE ''::text
END || '('::text) || c.query) || ') v'::text) ||
CASE
WHEN i_v.rank_variavel > 1 THEN NULL::integer
ELSE v.id_variavel
END) ||
CASE
WHEN i_v.rank > 1 AND NOT (v.coluna_data IS NULL AND v.coluna_dimensao IS NULL AND v.distribuicao = true) THEN ((((('
'::text || ' on '::text) ||
CASE
WHEN v.distribuicao = false THEN (((('v'::text || v_ant.id_variavel) || '.id_regiao = '::text) || 'v'::text) || v.id_variavel) || '.id_regiao '::text
ELSE ''::text
END) ||
CASE
WHEN v.distribuicao = false AND v.coluna_data IS NOT NULL AND v_ant.coluna_data IS NOT NULL THEN ' and '::text
ELSE ''::text
END) ||
CASE
WHEN v.coluna_data IS NOT NULL AND v_ant.coluna_data IS NOT NULL THEN (((('v'::text || v_ant.id_variavel) || '.data = '::text) || 'v'::text) || v.id_variavel) || '.data '::text
ELSE ''::text
END) ||
CASE
WHEN (v.distribuicao = false OR v.coluna_data IS NOT NULL AND v_ant.coluna_data IS NOT NULL) AND v.coluna_dimensao IS NOT NULL AND NOT ((v.desabilitar_dim_raiz = true OR v.desabilitar_dim_raiz = true) AND c.id_territorio = sistema.territorio_raiz(c.id_territorio)) THEN ' and '::text
ELSE ''::text
END) ||
CASE
WHEN v.coluna_dimensao IS NOT NULL AND NOT ((v.desabilitar_dim_raiz = true OR v.desabilitar_dim_raiz = true) AND c.id_territorio = sistema.territorio_raiz(c.id_territorio)) THEN (((('v'::text || v_ant.id_variavel) || '.dimensao = '::text) || 'v'::text) || v.id_variavel) || '.dimensao '::text
ELSE ''::text
END
ELSE ''::text
END, ''::text ORDER BY i_v.id_indicador, i_v.rank)) || '
'::text) || ' group by
coalesce('::text || string_agg(('cast(v'::text || v.id_variavel) || '.id_regiao as numeric)'::text, ','::text ORDER BY i_v.id_indicador, i_v.ordem) || ')
,cast(date_trunc( ' ||
CASE
WHEN indic.periodicidade = 'mensal'::text THEN '''month'''::text
WHEN indic.periodicidade = 'anual'::text THEN '''year'''::text
WHEN indic.periodicidade = 'trimestral'::text THEN '''quarter'''::text
ELSE ''::text
END || ',coalesce('::text || string_agg(('cast(v'::text || v.id_variavel) || '.data as date)'::text, ','::text ORDER BY i_v.id_indicador, i_v.ordem) || ')) as date)
,coalesce('::text || string_agg(('cast(v'::text || v.id_variavel) || '.dimensao as text)'::text, ','::text ORDER BY i_v.id_indicador, i_v.ordem) || ')
order by '::text) || '
'::text) || ' id_regiao'::text) || '
'::text) || ' ,data'::text) || '
'::text) || ' ,dimensao'::text AS query
FROM ( SELECT rank() OVER (PARTITION BY indicador_x_variavel.id_indicador ORDER BY indicador_x_variavel.ordem) AS rank,
rank() OVER (PARTITION BY indicador_x_variavel.id_indicador, indicador_x_variavel.id_variavel ORDER BY indicador_x_variavel.ordem) AS rank_variavel,
indicador_x_variavel.id_indicador,
indicador_x_variavel.id_variavel,
indicador_x_variavel.operador,
indicador_x_variavel.ordem,
indicador_x_variavel.aninhamento
FROM sistema.indicador_x_variavel) i_v
INNER JOIN sistema.indicador indic
ON indic.id_indicador = i_v.id_indicador
LEFT JOIN sistema.query_variavel c ON c.id_variavel = i_v.id_variavel
LEFT JOIN sistema.variavel v ON v.id_variavel = i_v.id_variavel
LEFT JOIN ( SELECT rank() OVER (PARTITION BY indicador_x_variavel.id_indicador ORDER BY indicador_x_variavel.ordem) AS rank,
indicador_x_variavel.id_indicador,
indicador_x_variavel.id_variavel,
indicador_x_variavel.operador,
indicador_x_variavel.ordem,
indicador_x_variavel.aninhamento
FROM sistema.indicador_x_variavel) i_v_ant ON i_v_ant.id_indicador = i_v.id_indicador AND i_v.rank = (i_v_ant.rank + 1)
LEFT JOIN sistema.variavel v_ant ON v_ant.id_variavel = i_v_ant.id_variavel
LEFT JOIN ( SELECT COALESCE(coluna.id_fonte_dados, f.id_fonte_dados) AS id_fonte_dados,
count(coluna.id_territorio) AS cont_terr
FROM sistema.coluna
FULL JOIN sistema.fonte_dados f ON f.id_fonte_dados = coluna.id_fonte_dados
GROUP BY (COALESCE(coluna.id_fonte_dados, f.id_fonte_dados))) col ON v.id_fonte_dados = col.id_fonte_dados
LEFT JOIN sistema.query_variavel c_ant ON c_ant.id_variavel = v_ant.id_variavel AND (col.cont_terr = 0 OR i_v.id_variavel IS NULL)
GROUP BY i_v.id_indicador, indic.periodicidade, (
CASE
WHEN col.cont_terr = 0 AND NOT c_ant.id_territorio IS NULL OR i_v.id_variavel IS NULL THEN c_ant.id_territorio
ELSE c.id_territorio
END)
ORDER BY i_v.id_indicador) query_indicador ON query_indicador.id_indicador = comp.id_indicador_filho;
以下是相应的视图SQL:
-- View: sistema.query_indicador
-- DROP VIEW sistema.query_indicador;
CREATE OR REPLACE VIEW sistema.query_indicador AS
SELECT COALESCE(comp.id_indicador_pai, query_indicador.id_indicador) AS id_indicador,
query_indicador.id_territorio,
'insert into sistema.indicador_calculo (id_indicador,data,id_regiao,dimensao,id_territorio,valor) '::text ||
CASE
WHEN comp.id_indicador_pai IS NOT NULL THEN (((((' select '::text || comp.id_indicador_pai) || ',data,id_regiao,'::text) || COALESCE((''''::text || comp.dimensao) || ''''::text, 'dimensao'::text)) || ' ,id_territorio,valor from ('::text) || query_indicador.query) || ') query_indicador '::text
ELSE query_indicador.query
END AS query
FROM sistema.indicador_composicao comp
FULL JOIN ( SELECT i_v.id_indicador,
CASE
WHEN col.cont_terr = 0 AND NOT c_ant.id_territorio IS NULL OR i_v.id_variavel IS NULL THEN c_ant.id_territorio
ELSE c.id_territorio
END AS id_territorio,
((((((((((((((((((((((((((((((((((((((((((((((((((((' select'::text || '
'::text) || i_v.id_indicador) || ' as id_indicador'::text) || '
'::text) || ','::text) || 'cast(date_trunc( '::text) ||
CASE
WHEN indic.periodicidade = 'mensal'::text THEN '''month'''::text
WHEN indic.periodicidade = 'anual'::text THEN '''year'''::text
WHEN indic.periodicidade = 'trimestral'::text THEN '''quarter'''::text
ELSE ''::text
END) || ', coalesce('::text) || string_agg(('cast(v'::text || v.id_variavel) || '.data as date)'::text, ','::text ORDER BY i_v.id_indicador, i_v.ordem)) || ')) as date) as data'::text) || '
'::text) || ','::text) || 'coalesce('::text) || string_agg(('cast(v'::text || v.id_variavel) || '.id_regiao as numeric)'::text, ','::text ORDER BY i_v.id_indicador, i_v.ordem)) || ') as id_regiao'::text) || '
'::text) || ','::text) || 'coalesce('::text) || string_agg(('cast(v'::text || v.id_variavel) || '.dimensao as text)'::text, ','::text ORDER BY i_v.id_indicador, i_v.ordem)) || ') as dimensao'::text) || '
'::text) || ','::text) ||
CASE
WHEN col.cont_terr = 0 AND NOT c_ant.id_territorio IS NULL OR i_v.id_variavel IS NULL THEN c_ant.id_territorio
ELSE c.id_territorio
END) || ' as id_territorio'::text) || '
'::text) || ','::text) || ' sum( '::text) ||
CASE
WHEN string_agg(i_v.operador, ' '::text ORDER BY i_v.id_indicador, i_v.ordem) ~~ '%/%'::text THEN (' case when '::text || string_agg(
CASE
WHEN i_v_ant.operador = '/'::text THEN COALESCE(('cast(coalesce(v'::text || v.id_variavel) || '.valor,0) as numeric) '::text, ''::text)
ELSE ''::text
END, ' '::text ORDER BY i_v.id_indicador, i_v.ordem)) || ' = 0 then 0 else '::text
ELSE ''::text
END) || 'round('::text) || string_agg((COALESCE(i_v.aninhamento, ''::text) || COALESCE(('+ cast(coalesce(v'::text || v.id_variavel) || '.valor,0) as numeric) '::text, ''::text)) || COALESCE(i_v.operador, ''::text), ' '::text ORDER BY i_v.id_indicador, i_v.ordem)) || ',4) '::text) ||
CASE
WHEN string_agg(i_v.operador, ' '::text ORDER BY i_v.id_indicador, i_v.ordem) ~~ '%/%'::text THEN ' end '::text
ELSE ''::text
END) || ' ) as valor '::text) || '
'::text) || ' from '::text) || '
'::text) || string_agg(((((
CASE
WHEN i_v.rank > 1 AND NOT (v.coluna_data IS NULL AND v.coluna_dimensao IS NULL AND v.distribuicao = true) THEN (('
'::text || v.tipo_cruzamento) || ' join '::text) || '
'::text
WHEN v.coluna_data IS NULL AND v.coluna_dimensao IS NULL AND v.distribuicao = true THEN ' cross join '::text
ELSE ''::text
END || '('::text) || c.query) || ') v'::text) ||
CASE
WHEN i_v.rank_variavel > 1 THEN NULL::integer
ELSE v.id_variavel
END) ||
CASE
WHEN i_v.rank > 1 AND NOT (v.coluna_data IS NULL AND v.coluna_dimensao IS NULL AND v.distribuicao = true) THEN ((((('
'::text || ' on '::text) ||
CASE
WHEN v.distribuicao = false THEN (((('v'::text || v_ant.id_variavel) || '.id_regiao = '::text) || 'v'::text) || v.id_variavel) || '.id_regiao '::text
ELSE ''::text
END) ||
CASE
WHEN v.distribuicao = false AND v.coluna_data IS NOT NULL AND v_ant.coluna_data IS NOT NULL THEN ' and '::text
ELSE ''::text
END) ||
CASE
WHEN v.coluna_data IS NOT NULL AND v_ant.coluna_data IS NOT NULL THEN (((('v'::text || v_ant.id_variavel) || '.data = '::text) || 'v'::text) || v.id_variavel) || '.data '::text
ELSE ''::text
END) ||
CASE
WHEN (v.distribuicao = false OR v.coluna_data IS NOT NULL AND v_ant.coluna_data IS NOT NULL) AND v.coluna_dimensao IS NOT NULL AND NOT ((v.desabilitar_dim_raiz = true OR v.desabilitar_dim_raiz = true) AND c.id_territorio = sistema.territorio_raiz(c.id_territorio)) THEN ' and '::text
ELSE ''::text
END) ||
CASE
WHEN v.coluna_dimensao IS NOT NULL AND NOT ((v.desabilitar_dim_raiz = true OR v.desabilitar_dim_raiz = true) AND c.id_territorio = sistema.territorio_raiz(c.id_territorio)) THEN (((('v'::text || v_ant.id_variavel) || '.dimensao = '::text) || 'v'::text) || v.id_variavel) || '.dimensao '::text
ELSE ''::text
END
ELSE ''::text
END, ''::text ORDER BY i_v.id_indicador, i_v.rank)) || '
'::text) || ' group by
coalesce('::text) || string_agg(('cast(v'::text || v.id_variavel) || '.id_regiao as numeric)'::text, ','::text ORDER BY i_v.id_indicador, i_v.ordem)) || ')
,cast(date_trunc( '::text) ||
CASE
WHEN indic.periodicidade = 'mensal'::text THEN '''month'''::text
WHEN indic.periodicidade = 'anual'::text THEN '''year'''::text
WHEN indic.periodicidade = 'trimestral'::text THEN '''quarter'''::text
ELSE ''::text
END) || ',coalesce('::text) || string_agg(('cast(v'::text || v.id_variavel) || '.data as date)'::text, ','::text ORDER BY i_v.id_indicador, i_v.ordem)) || ')) as date)
,coalesce('::text) || string_agg(('cast(v'::text || v.id_variavel) || '.dimensao as text)'::text, ','::text ORDER BY i_v.id_indicador, i_v.ordem)) || ')
order by '::text) || '
'::text) || ' id_regiao'::text) || '
'::text) || ' ,data'::text) || '
'::text) || ' ,dimensao'::text AS query
FROM ( SELECT rank() OVER (PARTITION BY indicador_x_variavel.id_indicador ORDER BY indicador_x_variavel.ordem) AS rank,
rank() OVER (PARTITION BY indicador_x_variavel.id_indicador, indicador_x_variavel.id_variavel ORDER BY indicador_x_variavel.ordem) AS rank_variavel,
indicador_x_variavel.id_indicador,
indicador_x_variavel.id_variavel,
indicador_x_variavel.operador,
indicador_x_variavel.ordem,
indicador_x_variavel.aninhamento
FROM sistema.indicador_x_variavel) i_v
JOIN sistema.indicador indic ON indic.id_indicador = i_v.id_indicador
LEFT JOIN sistema.query_variavel c ON c.id_variavel = i_v.id_variavel
LEFT JOIN sistema.variavel v ON v.id_variavel = i_v.id_variavel
LEFT JOIN ( SELECT rank() OVER (PARTITION BY indicador_x_variavel.id_indicador ORDER BY indicador_x_variavel.ordem) AS rank,
indicador_x_variavel.id_indicador,
indicador_x_variavel.id_variavel,
indicador_x_variavel.operador,
indicador_x_variavel.ordem,
indicador_x_variavel.aninhamento
FROM sistema.indicador_x_variavel) i_v_ant ON i_v_ant.id_indicador = i_v.id_indicador AND i_v.rank = (i_v_ant.rank + 1)
LEFT JOIN sistema.variavel v_ant ON v_ant.id_variavel = i_v_ant.id_variavel
LEFT JOIN ( SELECT COALESCE(coluna.id_fonte_dados, f.id_fonte_dados) AS id_fonte_dados,
count(coluna.id_territorio) AS cont_terr
FROM sistema.coluna
FULL JOIN sistema.fonte_dados f ON f.id_fonte_dados = coluna.id_fonte_dados
GROUP BY (COALESCE(coluna.id_fonte_dados, f.id_fonte_dados))) col ON v.id_fonte_dados = col.id_fonte_dados
LEFT JOIN sistema.query_variavel c_ant ON c_ant.id_variavel = v_ant.id_variavel AND (col.cont_terr = 0 OR i_v.id_variavel IS NULL)
GROUP BY i_v.id_indicador, indic.periodicidade, (
CASE
WHEN col.cont_terr = 0 AND NOT c_ant.id_territorio IS NULL OR i_v.id_variavel IS NULL THEN c_ant.id_territorio
ELSE c.id_territorio
END)
ORDER BY i_v.id_indicador) query_indicador ON query_indicador.id_indicador = comp.id_indicador_filho;
ALTER TABLE sistema.query_indicador
OWNER TO postgres;
...以及一个示例行(具有3列):
COLUMN(type): VALUE
-------------------
id_indicador(integer): 326
id_territorio(integer): 7
query(text): "insert into sistema.indicador_calculo (id_indicador,data,id_regiao,dimensao,id_territorio,valor) select
326 as id_indicador
,cast(date_trunc( 'year', coalesce(cast(v298.data as date),cast(v299.data as date))) as date) as data
,coalesce(cast(v298.id_regiao as numeric),cast(v299.id_regiao as numeric)) as id_regiao
,coalesce(cast(v298.dimensao as text),cast(v299.dimensao as text)) as dimensao
,7 as id_territorio
, sum( case when cast(coalesce(v299.valor,0) as numeric) = 0 then 0 else round(+ cast(coalesce(v298.valor,0) as numeric) / + cast(coalesce(v299.valor,0) as numeric) ,4) end ) as valor
from
(select
cast(date_trunc('year',ano) as date) as data
,id_ou as id_regiao
,trim(both ' ' from funcao_gov) as dimensao,298 as id_variavel
,7 as id_territorio
,sum(cast(replace(valor_gasto,',','.') as numeric)) as valor
from fonte_dados.ouc_gasto_funcao f
group by id_ou
,cast(date_trunc('year',ano) as date)
,trim(both ' ' from funcao_gov)
order by id_ou
,cast(date_trunc('year',ano) as date)
,trim(both ' ' from funcao_gov)) v298
inner join
(select
cast(date_trunc('year',ano) as date) as data
, cast(null as numeric) as id_regiao
,null as dimensao,299 as id_variavel
,4 as id_territorio
,sum(cast(replace(valor_gasto,',','.') as numeric)) as valor
from fonte_dados.ouc_gasto_funcao f
group by cast(null as numeric)
,cast(date_trunc('year',ano) as date)
, dimensao
order by cast(null as numeric)
,cast(date_trunc('year',ano) as date)
, dimensao ) v299
on v298.data = v299.data
group by
coalesce(cast(v298.id_regiao as numeric),cast(v299.id_regiao as numeric))
,cast(date_trunc( 'year',coalesce(cast(v298.data as date),cast(v299.data as date))) as date)
,coalesce(cast(v298.dimensao as text),cast(v299.dimensao as text))
order by
id_regiao
,data
,dimensao"