Хранимая процедура, возвращающая запись с нулевыми значениями (когда это не так)

#c# #sql-server #api #asp.net-core #stored-procedures

#c# #sql-сервер #API #asp.net-core #хранимые процедуры

Вопрос:

По какой-то причине, когда я пытаюсь выполнить запрос (через API) с идентификатором записи, я получаю доступ, где он содержит нулевые атрибуты. Но, если я выполняю вопрос, используя другие атрибуты (помимо ID), он имеет правильные значения.

Например: когда я выполняю (фактический код хранимой процедуры):

 CREATE PROCEDURE [dbo].[spClient_GetById]
    @Id int
AS
BEGIN
    SELECT *
    FROM dbo.Client
    WHERE Id = @Id;
END
  

Я получаю запись

 {
    "id": 2,
    "firstName": null,
    "lastName": null,
    "email": null,
    "phoneNumber": null,
    "houseNum": "1212",
    "street": "Downtown",
    "state": "WA",
    "city": "Vancouver",
    "cost": 12000.0000,
    "status": "Started",
    "eta": 0,
    "startDate": null,
    "completeDate": null,
    "contractorID": 0
}
  

Но когда я выполняю следующий запрос в той же базе данных,

 CREATE PROCEDURE [dbo].[spClient_GetByHouse]
    @HouseNum nvarchar(10),
    @Street nvarchar(50) = null
AS
    IF @Street IS NULL
    BEGIN
        SELECT *
        FROM dbo.Client
        WHERE HouseNum = @HouseNum;
    END
    ELSE
    BEGIN
        SELECT *
        FROM dbo.Client
        WHERE HouseNum = @HouseNum AND Street LIKE @Street;
    END
  

Я получаю следующую запись (кстати, ту же запись):

 {
    "id": 2,
    "firstName": "This",
    "lastName": "That",
    "email": "qwe@yahoo.com",
    "phoneNumber": "3603602334",
    "houseNum": "1212",
    "street": "Downtown",
    "state": "WA",
    "city": "Vancouver",
    "cost": 12000.0000,
    "status": "Started",
    "eta": 0,
    "startDate": null,
    "completeDate": null,
    "contractorID": 1
}
  

Кроме того, если я выполняю SQL-код в SQL Server, он возвращает все правильные значения. Итак, проблема в том, что когда я вызываю эту хранимую процедуру через API, она возвращает нулевые значения, когда должна.

Кроме того, имя, фамилия и номера телефонов определены так, чтобы не допускать нулей в схеме

Дополнительная информация: вот функция вызова хранимой процедуры запроса my ID:

 public async Task<ClientModel> GetProjectById(int id)
{
    var records = await _dataAccess.LoadData<ClientModel, dynamic>("dbo.spClient_GetById", new { Id = id },
                                                                        _connectionString.SqlConnectionName);
    return records.FirstOrDefault();
}
  

И вот функция для вызова запроса по другим атрибутам:

 public async Task<ClientModel> GetProjectByHouse(string house, string? street)
{
    var p = new { HouseNum = house, Street = street };
    var records = await _dataAccess.LoadData<ClientModel, dynamic>("dbo.spClient_GetByHouse", p,
                                                                        _connectionString.SqlConnectionName);
    return trimValues(records.FirstOrDefault());
    // return records.FirstOrDefault();
}
  

И вот функция API для вызова любой из предыдущих функций:

 public async Task<IActionResult> Get(int? projectId, string? house, string? street)
{
    if (projectId != null)
    {
        var project = await _clientData.GetProjectById(projectId ?? default(int));

        if (project == null)
            return NotFound();

        return Ok(project);
    }
    else if (house != null)
    {
        if (house.Length < 2)
            return BadRequest();

        var project = await _clientData.GetProjectByHouse(house, street);

        if (project == null)
            return NotFound();

        return Ok(project);
    }
    else
    {
        return BadRequest();
    }
}
  

Комментарии:

1. «когда я пытаюсь выполнить запрос (через API)». Можете ли вы опубликовать код C #, который вызывает сохраненную процедуру и возвращает неожиданные значения null? Я не вижу ничего плохого в T-SQL (игнорирование SELECT * является злом).

2. Согласен, здесь вообще нет C #, только json (что, мягко говоря, странно) и необработанный sql.

3. @Zer0 извините, просто добавил код. Надеюсь, это поможет отследить ошибку!

4. Я также не вижу ничего плохого в коде C #, и это странно, учитывая, что вы эффективно вызываете сохраненные процедуры таким же образом. Тем не менее, я понятия не имею, что _dataAccess есть и что LoadData делает. Вы пробовали пошаговое выполнение с помощью отладчика? Если в схеме эти столбцы помечены как NOT NULL, это не может быть база данных. Что-то теряется при переводе.

5. Я бы дважды проверил, является ли подключаемая в C # база данных такой же, где вы запускаете код. Другой вариант увидеть, какие значения передаются в хранимую процедуру, написав процедуру ведения журнала

Ответ №1:

Не уверен, что это решило проблему (но проблема решена). Мне пришлось удалить старую базу данных и опубликовать новую.

Ответ №2:

Есть два случая, которые я нашел

  1. С учетом регистра псевдоним должен совпадать с моделью.
  2. В хранимых процедурах, если столбец имеет тип данных integer, то модель также должна иметь тот же тип.