I am unable to think as to why this would fail. The block commands should work if it meets the condition?
On version 14.6
postgres# DO
postgres# $do$
postgres# DECLARE
postgres# lc_db_names CONSTANT text[] := array['dev3','dev2','dev1'];
postgres# BEGIN
postgres# IF current_database() = any(lc_db_names)
postgres# THEN
postgres# IF NOT EXISTS (
postgres# SELECT FROM pg_catalog.pg_roles WHERE rolname = 'test') THEN
postgres# create role test login encrypted password 'md5d2cdf586595c9e1ca7c7d7db3951f3fd';
postgres# create schema authorization test;
postgres# execute format('grant connect, temporary on database %I to %I', current_database(), 'test');
postgres# END IF;
postgres# END IF;
postgres# END
postgres# $do$
postgres# ;
ERROR: role "test" does not exist
CONTEXT: SQL statement "grant connect, temporary on database postgres to "test""
PL/pgSQL function inline_code_block line 11 at EXECUTE
Related
CREATE or REPLACE PROCEDURE admin.sp_pm_drop_all_scratch_tables (redshift_table_name IN VARCHAR)
LANGUAGE plpgsql
as $$
DECLARE
temp_table_name varchar(100);
row record;
BEGIN
temp_table_name := 'procedure_temp_table';
EXECUTE 'DROP TABLE if exists '||temp_table_name;
EXECUTE 'CREATE TEMP TABLE '||temp_table_name||' as select * from nidhi_test.'||redshift_table_name;
FOR row IN(
select 'DROP TABLE IF EXISTS '|| schemaname || '."'|| tablename|| '" cascade' as sql_name
from pg_tables
where schemaname in ('nidhi_scratch')
and schemaname || '.'|| tablename not in (select schema_name || '.'|| table_name from temp_table_name)
)
LOOP
EXECUTE row.sql_name;
END LOOP;
end;
$$ ;
i am trying to create this procedure but getting this error[42601][500310] Amazon Invalid operation: syntax error at or near "$1";
when i try to run this procedure it gives me the error
[42601][500310] Amazon Invalid operation: syntax error at or near "$1";
basically i want to drop the tables from schema nidhi_scratch and not drop tables which are there in temp_table_name
temp_table_name is getting filled from nidhi_test.‘||redshift_table_name
redshift_table_name is a variable getting filled from airflow
I am trying create this script where if it matches the current database , then do a chunk of work inside a sub block. As this is my first attempt, i cannot get this to work. Any thoughts?
DO
$do$
DECLARE
database CONSTANT text[] := array['prd1', 'prd2'];
BEGIN
IF current_database() = any(database)
THEN
**--execute the below sub block**
DECLARE
v_sql text;
BEGIN
v_sql :=
IF NOT EXISTS (
SELECT FROM pg_catalog.pg_roles -- SELECT list can be empty for this
WHERE rolname = 'dave') THEN
create role dave encrypted password 'md502bbddbc560b6470b360219ac95c13e2';
create schema authorization dave;
END IF;
END
);
-- end of sub block
END IF;
END
$do$;
SQL Error [42601]: ERROR: syntax error at or near "NOT" Position:
231
What i want do is a like where it does alot of actions in a sub block:
DO
$do$
DECLARE
database CONSTANT text[] := array['prd1', 'prd2'];
BEGIN
IF current_database() = any(database)
THEN
**--execute the below sub block**
DECLARE
v_sql text;
BEGIN
v_sql :=
IF NOT EXISTS (
SELECT FROM pg_catalog.pg_roles -- SELECT list can be empty for this
WHERE rolname = 'dave') THEN
create role dave encrypted password 'md502bbddbc560b6470b360219ac95c13e2';
create schema authorization dave;
END IF;
END
do
$$
begin
execute format('grant connect, temporary on database %I to %I', current_database(), 'user_monitor');
end;
$$;
CREATE OR REPLACE FUNCTION test.log_ddl()
RETURNS event_trigger AS $$
DECLARE
audit_query TEXT;
r RECORD;
BEGIN
[...]
END;
$$ LANGUAGE plpgsql;
**-- end of sub block**
END IF;
END
$do$;
Why use sub-block when you can use the IF conditional? 2) Why v_sql := ...? I see no point in assigning the query to a variable. Again all you want is to take CREATE actions based on the IF condition. –
Adrian Klaver
Below is a simplified postgres stored procedure I am trying to run:
create or replace procedure my_schema.tst(suffix varchar)
as $$
begin
execute(' select *
into my_schema.MyTable_'||suffix||'
From my_schema.MyTable
');
end;
$$
language plpgsql;
When I attempt to run using something like:
call my_schema.tst('test');
I get this error Invalid operation: EXECUTE of SELECT ... INTO is not supported;
Is it possible to execute a dynamic query that creates a new table? I have seen examples that look like:
Execute('... some query ...') into Table;
but for my use case I need the resulting tablename to be passed as a variable.
In PostgreSQL you can use INSERT INTO tname SELECT...
create or replace procedure my_schema.tst(suffix varchar)
as $$
begin
execute ' INSERT INTO my_schema.MyTable_'||suffix||' SELECT *
FROM my_schema.MyTable
';
end;
$$
language plpgsql;
or Use CREATE TABLE tname AS SELECT..., :
create or replace procedure my_schema.tst(suffix varchar)
as $$
begin
execute ' CREATE TABLE my_schema.MyTable_'||suffix||' as SELECT *
FROM my_schema.MyTable
';
end;
$$
language plpgsql;
I want to grant select rights on all the tables in database to particular user in db2 z/OS or mainframe.
I know with following query, we can grant select on table to user by running with ibmuser.
GRANT SELECT ON <TableName> TO <UserName>
However I have tried the same by using Db2 z/OS stored procedure in ibmuser:
CREATE PROCEDURE GRANT_SELECT_ON_DB(
IN DatabaseName varchar(255),
IN UserName varchar(255))
LANGUAGE SQL
BEGIN
DECLARE v_NAME VARCHAR(64);
DECLARE v_CREATOR VARCHAR(64);
DECLARE v_GrantQuery VARCHAR(320);
DECLARE c1 CURSOR FOR
(SELECT NAME,CREATOR FROM SYSIBM.SYSTABLES tabs WHERE upper(dBname)=upper(DatabaseName));
OPEN c1;
fetch_loop:
LOOP
FETCH c1 INTO v_NAME,v_CREATOR ;
SET v_GrantQuery = 'grant select on '|| v_CREATOR ||'.'|| v_NAME ||' to '|| UserName;
EXECUTE IMMEDIATE v_GrantQuery;
END LOOP fetch_loop;
CLOSE c1;
END%
On calling of stored procedure, it get stuck in loading and not producing any results or error.
call IBMUSER.GRANT_SELECT_ON_DB('<DatabaseName>','<UserName>')%
Also GRANT SELECT ON <DatabaseName> TO <UserName> is not working as it is not supported in DB2 z/OS.
Please suggest. May be I am missing some basics.
You can try below procedure, it worked for me:
CREATE PROCEDURE GRANT_SELECT_ON_DB(IN DatabaseName varchar(255),
IN UserName varchar(255))
LANGUAGE SQL
MODIFIES SQL DATA
BEGIN
DECLARE v_NAME VARCHAR(400);
DECLARE v_CREATOR VARCHAR(400);
DECLARE v_GrantQuery VARCHAR(1000);
FOR v1 AS
c1 CURSOR FOR
SELECT NAME,CREATOR FROM SYSIBM.SYSTABLES tabs WHERE upper(dBname)=upper(DatabaseName)
DO
SET v_NAME = NAME;
SET v_CREATOR = CREATOR;
SET v_GrantQuery = 'grant select on '|| v_CREATOR ||'.'|| v_NAME ||' to '|| UserName;
EXECUTE IMMEDIATE v_GrantQuery;
END FOR;
END%
call IBMUSER.GRANT_SELECT_ON_DB('<DatabaseName>','<UserName>')%
Well, after insert a user in systemuser, i like to create a ROLE for PostgreSQL, using the password of new user. But when i try create the user, this error appears:
Blockquote
ERROR: syntax error at or near "NEW"
LINE 24: ALTER USER NEW.login ENCRYPTED PASSWORD NEW.password...
CREATE OR REPLACE FUNCTION trg_insertuser()
RETURNS TRIGGER AS $trg_insertuser$
DECLARE
BEGIN
IF (TG_OP = 'DELETE') THEN
DROP USER OLD.login;
ELSIF (TG_OP = 'UPDATE') THEN
ALTER USER OLD.login ENCRYPTED PASSWORD NEW.password;
ELSIF (TG_OP = 'INSERT') THEN
CREATE USER NEW.login ENCRYPTED PASSWORD NEW.password CREATEDB IN GROUP group_user;
END IF;
RETURN NULL;
END;
$trg_insertuser$ LANGUAGE plpgsql;
What's happend?
use execute.
execute 'drop user ' || quote_ident(OLD.login);
etc...