How do I use variables in a postgresql function for loop query

半世苍凉 提交于 2021-02-07 18:32:06

问题


I have a rather complicated function in postgresql (Version 9.4.4) that I need a bit of help with.

I have a loop (with lots of work below) declared like this inside of my function:

CREATE OR REPLACE function getRSI(
    psymbol varchar,
    pstarttime timestamp with time zone,
    pendtime timestamp with time zone,
    pduration double precision,
    ptable varchar
    )
 RETURNS SETOF rsi AS
 $BODY$
 declare
    row_data record;
    -- some variables
 begin
    FOR row_data IN SELECT datetime, value FROM "4" WHERE symbol = 'AAPL' 
    AND datetime BETWEEN '2015-11-23 09:30:00 -0500' AND 
    '2015-11-23 15:59:59-0500' LOOP
       -- enter code here
    END LOOP;
 end
 $BODY$ LANGUAGE plpgsql

This works perfectly, I can get the result of my function and have it crunch all the numbers for me.

I would like to get the loop to work like this:

FOR row_data in select datetime, value from quote_ident(ptable) 
where symbol = quote_literal(psymbol) and datetime 
between quote_literal(pstarttime) AND quote_literal(pendtime) LOOP

where ptable, psymbol, pstarttime and pendtime are variables passed from the function call.

But I would be happy having to hardcode a table and getting the other three things to be based on a variable:

FOR row_data in select datetime, value from "4" where symbol =
quote_literal(psymbol) and datetime between quote_literal(pstarttime)
AND quote_literal(pendtime) LOOP

Yes, I know that I have a table named after a number, nothing I can do about it in my current setup.

When I try to call the function with either of the above setups, I just get a blank. Any help would be appreciated. I can't find any documentation about using a variable in a for loop so it might not be possible.


回答1:


You need dynamic SQL with EXECUTE - but only to parameterize the table name (or other identifiers) - not necessary to parameterize values.

And do not concatenate parameter values into the query. That's more expensive and error prone than necessary. Use the USING clause of EXECUTE instead.

FOR row_data IN
   EXECUTE '
    SELECT datetime, value FROM ' || quote_ident(ptable) || '
    WHERE  symbol = $1
    AND    datetime between $2 AND $3'
   USING psymbol, pstarttime, pendtime
LOOP
  -- do stuff
END LOOP;

Or use format():

   EXECUTE format('
    SELECT datetime, value FROM %I 
    WHERE  symbol = $1
    AND    datetime between $2 AND $3', ptable)
   USING psymbol, pstarttime, pendtime

Related:

  • The manual on record types
  • Table name as a PostgreSQL function parameter
  • plpgsql - using dynamic table name in declare statement



回答2:


change your for loop like this

FOR row_data in execute 'select datetime, value from "4" where symbol =' || 
quote_literal(psymbol)  || 'and datetime between' || quote_literal(pstarttime)
|| 'AND ' || quote_literal(pendtime) LOOP


来源:https://stackoverflow.com/questions/34526233/how-do-i-use-variables-in-a-postgresql-function-for-loop-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!