I was able to build the TDS_FDW and bring the extension into Postgresql 10. However, I'm getting the unusual message that it fails with a message of "Success".
ERROR: DB-Library error: DB #: 20002, DB Msg: Adaptive Server connection failed (secsql1.secdev.local:1433), OS #: 0, OS Msg: Success, Level: 9
SQL state: HV00L
The code generating the error is:
CREATE EXTENSION tds_fdw;
-- DROP SERVER mssql_acudb_server;
CREATE SERVER mssql_acudb_server
FOREIGN DATA WRAPPER tds_fdw
OPTIONS (servername 'wwww', port '1433', database 'AcuDB');
ALTER SERVER mssql_acudb_server
OPTIONS (ADD msg_handler 'notice');
-- DROP USER MAPPING FOR postgres SERVER mssql_acudb_server;
CREATE USER MAPPING FOR postgres
SERVER mssql_acudb_server
OPTIONS (username 'xxxx\yyyy', password 'zzzz');
-- DROP FOREIGN TABLE acudb_project;
CREATE FOREIGN TABLE acudb_project (
id BIGINT NOT NULL,
"name" TEXT NOT NULL,
path_prefix TEXT NOT NULL,
"type" TEXT NOT NULL,
sec_active_size BIGINT NULL
)
SERVER mssql_acudb_server
OPTIONS (query 'SELECT [id],[name],[path_prefix],[type],[sec_active_size]
FROM [projects]');
SELECT * FROM acudb_project
Was able to fix this issue by specifying the version of freeTDS in the "CREATE SERVER" statement:
-- DROP SERVER mssql_acudb_server;
CREATE SERVER mssql_acudb_server
FOREIGN DATA WRAPPER tds_fdw
OPTIONS (servername 'www', port '1433', database 'AcuDB', tds_version '7.1');
Related
Objective
I'm trying to put data from a couple different Azure databases into a new Azure database with a script similar to the following:
:setvar db1 [dbSource1]
:setvar db2 [dbSource2]
:setvar dbTarget "myNewDatabase"
USE master;
GO
DROP DATABASE IF EXISTS $(dbTarget)
GO
CREATE DATABASE $(dbTarget)
GO
CREATE TABLE $(dbTarget).[dbo].[Tenants](
[TenantId] [nvarchar](450) NOT NULL,
[OwnerObjectId] [nvarchar](max) NOT NULL,
[NetworkId] [nvarchar](450) NOT NULL,
[EndorserType] [int] NOT NULL,
[Active] [bit] NOT NULL DEFAULT 1,
[Region] [nvarchar](450) NOT NULL DEFAULT 'us-central',
CONSTRAINT [PK_Tenants] PRIMARY KEY CLUSTERED
(
[TenantId] ASC
)
CREATE TABLE $(dbTarget).[dbo].[ProductPlan](
[ProductPlanId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](max) NULL,
[Description] [nvarchar](max) NULL,
[IsStandard] [bit] NOT NULL,
[StripePlanId] [nvarchar](max) NULL,
[IsYearly] [bit] NOT NULL,
CONSTRAINT [PK_ProductPlan] PRIMARY KEY CLUSTERED
(
[ProductPlanId] ASC
)
INSERT INTO $(dbTarget).[dbo].[Tenants] (TenantId, OwnerObjectId, NetworkId, EndorserType)
SELECT TenantId, OwnerObjectId, NetworkId, EndorserType FROM $(db1).[domain].[Tenants]
INSERT INTO $(dbTarget).[dbo].[ProductPlan] (ProductPlanId, Name, Description, IsStandard, StripePlanId, IsYearly)
SELECT ProductPlanId, Name, Description, IsStandard, StripePlanId, IsYearly FROM $(db2).[dbo].[ProductPlan]
Essentially I am creating the tables in the new database with the exact same schemas that are in the source databases and then trying to insert all of data from those source tables into the target tables.
NOTE: This works just fine on local db but fails on the databases in my Azure SQL Server
The Problem
Reference to database and/or server name in 'myNewDatabase.dbo.Tenants' is not supported in this version of SQL Server.
So the script created the new database just fine but as soon as it tried to create a table in that database it spat the error above. Trying to switch context by inserting USE myNewDatabase after creating the database and before creating the first table throws another error: USE statement is not supported to switch between databases. Use a new connection to connect to a different database.
Attempted Solutions
I've tried making new connections like the second error states but can't seem to connect to a specific database. I always end up connecting to master and then getting the first error all over again.
Any ideas on what I need to do to make this work? Thank you in advanced!
In Azure SQL database, to create a database, a login must be one of the following:
The server-level principal login
The Azure AD administrator for the local Azure SQL Server
A login that is a member of the dbmanager database role
If you have the permission, you can run create database in each database, like in master DB or user DB.
But Azure SQL database doesn't support USE database or across database operations directly, even these databases are in the same Azure SQL Server.
Azure SQL database only support the across database query with elastic query. That still need many steps to achieve the across query. It's not supported to create table across the database. We must create a new connection(query session) on other databases.
Just for now, it's unsupported and we can not make this work.
For more details, please ref: Transact-SQL syntax not supported in Azure SQL Database
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.
I would like to insert data from prod server to dev server for a particular table.
I am using insert into SQL query and fully qualified name. That is I am specifying server name, databsename, schema name and table name.
insert into ServerADev.[ING_DB].dbo.[Table1]
select *
from ServerAProd.[ING_DB].dbo.[Table1]
where ID = '08914'
ID is the column in Table1.
For above query I am getting an error:
Cannot find ServerAProd in sys.servers. Verify that the correct server name was specified. If necessary, execute the stored procedure sp_addlinkedserver to add the server to sys.servers.
When I EXEC sp_addlinkedserver #server='ServerAProd', I am getting:
User does not have permission to perform this action.
Do I need to make a request to DBA (database admin) to grant permission to perform this query?
You need to set up a linked server to query a foreign server.
So, either:
ServerAProd is not what you named the linked server
or
You didn't create a linked server yet. You can use the sp_addlinkedserver from the error message, or browse to "server objects" in the object explorer then right-click -> new on "Linked Servers". See the link above for more details.
For your edit... yes this requires permissions:
When using Transact-SQL statements, requires ALTER ANY LINKED SERVER permission on the server or membership in the setupadmin fixed server role. When using Management Studio requires CONTROL SERVER permission or membership in the sysadmin fixed server role.
1. create linked server for the dev server on production server,
2. use this openquery() to insert data, so that you can insert large data very quickly.
INSERT OPENQUERY (devservername, 'SELECT * FROM devservar_database..dev_server_table_name')
select * from production_table_database_name..production_table_table_name
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;
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).