Postgresql create stored database link - sql

I know that in Oracle it's possible to create stored dblink and after that use it in query. For example:
Script for creation dblink:
CREATE PUBLIC DATABASE LINK my_link CONNECT TO my_schema IDENTIFIED BY shema_password USING 'remote';
And after that we can use it in our queries:
SELECT * FROM some_table#my_link;
I didn't find same solution for Postgres. I undestood that we can create named dblink connection:
For this we must use dblink_connect with name param. But created named dblink will destroy after session close.
Or we can create dblink connection for every queries:
SELECT *
FROM dblink('host= port= dbname= user= password=',
'select table_schema, table_name from information_schema.tables where table_schema = ''data''') AS t1 (table_schema TEXT, table_name TEXT);
Is it possible create stored dblink in Postgres and use it in different queries? Or I should create some function that return dblink connection params which encapsulate them?
I try use foreign table and do next steps:
Create postgres_fdw extension:
CREATE EXTENSION IF NOT EXISTS postgres_fdw;
Create Server:
CREATE SERVER my_server FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host '-', port '-', dbname '-');
And create mapping for user 'sys' where set remote user and password:
CREATE USER MAPPING FOR sys SERVER light_house OPTIONS ( USER 'remote_user', PASSWORD 'remove_password');
GRANT USAGE ON FOREIGN SERVER my_server TO sys;
Create foreign table in schema:
CREATE FOREIGN TABLE system.my_local_table (
colums ..
) SERVER my_server OPTIONS (schema_name 'remote_user', table_name 'remote_table'
);
GRANT SELECT ON TABLE system.home_measurement TO argus_sys;
after that I catch next exception:
[2F003] ERROR: password is required
Description: Non-superuser cannot connect if the server does not request a password.
Help: Target server's authentication method must be changed.

You should use a foreign table.
To get rid of the error message, change the pg_hba.conf file on the remote database server to use md5 authentication (don't forget to reload with pg_ctl reload).

Related

Azure SQL - Cannot create encrypted master key

I am trying to create a master key for my database, needed because I follow a tutorial to make cross db queries.
Tutorial: https://www.scarydba.com/2016/03/21/cross-database-queries-in-azure-sql-database/
It is a similar question to Cannot create master key for master database in azure sql, but I get the message:
Msg 15578, Level 16, State 1, Line 1 There is already a master key in
the database. Please drop it before performing this statement.
...when I am trying to create a master key which is encrypted. What do I do wrong and is there another option to make cross db calls with Azure?
I execute the following:
CREATE MASTER KEY ENCRYPTION BY PASSWORD='SUPERSTRONGPASSWORD'
GO
Regards
According my experience, the master key has already created and exist when we create the Azure SQL database.
When we create master key :
-- Create a db master key if one does not already exist, using your own password.
CREATE MASTER KEY ENCRYPTION BY PASSWORD='<EnterStrongPasswordHere>';
Since the master key is already exist, we could not create a new one.
For most situations, Azure SQL database cross db queries don't need create the master key.
For example, I use the bellow query to do cross db query from Mydatabase to Mydatabase2:
--The "username" and "password" should be the username and password used to log in into the Customers database.
CREATE DATABASE SCOPED CREDENTIAL ElasticDBQueryCred
WITH IDENTITY = '<username>',
SECRET = '<password>';
--To create an external data source, execute the following command on the Orders database:
CREATE EXTERNAL DATA SOURCE MyElasticDBQueryDataSrc WITH
(TYPE = RDBMS,
LOCATION = '<server_name>.database.windows.net',
DATABASE_NAME = 'Customers',
CREDENTIAL = ElasticDBQueryCred,
) ;
--Create an external table on the Orders database, which matches the definition of the CustomerInformation table:
CREATE EXTERNAL TABLE [dbo].[test]
( [id] [int] ,
[age] [int]
)
WITH
( DATA_SOURCE = MyElasticDBQueryDataSrc)
--query the table
select * from test
Test table in Mydatabase2:
Cross db query in Mydatabase:
For details, please reference: Get started with cross-database queries.
Hope this helps.

Postgres: user mapping not found for "postgres"

I'm connected to schema apm.
Trying to execute a function and getting below error:
ERROR: user mapping not found for "postgres"
Database connection info says:
apm on postgres#PostgreSQL 9.6
psql version: PostgreSQL 9.6.3, compiled by Visual C++ build 1800, 64-bit
How can this error be addressed?
It means that you are trying to use foreign table and your role (in this case postgres) does not have defined user and password for remote server.
You can add this by executing such query:
CREATE USER MAPPING
FOR postgres
SERVER remote_server_name
OPTIONS (user 'bob', password 'secret');
You can get server name for table like that:
SELECT srvname
FROM pg_foreign_table t
JOIN pg_foreign_server s ON s.oid = t.ftserver
WHERE ftrelid = 'schemaname.tablename'::regclass
If you want to create user mapping for all users, you can do it like this
CREATE USER MAPPING
FOR PUBLIC
SERVER remote_server_name
OPTIONS (user 'bob', password 'secret');
https://www.postgresql.org/docs/current/static/sql-createusermapping.html
CREATE USER MAPPING — define a new mapping of a user to a foreign
server
Your function queries foreign tables, using some server, for which you need a user mapping. Apparently it exists for the user owner, and not for you. Or just run the function with a user that has user mapping created.
you can view them with:
SELECT um.*,rolname
FROM pg_user_mapping um
JOIN pg_roles r ON r.oid = umuser
JOIN pg_foreign_server fs ON fs.oid = umserver;

Synonym support on PostgreSQL

How to create and use Synonyms on PostgreSQL as in Oracle. Do I need to create some DB link or any thing else. I could not find any good official doc on this topic.
Edit 1
Actually as of now i have an application which has two separate modules which connects with two different oracle databases; One modules need to access tables of other so for which we use synonyms over db link in oracle. Now we are migrating application to postgresql, so we need synonyms.
Edit 2
When i say two different oracle databases it means it can be two different oracle instances or two schemas of same db, it is configurable in application and application must support both modes.
PostgreSQL version: 9.6.3
Approach 1:-
Finally i got it working using foreign data wrapper postgres_fdw as below
I have two databases named dba and dbb. dbb has a table users and i need to access it in dba
CREATE SERVER myserver FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'localhost', dbname 'dbb', port '5432');
CREATE USER MAPPING FOR postgres
SERVER myserver
OPTIONS (user 'user', password 'password');
CREATE FOREIGN TABLE users (
username char(1))
SERVER myserver
OPTIONS (schema_name 'public', table_name 'users');
CREATE FOREIGN TABLE users (users char(1));
Now i can execute all select/update queries in dba.
Approach 2:-
Can be achieved by creating two schemas in same db, below are the steps:
create two schemas ex app_schema, common_schema.
Grant access:
GRANT CREATE,USAGE ON SCHEMA app_schema TO myuser;
GRANT CREATE,USAGE ON SCHEMA common_schema TO myuser;
Now set search path of user as below
alter user myuser set search_path to app_schema,common_schema;
Now tables in common_schema will be visible to myuser. For example let say we have a table user in common_schema and table app in app_schema then below queries will be running easily:
select * from user;
select * from app;
This is similar to synonyms in oracle.
Note- Above queries will work PostgreSQL 9.5.3+
I think you don't need synonyms in Postgres the way you need them in Oracle because unlike Oracle there is a clear distinction between a user and a schema in Postgres. It's not a 1:1 relationship and multiple users can easily use multiple schemas without the need to fully qualify the objects by exploiting Postgres' "search path" feature -  mydb.public.mytable.
If the tables are supposed to be in a different database in PostgreSQL as well, you'd create a foreign table using a foreign data wrapper.
If you used the Oracle synonym just to avoid having to write atable#dblink, you don't have to do anything in PostgreSQL, because foreign tables look and feel just like local tables in PostgreSQL.
If you use the synonym for some other purposes, you can either set search_path to include the schema where the target table is, or you can create a simple view that just selects everything from the target table.

Error in APEX SQL

I am working on Oracle 11g. I have created a table STUDENTS using APEX in my port: 8080 . After that when I use SQLPLUS in cmd and write SELECT * FROM STUDENTS it shows TABLE OR VIEW DOES NOT EXIST. What am I doing wrong here?
Ok...When you created the table using APEX, what schema was it created in? When you connect via SQL*Plus, are you logging in as the same user who owns the table?
If not, you'll need to grant select on the table to the user that wants to access the table, and also either specify the owner when referencing the table in your select statement, or create a synonym, or use alter session set current_schema statement.

PostgreSQL: Create schema in specific database

I need to write an sql script that creates both a new database AND a new schema in the database I just created.
How can I do it? Can I somehow change the current database to the new one? Or can I somehow specify the database for CREATE SCHEMA?
I'm using PostgreSQL 9.0
You can connect to the database, and execute the "CREATE SCHEMA" statement. That should result in a new schema in that database. It's not as tough as you think ;) When you want to do this from a .SQL file instead, you can use the \connect command as such:
CREATE DATABASE foo;
\connect foo;
CREATE SCHEMA yourschema;
Login to New-Database with new user:
postgres=> \connect newdb user1
...
You are now connected to database "newdb" as user "user1".
newdb=>
To create schema with new user "user1" in newdb:
newdb=> CREATE SCHEMA s1;
To list the schema :
SELECT * from information_schema.schemata;
Create database using
--CREATE DATABASE test;
Enter to the test database using
--psql -d test;
Create your schema in test database using
--create schema if not exists test_schema;