# CREATE SOURCE: SQL Server Connecting Materialize to a SQL Server database for Change Data Capture (CDC). > **Disambiguation:** This page reflects the new syntax which allows Materialize to handle upstream DDL changes, specifically adding or dropping columns, without downtime. For the deprecated syntax, see the [old reference page](/sql/create-source/sql-server/). ## Prerequisites [`CREATE SOURCE`](/sql/create-source/) connects Materialize to an external system you want to read data from, and provides details about how to decode and interpret that data. Materialize supports SQL Server (2016+) as a real-time data source. To connect to a SQL Server database, you first need to tweak its configuration to enable [Change Data Capture](https://learn.microsoft.com/en-us/sql/relational-databases/track-changes/enable-and-disable-change-data-capture-sql-server) and [`SNAPSHOT` transaction isolation](https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql/snapshot-isolation-in-sql-server) for the database that you would like to replicate. Then [create a connection](#prerequisite-creating-a-connection-to-sql-server) in Materialize that specifies access and authentication parameters. ## Syntax ```mzsql CREATE SOURCE [IF NOT EXISTS] [IN CLUSTER ] FROM SQL SERVER CONNECTION ``` | Syntax element | Description | | --- | --- | | `` | The name for the source. | | **IF NOT EXISTS** | Optional. If specified, do not throw an error if a source with the same name already exists. Instead, issue a notice and skip the source creation. | | **IN CLUSTER** `` | Optional. The [cluster](/sql/create-cluster) to maintain this source. | | **CONNECTION** `` | The name of the SQL Server connection to use in the source. For details on creating connections, check the [`CREATE CONNECTION`](/sql/create-connection/#sql-server) documentation page. | ## Ingesting data After a source is created, you can create tables from the source upstream SQL Server database that have [Change Data Capture enabled](https://learn.microsoft.com/en-us/sql/relational-databases/track-changes/about-change-data-capture-sql-server). You can create multiple tables that reference the same table in the source. See [`CREATE TABLE FROM SOURCE`](/sql/create-table/) for details. #### Handling table schema changes The use of the `CREATE SOURCE` with the new [`CREATE TABLE FROM SOURCE`](/sql/create-table/) allows for the handling of certain upstream DDL changes without downtime. See [Guide: Handle upstream schema changes with zero downtime](/ingest-data/sql-server/source-versioning/) for details. #### Supported types With the new syntax, after a SQL Server source is created, you [`CREATE TABLE FROM SOURCE`](/sql/create-table/) to create a corresponding table in Matererialize and start ingesting data.

Materialize natively supports the following SQL Server types:

  • tinyint
  • smallint
  • int
  • bigint
  • real
  • double precision
  • float
  • bit
  • decimal
  • numeric
  • money
  • smallmoney
  • char
  • nchar
  • varchar
  • varchar(max)
  • nvarchar
  • nvarchar(max)
  • sysname
  • binary
  • varbinary
  • json
  • date
  • time
  • smalldatetime
  • datetime
  • datetime2
  • datetimeoffset
  • uniqueidentifier
For more information, including strategies for handling unsupported types, see [`CREATE TABLE FROM SOURCE`](/sql/create-table/). ### Monitoring source progress [//]: # "TODO(morsapaes) Replace this section with guidance using the new progress metrics in mz_source_statistics + console monitoring, when available (also for PostgreSQL)." By default, SQL Server sources expose progress metadata as a subsource that you can use to monitor source **ingestion progress**. The name of the progress subsource can be specified when creating a source using the `EXPOSE PROGRESS AS` clause; otherwise, it will be named `_progress`. The following metadata is available for each source as a progress subsource: Field | Type | Details ----------|-------------------------------|-------------- `lsn` | [`bytea`](/sql/types/bytea/) | The upper-bound [Log Sequence Number](https://learn.microsoft.com/en-us/sql/relational-databases/sql-server-transaction-log-architecture-and-management-guide) replicated thus far into Materialize. And can be queried using: ```mzsql SELECT lsn FROM _progress; ``` The reported `lsn` should increase as Materialize consumes **new** CDC events from the upstream SQL Server database. For more details on monitoring source ingestion progress and debugging related issues, see [Troubleshooting](/ops/troubleshooting/). ## Example > **Important:** Before creating a SQL Server source, you must enable Change Data Capture and > `SNAPSHOT` transaction isolation in the upstream database. ### Creating a source {#create-source-example} #### Prerequisite: Creating a connection to SQL Server First, you must create a connection to your SQL Server database. A connection describes how to connect and authenticate to an external system you want Materialize to read data from. Once created, a connection is **reusable** across multiple `CREATE SOURCE` statements. For more details on creating connections, check the [`CREATE CONNECTION`](/sql/create-connection/#sql-server) documentation page. ```mzsql CREATE SECRET sqlserver_pass AS ''; CREATE CONNECTION sqlserver_connection TO SQL SERVER ( HOST 'instance.foo000.us-west-1.rds.amazonaws.com', PORT 1433, USER 'materialize', PASSWORD SECRET sqlserver_pass, DATABASE '' ); ``` If your SQL Server instance is not exposed to the public internet, you can [tunnel the connection](/sql/create-connection/#network-security-connections) through and SSH bastion host. **SSH tunnel:** ```mzsql CREATE CONNECTION ssh_connection TO SSH TUNNEL ( HOST 'bastion-host', PORT 22, USER 'materialize', DATABASE '' ); ``` ```mzsql CREATE CONNECTION sqlserver_connection TO SQL SERVER ( HOST 'instance.foo000.us-west-1.rds.amazonaws.com', SSH TUNNEL ssh_connection, DATABASE '' ); ``` For step-by-step instructions on creating SSH tunnel connections and configuring an SSH bastion server to accept connections from Materialize, check [this guide](/ops/network-security/ssh-tunnel/). #### Creating the source in Materialize You **must** enable Change Data Capture, see [Enable Change Data Capture SQL Server Instructions](/ingest-data/sql-server/self-hosted/#a-configure-sql-server). Once CDC is enabled for all of the tables you wish to create subsources for, you can create a `SOURCE` in Materialize to begin replicating data! _Create source from the connection we just created_ ```mzsql CREATE SOURCE mz_source FROM SQL SERVER CONNECTION sqlserver_connection; ``` After a source is created, you can create a table from the source, referencing specific table(s). _Creates a table in Materialize from the upstream table dbo.items_ ```mzsql CREATE TABLE items FROM SOURCE mz_source(REFERENCE dbo.items); ``` ## Related pages - [`CREATE SECRET`](/sql/create-secret) - [`CREATE CONNECTION`](/sql/create-connection) - [`CREATE SOURCE`](../)