diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs
index 78ac30190a..febde5acbc 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs
@@ -94,6 +94,9 @@ public static class DataTestUtility
//SQL Server EngineEdition
private static string s_sqlServerEngineEdition;
+ // JSON Coloumn type
+ public static readonly bool IsJsonSupported = false;
+
// Azure Synapse EngineEditionId == 6
// More could be read at https://learn.microsoft.com/en-us/sql/t-sql/functions/serverproperty-transact-sql?view=sql-server-ver16#propertyname
public static bool IsAzureSynapse
@@ -175,6 +178,7 @@ static DataTestUtility()
ManagedIdentitySupported = c.ManagedIdentitySupported;
IsManagedInstance = c.IsManagedInstance;
AliasName = c.AliasName;
+ IsJsonSupported = c.IsJsonSupported;
System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj
index 7a3dad589d..4821357f4c 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj
@@ -290,6 +290,7 @@
+
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs
new file mode 100644
index 0000000000..b4bd08c5dc
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs
@@ -0,0 +1,290 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Data;
+using System.Data.Common;
+using System.Data.SqlTypes;
+using System.Threading.Tasks;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Microsoft.Data.SqlClient.ManualTesting.Tests
+{
+ public class JsonTest
+ {
+ private readonly ITestOutputHelper _output;
+
+ public JsonTest(ITestOutputHelper output)
+ {
+ _output = output;
+ }
+
+ private static readonly string jsonDataString = "[{\"name\":\"Dave\",\"skills\":[\"Python\"]},{\"name\":\"Ron\",\"surname\":\"Peter\"}]";
+
+ private void ValidateRowsAffected(int rowsAffected)
+ {
+ _output.WriteLine($"Rows affected: {rowsAffected}");
+ Assert.Equal(1, rowsAffected);
+ }
+
+ private void ValidateRows(SqlDataReader reader)
+ {
+ while (reader.Read())
+ {
+ string jsonData = reader.GetString(0);
+ _output.WriteLine(jsonData);
+ Assert.Equal(jsonDataString, jsonData);
+ }
+ }
+
+ private async Task ValidateRowsAsync(SqlDataReader reader)
+ {
+ while (await reader.ReadAsync())
+ {
+ string jsonData = reader.GetString(0);
+ _output.WriteLine(jsonData);
+ Assert.Equal(jsonDataString, jsonData);
+ }
+ }
+
+ private void ValidateSchema(SqlDataReader reader)
+ {
+ System.Collections.ObjectModel.ReadOnlyCollection schema = reader.GetColumnSchema();
+ foreach (DbColumn column in schema)
+ {
+ _output.WriteLine("Column Name is " + column.ColumnName);
+ _output.WriteLine("Column DataType is " + column?.DataType.ToString());
+ _output.WriteLine("Column DataTypeName is " + column.DataTypeName);
+ Assert.Equal("json", column.DataTypeName);
+ }
+ }
+
+ [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))]
+ public void TestJsonWrite()
+ {
+ string tableName = DataTestUtility.GetUniqueNameForSqlServer("Json_Test");
+ string spName = DataTestUtility.GetUniqueNameForSqlServer("spJson_WriteTest");
+
+ string tableCreate = "CREATE TABLE " + tableName + " (Data json)";
+ string tableInsert = "INSERT INTO " + tableName + " VALUES (@jsonData)";
+ string spCreate = "CREATE PROCEDURE " + spName + " (@jsonData json) AS " + tableInsert;
+
+ using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString))
+ {
+ connection.Open();
+
+ using (SqlCommand command = connection.CreateCommand())
+ {
+ //Create Table
+ command.CommandText = tableCreate;
+ command.ExecuteNonQuery();
+
+ //Create SP for writing json values
+ command.CommandText = spCreate;
+ command.ExecuteNonQuery();
+
+ command.CommandText = tableInsert;
+ var parameter = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json);
+ command.Parameters.Add(parameter);
+
+ //Test 1
+ //Write json value using a parameterized query
+ parameter.Value = jsonDataString;
+ int rowsAffected = command.ExecuteNonQuery();
+ ValidateRowsAffected(rowsAffected);
+
+ //Test 2
+ //Write a SqlString type as json
+ parameter.Value = new SqlString(jsonDataString);
+ int rowsAffected2 = command.ExecuteNonQuery();
+ ValidateRowsAffected(rowsAffected2);
+
+ //Test 3
+ //Write json value using SP
+ using (SqlCommand command2 = connection.CreateCommand())
+ {
+ command2.CommandText = spName;
+ command2.CommandType = CommandType.StoredProcedure;
+ var parameter2 = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json);
+ parameter2.Value = jsonDataString;
+ command2.Parameters.Add(parameter2);
+ int rowsAffected3 = command2.ExecuteNonQuery();
+ ValidateRowsAffected(rowsAffected3);
+ }
+ }
+ }
+ }
+
+ [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))]
+ public async Task TestJsonWriteAsync()
+ {
+ string tableName = DataTestUtility.GetUniqueNameForSqlServer("Json_Test");
+ string spName = DataTestUtility.GetUniqueNameForSqlServer("spJson_WriteTest");
+
+ string tableCreate = "CREATE TABLE " + tableName + " (Data json)";
+ string tableInsert = "INSERT INTO " + tableName + " VALUES (@jsonData)";
+ string spCreate = "CREATE PROCEDURE " + spName + " (@jsonData json) AS " + tableInsert;
+
+ using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString))
+ {
+ await connection.OpenAsync();
+
+ using (SqlCommand command = connection.CreateCommand())
+ {
+ //Create Table
+ command.CommandText = tableCreate;
+ await command.ExecuteNonQueryAsync();
+
+ //Create SP for writing json values
+ command.CommandText = spCreate;
+ await command.ExecuteNonQueryAsync();
+
+ command.CommandText = tableInsert;
+ var parameter = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json);
+ command.Parameters.Add(parameter);
+
+ //Test 1
+ //Write json value using a parameterized query
+ parameter.Value = jsonDataString;
+ int rowsAffected = await command.ExecuteNonQueryAsync();
+ ValidateRowsAffected(rowsAffected);
+
+ //Test 2
+ //Write a SqlString type as json
+ parameter.Value = new SqlString(jsonDataString);
+ int rowsAffected2 = await command.ExecuteNonQueryAsync();
+ ValidateRowsAffected(rowsAffected2);
+
+ //Test 3
+ //Write json value using SP
+ using (SqlCommand command2 = connection.CreateCommand())
+ {
+ command2.CommandText = spName;
+ command2.CommandType = CommandType.StoredProcedure;
+ var parameter2 = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json);
+ parameter2.Value = jsonDataString;
+ command2.Parameters.Add(parameter2);
+ int rowsAffected3 = await command.ExecuteNonQueryAsync();
+ ValidateRowsAffected(rowsAffected3);
+ }
+ }
+ }
+ }
+
+ [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))]
+ public void TestJsonRead()
+ {
+ string tableName = DataTestUtility.GetUniqueNameForSqlServer("Json_Test");
+ string spName = DataTestUtility.GetUniqueNameForSqlServer("spJson_ReadTest");
+
+ string tableCreate = "CREATE TABLE " + tableName + " (Data json)";
+ string tableInsert = "INSERT INTO " + tableName + " VALUES (@jsonData)";
+ string tableRead = "SELECT * FROM " + tableName;
+ string spCreate = "CREATE PROCEDURE " + spName + "AS " + tableRead;
+
+ using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString))
+ {
+ connection.Open();
+ using (SqlCommand command = connection.CreateCommand())
+ {
+ //Create Table
+ command.CommandText = tableCreate;
+ command.ExecuteNonQuery();
+
+ //Create SP for reading from json column
+ command.CommandText = spCreate;
+ command.ExecuteNonQuery();
+
+ //Insert sample json data
+ //This will be used for reading
+ command.CommandText = tableInsert;
+ var parameter = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json);
+ parameter.Value = jsonDataString;
+ command.Parameters.Add(parameter);
+ command.ExecuteNonQuery();
+
+ //Test 1
+ //Read json value using query
+ command.CommandText = tableRead;
+ var reader = command.ExecuteReader();
+ ValidateRows(reader);
+
+ //Test 2
+ //Read the column metadata
+ ValidateSchema(reader);
+ reader.Close();
+
+ //Test 3
+ //Read json value using SP
+ using (SqlCommand command2 = connection.CreateCommand())
+ {
+ command2.CommandText = spName;
+ command2.CommandType = CommandType.StoredProcedure;
+ var reader2 = command2.ExecuteReader();
+ ValidateRows(reader2);
+ reader2.Close();
+ }
+ }
+ }
+ }
+
+ [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))]
+ public async Task TestJsonReadAsync()
+ {
+ string tableName = DataTestUtility.GetUniqueNameForSqlServer("Json_Test");
+ string spName = DataTestUtility.GetUniqueNameForSqlServer("spJson_ReadTest");
+
+ string tableCreate = "CREATE TABLE " + tableName + " (Data json)";
+ string tableInsert = "INSERT INTO " + tableName + " VALUES (@jsonData)";
+ string tableRead = "SELECT * FROM " + tableName;
+ string spCreate = "CREATE PROCEDURE " + spName + "AS " + tableRead;
+
+ using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString))
+ {
+ await connection.OpenAsync();
+ using (SqlCommand command = connection.CreateCommand())
+ {
+ //Create Table
+ command.CommandText = tableCreate;
+ await command.ExecuteNonQueryAsync();
+
+ //Create SP for reading from json column
+ command.CommandText = spCreate;
+ await command.ExecuteNonQueryAsync();
+
+ //Insert sample json data
+ //This will be used for reading
+ command.CommandText = tableInsert;
+ var parameter = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json);
+ parameter.Value = jsonDataString;
+ command.Parameters.Add(parameter);
+ await command.ExecuteNonQueryAsync();
+
+ //Test 1
+ //Read json value using query
+ command.CommandText = tableRead;
+ var reader = await command.ExecuteReaderAsync();
+ await ValidateRowsAsync(reader);
+
+ //Test 2
+ //Read the column metadata
+ ValidateSchema(reader);
+ reader.Close();
+
+ //Test 3
+ //Read json value using SP
+ using (SqlCommand command2 = connection.CreateCommand())
+ {
+ command2.CommandText = spName;
+ command2.CommandType = CommandType.StoredProcedure;
+ var reader2 = await command2.ExecuteReaderAsync();
+ await ValidateRowsAsync(reader2);
+ reader2.Close();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs
index 3fbe8313ee..1b712ceaf5 100644
--- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs
+++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs
@@ -42,6 +42,7 @@ public class Config
public string KerberosDomainUser = null;
public bool IsManagedInstance = false;
public string AliasName = null;
+ public bool IsJsonSupported = false;
public static Config Load(string configPath = @"config.json")
{
try