“SQLServer access denied” indicates the server rejected your login or object-level permission when PostgreSQL (or any client) tried to connect or run a query.
SQL Server returns the message when the supplied login lacks CONNECT permission on the instance or required object-level rights. PostgreSQL users usually hit it through an FDW, ODBC, or ETL job.
Start by confirming the SQL Server login exists and is mapped to a database user. Then verify the user has CONNECT, SELECT, INSERT, UPDATE, or EXECUTE as needed on target schemas, tables, or procedures.
For tds_fdw
, your local Postgres role must map to a SQL Server login with adequate permissions. Without it, every foreign table access fails with “access denied.”
Always grant least privilege: CONNECT to the database and specific DML rights to tables such as Customers
, Orders
, Products
, and OrderItems
.
Prefer GRANT
to allow access. Only use DENY
to explicitly block a permission that would otherwise be inherited.
1) Create a dedicated login. 2) Add it to a low-privilege database role. 3) GRANT needed rights. 4) Map the Postgres role with CREATE USER MAPPING
.
Run SELECT * FROM sys.fn_my_permissions(...)
for object-level checks and review SQL Server error log or Extended Events for failed login details.
The snippet below creates a login, maps it, and grants read-only access so Postgres can query Products
.
Yes, GRANT SELECT ON DATABASE::EcommerceDB TO pg_reader;
works, but increases risk. Stick to per-table grants for production.
No. Standard TCP 1433 is sufficient. Ensure firewalls allow inbound traffic from the PostgreSQL host.
If the default schema differs, qualify object names (e.g., dbo.Products
) or set search_path
in the FDW options.