DEV Community

Cover image for SQL Database Projects and AI: A Match Made in Heaven
Lou Creemers
Lou Creemers

Posted on

SQL Database Projects and AI: A Match Made in Heaven

Hey lovely readers,

If you have ever asked an AI tool to write some SQL for you, you have probably seen this happen. You ask for a query, you get something that looks great, and then you run it and find out it uses a column that does not exist. Or a function your SQL Server version does not support. Or it quietly drops something you really wanted to keep.

I wrote before about how AI tools are confident even when they are wrong. That is annoying in C#, but at least the compiler yells at you. With databases, there often is no compiler. There is just you, a script, and a database that is about to find out.

That is exactly why I think SQL Database projects and AI are a match made in heaven. Let's talk about why.

If you have worked with SQL Database projects before, feel free to skip to "Why AI and SQL projects get along so well". If you have never heard of them, don't worry, we will start from the beginning.

What is a SQL Database project?

A SQL Database project is a local representation of your database schema. Your tables, views, stored procedures, and functions all live in .sql files inside a project on your machine, right next to your application code and in the same Git repository.

If you are a .NET developer, you can think of it as a .csproj, but for your database. You write files, you build the project, and you get an output you can deploy.

Here is what a table looks like in a SQL project:

CREATE TABLE [dbo].[Customers]
(
    [Id] INT NOT NULL PRIMARY KEY,
    [Name] NVARCHAR(100) NOT NULL,
    [Email] NVARCHAR(256) NOT NULL
);
Enter fullscreen mode Exit fullscreen mode

Nothing special, right? The special part is what happens when you want to change it.

Declarative instead of step by step

Most of us learned to change databases step by step. First you create the table. Then, a bit later, you write a script that adds a column. Then another script that changes a data type. After a year, you have a folder with 80 scripts that need to run in exactly the right order.

SQL projects work differently. They are declarative, which means you describe what the database should look like, not how to get there. Each object is declared once, in one file. Want to add a phone number to your customers? You do not write an ALTER TABLE script. You just edit the same file:

CREATE TABLE [dbo].[Customers]
(
    [Id] INT NOT NULL PRIMARY KEY,
    [Name] NVARCHAR(100) NOT NULL,
    [Email] NVARCHAR(256) NOT NULL,
    [PhoneNumber] NVARCHAR(20) NULL
);
Enter fullscreen mode Exit fullscreen mode

Think of it like a blueprint of a house. You do not hand the builder a list of "knock down this wall, then add a window here". You hand them the blueprint of what the house should look like, and they figure out what needs to change.

Build and deploy

When you build a SQL project with dotnet build, two things happen.

First, the project gets validated. The build checks that every object you reference actually exists. A view can't use a table or column that is not in your project. The build also checks your syntax against a target platform, which is the SQL version you are targeting. For example, if your project targets SQL Server 2017, you can't use JSON functions that were added in SQL Server 2022.

Second, you get a .dacpac file. That is the build artifact, a package that contains your whole schema.

To deploy it, you use a tool like SqlPackage. When you publish a .dacpac to a new database, it creates everything in the right order, so a table with a foreign key is created after the table it points to. When you publish to an existing database, it compares your .dacpac to that database and only generates the changes that are needed. Missing two columns? You get an ALTER TABLE. Changed a stored procedure? You get an ALTER PROCEDURE.

So the blueprint is yours, and the builder is SqlPackage.

A quick note on project formats

If you worked with SQL projects years ago, you probably remember the original format, based on .NET Framework and mostly tied to Visual Studio on Windows.

The newer format is SDK-style, using the Microsoft.Build.Sql SDK. It runs on modern .NET, works cross-platform, supports NuGet package references for database references, and automatically includes all .sql files in your project folder. Microsoft recommends it for new development, and it is the format that will be supported in the future.

Tooling support is different per IDE, so here is where things stand right now. SDK-style projects are generally available in the SQL Database Projects extension for VS Code. JetBrains Rider supports them since version 2025.2 through a bundled plugin, with project templates, importing from an existing database, schema compare, and publishing. In Visual Studio 2022, they are available as a preview component. Visual Studio 2026 only supports the original format for now, so if Visual Studio is your IDE of choice, keep that in mind when picking your tools.

Getting started with the SDK-style format looks like this:

dotnet new install Microsoft.Build.Sql.Templates
dotnet new sqlproj -n MyDatabase
dotnet build
Enter fullscreen mode Exit fullscreen mode

Why AI and SQL projects get along so well

Now for the fun part. Here is why I think this combination works so well.

The whole schema is right there as context

AI tools are only as good as the context you give them. If your schema lives only inside a running database, the AI either has to guess what your tables look like, or you have to give it a connection to your database. Please do NOT give an AI agent a connection string to production.

With a SQL project, your entire schema is plain text in your repository. One object per file, easy to search, easy to read. An AI agent in your editor can open Tables/Customers.sql and see exactly what columns exist, what the types are, and what the foreign keys point to. No guessing, no database access needed.

And if you already have a database without a SQL project, you can extract one. You can do this from VS Code, or from the command line:

sqlpackage /Action:Extract /SourceConnectionString:"<your connection string>" /TargetFile:MyDatabase /p:ExtractTarget=SchemaObjectType
Enter fullscreen mode Exit fullscreen mode

This works no matter how the database was created, even if you use an ORM like EF Core. That means you can give AI tools a readable picture of your schema without changing how your team works.

The build is a fact-checker

This is my favorite part. Remember the AI that confidently used a column that does not exist? In a SQL project, that is a build error.

Say you ask an AI to create a view, and it comes up with this:

CREATE VIEW [dbo].[CustomerContacts]
AS
SELECT [Name], [Email], [Phone]
FROM [dbo].[Customers];
Enter fullscreen mode Exit fullscreen mode

Imagine that our column is called PhoneNumber, not Phone. Run dotnet build, and you get an unresolved reference error (SQL71501) pointing right at the problem. Same for syntax your target platform does not support.

This gives AI agents something they are really good at using: a feedback loop. Make a change, build, read the errors, fix them, build again. The agent can find its own mistakes before you ever have to look at them. The database finally gets something that feels like a compiler.

AI describes the destination, not the route

Migration scripts are where things tend to go wrong. The order matters, the current state of the database matters, and one wrong assumption can break everything.

With a SQL project, the AI does not have to write migration scripts at all. It only has to edit the file that describes what the object should look like. Figuring out how to get the actual database from its current state to that new state is SqlPackage's job, and SqlPackage has been doing that reliably for a long time.

So the AI does the part it is good at (writing a clear description of what you want) and a deterministic tool does the risky part (calculating the changes). I love that split.

You can review every change like normal code

Because everything is a file in Git, every AI change to your database shows up as a normal diff in a pull request. You see exactly which column was added, which view changed, and which procedure got rewritten. Your teammates can review it the same way they review C# code.

That also means your normal CI/CD pipeline can build the project on every pull request. If the AI (or a human, let's be honest) broke something, the pipeline catches it before it gets merged.

Code analysis adds extra guardrails

SQL projects can also run code analysis during the build. You turn it on in your project file:

<PropertyGroup>
  <RunSqlCodeAnalysis>True</RunSqlCodeAnalysis>
</PropertyGroup>
Enter fullscreen mode Exit fullscreen mode

Now you get warnings for common bad practices, like using SELECT * in views and stored procedures. AI tools love SELECT *, so this one alone is worth it. You can customize which rules apply, and if you want to go further, you can even write your own rules.

You see the plan before anything touches a database

Before you deploy, you can ask SqlPackage to generate the script it would run, instead of running it right away:

sqlpackage /Action:Script /SourceFile:bin/Debug/MyDatabase.dacpac /TargetConnectionString:"<your connection string>" /OutputPath:deploy.sql
Enter fullscreen mode Exit fullscreen mode

Or use /Action:DeployReport to get an overview of the changes. That way there are two review moments: the diff of the SQL files, and the actual script that will run against your database. Nothing reaches a real database without you seeing it first.

Making it work in practice

A few things that help a lot when you let AI work on a SQL project.

Tell your AI tool how your project works. Most AI coding tools support an instructions file in your repository. Add a small section about your database, something like this:

## Database changes
- The database schema lives in /database as a SQL Database project.
- Each object is declared once, in its own file. Never write ALTER statements or migration scripts.
- After every schema change, run `dotnet build database/MyDatabase.sqlproj` and fix all errors before continuing.
- The target platform is SQL Server 2022. Do not use features from newer versions.
Enter fullscreen mode Exit fullscreen mode

Set the right target platform. The build can only protect you from unsupported syntax if the target platform matches the SQL version you actually deploy to.

Keep the AI away from real databases. Let it work on files and run builds. Deploying stays a human decision, or a pipeline decision with a human approving it.

What it does not solve

I do not want to pretend this is magic so here are a few honest limitations.

Renames are tricky. If an AI renames a column by just editing the file, the deployment can see that as "drop the old column, add a new one", and that means data loss. By default, SqlPackage blocks deployments that might lose data, which is great. However, you still need to handle renames properly. SQL projects have a refactor log for this, which the tooling creates when you use the rename refactoring. An AI editing text files will not create that for you, so keep an eye on renames in reviews.

Data changes are also a different story. SQL projects describe the schema, not the data. If you need to move or transform data, you still write that yourself, for example in a post-deployment script.

And of course, a green build does not mean the change is a good idea. The build tells you the schema is valid, not that the design makes sense. Reviewing is still your job.

That's a wrap!

SQL Database projects give your database the things we take for granted in application code: files you can read, a build that catches mistakes, and changes you can review. It turns out those are exactly the things AI tools need to be actually useful instead of confidently wrong.

If you are a junior developer, this is a really nice way to learn database development with a safety net. If you have worked with SQL projects for years, you might find they suddenly got a lot more interesting now that an AI agent can use that same build to check its own work.

Thanks for reading! If you have thoughts, questions, or your own experience with AI and databases, feel free to leave a comment or reach out to me on my socials.

See ya!

Top comments (0)