C# sql запрос останавливается на cmd.execute - PullRequest
0 голосов
/ 30 марта 2020

Здравствуйте. Я создал метод, который принимает параметры поиска, а затем возвращает запрос. Это было сделано с использованием ADO. net Теперь я заметил, что мой метод внезапно заканчивается cmd.execute. Вот мой метод.

  public class SQLStringSearchService
    {
        string connectionString = string




        public async Task<List<TransactionJournal>> SearchArchivedTransactionJournal(DateTime transactionDate, string Region, string MCC, string MerchantID, string TxnCurrency, string TerminalID, decimal TxnAmount, string BIN, string MsgType, string MaskedPan, string ProcessingCode, string ClearPan, string ResponseCode, string AuthorizationCode, string EntryMode, [FromQuery] PaginationDTO pagination)
        {
            var monthString = string.Empty;

            if (transactionDate.Month < 10)
            {
              monthString = transactionDate.Month.ToString().Insert(0,"0");
            }
            else
            {
                monthString = transactionDate.Month.ToString();
            }
            var DbTable = "TRANSACTIONJOURNAL_" + transactionDate.Year.ToString() + monthString;
            var queryable = new List<TransactionJournal>();

         using (SqlConnection connection = new SqlConnection(connectionString))
            {
                using (var cmd = new SqlCommand())
                {
                    connection.Open();
                    cmd.Connection = connection;
                    cmd.CommandType = CommandType.Text;
                    cmd.CommandText = "Select * From Table = @Table Where TransactionDateTime <= @DateTime and AcquirerID = @Region and MerchantCategoryCode = @MCC and MerchantID = @MerchantId and Currency = @TxnCurrency and TerminalID = @TerminalId and " +
                        "TransactionAmount = @TxnAmount and Bin = @Bin and MessageType = @MsgType and ProcessingCode = @ProcessingCode and PANM = @Panm and PAN = @Pan and ResponseCode = @ResponseCode and AuthorizationCode = @AuthCode and ResponseCode = @ResponseCode";
                    cmd.Parameters.AddWithValue("@Table", DbTable);
                    cmd.Parameters.AddWithValue("@DateTime", transactionDate);
                    cmd.Parameters.AddWithValue("@Region", Region);
                    cmd.Parameters.AddWithValue("@MCC", MCC);
                    cmd.Parameters.AddWithValue("@MerchantId", MerchantID);
                    cmd.Parameters.AddWithValue("@TxnCurrency", TxnCurrency);
                    cmd.Parameters.AddWithValue("@TerminalId", TerminalID);
                    cmd.Parameters.AddWithValue("@TxnAmount", TxnAmount);
                    cmd.Parameters.AddWithValue("@Bin", BIN);
                    cmd.Parameters.AddWithValue("@MsgType", MsgType);
                    cmd.Parameters.AddWithValue("@ProcessingCode", ProcessingCode);
                    cmd.Parameters.AddWithValue("@Panm", MaskedPan);
                    cmd.Parameters.AddWithValue("@Pan", ClearPan);
                    cmd.Parameters.AddWithValue("@ResponseCode", ResponseCode);
                    cmd.Parameters.AddWithValue("@AuthCode", AuthorizationCode);
                    cmd.Parameters.AddWithValue("@ResponseCode", ResponseCode);
                    queryable = (List<TransactionJournal>)cmd.ExecuteScalar();
                    cmd.Dispose();
                }
            }
            var orderedQuery = queryable.OrderByDescending(x=> x.TransactionDateTime).AsQueryable();
            await HttpContextExtensions.GetPage<TransactionJournal>(orderedQuery, pagination.Page, pagination.QuantityPerPage);
            return await orderedQuery.Paginate(pagination).ToListAsync();

        }

    }

Я попробовал отладку, и метод только что закончился, я не могу понять, в чем проблема. Если кто-то может показать мне пример, может быть, правильный путь, поэтому я был бы очень признателен. Спасибо!

Ответы [ 2 ]

0 голосов
/ 02 апреля 2020

У вас неправильный запрос. Вы не можете передать таблицу как переменную так, как пытаетесь. Чтобы достичь такого типа функциональности, вы должны использовать string.Fromat.

Попробуйте что-то вроде:

using (var cmd = new SqlCommand())
{
    connection.Open();
    cmd.Connection = connection;
    cmd.CommandType = CommandType.Text;
    cmd.CommandText = string.Join(
        string.Fromat("SELECT * FROM {0} ",DbTable),
        "WHERE TransactionDateTime <= @DateTime ",
        "AND AcquirerID = @Region ",
        "AND MerchantCategoryCode = @MCC",
        "AND MerchantID = @MerchantId ",
        "AND Currency = @TxnCurrency ",
        "AND TerminalID = @TerminalId ",
        "AND TransactionAmount = @TxnAmount ",
        "AND Bin = @Bin ",
        "AND MessageType = @MsgType ",
        "AND ProcessingCode = @ProcessingCode ",
        "AND PANM = @Panm ",
        "AND PAN = @Pan ",
        "AND ResponseCode = @ResponseCode ",
        "AND AuthorizationCode = @AuthCode ",
        "AND ResponseCode = @ResponseCode");

    cmd.Parameters.AddWithValue("@DateTime", transactionDate);
    cmd.Parameters.AddWithValue("@Region", Region);
    cmd.Parameters.AddWithValue("@MCC", MCC);
    cmd.Parameters.AddWithValue("@MerchantId", MerchantID);
    cmd.Parameters.AddWithValue("@TxnCurrency", TxnCurrency);
    cmd.Parameters.AddWithValue("@TerminalId", TerminalID);
    cmd.Parameters.AddWithValue("@TxnAmount", TxnAmount);
    cmd.Parameters.AddWithValue("@Bin", BIN);
    cmd.Parameters.AddWithValue("@MsgType", MsgType);
    cmd.Parameters.AddWithValue("@ProcessingCode", ProcessingCode);
    cmd.Parameters.AddWithValue("@Panm", MaskedPan);
    cmd.Parameters.AddWithValue("@Pan", ClearPan);
    cmd.Parameters.AddWithValue("@ResponseCode", ResponseCode);
    cmd.Parameters.AddWithValue("@AuthCode", AuthorizationCode);
    cmd.Parameters.AddWithValue("@ResponseCode", ResponseCode);
    queryable = (List<TransactionJournal>)cmd.ExecuteScalar();
}

Вам не нужно использовать string.Join, как я. Я просто хотел разделить запрос на части, чтобы сделать его более читабельным для меня. Вы можете отформатировать все виды способов.

Когда это возможно, я бы порекомендовал вам написать свои запросы и протестировать их на SQL сервере или локальном экземпляре. Затем вы можете использовать его для создания текстовой строки вашей команды.

Нечто подобное могло бы помочь вам обнаружить проблему:

DECLARE @Table varchar(50) = 'TRANSACTIONJOURNAL_202003',
        @DateTime datetime = GETDATE(),
-- ... And so on with the rest of the variables you need
-- you have lots of variables
-- you get the gist


SELECT * FROM  Table = @Table
WHERE TransactionDateTime <= @DateTime
AND AcquirerID = @Region
AND MerchantCategoryCode = @MCC
AND MerchantID = @MerchantId
AND Currency = @TxnCurrency
AND TerminalID = @TerminalId
AND TransactionAmount = @TxnAmount
AND Bin = @Bin
AND MessageType = @MsgType
AND ProcessingCode = @ProcessingCode
AND PANM = @Panm
AND PAN = @Pan
AND ResponseCode = @ResponseCode
AND AuthorizationCode = @AuthCode
AND ResponseCode = @ResponseCode;

Еще одна вещь. Я бы порекомендовал не использовать SELECT *. Вместо этого я бы явно выписал имена столбцов. Если они когда-нибудь добавят другой столбец в эту таблицу, это может сломать вещи. Особенно, если они меняют порядок столбцов.

Надеюсь, это поможет.

0 голосов
/ 31 марта 2020

Код не просто останавливается, но всякий раз, когда кажется, что он это делает, он, вероятно, встречает исключение, которое не обрабатывается должным образом, внутри конструкции кодирования, которая не может его терпеть - я чаще всего вижу это, если есть какой-то фон задействована многопоточность, поток попадает в исключение, останавливается, и исключение передается тому, кто управлял потоком (который затем ничего с этим не делает). Поток просто исчезает, и VS перестает его отслеживать. Возможно, вы обнаружите, что он переключается на другой поток, но выглядит так, будто код «только что остановился» - возможно, мы обнаружим, что этот метод был вызван без await или в рабочем файле backgrounder, который не получает исключение

В общем, этот код имеет некоторый fl aws и не может работать. Согласно комментариям sql является недействительным. Вы также не сможете / не сможете выполнить Scalar и надеетесь получить список из него. По определению, скаляр - это одно значение, верхняя левая ячейка любого результирующего набора - для него нет возможности быть списком значений. Если вам нужен список, вам нужно выполнитьReReader и заполнить список ...

Если вы включили разрыв при выбросе (go в меню отладки, найдите окно исключений, поставьте галочку рядом с Common Language Runtime - теперь, как только любое исключение будет поднято, обработано или нет, код остановится. Вы, вероятно, обнаружите, что теперь ваш код останавливается на исключении sql, но, по крайней мере, вы можете исправить его и двигаться дальше. Рекомендуем по крайней мере, вы заверните свой executeXxx в попытку поймать ...

...