Skip to content

Complete removal of SQL 2000 support #3217

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Mar 17, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -2350,8 +2350,7 @@ private static void ChangePassword(string connectionString, SqlConnectionString
}
finally
{
if (con != null)
con.Dispose();
con?.Dispose();
}
SqlConnectionPoolKey key = new SqlConnectionPoolKey(connectionString, credential, accessToken: null, accessTokenCallback: null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,6 @@ internal EncryptionOptions EncryptionOptions
}
}

internal bool Is2005OrNewer => true;

internal bool Is2008OrNewer
{
get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,6 @@ internal object[] CreateRowBuffer()
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopy.xml' path='docs/members[@name="SqlBulkCopy"]/SqlBulkCopy/*'/>
public sealed class SqlBulkCopy : IDisposable
{
private enum TableNameComponents
{
Server = 0,
Catalog,
Owner,
TableName,
}

private enum ValueSourceType
{
Unspecified = 0,
Expand Down Expand Up @@ -161,10 +153,6 @@ public SourceColumnMetadata(ValueMethod method, bool isSqlType, bool isDataFeed)
// MetaData has n columns but no rows
// Collation has 4 columns and n rows

private const int TranCountResultId = 0;
private const int TranCountRowId = 0;
private const int TranCountValueId = 0;

private const int MetaDataResultId = 1;

private const int CollationResultId = 2;
Expand Down Expand Up @@ -439,66 +427,60 @@ private string CreateInitialQuery()
string TDSCommand;

TDSCommand = "select @@trancount; SET FMTONLY ON select * from " + ADP.BuildMultiPartName(parts) + " SET FMTONLY OFF ";
if (_connection.Is2000)
{
// If its a temp DB then try to connect

string TableCollationsStoredProc;
if (_connection.Is2008OrNewer)
{
TableCollationsStoredProc = "sp_tablecollations_100";
}
else if (_connection.Is2005OrNewer)
{
TableCollationsStoredProc = "sp_tablecollations_90";
}
else
{
TableCollationsStoredProc = "sp_tablecollations";
}
// If its a temp DB then try to connect

string TableName = parts[MultipartIdentifier.TableIndex];
bool isTempTable = TableName.Length > 0 && '#' == TableName[0];
if (!ADP.IsEmpty(TableName))
{
// Escape table name to be put inside TSQL literal block (within N'').
TableName = SqlServerEscapeHelper.EscapeStringAsLiteral(TableName);
// VSDD 581951 - escape the table name
TableName = SqlServerEscapeHelper.EscapeIdentifier(TableName);
}
string TableCollationsStoredProc;
if (_connection.Is2008OrNewer)
{
TableCollationsStoredProc = "sp_tablecollations_100";
}
else
{
TableCollationsStoredProc = "sp_tablecollations_90";
}

string SchemaName = parts[MultipartIdentifier.SchemaIndex];
if (!ADP.IsEmpty(SchemaName))
{
// Escape schema name to be put inside TSQL literal block (within N'').
SchemaName = SqlServerEscapeHelper.EscapeStringAsLiteral(SchemaName);
// VSDD 581951 - escape the schema name
SchemaName = SqlServerEscapeHelper.EscapeIdentifier(SchemaName);
}
string TableName = parts[MultipartIdentifier.TableIndex];
bool isTempTable = TableName.Length > 0 && '#' == TableName[0];
if (!ADP.IsEmpty(TableName))
{
// Escape table name to be put inside TSQL literal block (within N'').
TableName = SqlServerEscapeHelper.EscapeStringAsLiteral(TableName);
// VSDD 581951 - escape the table name
TableName = SqlServerEscapeHelper.EscapeIdentifier(TableName);
}

string CatalogName = parts[MultipartIdentifier.CatalogIndex];
if (isTempTable && ADP.IsEmpty(CatalogName))
{
TDSCommand += string.Format("exec tempdb..{0} N'{1}.{2}'",
TableCollationsStoredProc,
SchemaName,
TableName
);
}
else
string SchemaName = parts[MultipartIdentifier.SchemaIndex];
if (!ADP.IsEmpty(SchemaName))
{
// Escape schema name to be put inside TSQL literal block (within N'').
SchemaName = SqlServerEscapeHelper.EscapeStringAsLiteral(SchemaName);
// VSDD 581951 - escape the schema name
SchemaName = SqlServerEscapeHelper.EscapeIdentifier(SchemaName);
}

string CatalogName = parts[MultipartIdentifier.CatalogIndex];
if (isTempTable && ADP.IsEmpty(CatalogName))
{
TDSCommand += string.Format("exec tempdb..{0} N'{1}.{2}'",
TableCollationsStoredProc,
SchemaName,
TableName
);
}
else
{
// VSDD 581951 - escape the catalog name
if (!ADP.IsEmpty(CatalogName))
{
// VSDD 581951 - escape the catalog name
if (!ADP.IsEmpty(CatalogName))
{
CatalogName = SqlServerEscapeHelper.EscapeIdentifier(CatalogName);
}
TDSCommand += string.Format("exec {0}..{1} N'{2}.{3}'",
CatalogName,
TableCollationsStoredProc,
SchemaName,
TableName
);
CatalogName = SqlServerEscapeHelper.EscapeIdentifier(CatalogName);
}
TDSCommand += string.Format("exec {0}..{1} N'{2}.{3}'",
CatalogName,
TableCollationsStoredProc,
SchemaName,
TableName
);
}
return TDSCommand;
}
Expand Down Expand Up @@ -549,7 +531,7 @@ private string AnalyzeTargetAndCreateUpdateBulkCommand(BulkCopySimpleResultSet i

StringBuilder updateBulkCommandText = new StringBuilder();

if (_connection.Is2000 && 0 == internalResults[CollationResultId].Count)
if (0 == internalResults[CollationResultId].Count)
{
throw SQL.BulkLoadNoCollation();
}
Expand All @@ -562,15 +544,7 @@ private string AnalyzeTargetAndCreateUpdateBulkCommand(BulkCopySimpleResultSet i

bool isInTransaction;

if (_parser.Is2005OrNewer)
{
isInTransaction = _connection.HasLocalTransaction;
}
else
{
isInTransaction = (bool)(0 < (SqlInt32)(internalResults[TranCountResultId][TranCountRowId][TranCountValueId]));
}

isInTransaction = _connection.HasLocalTransaction;
// Throw if there is a transaction but no flag is set
if (isInTransaction &&
_externalTransaction == null &&
Expand Down Expand Up @@ -701,50 +675,45 @@ private string AnalyzeTargetAndCreateUpdateBulkCommand(BulkCopySimpleResultSet i
}
}

if (_connection.Is2000)
{
// 2000 or above!
// get collation for column i
// Get collation for column i
Result rowset = internalResults[CollationResultId];
object rowvalue = rowset[i][CollationId];

Result rowset = internalResults[CollationResultId];
object rowvalue = rowset[i][CollationId];
bool shouldSendCollation;
switch (metadata.type)
{
case SqlDbType.Char:
case SqlDbType.NChar:
case SqlDbType.VarChar:
case SqlDbType.NVarChar:
case SqlDbType.Text:
case SqlDbType.NText:
shouldSendCollation = true;
break;

bool shouldSendCollation;
switch (metadata.type)
{
case SqlDbType.Char:
case SqlDbType.NChar:
case SqlDbType.VarChar:
case SqlDbType.NVarChar:
case SqlDbType.Text:
case SqlDbType.NText:
shouldSendCollation = true;
break;
default:
shouldSendCollation = false;
break;
}

default:
shouldSendCollation = false;
break;
}
if (rowvalue != null && shouldSendCollation)
{
Debug.Assert(rowvalue is SqlString);
SqlString collation_name = (SqlString)rowvalue;

if (rowvalue != null && shouldSendCollation)
if (!collation_name.IsNull)
{
Debug.Assert(rowvalue is SqlString);
SqlString collation_name = (SqlString)rowvalue;

if (!collation_name.IsNull)
updateBulkCommandText.Append(" COLLATE " + collation_name.Value);
// VSTFDEVDIV 461426: compare collations only if the collation value was set on the metadata
if (_sqlDataReaderRowSource != null && metadata.collation != null)
{
updateBulkCommandText.Append(" COLLATE " + collation_name.Value);
// VSTFDEVDIV 461426: compare collations only if the collation value was set on the metadata
if (_sqlDataReaderRowSource != null && metadata.collation != null)
// On SqlDataReader we can verify the sourcecolumn collation!
int sourceColumnId = _localColumnMappings[assocId]._internalSourceColumnOrdinal;
int destinationLcid = metadata.collation.LCID;
int sourceLcid = _sqlDataReaderRowSource.GetLocaleId(sourceColumnId);
if (sourceLcid != destinationLcid)
{
// On SqlDataReader we can verify the sourcecolumn collation!
int sourceColumnId = _localColumnMappings[assocId]._internalSourceColumnOrdinal;
int destinationLcid = metadata.collation.LCID;
int sourceLcid = _sqlDataReaderRowSource.GetLocaleId(sourceColumnId);
if (sourceLcid != destinationLcid)
{
throw SQL.BulkLoadLcidMismatch(sourceLcid, _sqlDataReaderRowSource.GetName(sourceColumnId), destinationLcid, metadata.column);
}
throw SQL.BulkLoadLcidMismatch(sourceLcid, _sqlDataReaderRowSource.GetName(sourceColumnId), destinationLcid, metadata.column);
}
}
}
Expand Down
Loading