> ## Documentation Index
> Fetch the complete documentation index at: https://ngquct-fix-mongodb-shell-write-concern.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Microsoft SQL Server

> Connect to SQL Server and Azure SQL Database with the FreeTDS-based driver plugin

export const name_0 = "SQL Server"

export const plugin_0 = "MSSQL Driver"

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 {name_0} driver is not in the app. Picking {name_0} in the **Choose a Database** sheet offers the
download before the form opens, and opening a saved {name_0} connection installs it without asking.
**Settings > Plugins > Browse > {plugin_0}** installs it up front. See [Plugins](/features/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.

| Field              | Default                   | Notes                                                                                                                  |
| ------------------ | ------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **Host**           | `localhost`               | A hostname, or an IP for anything but Kerberos                                                                         |
| **Port**           | `1433`                    |                                                                                                                        |
| **Authentication** | SQL Server Authentication | Or Windows Authentication (Kerberos), or Microsoft Entra ID                                                            |
| **Username**       | -                         | The SQL Server login. Hidden under the other two methods                                                               |
| **Database**       | -                         | Optional, sent during login when set. Required for a login scoped to one database, such as an Azure SQL contained user |
| **Schema**         | `dbo`                     | Selected after connecting. Clear it to take the login's own default                                                    |

<Frame caption="SQL Server connection form">
  <img className="block dark:hidden" src="https://mintcdn.com/ngquct-fix-mongodb-shell-write-concern/jYB68h8kp8zgNAqF/images/mssql-connection-form.png?fit=max&auto=format&n=jYB68h8kp8zgNAqF&q=85&s=fe79064334414f4196cc155d4c1982c8" alt="SQL Server connection form with host, port, credentials, database, and schema fields" width="1560" height="960" data-path="images/mssql-connection-form.png" />

  <img className="hidden dark:block" src="https://mintcdn.com/ngquct-fix-mongodb-shell-write-concern/jYB68h8kp8zgNAqF/images/mssql-connection-form-dark.png?fit=max&auto=format&n=jYB68h8kp8zgNAqF&q=85&s=ed8c168311f4d3be999e31f9bf828b10" alt="SQL Server connection form with host, port, credentials, database, and schema fields" width="1560" height="960" data-path="images/mssql-connection-form-dark.png" />
</Frame>

## Connection URL

```text theme={null}
sqlserver://user:password@host:1433/database
mssql://user:password@host:1433/database
```

See [Connection URL Reference](/connections/urls) 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:

```ini theme={null}
[domain_realm]
  .sql.example.com = RESOURCE.REALM.COM
```

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.

| Field                       | Notes                                                                              |
| --------------------------- | ---------------------------------------------------------------------------------- |
| **Application (Client) ID** | The application registration TablePro signs in as. Required                        |
| **Directory (Tenant) ID**   | Your directory ID or domain. Blank uses the multi-tenant `organizations` authority |

<Steps>
  <Step title="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**.
  </Step>

  <Step title="Create the database user">
    ```sql theme={null}
    CREATE USER [you@contoso.com] FROM EXTERNAL PROVIDER;
    ALTER ROLE db_datareader ADD MEMBER [you@contoso.com];
    ```
  </Step>

  <Step title="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.
  </Step>
</Steps>

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**](/customization/general-settings#tabs-and-sidebar) 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:

| Option                                                       | Value |
| ------------------------------------------------------------ | ----- |
| `ANSI_NULLS`, `ANSI_PADDING`, `ANSI_WARNINGS`                | ON    |
| `ARITHABORT`, `CONCAT_NULL_YIELDS_NULL`, `QUOTED_IDENTIFIER` | ON    |
| `NUMERIC_ROUNDABORT`                                         | OFF   |

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:

```sql theme={null}
DECLARE @sn NVARCHAR(50) = N'2404GQV000066A00105';

SELECT * FROM serialnew WHERE [S/N] = @sn;
SELECT * FROM serial_existed WHERE sn_code = @sn;
```

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.

| Mode                       | Behavior                                                                                                          |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| **Disabled**               | The login over TLS when the server offers it, then plain TCP. A server that forces encryption gets TLS throughout |
| **Preferred**              | Same as Disabled                                                                                                  |
| **Required (skip verify)** | TLS throughout, certificate unchecked. A server without TLS is refused                                            |
| **Verify CA**              | TLS throughout, certificate chained to a trusted authority. The host name is not checked                          |
| **Verify Identity**        | TLS throughout, chain checked, and the certificate names the host you dialled                                     |

Verification runs against the macOS system roots at `/etc/ssl/cert.pem`, which covers Azure SQL and anything else publicly trusted. See [SSL/TLS](/connections/ssl).

SQL Server connections can also run through the [Cloud SQL Auth Proxy](/connections/cloud-sql-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](/customization/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.

## Related

* [SSL/TLS](/connections/ssl)
* [SSH Tunneling](/connections/ssh-tunneling)
* [Work on Several Databases at Once](/features/table-operations#databases-and-schemas)
