Я создаю хранимую процедуру для репликации вывода запроса, найденного в файле карты на нашем сервере карт.Возврат таблицы с хранимой процедурой plpgsql
Запрос:
select g.gid, g.geom, g.basin, a.\"DATE\", a.\"VALUE\"
from sarffg_basins_00_regional_3sec as g
join \"%prod_table%\" as a on g.basin = a.\"BASIN\"
where a.\"DATE\" = '%prod_date%'
Я не могу отправить вывод в целом из-за SO размещать ограничения длины, но важно то, что этот запрос дает мне мой вывод с именами столбцов. Регулировка синтаксиса, чтобы соответствовать обычной SQL для запуска внутри SQL-оболочки:
select g.gid,
g.geom,
g.basin,
a."DATE",
a."VALUE" from sarffg_basins_00_regional_3sec
as g
join "FFGS_PROCESSED_PRODUCT_ASM_SACSMA_UPPER_BASIN_TIMESERIES"
as a on g.basin = a."BASIN" where a."DATE" = '2017-01-12 18:00:00+00';
дает столбцы
gid | geom | basin | DATE | VALUE
Моя хранимая процедура имеет следующий обратный заголовок:
RETURNS table (
gid integer,
geom geometry(MultiPolygon,4326),
basin double precision,
date timestamptz,
value double precision
)
И с возвратом:
RETURN QUERY
EXECUTE 'SELECT g.'||quote_ident('gid')||',
g.'||quote_ident('geom')||',
g.'||quote_ident('basin')||',
a.'||quote_ident('DATE')||',
a.'||quote_ident('VALUE')||'
FROM sarffg_basins_00_regional_3sec AS g JOIN '||quote_ident(prod_table)||' AS a
ON g.'||quote_ident('basin')||' = a.'||quote_ident('BASIN')||'
WHERE a.'||quote_ident('DATE')||' = '''||adj_timestamp||'''';
Это дает мне тот же результат, за исключением имен столбцов. Я думаю, что это является причиной этой ошибки в моем файле проекта журнала ошибок:
Query error. Error executing query: ERROR: column "VALUE" does not exist LINE 1: select "VALUE",encode(ST_AsBinary(ST_Force2D("geom"),'NDR'),...
Я знаю, что колонка «VALUE» существует в prod_table, особенно принимая во внимание эту функцию отлично работает при вызове в Psql оболочки.
Что мне нужно сделать, чтобы мои выходные данные имели заголовки столбцов?
EDIT: немного больше контекста на файле карты.
Весь запрос в файле проекта заключается в следующем:
geom from (select g.gid, g.geom, g.basin, a.\"DATE\", a.\"VALUE\" from sarffg_basins_00_regional_3sec as g join \"%prod_table%\" as a on g.basin = a.\"BASIN\" where a.\"DATE\" = '%prod_date%') as subquery using unique gid using srid=4326
я в основном нужно повторить эту функцию с помощью хранимой процедуры, либо в его полностью или только подзапроса. Мои различные попытки можно найти здесь: Syntax error at or near "USING". Кажется, я пришел ближе с попыткой повторить только подзапроса - т.е.
geom from (select * from ingest_ffgs_prod_composite_csv('%prod_table%', 1484438400)) as subquery using unique gid using srid=4326
EDIT 2: Теперь, когда я провел больше времени, думая об этом, я не знаю, почему «VALUE» будет недостающее столбец, когда запрос выбирает только «geom» из подзапроса, возвращаемого из моей хранимой процедуры. Возможно, это не причина ошибки в конце концов.
РЕДАКТИРОВАТЬ 3: В соответствии с запросом здесь представлена вся функция.
CREATE OR REPLACE FUNCTION ingest_ffgs_prod_composite_csv(prod_table text, epoch_seconds bigint, original boolean DEFAULT false, roll_back boolean DEFAULT true)
RETURNS table (
gid integer,
geom geometry(MultiPolygon,4326),
basin double precision,
date timestamptz,
VALUE double precision
)
AS $$
DECLARE
c01n text := 'BASIN'; c01t text := 'double precision';
c02n text := 'MAP01'; c02t text := 'double precision';
c03n text := 'MAP03'; c03t text := 'double precision';
c04n text := 'MAP06'; c04t text := 'double precision';
c05n text := 'MAP24'; c05t text := 'double precision';
c06n text := 'GMAP06'; c06t text := 'double precision';
c07n text := 'GMAP24'; c07t text := 'double precision';
c08n text := 'ASMU06'; c08t text := 'double precision';
c09n text := 'ASML06'; c09t text := 'double precision';
c10n text := 'ASMT06'; c10t text := 'double precision';
c11n text := 'FFG01'; c11t text := 'double precision';
c12n text := 'FFG03'; c12t text := 'double precision';
c13n text := 'FFG06'; c13t text := 'double precision';
c14n text := 'PREVFFG01'; c14t text := 'double precision';
c15n text := 'PREVFFG03'; c15t text := 'double precision';
c16n text := 'PREVFFG06'; c16t text := 'double precision';
c17n text := 'FMAP01'; c17t text := 'double precision';
c18n text := 'FMAP03'; c18t text := 'double precision';
c19n text := 'FMAP06'; c19t text := 'double precision';
c20n text := 'IFFT01'; c20t text := 'double precision';
c21n text := 'IFFT03'; c21t text := 'double precision';
c22n text := 'IFFT06'; c22t text := 'double precision';
c23n text := 'PFFT01'; c23t text := 'double precision';
c24n text := 'PFFT03'; c24t text := 'double precision';
c25n text := 'PFFT06'; c25t text := 'double precision';
c26n text := 'FFFT01'; c26t text := 'double precision';
c27n text := 'FFFT03'; c27t text := 'double precision';
c28n text := 'FFFT06'; c28t text := 'double precision';
c29n text := 'PET06'; c29t text := 'double precision';
tablename_csv text := 'temp_table_csv';
tablename_ts text := 'temp_table_ts';
tablename_ret text := 'temp_table_ret';
full_timestamp timestamptz;
adj_timestamp_text text;
adj_timestamp timestamptz;
year double precision;
month double precision;
day double precision;
hour double precision;
year_text text;
month_text text;
day_text text;
hour_text text;
csv_base_path text;
csv_filename text;
csv_file_full_path text;
ret_rec record;
product text;
interval text;
curr_basin int;
curr_val double precision;
rec record;
existing_table boolean;
existing_data boolean := false;
ret_geom geometry(MultiPolygon,4326);
BEGIN
-- parse prod_table name to determine which product and time interval we need to build a timeseries for
-------------------------------------------------------------------------------------------------------
product := split_part(prod_table, '_', 4);
interval := rtrim(split_part(prod_table, '_', 6), 'HR');
IF interval = 'UPPE' THEN -- asm interval reads as 'UPPE'. Default to 6 hours
interval := '06';
END IF;
raise notice 'product: %', product;
raise notice 'interval: %', interval;
-- convert epoch seconds to timestamp for parsing
-------------------------------------------------
full_timestamp := to_timestamp(epoch_seconds);
year := date_part('year', full_timestamp);
month := date_part('month', full_timestamp);
day := date_part('day', full_timestamp);
IF roll_back THEN
hour := date_part('hour', full_timestamp) - (date_part('hour', full_timestamp)::integer % interval::int);
ELSE
hour := date_part('hour', full_timestamp);
END IF;
year_text := year;
month_text := month;
day_text := day;
hour_text := hour;
IF month < 10 THEN
month_text := '0' || month;
END IF;
IF day < 10 THEN
day_text := '0' || day;
END IF;
IF hour < 10 THEN
hour_text := '0' || hour;
END IF;
adj_timestamp_text := year_text || '-' || month_text || '-' || day_text || ' ' || hour_text || ':00:00+00';
adj_timestamp := adj_timestamp_text::timestamptz;
raise notice 'year: %', year_text;
raise notice 'month: %', month_text;
raise notice 'day: %', day_text;
raise notice 'hour: %', hour_text;
-- check if table with the desired data already exists within the database
--------------------------------------------------------------------------
EXECUTE format('SELECT EXISTS (
SELECT 1
FROM pg_tables
WHERE schemaname = ''public''
AND tablename = '''||prod_table||''')') INTO existing_table;
IF existing_table THEN
EXECUTE format('SELECT EXISTS (
SELECT 1
FROM '||quote_ident(prod_table)||'
WHERE '||quote_ident('DATE')||' = '''||adj_timestamp||''')') INTO existing_data;
END IF;
raise notice 'existing_table: %', existing_table;
raise notice 'existing_data: %', existing_data;
IF NOT existing_data THEN -- need to manually create tables from csv file
-- construct full path to csv file
----------------------------------
csv_base_path := '/SARFFG/EXP/DATA/EXPORTS/REGIONAL/'||year_text||'/'||month_text||'/'||day_text||'/COMPOSITE_CSV';
IF original THEN
csv_filename := year_text||month_text||day_text||'-'||hour_text||'00_ffgs_prod_composite_table_01hr_regional_original.csv';
ELSE
csv_filename := year_text||month_text||day_text||'-'||hour_text||'00_ffgs_prod_composite_table_01hr_regional.csv';
END IF;
csv_file_full_path := csv_base_path||'/'||csv_filename;
-----------------------------------------------
raise notice 'csv file: %', csv_file_full_path;
-- create temporary table to store CSV contents
-----------------------------------------------
EXECUTE format('CREATE TEMP TABLE '||tablename_csv||' ('||c01n||' '||c01t||',
'||c02n||' '||c02t||',
'||c03n||' '||c03t||',
'||c04n||' '||c04t||',
'||c05n||' '||c05t||',
'||c06n||' '||c06t||',
'||c07n||' '||c07t||',
'||c08n||' '||c08t||',
'||c09n||' '||c09t||',
'||c10n||' '||c10t||',
'||c11n||' '||c11t||',
'||c12n||' '||c12t||',
'||c13n||' '||c13t||',
'||c14n||' '||c14t||',
'||c15n||' '||c15t||',
'||c16n||' '||c16t||',
'||c17n||' '||c17t||',
'||c18n||' '||c18t||',
'||c19n||' '||c19t||',
'||c20n||' '||c20t||',
'||c21n||' '||c21t||',
'||c22n||' '||c22t||',
'||c23n||' '||c23t||',
'||c24n||' '||c24t||',
'||c25n||' '||c25t||',
'||c26n||' '||c26t||',
'||c27n||' '||c27t||',
'||c28n||' '||c28t||',
'||c29n||' '||c29t||') ON COMMIT DROP');
EXECUTE format('COPY '||tablename_csv||' FROM '''||csv_file_full_path||''' DELIMITER '','' CSV HEADER');
-- create temp timeseries table
-------------------------------
EXECUTE format('CREATE TEMP TABLE '||tablename_ts||' (date timestamptz, basin int, value double precision) ON COMMIT DROP');
FOR rec in SELECT * FROM temp_table_csv
LOOP
curr_basin := rec.basin;
IF product = 'MAP' THEN
IF interval = '01' THEN
curr_val := rec.map01;
ELSIF interval = '03' THEN
curr_val := rec.map03;
ELSIF interval = '06' THEN
curr_val := rec.map06;
ELSIF interval = '24' THEN
curr_val := rec.map24;
ELSE
raise warning 'interval not found';
EXIT;
END IF;
ELSIF product = 'ASM' THEN
IF interval = '06' THEN
curr_val := rec.asmu06;
ELSE
raise warning 'interval not found';
EXIT;
END IF;
ELSIF product = 'FFG' THEN
IF interval = '01' THEN
curr_val := rec.ffg01;
ELSIF interval = '03' THEN
curr_val := rec.ffg03;
ELSIF interval = '06' THEN
curr_val := rec.ffg06;
ELSE
raise warning 'interval not found';
EXIT;
END IF;
ELSIF product = 'FFT' THEN
IF interval = '01' THEN
curr_val := rec.fft01;
ELSIF interval = '03' THEN
curr_val := rec.fft03;
ELSIF interval = '06' THEN
curr_val := rec.fft06;
ELSE
raise warning 'interval not found';
EXIT;
END IF;
ELSE
raise warning 'product not found';
EXIT;
END IF;
INSERT INTO temp_table_ts (date, basin, value) VALUES (adj_timestamp, curr_basin, curr_val);
END LOOP;
RETURN QUERY
EXECUTE 'SELECT g.gid,
g.geom,
g.basin,
a.date,
a.value
FROM sarffg_basins_00_regional_3sec
AS g
JOIN '||tablename_ts||'
AS a
ON g.'||quote_ident('basin')||' = a.'||quote_ident('basin')||'
WHERE a.'||quote_ident('date')||' = '''||adj_timestamp||'''';
ELSE
RETURN QUERY
EXECUTE format('SELECT g.gid,
g.geom,
g.basin,
a."DATE",
a."VALUE"
FROM sarffg_basins_00_regional_3sec AS g
JOIN %I AS a ON g.basin = a."BASIN"
WHERE a."DATE" = $1', prod_table)
using adj_timestamp;
END IF;
END;
$$ LANGUAGE plpgsql;
EDIT 4: После того, как какой-то более должной осмотрительности, я вернулся к мысли вопрос приходит из-за отсутствия имен столбцов в моем выходе. Мои значения colorscales явно указывают «VALUE», но, очевидно, без имен столбцов он не знает, какой из них «VALUE».
Изменение моего запроса
select gid, geom, basin, "DATE", "VALUE" from ingest_ffgs_prod_composite_csv('%prod_table%', 1484438400)
дает мне мои имена столбцов, но не решить мою проблему, к сожалению.
SQL, в файле проекта работает как есть, единственное объяснение, у меня есть для этого является то, что mapfiles не использовать обычный синтаксис SQL. Запрос, который я запускал в оболочке sql для соответствия запросу mapfile: «select g.gid, g.geom, g.basin, a.» DATE », a.« VALUE »из sarffg_basins_00_regional_3sec, поскольку g присоединяется к« FFGS_PROCESSED_PRODUCT_ASM_SACSMA_UPPER_BASIN_TIMESERIES »в качестве на g.basin = a. "BASIN" где a. "DATE" = '2017-01-12 18: 00: 00 + 00'; ' –
Я думаю, что этот вопрос является дубликатом этого http: // stackoverflow. com/questions/41842492/syntax-error-at-or-near-using? noredirect = 1 # comment70881921_41842492, который уже принял ответ –