文档/SQL Server
此页面尚未翻译,当前显示英文版本。 查看英文版本
SQL Server
Microsoft SQL Server relational database.
At a glance
- Category — Relational
- Query language — T-SQL
- Default port — 1433
- URI scheme —
sqlserver
Microsoft SQL Server driver for DBFlux, built on the
tiberius TDS client.
Features
- SQL Server / Azure SQL relational driver with SQL query execution and schema discovery.
- Authentication via SQL Server logins (username + password); URI mode accepts
ADO, JDBC, and
sqlserver://user:pass@host:port/dbconnection strings. - Reports
Application Nameasdbflux/<version>unless the connection string or URI already sets one, in which case the user-supplied value always wins; thesqlserver:///mssql://URL scheme accepts anapplicationnamequery parameter for this. - TLS encryption modes (
off,on,required) via tiberiusEncryptionLevel. The form exposes a single SSL Mode dropdown; theTrustServerCertificateflag is derived automatically:off— no encryption (login packet still encrypted by TDS).on— encrypted, accepts self-signed certs. Best for local/dev SQL Server with its auto-generated cert.required— encrypted, validates the cert chain. Use against servers with a real CA-signed cert (Azure SQL, etc.). In URI mode,?trust=true|falseexplicitly overrides the derived value if you need an unusual combination (e.g.?encrypt=required&trust=true).
- Optional SQL Server named instances (
SQLEXPRESS,MSSQLSERVER2019, etc.) resolved at connect time by querying SQL Browser on UDP 1434 (enabled via tiberius’ssql-browser-tokiofeature). The form’s Instance field, the SSMS-stylehost\instanceform in URI mode, and the?instance=URI query parameter all set the sameinstance_nameon the tiberius config. - SSH tunnel support for connecting through bastion hosts (named instance lookup is not available through a TCP-only tunnel).
- Per-tab database switching via
USE [database]; session state (SET options, temp tables, transactions) persists acrossexecute()calls on the same connection. - Multi-result-set batches: when a batch produces several result sets (e.g.
SELECT 1; SELECT 2;or a stored procedure with multipleSELECTs), the driver returns the last non-empty set as the primaryQueryResult(preserving the historical “last statement wins” UX) and attaches every earlier non-empty set toQueryResult.additional_resultsin batch order. Pure preparation batches (SET LOCK_TIMEOUT 5000) still surface as a single empty primary. Callers that want to walk every set useQueryResult::iter_result_sets(). - Data-transfer engine: native multi-row
INSERTbulk-load (BULK_INSERT, capped at 1000 rows per statement per T-SQL’sVALUESrow limit, exposed viaDriverLimits::max_bulk_insert_rows) and driver-nativeCREATE TABLEDDL from a source table’s columns (TRUNCATE_TABLEis also supported).
Instance Metrics
Exposes a curated set of live server metrics sourced from sys.dm_os_performance_counters:
mssql.batch_requests_per_sec— T-SQL batch requests per secondmssql.compilations_per_sec— SQL compilations per secondmssql.recompilations_per_sec— SQL re-compilations per secondmssql.user_connections— current open user connectionsmssql.lock_waits_per_sec— lock waits per second (_Totalinstance)mssql.page_reads_per_sec— buffer pool page reads per secondmssql.page_writes_per_sec— buffer pool page writes per secondmssql.buffer_cache_hit_ratio— buffer cache hit ratio (percent)mssql.server_memory_kb— total server memory in KB
Each metric is returned as a single (timestamp_ms, value) row for live charting.
Requires the VIEW SERVER STATE server permission. Without it, list_metrics() returns an empty list and a warning is logged. The driver probes this permission once at catalog construction time.
Instance Inspector
Exposes tabular snapshots of running server state:
mssql.active_sessions— user sessions fromsys.dm_exec_sessionsjoined withsys.dm_exec_requests(session id, login name, host name, program name, status, CPU time, memory usage, command, request status, wait type, wait time, blocking session id)
Requires the VIEW SERVER STATE permission.
Query cancellation
- Cancellation is implemented as
KILL <spid>issued from a fresh side-channel connection. tiberius does not currently expose the TDS Attention primitive that SSMS uses, so the next best option is to ask the server to terminate the session running the query. - At connect time the driver captures
@@SPIDand caches a clone of the tiberiusConfig(with the login already baked in). The cancel handle opens a second connection on demand, runsKILL <spid>, and marks the primary connection as poisoned. - After cancellation,
cleanup_after_cancel()rebuilds the primary tiberius client, captures the new SPID, and re-issues the previousUSE [db]so the next query runs in the same database. From the UI’s perspective the connection stays connected; only the underlying session id changes. - Errors raised on the killed session (codes 596 / 233 / 6005) are
translated to
DbError::Cancelledso the UI shows “query cancelled” rather than a transport-level failure. - The session owner can
KILLits own SPID on modern SQL Server without theALTER ANY CONNECTIONpermission. On older or restricted logins, the KILL itself may fail with a permission error; the driver surfaces that to the user.
Schema discovery
- Databases (
sys.databases, hides system DBs). - Tables and views per database (
sys.tables,sys.views). - Per-table columns + primary key flag, indexes, foreign keys.
- Per-table constraints: CHECK constraints (with their definition) and
UNIQUE constraints (via
sys.indexes.is_unique_constraint). - Whole-schema indexes and foreign keys for the schema browser sidebar.
- User-defined types (
sys.types where is_user_defined = 1) classified asDomain(alias types) orComposite(table types). view_details()verifies the view exists in the requested database.- Routines: stored procedures (
P), scalar functions (FN), inline table-valued functions (IF), multi-statement table-valued functions (TF), and CLR aggregates (AF) are listed per schema viasys.objects. Source definitions are fetched withOBJECT_DEFINITION(object_id).
CRUD with OUTPUT
- INSERT/UPDATE/DELETE on a row use SQL Server’s
OUTPUT INSERTED.*/OUTPUT DELETED.*clause so the post-mutation row data is returned to the caller (CrudResult::success(row)), the same way the Postgres driver usesRETURNING *. MutationCapabilities::supports_returningistrue.- Row identity must be a composite primary key (the only
RecordIdentityvariant that makes sense for a relational driver).
Query planning
explain()runs the query underSET SHOWPLAN_XML ONand returns the query plan as XML. The driver always runsSET SHOWPLAN_XML OFFafterward so session state does not leak.version_query()returnsSELECT @@VERSION.
Dialect
[bracket]identifier quoting with]escaping.N'…'Unicode string literals;0x…(uppercase) binary literals;1/0for boolean (BIT) values.OFFSET … ROWS FETCH NEXT … ROWS ONLYpagination (with a fallbackORDER BY 1so OFFSET-without-ORDER-BY queries do not error out).SELECT TOP Nis not used; OFFSET/FETCH is the canonical pagination form.UPSERTis intentionally not generated; SQL Server’sMERGEhas known bugs and should be written by hand.
Error reporting
-
Tiberius
Servertoken errors surface their numeric code, severity state, and source line throughFormattedError. -
Common MSSQL error numbers are mapped to semantic
DbErrorvariants rather than the genericQueryFailed:Code(s) DbError variant 4060, 18450, 18452, 18456, 18486, 18487, 18488 AuthFailed229, 230, 262, 297, 916 PermissionDenied207, 208, 2812, 4902 ObjectNotFound245, 334, 515, 547, 2601, 2627, 8152 ConstraintViolation102, 156, 8180 SyntaxError -
Constraint-violation messages are parsed to populate
ErrorLocation(schema, table, column, constraint name) so the UI can highlight the offending object.
Operations and limits
- All operations declare
transactional_ddl: trueandsupports_savepoints: true. - Supported isolation levels: ReadUncommitted, ReadCommitted, RepeatableRead, Serializable, Snapshot. Default is ReadCommitted.
DDL behavior
- Transactional DDL. Most DDL in SQL Server is transactional. Wrapping
CREATE,ALTER, orDROP TABLEinsideBEGIN TRAN … COMMIT/ROLLBACKworks. Exceptions:CREATE DATABASE,DROP DATABASE,ALTER DATABASE,BACKUP/RESTORE, andCREATE FULLTEXT INDEXcannot run inside an explicit transaction. - ALTER TABLE locking.
ALTER TABLE … ADD COLUMN <nullable>is fast (metadata-only). Adding a NOT NULL column with a default writes to every page and takes a Sch-M lock.ALTER TABLE … ALTER COLUMNmay rewrite the table and blocks reads and writes until it finishes. - Online index operations (Enterprise / Azure SQL):
CREATE INDEX … WITH (ONLINE = ON)andALTER INDEX … REBUILD WITH (ONLINE = ON)allow concurrent DML. WithoutONLINE = ON, index builds take Sch-M and block writes (Standard/Express editions only support offline). - TRUNCATE TABLE. Metadata-only, fast, transactional, requires
ALTERpermission on the table. Cannot be used on tables referenced by a foreign key (useDELETEor drop the FK first). - DROP TABLE / DROP VIEW. Transactional.
IF EXISTSis supported on 2016+. - Constraints. Adding
CHECK/UNIQUE/FOREIGN KEYconstraints validates all existing rows by default (takes Sch-M briefly). UseWITH NOCHECKto add the constraint without scanning, thenWITH CHECK CHECK CONSTRAINTlater to validate at your leisure — same pattern as Postgres’sNOT VALID+VALIDATE CONSTRAINT.
Limitations
-
Instance metrics and inspector features require the
VIEW SERVER STATEserver permission. Without it, bothlist_metrics()andlist_inspectors()return empty lists rather than an error. -
Instance metrics return a single data point per call (current value from
sys.dm_os_performance_counters), not a historical time series. Rate counters (e.g.mssql.batch_requests_per_sec) represent the server-side running average as reported by the DMV, not a delta computed by the driver. -
Minimum supported SQL Server: 2016 (13.0). The driver uses
DROP INDEX IF EXISTS … ON …syntax that older servers reject with a syntax error (102). Azure SQL Database and Managed Instance are fine. -
CRUD on tables (or updateable views) with
INSTEAD OFtriggers is not supported. The driver returns the post-mutation row viaOUTPUT INSERTED.*/OUTPUT DELETED.*without anINTOclause, which SQL Server rejects with error 334 (“the target table cannot have any enabled triggers if the statement contains an OUTPUT clause without INTO”). The error is surfaced asConstraintViolation. -
SQL-only driver; it does not expose document or key-value APIs.
-
Cancellation kills the underlying session and transparently reconnects; it is not the surgical TDS-Attention cancel that SSMS uses (tiberius does not currently expose that primitive). In practice the only user-visible difference is that any session-local state (
SEToptions, temp tables, open transactions) is reset by the cancel. The active database is restored automatically. -
Cancellation latency depends on the SQL Server scheduler: typically a few milliseconds for CPU-bound queries, immediate for lock-waiters. Long rollbacks (e.g. cancelling a large
DELETEmid-transaction) can keep the server-side SPID in the KILLED/ROLLBACK state for a while after the driver has already moved on to a fresh session. -
Parameter binding is not used — statements are dispatched via
simple_query. CRUD helpers compose values into the SQL text through the sharedSqlQueryBuilderand dialect literal formatters. Large binary or Unicode payloads are inlined as0x…orN'…'literals. -
Streaming: result sets are materialized into
Vec<Row>. TheConnection::executetrait returns a fully-resolvedQueryResult, so cursor-style streaming would require a workspace-level API change rather than a driver-only fix. -
Multi-statement batches surface every non-empty result set via
QueryResult.additional_results, but the UI currently renders only the primary (last) set. Until the result-tab system readsadditional_results, the earlier sets are captured by the driver but invisible in the editor. -
PRINTand informational messages emitted during a batch are dropped. Surfacing them would require driving tiberius’s lower-levelTokenStreaminstead ofQueryStream::into_results(). -
UPSERTis intentionally not generated. UseMERGEmanually when needed. -
Named instances are honored when connecting directly (tiberius queries the SQL Browser service on UDP 1434) but not when going through an SSH tunnel, since libssh2 only forwards TCP. The standard workaround is to assign a static TCP port to the instance and connect to that port directly.
-
Schema introspection uses the
sys.*catalog views; users without the defaultVIEW DEFINITIONpermission will see partial metadata. SQL Server’s metadata visibility rules apply. -
CLR routines (CLR scalar functions, CLR table-valued functions, CLR stored procedures) and any routine created with
ENCRYPTIONreturnNULLfromOBJECT_DEFINITION, in which case the driver surfaces a short fallback message rather than an error. -
parameter_typesis not populated for routines;sys.parametersis not queried in this implementation. -
SQL Server has no
Windowfunction kind in thesys.objects.typetaxonomy;RoutineKind::Windowis never emitted by this driver. -
No referential-integrity toggle for the data-transfer engine’s migration path (
DriverCapabilities::DISABLE_FK_CHECKSis not set;Connection::set_referential_integrityreturnsNotSupported). SQL Server disables FK checking per-table viaALTER TABLE ... NOCHECK CONSTRAINT, which does not fit the engine’s single global toggle; a per-table variant is a possible future addition.