How do I execute the result of a query using the psql client? - postgresql

Using the psql client version 8.4.20, I created this select command that generates a bunch of other select commands:
mydatabase=# select concat('select count(*) from ', table_schema, '.', table_name, ';') from information_schema.tables where table_name like '%stockindex_alias%';
select count(*) from de_de.merged_stockindex_alias_de_de;
select count(*) from en_us.merged_stockindex_alias_en_us;
select count(*) from es_la.merged_stockindex_alias_es_la;
select count(*) from fr_fr.merged_stockindex_alias_fr_fr;
select count(*) from nl_nl.merged_stockindex_alias_nl_nl;
select count(*) from pt_br.merged_stockindex_alias_pt_br;
select count(*) from zh_hk.merged_stockindex_alias_zh_hk;
I know I can use \g to store those seven statements into a file, then execute the file with \i.
How can I execute the result of the query (those seven statements) in a single command without the intermediate file? I've tried \set, EXECUTE, searched the web, but can't get it right.
EDIT: The previous select statements erroneously had the word "table" in them, which I have fixed.

I don't know if it works in 8.4; it works in 9.2.
DO $$
DECLARE
x text;
BEGIN
FOR x IN (select concat('select count(*) from ', table_schema, '.', table_name, ';') from information_schema.tables where table_name like '%stockindex_alias%' LOOP
EXECUTE x;
END LOOP;
END;
$$;
Basically you create an anonymous function block and execute it. Function blocks (or whatever the correct name is) allow for variable declaration and dynamic execution.

If you can get by with an approximate count, you can use the system catalogs:
SELECT s.nspname AS locale, c.reltuples AS count
FROM pg_class c
JOIN pg_namespace s ON s.oid = c.relnamespace
WHERE c.relname LIKE '%stockindex_alias%';
This will be most accurate immediately after a VACUUM ANALYZE (assuming you are a superuser or own all the affected tables) and gradually reducing in accuracy as the affected tables are modified.

Related

Compare tables of two PostgreSQL Databases with PK and FK

I need to compare two PostgreSQL databases with exactly one SQL-query. I tried with the following query:
SELECT *
FROM information_schema.columns
WHERE table_name IN (SELECT table_name
FROM information_schema.tables
WHERE table_schema NOT IN ('information_schema', 'pg_catalog')
AND table_type = 'BASE TABLE'
ORDER BY table_schema, TABLE_NAME);
It works for my problem but the foreign and primary keys are missing in this table. Is there are way to include them into my sql-query?
It is ok if the result table is not normalized and displays data multiple times. It is purely a runtime comparison, which is why the result tables are deleted again when the program has run through.

How to find the number of functions, stored procedures in postgresql?

How can I find the number of User-defined functions and Stored Procedures in PostgreSQL database?
It will work for you :
(editted by #a_horse_with_no_name 's warn)
SELECT count(*)
FROM information_schema.routines
WHERE routines.specific_schema='schema_name'
This excludes metadata schemas of postgres:
select count(*) from information_schema.routines t where t.routine_schema not in ('pg_catalog', 'information_schema');
If you're only interested in the number of procedures then:
select count(*) from information_schema.routines t where t.routine_schema not in ('pg_catalog', 'information_schema') and t.routine_type = 'PROCEDURE';

MS SQLServer Searching to see if a value is contained in other values

I come from a background in PostgreSQL.
If I wanted to search all of the columns in all of the tables for any column name that contained "the" somewhere in the value, I would do this:
select *
from information_schema.columns
where column_name ilike '%the%'
This does not work in SQL Server 2008 R2, does anyone have any suggestions? I am running this query so far:
select t.name as table_name, c.name as column_name
from sys.tables as t
inner join
sys.all_columns as c
on
c.object_id = t.object_id
where t.name ilike '%the%'
order by c.name, t.name;
The where t.name ilike '%the%' is what makes the query fail with the following error message:
An expression of non-boolean type specified in a context where a
condition is expected, near 'ilike'.
Does anyone have any suggestions?
Thank you
ilike doesn't exist in sql server, you can use like instead.

Is there a way to track Functions dependencies in Postgresql?

I have a lot of functions and stored procedures in my PostgreSQL database that is dependent on each other. I want to run a script that will compile those function fist which is independent and not referring any other functions. Then I want to compile next level functions and so on until I reach top level function.
SQL Server has sys.sql_expression_dependencies table which keeps track of referencing objects and referenced objects? Do we have anything like that in Postgres? if not how to achieve it.
What is reason? PostgreSQL PL/pgSQL functions has not compile (better validation) time dependency. There is runtime dependency only. Currently there is not a tool for this purpose, what I know. But some dependency can be taken from PL profiler https://bitbucket.org/openscg/plprofiler.
You can try this query:
select t.*, f.* from
(
SELECT table_name,table_schema,
table_schema||'.'||table_name full_name,
table_type
FROM information_schema.tables
WHERE table_schema not in ('information_schema') and table_schema not like 'pg%'
) t
JOIN
(
SELECT n.nspname AS schema_name,
p.proname AS function_name,
pg_get_function_arguments(p.oid) AS args,
pg_get_functiondef(p.oid) AS func_def
FROM pg_proc p
JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE n.nspname not in ('pg_catalog','information_schema') and n.nspname not like 'pg%'
) f
on position(t.table_name in f.func_def) >0

Find out if user got permission to select/update/... a table/function/... in PostgreSQL

What is the recommended way to figure out if a user got a certain right (e.g. select or execute) on a certain class (e.g. table or function) in PostgreSQL?
At the moment I got something like
aclcontains(
someColumnWithAclitemArray,
makeaclitem(userOid,grantorOid,someRight,false))
but it's terrible since I have to check for every grantorOid that is possible and for every userOid the user can belong to.
On a related note: what are the possible rights you can test for?
I haven't found any documentation but reading the source code I guess:
INSERT
SELECT
UPDATE
DELETE
TRUNCATE
REFERENCES
TRIGGER
EXECUTE
USAGE
CREATE
CONNECT
There also seems to be a CREATE TEMP right, but I can't figure out the correct text to use in the makeaclitem-function.
I've found that a better approach (and I seem to remember this was taken from some queries built into psql, or maybe the information_schema views) is to use the has_*_privilege functions, and simply apply them to a set of all possible combinations of user and object. This will take account of having access to an object via some group role as well.
For example, this will show which users have which access to non-catalogue tables and views:
select usename, nspname || '.' || relname as relation,
case relkind when 'r' then 'TABLE' when 'v' then 'VIEW' end as relation_type,
priv
from pg_class join pg_namespace on pg_namespace.oid = pg_class.relnamespace,
pg_user,
(values('SELECT', 1),('INSERT', 2),('UPDATE', 3),('DELETE', 4)) privs(priv, privorder)
where relkind in ('r', 'v')
and has_table_privilege(pg_user.usesysid, pg_class.oid, priv)
and not (nspname ~ '^pg_' or nspname = 'information_schema')
order by 2, 1, 3, privorder;
The possible privileges are detailed in the description of the has_*_privilege functions at http://www.postgresql.org/docs/current/static/functions-info.html#FUNCTIONS-INFO-ACCESS-TABLE.
'CREATE TEMP' is a database-level privilege: it permits a user to use a pg_temp_* schema. It can be tested with has_database_privilege(useroid, datoid, 'TEMP').
Take a look at the "Access Privilege Inquiry Functions" and also the "GRANT" reference page.
Because Redshift is supporting values() only in INSERT INTO queries, the below query can be used with the obviously not-so-nice union all select.
select usename, nspname || '.' || relname as relation,
case relkind when 'r' then 'table' when 'v' then 'view' end as relation_type,
priv
from pg_class join pg_namespace on pg_namespace.oid = pg_class.relnamespace,
pg_user,
(select 'select' as priv,1 as privorder union all select 'insert',2 union all select 'update',3 union all select 'delete',4)
where relkind in ('r', 'v')
and has_table_privilege(pg_user.usesysid, pg_class.oid, priv)
and not (nspname ~ '^pg_' or nspname = 'information_schema')
order by 2, 1, 3, privorder;
Edit:
Also, I realized, that in our db Dataiku creates tables that can have CAPITAL letter in them, so, if table not exist error happens, you should use the lower() function