---
title: Get a SQL Server connection string
summary: Return a ready-to-use SQL Server connection string for the requested target.
status: draft
owner: Framework.NCore maintainers
last_reviewed: 2026-10-02
library: SAIF.NetCore.DBConnectionClient
reference_type: package
operation_id: OP-DBC-03
trigger: Caller invokes GetSqlServerConnection
---

# Get a SQL Server connection string

This operation returns a fully formatted SQL Server connection string for a given server, instance, and user, serving it from the in-memory cache when available and retrieving it from the DBConnectionAPI otherwise.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-DBC-03 |
| **Trigger** | Caller invokes `GetSqlServerConnection(server, instance, userName)` |
| **Inputs** | `server`, `instance`, `userName` |
| **Outputs** | Full SQL Server connection string |
| **Primary components** | `ConnectionClient.GetSqlServerConnection` |
| **Entry point** | `src/SAIF.NetCore.DbConnectionClient/SAIF.NetCore.DBConnectionClient/SAIF.NetCore.DBConnectionClient/ConnectionClient.cs` |

## Steps

1. Build the engine-prefixed cache key `SQL_{server}_{instance}_{userName}` ([BR-DBC-04](../business-rules.md#br-dbc-04-cache-keys-are-engine-prefixed)).
2. Build the URL path `/{SqlEndpoint}/{server}/{instance}/{userName}`.
3. Acquire the instance-wide connection-string lock and check the cache for this key. On a cache hit, release the lock and return the cached value immediately — no HTTP call is made.
4. On a cache miss (still under the lock): validate the backoff configuration, then call `HttpClient.GetAsync(urlPath)` in a loop of up to `MaxRetrieveAttempts` (4, by default). A successful non-empty response is decoded, cached, and returned. HTTP 401/403/404 fail fast with no retry ([BR-DBC-09](../business-rules.md#br-dbc-09-401%2F403%2F404-are-permanent-failures)). A 503 or network-level error is transient and retries with fixed backoff (2s, 3s, 5s) until attempts are exhausted ([BR-DBC-10](../business-rules.md#br-dbc-10-503-or-network-level-failure-is-transient)). Any other non-success or an empty body fails immediately ([BR-DBC-11](../business-rules.md#br-dbc-11-other-failures-and-empty-bodies-fail-immediately)). A failed attempt is never cached; the lock is released once the outcome (value or exception) is determined.
   - > **Origin**: Steps 3.1–3.5 of [Cached lookup](cached-lookup.md), which embed the retry and classification logic from [Retrieve with retry](retrieve-with-retry.md), are executed on behalf of this operation.

## Process flow

```mermaid
flowchart TD
	Start([GetSqlServerConnection called]) --> Key[Build key SQL_server_instance_userName]
	Key --> Path[Build URL path /SqlEndpoint/server/instance/userName]
	Path --> Lock["Acquire lock, check cache"]
	Lock --> Hit{Cache hit?}
	Hit -->|Yes| Return([Return cached value])
	Hit -->|No| Get["GetAsync, up to 4 attempts"]
	Get --> Outcome{Outcome}
	Outcome -->|Success| Return
	Outcome -->|"401/403/404"| FailFast(["Throw DBClientException, no retry"])
	Outcome -->|"503/network error"| Retry["Backoff 2s/3s/5s, retry or throw"]
	Outcome -->|Other failure| ImmediateFail(["Throw DBClientException"])
```

## Failure and edge-case behavior
- Any exception from the underlying cached lookup (including `DBClientException` on permanent or exhausted-retry failures) propagates to the caller unchanged.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- `src/SAIF.NetCore.DbConnectionClient/SAIF.NetCore.DBConnectionClient/SAIF.NetCore.DBConnectionClient/ConnectionClient.cs`
