if (parameter.IsDerivedParameterTypeName)
{
string[] parts = MultipartIdentifier.ParseMultipartIdentifier(parameter.TypeName, "[\"", "]\"", SR.SQL_TDSParserTableName, false);
- if (parts != null)
+ if (parts != null && parts.Length==4) // will always return int[4] right justified
{
- int length = parts.Length;
if (
- length >= 3 && //require at least 3 parts
- parts[length - 1] != null && // name must not be null
- parts[length - 2] != null && // schema must not be null
- parts[length - 3] != null && // server should not be null or we don't need to remove it
- (length == 3 || parts[length - 4] == null) // if a database space is availble then is must be null
+ parts[3] != null && // name must not be null
+ parts[2] != null && // schema must not be null
+ parts[1] != null // server should not be null or we don't need to remove it
)
{
- parameter.TypeName = QuoteIdentifier(parts.AsSpan(length-2));
+ parameter.TypeName = QuoteIdentifier(parts.AsSpan(2,2));
}
}
}
}
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsUdtTestDatabasePresent), nameof(DataTestUtility.AreConnStringsSetup))]
- public void UDTParams_DeriveParameters()
+ public void UDTParams_DeriveParameters_CheckAutoFixSuccess()
{
// the type and sproc must be commited to the database or this test will deadlock with a schema lock violation
// if you are missing these database entities then you should look for an updated version of the database creation script
}
}
+ [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsUdtTestDatabasePresent), nameof(DataTestUtility.AreConnStringsSetup))]
+ public void UDTParams_DeriveParameters_CheckAutoFixOverride()
+ {
+ // the type and sproc must be commited to the database or this test will deadlock with a schema lock violation
+ // if you are missing these database entities then you should look for an updated version of the database creation script
+
+ string sprocName = "sp_insert_customers";
+ string typeName = "CustomerAddress";
+ string customerAddressTypeIncorrectName = $"{DataTestUtility.UdtTestDbName}.dbo.{typeName.Trim('[', ']')}";
+ string customerAddressTypeCorrectedName = $"[dbo].[{typeName.Trim('[', ']')}]";
+ string customerParameterName = "@customers";
+
+ Address addr = Address.Parse("123 baker st || Redmond");
+ DataTable table = new DataTable();
+ table.Columns.Add();
+ table.Columns.Add();
+ table.Rows.Add("john", addr);
+
+ using (SqlConnection connection = new SqlConnection(_connStr))
+ {
+ connection.Open();
+ using (SqlTransaction transaction = connection.BeginTransaction())
+ using (SqlCommand cmd = new SqlCommand(sprocName, connection, transaction))
+ {
+ try
+ {
+ cmd.CommandType = CommandType.StoredProcedure;
+
+ SqlCommandBuilder.DeriveParameters(cmd);
+
+ Assert.NotNull(cmd.Parameters);
+ Assert.Equal(2, cmd.Parameters.Count); // [return_value, table]
+
+ SqlParameter p = cmd.Parameters[1];
+
+ Assert.Equal(customerParameterName, p.ParameterName);
+ Assert.Equal(SqlDbType.Structured, p.SqlDbType);
+ Assert.Equal(customerAddressTypeIncorrectName, p.TypeName); // the 3 part name is incorrect but needs to be maintained for compatibility
+ p.Value = table;
+
+ p.TypeName = customerAddressTypeIncorrectName; // force using the incorrect name by manually setting it
+
+ Assert.Throws<SqlException>(
+ () => cmd.ExecuteNonQuery()
+ );
+ }
+ finally
+ {
+ try
+ {
+ transaction.Rollback();
+ }
+ catch
+ {
+ // ignore rollback failure exceptions to preserve original thrown error in test result
+ }
+ }
+ }
+
+ }
+ }
+
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsUdtTestDatabasePresent), nameof(DataTestUtility.AreConnStringsSetup))]
public void Reader_PointEarly()
{