From 1b21c6369a9f7dcfa2310b0ee3f244930cc37ab7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:50:04 +0000 Subject: [PATCH 1/4] Initial plan From bd65ac4b215f5cc455b76f50c5fcde1625db6f8e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:53:13 +0000 Subject: [PATCH 2/4] Document vector index stored procedure limitations for Azure SQL Co-authored-by: elbruno <3533489+elbruno@users.noreply.github.com> --- scenarios/08-Sql2025/docs/README.md | 4 + .../08-Sql2025/docs/native-vector-search.md | 92 +++++++++++++++++++ .../08-Sql2025/docs/sql-server-2025-setup.md | 2 + 3 files changed, 98 insertions(+) diff --git a/scenarios/08-Sql2025/docs/README.md b/scenarios/08-Sql2025/docs/README.md index 0c3d9f4..5afc1b2 100644 --- a/scenarios/08-Sql2025/docs/README.md +++ b/scenarios/08-Sql2025/docs/README.md @@ -164,6 +164,10 @@ builder.AddAzureOpenAIClient(azureOpenAiClientName, configureSettings: settings - Azure OpenAI service with text-embedding-3-small model - .NET 9.0 SDK +### Important Considerations + +> **⚠️ Azure SQL Database Limitations**: When deploying to Azure SQL Database (as opposed to the containerized SQL Server 2025), be aware that vector indexes cannot be created inside stored procedures. See the [Native Vector Search documentation](./native-vector-search.md#known-issue-vector-indexes-in-stored-procedures-azure-sql-database) for detailed guidance on workarounds and best practices. + ### Local Development 1. Configure Azure OpenAI user secrets 2. Ensure Docker is running diff --git a/scenarios/08-Sql2025/docs/native-vector-search.md b/scenarios/08-Sql2025/docs/native-vector-search.md index b48d5bf..eb546fc 100644 --- a/scenarios/08-Sql2025/docs/native-vector-search.md +++ b/scenarios/08-Sql2025/docs/native-vector-search.md @@ -166,6 +166,98 @@ WITH (METRIC = 'cosine', TYPE = 'DiskANN'); - No partition support - Views and temporary tables not supported +### Known Issue: Vector Indexes in Stored Procedures (Azure SQL Database) + +> **⚠️ Important**: Creating vector indexes inside stored procedures is not currently supported in Azure SQL Database and will fail with permission errors. + +When attempting to create a vector index within a stored procedure in Azure SQL Database, you may encounter the following error: + +```sql +CREATE PROCEDURE vector_sample AS +BEGIN + DROP TABLE IF EXISTS dbo.Products; + + CREATE TABLE dbo.Products ( + Id int PRIMARY KEY, + EmbeddingVector vector(1536) + ); + + DROP INDEX IF EXISTS IX_Products_EmbeddingVector ON dbo.Products; + + CREATE VECTOR INDEX IX_Products_EmbeddingVector + ON dbo.Products(EmbeddingVector) + WITH (METRIC = 'COSINE'); +END; +``` + +**Error Message:** + +``` +Msg: 2571, Line 13, State: 3, Level: 14 +User 'dbo' does not have permission to run DBCC TRACEON. +Msg: 42234, Line 13, State: 1, Level: 16 +DiskANN vector index build failed with an internal error 200. +``` + +**Root Cause:** + +The DiskANN vector index creation process requires internal operations (including DBCC TRACEON) that are not permitted within stored procedure execution contexts in Azure SQL Database. + +**Workarounds:** + +1. **Direct Execution (Recommended)**: Execute vector index creation statements directly outside stored procedures: + ```sql + -- Create table first + CREATE TABLE dbo.Products ( + Id int PRIMARY KEY, + EmbeddingVector vector(1536) + ); + + -- Then create the vector index separately + CREATE VECTOR INDEX IX_Products_EmbeddingVector + ON dbo.Products(EmbeddingVector) + WITH (METRIC = 'COSINE'); + ``` + +2. **Dynamic SQL with sp_executesql**: Use dynamic SQL outside the stored procedure context: + ```sql + -- Create a helper procedure that uses dynamic SQL + CREATE PROCEDURE CreateVectorIndex + @TableName NVARCHAR(128), + @ColumnName NVARCHAR(128), + @IndexName NVARCHAR(128) + AS + BEGIN + DECLARE @SQL NVARCHAR(MAX); + SET @SQL = N'CREATE VECTOR INDEX ' + QUOTENAME(@IndexName) + + N' ON ' + QUOTENAME(@TableName) + N'(' + QUOTENAME(@ColumnName) + N')' + + N' WITH (METRIC = ''COSINE'');'; + + -- Execute outside stored procedure via a job or manual execution + PRINT @SQL; + END; + ``` + +3. **Migration Scripts**: Use separate migration scripts for schema changes: + ```sql + -- migration-001-create-tables.sql + CREATE TABLE dbo.Products ( + Id int PRIMARY KEY, + EmbeddingVector vector(1536) + ); + + -- migration-002-create-vector-indexes.sql + CREATE VECTOR INDEX IX_Products_EmbeddingVector + ON dbo.Products(EmbeddingVector) + WITH (METRIC = 'COSINE'); + ``` + +4. **SQL Server 2025 (Self-Hosted)**: If you require stored procedure-based index creation, consider using SQL Server 2025 in a self-hosted environment where these restrictions may not apply. + +**Best Practice:** + +For production deployments with Azure SQL Database, maintain vector index creation in dedicated deployment scripts separate from stored procedures, and execute them as part of your database migration pipeline. + ## Approximate Nearest Neighbor Search ### VECTOR_SEARCH Function diff --git a/scenarios/08-Sql2025/docs/sql-server-2025-setup.md b/scenarios/08-Sql2025/docs/sql-server-2025-setup.md index 3dae0a8..c4d7e1b 100644 --- a/scenarios/08-Sql2025/docs/sql-server-2025-setup.md +++ b/scenarios/08-Sql2025/docs/sql-server-2025-setup.md @@ -89,6 +89,8 @@ WITH (METRIC = 'cosine', TYPE = 'DiskANN'); - Table becomes read-only while the vector index exists - Vector index must be dropped and recreated to incorporate new data +> **⚠️ Azure SQL Database Limitation**: Vector indexes cannot be created inside stored procedures in Azure SQL Database due to internal permission requirements. Create vector indexes using direct SQL statements outside stored procedure contexts. See the [Native Vector Search](./native-vector-search.md#known-issue-vector-indexes-in-stored-procedures-azure-sql-database) documentation for detailed workarounds. + ## Development Environment Setup ### Prerequisites From 2e5bdc277a573e297e81f68635a8837e7952fffb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:55:25 +0000 Subject: [PATCH 3/4] Fix metric case consistency and improve workaround guidance Co-authored-by: elbruno <3533489+elbruno@users.noreply.github.com> --- .../08-Sql2025/docs/native-vector-search.md | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/scenarios/08-Sql2025/docs/native-vector-search.md b/scenarios/08-Sql2025/docs/native-vector-search.md index eb546fc..b1b4622 100644 --- a/scenarios/08-Sql2025/docs/native-vector-search.md +++ b/scenarios/08-Sql2025/docs/native-vector-search.md @@ -186,7 +186,7 @@ BEGIN CREATE VECTOR INDEX IX_Products_EmbeddingVector ON dbo.Products(EmbeddingVector) - WITH (METRIC = 'COSINE'); + WITH (METRIC = 'cosine'); END; ``` @@ -216,26 +216,22 @@ The DiskANN vector index creation process requires internal operations (includin -- Then create the vector index separately CREATE VECTOR INDEX IX_Products_EmbeddingVector ON dbo.Products(EmbeddingVector) - WITH (METRIC = 'COSINE'); + WITH (METRIC = 'cosine'); ``` -2. **Dynamic SQL with sp_executesql**: Use dynamic SQL outside the stored procedure context: +2. **SQL Generation Script**: Create a utility to generate vector index statements for manual execution: ```sql - -- Create a helper procedure that uses dynamic SQL - CREATE PROCEDURE CreateVectorIndex - @TableName NVARCHAR(128), - @ColumnName NVARCHAR(128), - @IndexName NVARCHAR(128) - AS - BEGIN - DECLARE @SQL NVARCHAR(MAX); - SET @SQL = N'CREATE VECTOR INDEX ' + QUOTENAME(@IndexName) + - N' ON ' + QUOTENAME(@TableName) + N'(' + QUOTENAME(@ColumnName) + N')' + - N' WITH (METRIC = ''COSINE'');'; - - -- Execute outside stored procedure via a job or manual execution - PRINT @SQL; - END; + -- Utility to generate vector index creation SQL + SELECT + 'CREATE VECTOR INDEX IX_' + t.name + '_' + c.name + + ' ON ' + SCHEMA_NAME(t.schema_id) + '.' + t.name + + '(' + c.name + ') WITH (METRIC = ''cosine'');' AS IndexCreationSQL + FROM sys.tables t + INNER JOIN sys.columns c ON t.object_id = c.object_id + INNER JOIN sys.types ty ON c.user_type_id = ty.user_type_id + WHERE ty.name = 'vector'; + + -- Copy the generated SQL and execute it directly (outside any stored procedure) ``` 3. **Migration Scripts**: Use separate migration scripts for schema changes: @@ -249,7 +245,7 @@ The DiskANN vector index creation process requires internal operations (includin -- migration-002-create-vector-indexes.sql CREATE VECTOR INDEX IX_Products_EmbeddingVector ON dbo.Products(EmbeddingVector) - WITH (METRIC = 'COSINE'); + WITH (METRIC = 'cosine'); ``` 4. **SQL Server 2025 (Self-Hosted)**: If you require stored procedure-based index creation, consider using SQL Server 2025 in a self-hosted environment where these restrictions may not apply. From 879350ef18629876cbd33bbb5beacff543049ed4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:56:50 +0000 Subject: [PATCH 4/4] Improve SQL generation script robustness with CONCAT Co-authored-by: elbruno <3533489+elbruno@users.noreply.github.com> --- scenarios/08-Sql2025/docs/native-vector-search.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scenarios/08-Sql2025/docs/native-vector-search.md b/scenarios/08-Sql2025/docs/native-vector-search.md index b1b4622..e6ab973 100644 --- a/scenarios/08-Sql2025/docs/native-vector-search.md +++ b/scenarios/08-Sql2025/docs/native-vector-search.md @@ -223,9 +223,11 @@ The DiskANN vector index creation process requires internal operations (includin ```sql -- Utility to generate vector index creation SQL SELECT - 'CREATE VECTOR INDEX IX_' + t.name + '_' + c.name + - ' ON ' + SCHEMA_NAME(t.schema_id) + '.' + t.name + - '(' + c.name + ') WITH (METRIC = ''cosine'');' AS IndexCreationSQL + CONCAT( + 'CREATE VECTOR INDEX IX_', t.name, '_', c.name, + ' ON ', SCHEMA_NAME(t.schema_id), '.', t.name, + '(', c.name, ') WITH (METRIC = ''cosine'');' + ) AS IndexCreationSQL FROM sys.tables t INNER JOIN sys.columns c ON t.object_id = c.object_id INNER JOIN sys.types ty ON c.user_type_id = ty.user_type_id