Question :
I wanted to pivot a table using cross tab function which have dynamic number of category names. By digging out the web I have found a solution.
Solution – http://www.rummandba.com/2013/03/postgresql-dynamic-crosstab-function.html
Function Used
DROP FUNCTION crosstab_dynamic_sql_gen_fn (source_sql text, category_sql
text, v_matrix_col_type varchar(100), v_matrix_rows_name_and_type
varchar(100),debug bool);
CREATE OR REPLACE FUNCTION crosstab_dynamic_sql_gen_fn (source_sql text,
category_sql text, v_matrix_col_type varchar(100),
v_matrix_rows_name_and_type varchar(100),debug bool default false)
RETURNS text AS $$
DECLARE
v_sql text;
curs1 refcursor;
v_val text;
BEGIN
v_sql = v_matrix_rows_name_and_type;
OPEN curs1 FOR execute category_sql;
Loop
FETCH curs1 INTO v_val;
exit when v_val IS NULL;
v_sql = v_sql ||' , "'||v_val||'" '||v_matrix_col_type;
IF debug THEN
RAISE NOTICE 'v_val = %',v_val;
END IF;
END LOOP;
CLOSE curs1;
v_sql := 'SELECT * from crosstab(' || chr(10) || E' ''||source_sql ||
E'','||chr(10) || E' ''||category_sql || E''' || chr(10)|| ' ) AS (' || v_sql ||')';
IF debug THEN
RAISE NOTICE 'v_sql = %',v_sql;
END IF;
RETURN v_sql;
END;
$$ language 'plpgsql';
Query used to get the result of the function
select crosstab_dynamic_sql_gen_fn('select emp_id, month, qty from sales
order by 1','select distinct month from sales','int','year text');
The result of the query is string. Can somebody tell me how to execute the query inside the string. Below is the result of query
Answer :
You pull it down to the client, and send it back to the server. That makes this a really bad idea. Even if you can dynamically generate the types of the return column in a string, which is proven here, you can’t dynamically return anything with standards-compliant SQL.
If you’re using psql, there is a command to automate that processes. After something returns a string of sql, you can run it with gexec
As they say in the source above,
As long as you get the generated sql, you may do whatever you like with that. You may create function, view etc.
So you can do that kind of stuff too. That is, things that don’t return a dynamic list of columns, like issue a CREATE FUNCTION
or a CREATE SQL
command.
You can store the string (sql query) in a variable and run
execute immediately variable_name
.