SqlDataReader (в сборке) возвращает разные типы данных по сравнению с sp_help - PullRequest
0 голосов
/ 20 июня 2020

У меня есть настраиваемая сборка, которая возвращает информацию о столбце для любого запроса, который ей брошен. Пока я просматривал и дважды проверял значения, оказалось, что некоторые из значений DataTypeName, возвращаемых GetSchemaTable (), немного отличаются от того, что sp_help возвращает для типа в том же запросе. Это выглядит исключительно для десятичных и числовых c полей.

Для справки, вот код сборки:

using System;
using System.Linq;
using System.Data;
using System.Data.SqlTypes;
using System.Data.SqlClient;
using Microsoft.SqlServer.Server;

public class StoredProcedures
{
    /// <summary>
    /// example of sending a tabular result and a message through SqlPipe.
    /// </summary>
    [SqlProcedure]
    public static void CLRExec(SqlString query)
    {
        DataTable schema = null;
        SqlContext.Pipe.Send(DateTime.Now.ToString() + " -- " + query.ToString());
        using (SqlConnection connection = new SqlConnection("context connection=true"))
        {
            string sQuery = query.ToString();

            // Create the record and specify the metadata for the columns.
            SqlDataRecord record = new SqlDataRecord(
                new SqlMetaData("ColumnName", SqlDbType.NVarChar, 100),
                new SqlMetaData("DataTypeName", SqlDbType.NVarChar, 100),
                new SqlMetaData("ColumnSize", SqlDbType.Int),
                new SqlMetaData("NumericPrecision", SqlDbType.Int),
                new SqlMetaData("NumericScale", SqlDbType.Int));

            connection.Open();

            SqlCommand command = new SqlCommand(sQuery, connection);
            SqlDataReader reader = command.ExecuteReader();

            schema = reader.GetSchemaTable();

            //Mark the begining of the result-set.
             SqlContext.Pipe.SendResultsStart(record);
            foreach (DataRow col in schema.Rows)
            {
                record.SetString(0, col.Field<String>("ColumnName").ToString());
                record.SetString(1, col.Field<String>("DataTypeName").ToString());
                record.SetInt32(2, col.Field<int>("ColumnSize"));
                record.SetInt32(3, col.Field<short>("NumericPrecision"));
                //if column is type int, scale of 255 = 0 else 255 = ''
                record.SetInt32(4, col.Field<short>("NumericScale"));

                // Send the row back to the client.
                SqlContext.Pipe.SendResultsRow(record);
            }

             SqlContext.Pipe.SendResultsEnd();
        }
    }
}

Вот скриншот, демонстрирующий различия: https://i.imgur.com/8Y0V9mx.png

Я не думаю, что это такая большая проблема, поскольку точность и масштаб кажутся правильными везде. Однако я планирую использовать эту сборку, чтобы позволить пользователям создавать собственные источники данных во внешнем интерфейсе, и хочу быть уверенным, что это больше не вызовет головной боли в дальнейшем.

...