question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Connection to database with valid collation returns "The Collation specified by SQL Server is not supported." (Kazakh_90_CI_AS)

See original GitHub issue

Description

When we connect to databases that have the collation Kazakh_90_CI_AS and run queries with explicit text on field names (such as “select ‘test’”) we get the following error:

Exception message: The Collation specified by SQL Server is not supported
Stack trace:
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)

   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bul
kCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCo
pyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParser.DrainData(TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParser.ThrowUnsupportedCollationEncountered(TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParserStateObject.TryReadStringWithEncoding(Int32 length, Encoding encoding, Boolean isPlp, String& value)
   at System.Data.SqlClient.TdsParser.TryReadSqlStringValue(SqlBuffer value, Byte type, Int32 length, Encoding encoding, Boolean isPlp, TdsParserS
tateObject stateObj)
   at System.Data.SqlClient.TdsParser.TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, Int32 length, TdsParserStateObject stateObj, SqlCommand
ColumnEncryptionSetting columnEncryptionOverride, String columnName)
   at System.Data.SqlClient.SqlDataReader.TryReadColumnInternal(Int32 i, Boolean readHeaderOnly)
   at System.Data.SqlClient.SqlDataReader.TryReadColumn(Int32 i, Boolean setTimeout, Boolean allowPartiallyReadColumn)
   at System.Data.SqlClient.SqlDataReader.GetValues(Object[] values)
   at System.Data.ProviderBase.SchemaMapping.LoadDataRow()
   at System.Data.Common.DataAdapter.FillLoadDataRow(SchemaMapping mapping)
   at System.Data.Common.DataAdapter.FillFromReader(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 s
tartRecord, Int32 maxRecords, DataColumn parentChapterColumn, Object parentChapterValue)
   at System.Data.Common.DataAdapter.Fill(DataSet dataSet, String srcTable, IDataReader dataReader, Int32 startRecord, Int32 maxRecords)
   at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable,
 IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBeha
vior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet)
   at CallSite.Target(Closure , CallSite , Object , Object )

To reproduce

  1. Create a database using the collation Kazakh_90_CI_AS
  2. Connect to the database using the database name as the Initial Catalog (as the example below):
Data Source=localhost;Initial Catalog=CollationKazakh;Integrated Security=SSPI;MultiSubnetFailover=False;Connect Timeout=15;Pooling=False
  1. Run the query SELECT ‘test’

Here is a powershell script that connects and executes the query:

try
{
$conn = New-Object System.Data.SqlClient.SqlConnection
$conn.ConnectionString = "Data Source=localhost;Initial Catalog=CollationKazakh;Integrated Security=SSPI;MultiSubnetFailover=False;Connect Timeout=15;Pooling=False"
$conn.open()

# SELECT 'test'
$cmd = New-Object System.Data.SqlClient.SqlCommand
$cmd.connection = $conn
$cmd.CommandText = "SELECT 'test'"
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $cmd
$DataSet = New-Object System.Data.DataSet
$res = $SqlAdapter.Fill($DataSet)


}
catch
{
	$_.Exception.Message
	$_.Exception.StackTrace
    if ($_.Exception.InnerException -ne $null)
	{
		$_.Exception.InnerException.Message
		$_.Exception.InnerException.StackTrace
    }
}

Expected behavior

It was expected to have one row with ‘test’ as a result.

Further technical details

dotnet --info:

.NET Core SDK (reflecting any global.json):
 Version:   3.1.201
 Commit:    b1768b4ae7

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.14393
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.1.201\

Host (useful for support):
  Version: 3.1.3
  Commit:  4a9f85e9f8

.NET Core SDKs installed:
  3.1.201 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.App 3.1.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

.NET Framework Version (Registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full): 4.8.03761

System.Data.dll:

PS C:\Windows\Microsoft.NET\assembly\GAC_64\System.Data> Get-ChildItem -Filter *.dll -Recurse | Select-Object -ExpandProperty VersionInfo

ProductVersion   FileVersion      FileName                                                                                                       
--------------   -----------      --------                                                                                                       
4.8.4121.0       4.8.4121.0 bu... C:\Windows\Microsoft.NET\assembly\GAC_64\System.Data\v4.0_4.0.0.0__b77a5c561934e089\System.Data.dll 

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
karinazhoucommented, May 28, 2020

@dineubr I look more into the driver’s code. We get CollationUnsupportedException because the code page we get from CultureInfo.GetCultureInfo(cultureId).TextInfo.ANSICodePage equals zero when cultureId is 1087 (Kazakh_90_CI_AS).

This piece of code can be found in src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs : GetCodePage().

When we reach codePage = 0, we won’t be able to get its corresponding encoding. The following query you are using SELECT 'test'

will follow the path of how we deal with narrow characters in the driver. This requires valid encoding for the database collation. Otherwise, it will throw CollationUnsupportedException.

One workaround for your case is to use wide characters in the query: SELECT N'test'

In this way, the driver will pass the test value as a Unicode string to the server which doesn’t require encoding conversion.

0reactions
cheenamalhotracommented, Jun 10, 2020

Hi @dineubr

Since https://github.com/dotnet/SqlClient/pull/584 is now merged, we will close the issue. It will be released with v2.0.0 soon. Feel free to re-open if you face any issues.

Read more comments on GitHub >

github_iconTop Results From Across the Web

The Collation specified by SQL Server is not supported
We are using entityframework and we cannot run application on client server.We cannot run query but when we edit table we can see...
Read more >
How to fix the collation of a Microsoft SQL Server database
Firstly, create a new database as per the guidelines for your specific application. Ensure the collation is set correctly; as well as any...
Read more >
Set or change the database collation - SQL Server
You can change the collation of any new objects that are created in a user database by using the COLLATE clause of the...
Read more >
SQL Server collation introduction with collate SQL casting
SQL Server collation indicates set of rules on how information can be stored, compared, and arranged in the T-SQL query statement.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found