Skip to main content
Named instances are not supported. Give the host and the TCP port, 1433 by default, and let the Authentication dropdown decide the rest of the form: a SQL Server login, a Kerberos ticket from your domain, or a Microsoft Entra ID work account. The protocol underneath is TDS 7.4, which every server from 2012 on speaks, so Windows, Linux, Docker and Azure SQL Database are all reachable. The SQL Server driver is not in the app. Picking SQL Server in the Choose a Database sheet offers the download before the form opens, and opening a saved SQL Server connection installs it without asking. Settings > Plugins > Browse > MSSQL Driver installs it up front. See Plugins.

Quick setup

Click New Connection…, select SQL Server, fill in the fields, then click Save & Connect. For Azure SQL Database, use yourserver.database.windows.net and an SSL mode of Required (skip verify) or stricter.
SQL Server connection form with host, port, credentials, database, and schema fieldsSQL Server connection form with host, port, credentials, database, and schema fields

SQL Server connection form

Connection URL

See Connection URL Reference for all parameters.

Windows Authentication (Kerberos)

On macOS, Windows Authentication means Kerberos. Set Authentication to Windows Authentication (Kerberos), then either leave Kerberos Principal and Password blank to use the ticket in your credential cache, or enter user@REALM.COM and your domain password to have one requested at connect. Get a cached ticket with kinit user@REALM.COM; klist shows it. Four things have to hold:
  • Connect by hostname, never an IP address. Kerberos targets the service principal name MSSQLSvc/host.domain.com:1433, registered against the host name.
  • Write the realm in uppercase, usually the DNS domain: CONTOSO.COM.
  • This Mac has to reach the domain’s KDC, through DNS SRV records or /etc/krb5.conf.
  • The SQL Server service account has to own that SPN. Your administrator registers it.
For a server in a realm other than your default_realm, map its DNS domain and the ticket is requested there instead:
A host with no [domain_realm] entry falls back to default_realm. TablePro never runs kinit or edits /etc/krb5.conf.

Microsoft Entra ID

Set Authentication to Microsoft Entra ID to sign in with a work account instead of a SQL Server login: Azure SQL Database, Azure SQL Managed Instance, and SQL Server 2022 with Entra authentication enabled.
1

Register an application

In the Azure portal, under App registrations, add one with platform Mobile and desktop applications, Allow public client flows set to Yes, and the delegated permission Azure SQL Database → user_impersonation.
2

Create the database user

3

Sign in

Fill in the two fields and click Test Connection. A one-time code goes to the clipboard and your browser opens on the sign-in page. Paste it, approve, then test again.
The device code flow honors multifactor authentication and Conditional Access. Tokens land in your login keychain marked device-only, so they never travel through iCloud Keychain, and the access token refreshes in the background. You sign in again only when the refresh token expires or is revoked. A sign-in that succeeds and is then refused by the database means no database user matches the token. Run CREATE USER … FROM EXTERNAL PROVIDER against the database you are opening.

Databases and schemas

The sidebar nests tables under their schema, hides the built-in role schemas (db_owner, guest, and the rest), and lists master, tempdb, model and msdb only with Show system databases and schemas on. Press Cmd+K to change database, system databases included: the switch happens in place, with no reconnect. Opening a table queries it in the schema it is listed under, so a table outside dbo needs no switch first. INSERTs from the data grid leave IDENTITY columns out, so the server assigns them, and TEXTSIZE is raised at connect, so nvarchar(max) and text values arrive whole rather than cut to FreeTDS’s 2048-byte default.

Session options

Every connection opens with the SET profile SQL Server requires for filtered indexes, indexes on computed columns, indexed views and XML data type methods: FreeTDS leaves all of them at Sybase’s defaults, and a session that misses any one of them refuses every write to a table carrying a filtered index or an index on a computed column, with an error naming the SET options rather than the table. Two things change in the SQL editor as a result. col = NULL matches nothing, so compare with col IS NULL. And 'total: ' + @value is NULL when @value is, so wrap it in ISNULL(@value, '') to keep the rest of the string.

Scripts and batches

A script run with Cmd+Shift+Enter, or a selection of several statements run with Cmd+Enter, reaches the server one batch at a time, the way sqlcmd and SQL Server Management Studio send it. A line holding only GO ends a batch, and a script with no GO line is one batch. A variable, a table variable or a TRY...CATCH lasts until the end of its batch:
Every result set a batch returns opens in its own result tab. In a batch of plain queries each tab is named after its query; a procedure call, a loop or an IF numbers them Result 1, Result 2 instead. PRINT output and messages up to severity 10 appear in the Output view.
  • Give CREATE PROCEDURE, CREATE VIEW, CREATE FUNCTION, CREATE TRIGGER and CREATE SCHEMA a batch of their own. The server refuses each of them after another statement in the same batch.
  • GO 5 runs the batch before it five times.
  • No transaction is opened around a script. Put BEGIN TRAN and COMMIT in it when a failure has to undo what ran before it. A script that leaves a transaction open ends with a notice saying so.
  • The run stops at the first batch that fails, and the error names the line in the editor: Line 12: Invalid object name 'orders'. An error raised inside a procedure names the procedure and the line inside it instead.
  • Cmd+Enter with nothing selected runs only the statement at the insertion point. Select the DECLARE along with a statement that reads its variable.
File > Import runs a .sql file that holds a GO line the same way, GO 5 included, and never sends a GO line. A file with no GO line runs one statement at a time, split at each ;: dumps from TablePro 0.75 and earlier have none and import this way. End such a file with a GO line to run it as one batch instead. A failure is reported at the line its batch or statement starts on, and its error names the line in the file: Failed at line 3. Line 5: Invalid object name 'orders'. A batch past 64 million characters, about half of what SQL Server takes in one request, ends at its next ;.

SSL/TLS

New connections start on Preferred, which encrypts the login and leaves queries and results in plain TCP unless the server forces encryption. Pick Required (skip verify) or stricter to encrypt the whole session. Verification runs against the macOS system roots at /etc/ssl/cert.pem, which covers Azure SQL and anything else publicly trusted. See SSL/TLS. SQL Server connections can also run through the Cloud SQL Auth Proxy, which TablePro starts and stops for you.

Limitations

  • Named instances are not supported. Give the host and the TCP port that instance listens on.
  • NTLM is not supported: Windows Authentication on macOS is Kerberos only.
  • Entra ID connections are created on the Mac only, through the device code flow only. iPhone and iPad take them over sync and prompt to sign in when you open one.
  • The SSL pane offers no certificate fields here, and your own freetds.conf is not read. A server certificate from a private CA fails Verify CA and Verify Identity: use Required (skip verify) for that server.
  • A result set from a batch offers Fetch All, and sorts on the server, only when its query can run again on its own. One that reads a variable, or comes from a procedure call or a loop, stays at the row limit and sorts the rows already shown: raise Row cap in Settings, or run the query by itself.
  • A batch keeps its first 100 result sets. The statements behind the rest still run, and the status bar says how many result sets were not kept.
  • With a transaction open under SET XACT_ABORT ON, a query cut at the row limit reads its whole result before any rows appear. Stop ends it, and SQL Server then rolls the transaction back.
  • Imported from a file with no GO line, a procedure, function or trigger whose body is not wrapped in BEGIN...END keeps only the first statement of its body, and the statements after it run on their own. Wrap the body in BEGIN and END, or give every statement of the file a GO line after it.

Troubleshooting

Failed to connect to host:1433: …

The tail is FreeTDS’s own message. Nothing listening means TCP/IP is off in SQL Server Configuration Manager, the service is down, or port 1433 is closed. A rejected login means the credentials, or a server that takes Windows Authentication only: SELECT SERVERPROPERTY('IsIntegratedSecurityOnly') returns 1 for that, and mixed mode goes on in SSMS under Server Properties > Security. A login scoped to one database, an Azure SQL contained user for instance, needs Database filled in; without it the server authenticates against master and refuses.

No Kerberos ticket was found.

There is no ticket in the credential cache. Run kinit user@REALM.COM, or fill in Kerberos Principal and Password, then reconnect.

Server not found in Kerberos database

Reported as The SQL Server Kerberos service principal name is not registered. The server has no SPN, or has one in a realm this Mac does not map the host to. Ask your administrator to register MSSQLSvc/host.domain.com:1433, connect by hostname rather than IP, and add a [domain_realm] entry for a cross-realm server.

This Mac’s clock is too far out of sync with the domain controller.

Turn on Set time automatically in System Settings > General > Date & Time, then reconnect.

Set the Microsoft Entra ID application (client) ID for this connection.

The connection carries no client ID. Fill in Application (Client) ID.

The Microsoft Entra ID sign-in timed out before it was approved.

The one-time code expired first. Click Test Connection to start a new one.

Must declare the scalar variable ”@…”.

The statement that reads the variable ran in a different batch from its DECLARE. Check for a GO line between them, or a Cmd+Enter that ran only the statement at the insertion point. Select both statements, or run the whole script with Cmd+Shift+Enter.

AADSTS7000218

The app registration does not allow public client flows, which the device code flow needs. Turn it on in the Azure portal.