SQL Server 2012: Add a linked server to PostgreSQL
Ok, I found the solution.
In the pg_hba.conf file, I change the method for sending passwords from MD5 to trust. After reloading the server, my linked server connection works.
the entry is now:
Type Database User Address Method
host all all x.x.x.x/x trust
In hope that help others peoples.
Error connecting PostgreSQL 9.5 (odbc) as Linked Server to SQL Server 2012
I found a solution that works for me.
The wizard in the Microsoft SQL Server Management Studio isn't helpful, I set up the connection by myself. I've tested it with selects and it works
Here's the code I used:
EXEC master.dbo.sp_addlinkedserver
@server = N'NameShownInMSSQLSrvMgmtStudio',
@srvproduct=N'PostgreSQL Unicode(x64)',
@provider=N'MSDASQL',
@provstr=N'Driver=PostgreSQL Unicode(x64);uid=postgres;Server=SERVERNAME;database=DBNAME;pwd=MyPWD;SSLmode=disable;PORT=5432'
EXEC master.dbo.sp_addlinkedsrvlogin
@rmtsrvname=N'postgresql',
@useself=N'True',
@locallogin=NULL,
@rmtuser=YourUser,
@rmtpassword=YourPW
SQL Server Linked Server to PostgreSQL Turkish Character Issue
The problem is that the source encoding is 8-bit Extended ASCII using Code Page 1254 -- Windows Latin 5 (Turkish). If you follow that link, you will see the Latin5 chart of characters to values. The value of the Ş
character -- "Latin Capital Letter S with Cedilla" -- is 222 (Decimal) / DE (Hex). Your local server (i.e. SQL Server) has a default Collation of SQL_Latin1_General_CP1_CI_AS
which is also 8-bit Extended ASCII, but using Code Page 1252 -- Windows Latin 1 (ANSI). If you follow that link, you will see the Latin1 chart that shows the Þ
character -- "Latin Capital Letter Thorn" -- also having a value of 222 (Decimal) / DE (Hex). This is why your characters are getting translated in that manner.
There are a few things you can try:
Use sp_serveroption to set the following two options:
EXEC sp_serveroption @server=N'linked_server_name',
@optname='use remote collation',
@optvalue=N'true';
EXEC sp_serveroption @server=N'linked_server_name',
@optname='collation name',
@optvalue=N'Turkish_100_CI_AS';Not sure if that will work with PostgreSQL as the remote system, but it's worth trying at least. Please note that this requires that all remote column collations be set to this particular value: Turkish / Code Page 1254.
Force the Collation per each column:
SELECT [ACCOUNTNUM], [NAME] COLLATE Turkish_100_CI_AS
FROM OPENQUERY(CARGO, 'SELECT taxno AS ACCOUNTNUM, title AS NAME FROM view_company');Convert the string values (just the ones with character mapping issues) to
VARBINARY
and insert into a temporary table where the column is set to the proper Collation:CREATE TABLE #Temp ([AccountNum] INT, [Name] VARCHAR(100) COLLATE Turkish_100_CI_AS);
INSERT INTO #Temp ([AccountNum], [Name])
SELECT [ACCOUNTNUM], CONVERT(VARBINARY(100), [NAME])
FROM OPENQUERY(CARGO, 'SELECT taxno AS ACCOUNTNUM, title AS NAME FROM view_company');
SELECT * FROM #Temp;This approach will first convert the incoming characters into their binary / hex representation (e.g.
Ş
-->0xDE
), and then, upon inserting0xDE
into theVARCHAR
column in the temp table, it will translate0xDE
into the expected character of that value for Code Page 1254 (since that is the Collation of that column). The result will beŞ
instead ofÞ
.
UPDATE
Option # 1 worked for the O.P.
copy large table from sql server to odbc linked database (postgresql) in ssms
I ended up using the OFFSET X ROWS FETCH NEXT Y ROWS ONLY
introduced in SQL Server 2012 so the complete statement looked like this:
INSERT INTO OPENQUERY(POSTGRES,'SELECT * FROM targettable')
SELECT *
FROM sourcetable
ORDER BY 1
OFFSET 0 ROWS FETCH NEXT 10000 ROWS ONLY
And everything is working and error appears! I actually iterate through the OFFSET
value adding 10,000 to it on every iteration using dynamic SQL.
Not the cleanest or nicest solution. I think most people would be better writing something in another language as mentioned by Michal Niklas, but this worked for me.
Add Catalog to an Existing Linked Server
You can do this by sending dynamic SQL via the linked server:
EXEC DB4_LINK.master..sp_executesql N'CREATE DATABASE foo;';
Of course this requires that you have the permissions to do so, and it's a simplistic command assuming that the default settings are fine - you may want to customize the CREATE DATABASE
command.
How to insert a row into a linked server table?
INSERT INTO [TargetServer].[TestDatabase].[dbo].TestTable (Name)
SELECT Name From [SourceServer].[SourceDatabase].[dbo].[Names] where Id = 1
Does merge command work with link on different sql servers? (S: Potrgesql, T: MsSQL = MERGE)
Yes you're right, the following code worked in the small table. Giving OleDB link to large tables will solve the situation. Sorry, there is currently no free OleDB provider for PostgreSQL.
MERGE INTO [MYTEST_STAGE1].dbo.DimOrganizationType AS t USING
(SELECT ID,
CompanyID,
Name,
LocationTypeID
FROM POSTGRESQL35W.erp.[ERP].OrganizationType) AS s (ID, CompanyID, Name, LocationTypeID) ON t.ID=s.ID WHEN MATCHED
AND (isnull(t.CompanyID, 0)<>isnull(s.CompanyID, 0)
OR t.Name<>s.Name
OR isnull(t.LocationTypeID, 0)<>isnull(s.LocationTypeID, 0)) THEN
UPDATE
SET t.CompanyID=s.CompanyID,
t.Name=s.Name,
t.LocationTypeID=s.LocationTypeID,
t.ModifiedDate=GETDATE(),
t.ModifiedByUser=@@SERVERNAME+'/'+@@SERVICENAME WHEN NOT MATCHED BY TARGET THEN
INSERT (ID,
CompanyID,
Name,
LocationTypeID,
loadDate,
LoadByUser)
VALUES (s.ID, s.CompanyID, s.Name, s.LocationTypeID, GETDATE(), @@SERVERNAME+'/'+@@SERVICENAME) WHEN NOT MATCHED BY SOURCE THEN
DELETE;
Related Topics
The Identifier That Starts with ...... Is Too Long. Maximum Length Is 128
Sql Server Database Change Workflow Best Practices
Creating Groups of Consecutive Days Meeting a Given Criteria
How to Check If a Directory Exists Using SQL Server
Oracle Locking with Select...For Update Of
How to Override SQL Sanitization in Coldfusion
Insufficient Privileges When Creating Tables in Oracle SQL Developer
Setting Identity to on or Off in SQL Server
Order by Column1 If Column1 Is Not Null, Otherwise Order by Column2
Postgresql: Defining a Primary Key on a Large Database
Sql Query with Count and Case Statement
What Is The Most Efficient Way to Count Rows in a Table in Sqlite
Difference Between "||" Operator and Concat Function in Oracle
Sql Date Format Conversion from Int(Yyyymmdd) Type to Date(Mm/Dd/Yyyy)