mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-01 09:35:39 -05:00
Edit Data: Better errors for possible truncation (#514)
* Fix to make sql exceptions surface properly to user (with important notes!) * Adding support for detecting column size issues when updating a cell * Adding unit tests for the exception on read scenario
This commit is contained in:
committed by
Karl Burtram
parent
9499d73cec
commit
e9bc97e290
@@ -49,10 +49,7 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
}
|
||||
else if (columnType == typeof(string))
|
||||
{
|
||||
// Special case for strings because the string value should stay the same as provided
|
||||
// If user typed 'NULL' they mean NULL as text
|
||||
Value = valueAsString == TextNullString ? NullString : valueAsString;
|
||||
ValueAsString = valueAsString;
|
||||
ProcessTextCell(valueAsString);
|
||||
}
|
||||
else if (columnType == typeof(Guid))
|
||||
{
|
||||
@@ -245,6 +242,23 @@ namespace Microsoft.SqlTools.ServiceLayer.EditData.UpdateManagement
|
||||
ValueAsString = NullString;
|
||||
}
|
||||
|
||||
private void ProcessTextCell(string valueAsString)
|
||||
{
|
||||
// Special case for strings because the string value should stay the same as provided
|
||||
// If user typed 'NULL' they mean NULL as text
|
||||
Value = valueAsString == TextNullString ? NullString : valueAsString;
|
||||
|
||||
// Make sure that the value fits inside the size of the column
|
||||
if (Column.ColumnSize.HasValue && valueAsString.Length > Column.ColumnSize)
|
||||
{
|
||||
string columnSizeString = $"({Column.ColumnSize.Value})";
|
||||
string columnTypeString = Column.DataTypeName.ToUpperInvariant() + columnSizeString;
|
||||
throw new FormatException(SR.EditDataValueTooLarge(valueAsString, columnTypeString));
|
||||
}
|
||||
|
||||
ValueAsString = valueAsString;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3651,6 +3651,11 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
return Keys.GetString(Keys.EditDataUnsupportedObjectType, typeName);
|
||||
}
|
||||
|
||||
public static string EditDataValueTooLarge(string value, string columnType)
|
||||
{
|
||||
return Keys.GetString(Keys.EditDataValueTooLarge, value, columnType);
|
||||
}
|
||||
|
||||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class Keys
|
||||
{
|
||||
@@ -3932,6 +3937,9 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
public const string EditDataNullNotAllowed = "EditDataNullNotAllowed";
|
||||
|
||||
|
||||
public const string EditDataValueTooLarge = "EditDataValueTooLarge";
|
||||
|
||||
|
||||
public const string EE_BatchSqlMessageNoProcedureInfo = "EE_BatchSqlMessageNoProcedureInfo";
|
||||
|
||||
|
||||
|
||||
@@ -495,6 +495,11 @@
|
||||
<value>NULL is not allowed for this column</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="EditDataValueTooLarge" xml:space="preserve">
|
||||
<value>Value {0} is too large to fit in column of type {1}</value>
|
||||
<comment>.
|
||||
Parameters: 0 - value (string), 1 - columnType (string) </comment>
|
||||
</data>
|
||||
<data name="EE_BatchSqlMessageNoProcedureInfo" xml:space="preserve">
|
||||
<value>Msg {0}, Level {1}, State {2}, Line {3}</value>
|
||||
<comment></comment>
|
||||
|
||||
@@ -232,6 +232,8 @@ EditDataTimeOver24Hrs = TIME column values must be between 00:00:00.0000000 and
|
||||
|
||||
EditDataNullNotAllowed = NULL is not allowed for this column
|
||||
|
||||
EditDataValueTooLarge(string value, string columnType) = Value {0} is too large to fit in column of type {1}
|
||||
|
||||
############################################################################
|
||||
# DacFx Resources
|
||||
|
||||
|
||||
@@ -2305,6 +2305,12 @@
|
||||
<target state="new">For directory {0} a file with name {1} already exists</target>
|
||||
<note></note>
|
||||
</trans-unit>
|
||||
<trans-unit id="EditDataValueTooLarge">
|
||||
<source>Value {0} is too large to fit in column of type {1}</source>
|
||||
<target state="new">Value {0} is too large to fit in column of type {1}</target>
|
||||
<note>.
|
||||
Parameters: 0 - value (string), 1 - columnType (string) </note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -616,19 +616,23 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
|
||||
{
|
||||
throw new InvalidOperationException(SR.QueryServiceResultSetNotRead);
|
||||
}
|
||||
if (!dbDataReader.HasRows)
|
||||
// NOTE: We are no longer checking to see if the data reader has rows before reading
|
||||
// b/c of a quirk in SqlClient. In some scenarios, a SqlException isn't thrown until we
|
||||
// read. In order to get appropriate errors back to the user, we'll read first.
|
||||
// Returning false from .ReadAsync means there aren't any rows.
|
||||
|
||||
// Create a storage data reader, read it, make sure there were results
|
||||
StorageDataReader dataReader = new StorageDataReader(dbDataReader);
|
||||
if (!await dataReader.ReadAsync(CancellationToken.None))
|
||||
{
|
||||
throw new InvalidOperationException(SR.QueryServiceResultSetAddNoRows);
|
||||
}
|
||||
|
||||
StorageDataReader dataReader = new StorageDataReader(dbDataReader);
|
||||
|
||||
|
||||
using (IFileStreamWriter writer = fileStreamFactory.GetWriter(outputFileName))
|
||||
{
|
||||
// Write the row to the end of the file
|
||||
long currentFileOffset = totalBytesWritten;
|
||||
writer.Seek(currentFileOffset);
|
||||
await dataReader.ReadAsync(CancellationToken.None);
|
||||
totalBytesWritten += writer.WriteRow(dataReader);
|
||||
return currentFileOffset;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user