Skip to content

Commit f7f3484

Browse files
committed
Handle SQL Graph tables
These tables have columns which cannot be selected explicitly.
1 parent f6df23d commit f7f3484

File tree

4 files changed

+62
-1
lines changed

4 files changed

+62
-1
lines changed

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,11 +466,20 @@ private string CreateInitialQuery()
466466
// If the target table doesn't exist, OBJECT_ID will return NULL and @Column_Names will remain non-null. The subsequent SELECT *
467467
// query will then continue to fail with "Invalid object name" rather than with an unusual error because the query being executed
468468
// is NULL.
469+
// Some hidden columns (e.g. SQL Graph columns) cannot be selected, so we need to exclude them explicitly.
469470
return $"""
470471
SELECT @@TRANCOUNT;
471472
472473
DECLARE @Column_Names NVARCHAR(MAX) = NULL;
473-
SELECT @Column_Names = COALESCE(@Column_Names + ', ', '') + QUOTENAME(name) FROM {CatalogName}.sys.all_columns WHERE OBJECT_ID = OBJECT_ID('{escapedObjectName}') ORDER BY column_id ASC;
474+
IF EXISTS (SELECT TOP 1 * FROM sys.all_columns where object_id = object_id('sys.all_columns') AND [name] = 'graph_type')
475+
BEGIN
476+
SELECT @Column_Names = COALESCE(@Column_Names + ', ', '') + QUOTENAME(name) FROM {CatalogName}.sys.all_columns WHERE OBJECT_ID = OBJECT_ID('{escapedObjectName}') AND COALESCE(graph_type, 0) NOT IN (1, 3, 4, 6, 7) ORDER BY column_id ASC;
477+
END
478+
ELSE
479+
BEGIN
480+
SELECT @Column_Names = COALESCE(@Column_Names + ', ', '') + QUOTENAME(name) FROM {CatalogName}.sys.all_columns WHERE OBJECT_ID = OBJECT_ID('{escapedObjectName}') ORDER BY column_id ASC;
481+
END
482+
474483
SELECT @Column_Names = COALESCE(@Column_Names, '*');
475484
476485
SET FMTONLY ON;

src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@
148148
<Compile Include="SQL\SqlBulkCopyTest\MissingTargetColumns.cs" />
149149
<Compile Include="SQL\SqlBulkCopyTest\MissingTargetTable.cs" />
150150
<Compile Include="SQL\SqlBulkCopyTest\SqlBulkCopyTest.cs" />
151+
<Compile Include="SQL\SqlBulkCopyTest\SqlGraphTables.cs" />
151152
<Compile Include="SQL\SqlBulkCopyTest\TestBulkCopyWithUTF8.cs" />
152153
<Compile Include="SQL\SqlBulkCopyTest\Transaction.cs" />
153154
<Compile Include="SQL\SqlBulkCopyTest\Transaction1.cs" />

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/SqlBulkCopyTest.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ public void HiddenTargetColumnTest()
115115
HiddenTargetColumn.Test(_connStr, _connStr, AddGuid("SqlBulkCopyTest_HiddenTargetColumn"));
116116
}
117117

118+
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer))]
119+
public void SqlGraphTablesTest()
120+
{
121+
SqlGraphTables.Test(_connStr, AddGuid("SqlBulkCopyTest_SqlGraphTables_Node"));
122+
}
123+
118124
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer))]
119125
public void Bug85007Test()
120126
{
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Data;
7+
using System.Data.Common;
8+
using Xunit;
9+
10+
namespace Microsoft.Data.SqlClient.ManualTesting.Tests
11+
{
12+
public class SqlGraphTables
13+
{
14+
public static void Test(string dstConnectionString, string dstNodeTable)
15+
{
16+
using SqlConnection dstConn = new SqlConnection(dstConnectionString);
17+
using DataTable nodes = new DataTable()
18+
{
19+
Columns = { new DataColumn("Name", typeof(string)) }
20+
};
21+
22+
dstConn.Open();
23+
24+
for (int i = 0; i < 5; i++)
25+
{
26+
nodes.Rows.Add($"Name {i}");
27+
}
28+
29+
try
30+
{
31+
DataTestUtility.CreateTable(dstConn, dstNodeTable, "(Id INT PRIMARY KEY IDENTITY(1,1), [Name] VARCHAR(100)) AS NODE");
32+
33+
using SqlBulkCopy nodeCopy = new SqlBulkCopy(dstConn);
34+
35+
nodeCopy.DestinationTableName = dstNodeTable;
36+
nodeCopy.ColumnMappings.Add("Name", "Name");
37+
nodeCopy.WriteToServer(nodes);
38+
}
39+
finally
40+
{
41+
DataTestUtility.DropTable(dstConn, dstNodeTable);
42+
}
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)