Форум программистов, компьютерный форум, киберфорум
C#: Базы данных, ADO.NET
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
0 / 0 / 0
Регистрация: 28.05.2016
Сообщений: 41
1

SqlException: Incorrect syntax near 'townName'

30.06.2020, 17:28. Просмотров 1284. Ответов 30
Метки нет (Все метки)

Привет ребята
Я пытаюсь создать одну веб страницу, использую razor page. При компиляции никаких проблем нет. Открывается страница тоже успешно, затем когда я пытаюсь сохранить данные в бд, выскакивает исключение(SqlException: Incorrect syntax near 'townName'.) оно говорит, что ошибки в 3 местах.
А именно тут
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class TownRepository : ITownRepository
    {
        private readonly ILogger<TownRepository> _logger;
        protected readonly IConnectionFactory _connectionFactory;
 
        public TownRepository(ILogger<TownRepository> logger
                                , IConnectionFactory connectionFactory)
        {
            _logger = logger;
            _connectionFactory = connectionFactory;
        }
 
        public Town InsertTownName(string townName)
        {
            using var connection = _connectionFactory.GetConnection();
 
            string query = $"INSERT INTO town (townName) " +                        //???
                           $"VALUES townName = {townName}";
 
            return connection.QueryFirstOrDefault<Town>(query);
        }
    }
Строка
C#
1
return connection.QueryFirstOrDefault<Town>(query);
---
тут
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 public class TownService : ITownService
    {
        public readonly ITownRepository _townRepository;
        private readonly IMapper _mapper;
 
        public TownService(ITownRepository townRepository
                             , IMapper mapper)
        {
            _townRepository = townRepository;
            _mapper = mapper;
        }
 
        public TownViewModel InsertTownName(string townName)
        {
            var townList = _townRepository.InsertTownName(townName);
 
            return _mapper.Map<TownViewModel>(townList);
        }
    }
Строка
C#
1
var townList = _townRepository.InsertTownName(townName);

---
тут
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
     private readonly ILogger<AddTownModel> _logger;
        private readonly ITownService _townService;
 
        public AddTownModel(ILogger<AddTownModel> logger
                        , ITownService townService)
        {
            _logger = logger;
            _townService = townService;
        }
 
        public TownViewModel Towns { get; set; }
 
        [BindProperty]
        public string TownName { get; set; }
 
        public async Task<IActionResult> OnPost()
        {
            if (!string.IsNullOrEmpty(TownName))
            {
                Towns = /*await*/ _townService.InsertTownName(TownName);
            }
 
            return Page();
        }
    }
Строка
C#
1
Towns = /*await*/ _townService.InsertTownName(TownName);
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.06.2020, 17:28
Ответы с готовыми решениями:

Ошибка System.Data.SqlClient.SqlException: "Incorrect syntax near 'MaterialTable'."
Здравствуйте. Делаю программу на WPF. В dataGrid загружаю данные из MSSQL БД. С добавлением данных...

Incorrect syntax near
Здравствуйте, ошибка(см.вложения), с которой мучаюсь пару дней... Помогите решить, пожалуйста. ...

Incorrect syntax near 'nvarchar'
Короче, вот код: private void btnAdd_Click(object sender, EventArgs e) { ...

Incorrect syntax near 'nvarchar'
Всю голову уже изломал, не могу решить проблему выдаёт - Incorrect syntax near 'nvarchar'...

30
1923 / 1518 / 458
Регистрация: 02.08.2011
Сообщений: 4,383
30.06.2020, 17:49 2
C#
1
2
string query = $"INSERT INTO town (townName) " +                    
                           $"VALUES ({townName})";
Добавлено через 3 минуты
А почему ITownRepository.InsertTown возвращает список, какая тут логика?

Добавлено через 3 минуты
И почему при выполнении операции на вставку объект connection вызывает метод QueryFirstOrDefault?
Здесь какая логика?
Вы ошиблись еще на этапе проектирования интерфейсов.

Добавлено через 1 минуту
Почему бы в самом ITownRepository не использовать уже напрямую классы ADO.NET?
Зачем ненужная абстракция над Connection-ом?

Добавлено через 7 минут
Пардон, возвращается объект Town, а не список.
0
0 / 0 / 0
Регистрация: 28.05.2016
Сообщений: 41
30.06.2020, 17:57  [ТС] 3
Добавлено через 5 минут
Ну насколько я понимаю, то ITownRepository.InsertTown будет возвращать не список, а один объект (который мы будем добавлять в бд)

Сказать по правде, я тоже считаю эту архитектуру несколько мудреной и не совсем удобной, однако мне ее необходимо придерживаться (не я разрабатывал), поэтому я бы тоже постарался разработать максимально просто, а сейчас, тут сложная архитектура (не совсем понятная мне) и ещё ошибки. Спасибо за ваш ответ, буду признателен, если подскажете как устранить появившиеся ошибки
0
1923 / 1518 / 458
Регистрация: 02.08.2011
Сообщений: 4,383
30.06.2020, 18:02 4
Ну по самой ошибке я уже показал, синтаксис вставки для SQL Server (если это SQL Server) insert... values выглядит так:
SQL
1
2
INSERT INTO TABLE_NAME (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
Можно вставить несколько значений, через повторное открытие скобок. И это будет атомарная вставка для всех записей.
Вам надо копнуть в объект который возвращается у IConnectionFactory.GetConnection и посмотреть что у него есть. А то чистым кодом это точно не назовешь.

Добавлено через 1 минуту
Если уверенности нет (еще джун), то делайте по шаблону, и набирайте знания.
Если есть, то можно смело ломать и рефакторить, понемногу и очень аккуратно.

Добавлено через 3 минуты
INTO в запросе можно опустить - так лаконичнее.
0
0 / 0 / 0
Регистрация: 28.05.2016
Сообщений: 41
30.06.2020, 18:06  [ТС] 5
Ну да, я только начинаю. Я отлично знаю эту конструкцию по запросам которую вы прикрепили, однако я, как Джун, ввиду отсутствия опыта стал делать по шаблону. Ниже код для другого репозитория
C#
1
2
3
4
5
6
7
8
9
10
 public Property GetPropertyByPropertyId(int propertyId)
        {
            using var connection = _connectionFactory.GetConnection();
 
            string query = $"SELECT PropertyId, PropertyName, cl.ClientId  from property_published_v ppv " +
                               $"INNER JOIN client cl ON cl.ClientId = ppv.ClientId " +
                               $"WHERE PropertyId = {propertyId}";
 
            return connection.QueryFirstOrDefault<Property>(query);
        }
У меня должно тогда быть что-то вроде этого?
C#
1
2
string query = $"INSERT town (townName) " +                        //???
                           $"VALUES (townName)";
0
1923 / 1518 / 458
Регистрация: 02.08.2011
Сообщений: 4,383
30.06.2020, 18:16 6
В том что показали идет выборка, поэтому наличие QueryFirstOrDefault корректно.
В вашем случае нужно использовать какой-то другой метод, который предоставляет тип у переменной connection.

Цитата Сообщение от КИРилл_123 Посмотреть сообщение
должно тогда быть что-то вроде этого?
Найдите разницу.
C#
1
string query = $"INSERT INTO town (townName) VALUES ({townName})";
Добавлено через 4 минуты
И кстати, совсем необязательно возвзращать объект типа Town в ITownRepository.InsertTownName.
Нужно вернуть PK, а метод сервиса сам уже создаст нужную вью модель, ибо у него есть вся информация для этого (TownName, и id вновь добавленной записи). И не нужно ничего мапить будет.

Что-то мне подсказывает что код интерфейса тоже писали вы.
0
0 / 0 / 0
Регистрация: 28.05.2016
Сообщений: 41
30.06.2020, 18:53  [ТС] 7
Я почитал, и действительно, я написал полнейшую глупость. QueryFirstOrDefault
это глупость и мне нужно добавить данные, но я не совсем понимаю, как это делается с даппером , я попробовал Execute , Но не помогло. Может быть что-то вроде такого? Но на данный момент тоже ошибка
C#
1
2
3
4
5
6
7
8
9
10
 public Town InsertTownName(string townName)
        {
            using var connection = _connectionFactory.GetConnection();
 
            //string query = $"INSERT INTO town (townName) VALUES ({townName})";
 
            var reader = connection.ExecuteReader($"INSERT INTO town (townName) VALUES ({townName})");
 
            return reader;//connection.QueryFirstOrDefault<Town>(query);
        }
Cannot implicitly convert type 'System.Data.IDataReader' to 'innRoad.innSupportTools.Models.Town'.

---
connection
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 private readonly ConnectionStrings _connectionStrings;
        private readonly AppSettings _appSettings;
 
        public ConnectionFactory(IOptions<ConnectionStrings> connectionStrings
                               , IOptions<AppSettings> appSettings)
        {
            _connectionStrings = connectionStrings.Value;
            _appSettings = appSettings.Value;
        }
 
        public IDbConnection GetConnection()
        {
            var connectionString = _connectionStrings.InnCenter;
 
            var connection = new SqlConnection(connectionString);
 
            connection.Open();
 
            return connection;
        }
Ну вообще мне самому приходилось создавать эту вью модель, согласно общей архитектуре. Думаете лучше вернуть РК, но мне нельзя удалять мою вью модель?
Да, интерфейс тоже я создавал
0
1923 / 1518 / 458
Регистрация: 02.08.2011
Сообщений: 4,383
30.06.2020, 19:10 8
Ух, читайте про ADO.NET классы, рано вам еще за даппер браться.
ExecuteReader - прочитать коллекцию из БД.
ExecuteScalar - получить скаляр.
ExecuteNonQuery - вставка, удаление + DDL команды (изменение схемы, создание чего-либо и много другое)
И раз это IDbConnection, то townName нужно передавать через параметры, а не интерполяцией строк.
Просто поначалу показалось, это какая то доп.абстракция над IDbConnection-ом сверху со своим парсингом строк.

Добавлено через 2 минуты
У Троелсена в книге была целая глава про ADO.NET (подключенный уровень, отсоединенный уровень (DataSet и ко, сейчас особо неактуален)).
Можете по MSDN полазить.

Добавлено через 7 минут
Цитата Сообщение от КИРилл_123 Посмотреть сообщение
но мне нельзя удалять мою вью модель?
Удалять ее не надо.
1
0 / 0 / 0
Регистрация: 28.05.2016
Сообщений: 41
30.06.2020, 19:11  [ТС] 9
Я почитаю про sqlparameter
Но в случае если мне нужно это реализовывать через dapper?
Прошу прощения за большое количество вопросов, но я только стараюсь переключиться в эту область
0
1923 / 1518 / 458
Регистрация: 02.08.2011
Сообщений: 4,383
30.06.2020, 19:21 10
Цитата Сообщение от КИРилл_123 Посмотреть сообщение
Но в случае если мне нужно это реализовывать через dapper?
Да не нужен тут даппер. Для покупки только лишь одного яблока в магазине вы берете целофановый пакет или покупаете еще отдельную сумку-майку? Во втором случае это выглядело бы очень странно.
0
Эксперт .NET
7398 / 5164 / 889
Регистрация: 21.01.2016
Сообщений: 19,892
01.07.2020, 06:49 11
КИРилл_123,

C#
1
2
3
4
var query = $@"INSERT INTO town (townName) VALUES (@townName);
 SELECT TOP 1 * FROM town WHERE Id = scope_identity()";
 
return connection.QueryFirstOrDefault<Town>(query, new { townName });
0
Эксперт .NET
7398 / 5164 / 889
Регистрация: 21.01.2016
Сообщений: 19,892
01.07.2020, 07:03 12
Цитата Сообщение от IamRain Посмотреть сообщение
Да не нужен тут даппер. Для покупки только лишь одного яблока в магазине вы берете целофановый пакет или покупаете еще отдельную сумку-майку? Во втором случае это выглядело бы очень странно.
Даппер очень маленькая и удобная библиотечка. Это не сумка-тройка, а именно целофановый пакетик.

КИРилл_123, зачем вы темы плодите? Я вам уже ответ дал.

C#
1
2
3
4
var query = $@"INSERT INTO town (townName) VALUES (@townName);
 SELECT TOP 1 * FROM town WHERE Id = scope_identity()";
 
return connection.QueryFirstOrDefault<Town>(query, new { townName });
0
0 / 0 / 0
Регистрация: 28.05.2016
Сообщений: 41
01.07.2020, 08:02  [ТС] 13
Мне кажется что использовать QueryFirstOrDefault это неправильно, разве нет. Этот метод выполняет запрос и отображает результат, в то время, как мне нужно добавить , а не отобразить
0
Эксперт .NET
7398 / 5164 / 889
Регистрация: 21.01.2016
Сообщений: 19,892
01.07.2020, 08:16 14
КИРилл_123, ну, это вы уже для себя сами решайте. Такой подход вполне себе используется. Если из базы вам ничего не надо, то QueryFirstOrDefault надо заменить на Execute.
0
0 / 0 / 0
Регистрация: 28.05.2016
Сообщений: 41
01.07.2020, 08:42  [ТС] 15
Я попытался сделать согласно вашей рекомендации(Execute method) и у меня появляется ошибка : 'IDbConnection' does not contain a definition for 'Execute' and no accessible extension method 'Execute' accepting a first argument of type 'IDbConnection' could be found

Вы ставите $ перед запросом query, однако нигде не используете { }
Ещё пробовал ExecuteScalar - тогда в компиляторе нет ошибок. Однако когда я пытаюсь вставить данные, у меня появляется исключение о том что null не может быть вставлен в townID.
Я попытался сделать такой sql запрос, но тоже не помогло
C#
1
2
3
var query = $@"INSERT INTO town (townName) VALUES (@{townName})";
 
            return connection.ExecuteScalar<Town>(query, new { townName });
- Must declare the scalar variable "@Test".
---
C#
1
2
3
var query = $@"INSERT INTO town (townName) VALUES (@townName)";
 
            return connection.ExecuteScalar<Town>(query, new { townName });
- Cannot insert the value NULL into column 'townID', table 'inncenter01p.dbo.town'; column does not allow nulls.

Если честно, я не совсем понимаю, как это правильно реализовать, могли бы вы подсказать?
0
Эксперт .NET
7398 / 5164 / 889
Регистрация: 21.01.2016
Сообщений: 19,892
01.07.2020, 08:49 16
Цитата Сообщение от КИРилл_123 Посмотреть сообщение
Я попытался сделать согласно вашей рекомендации(Execute method) и у меня появляется ошибка : 'IDbConnection' does not contain a definition for 'Execute' and no accessible extension method 'Execute' accepting a first argument of type 'IDbConnection' could be found
Справка говорит, что такой метод есть. МОжет пространство имён не подключили нужное.

Цитата Сообщение от КИРилл_123 Посмотреть сообщение
Вы ставите $ перед запросом query, однако нигде не используете { }
Просто уберите. Оно ни на что не влияет.

Цитата Сообщение от КИРилл_123 Посмотреть сообщение
Cannot insert the value NULL into column 'townID', table 'inncenter01p.dbo.town'; column does not allow nulls.
А значение первичного ключа откуда возьмётся? Либо вы его генерируете и руками вставляется, либо используете IDENTITY для автогенерации ключей.

Добавлено через 58 секунд
Цитата Сообщение от КИРилл_123 Посмотреть сообщение
Я попытался сделать такой sql запрос, но тоже не помогло
Не надо так. У вас возвращается число, а не Town.
0
0 / 0 / 0
Регистрация: 28.05.2016
Сообщений: 41
01.07.2020, 09:09  [ТС] 17
Метод execute точно есть и пространство имён я подключил, как мне кажется с этим методом нельзя использовать <T>, а если я убираю, и добавляю ваш sql запрос,
C#
1
2
3
4
            var query = @"INSERT INTO town (townName) VALUES (@townName);
                        SELECT TOP 1 * FROM town WHERE townID = scope_identity()"; ;
 
            return connection.Execute(query, new { townName });
то он пишет, что не может конвертировать int в модель. Хотя сейчас не int же должен возвращаться

--Cannot implicitly convert type 'int' to 'innRoad.innSupportTools.Models.Town'
0
Эксперт .NET
7398 / 5164 / 889
Регистрация: 21.01.2016
Сообщений: 19,892
01.07.2020, 09:12 18
Цитата Сообщение от КИРилл_123 Посмотреть сообщение
как мне кажется с этим методом нельзя использовать <T>
Конечно нельзя.

Цитата Сообщение от КИРилл_123 Посмотреть сообщение
то он пишет, что не может конвертировать int в модель. Хотя сейчас не int же должен возвращаться
--Cannot implicitly convert type 'int' to 'innRoad.innSupportTools.Models.Town'
Это уже у вас в коде где-то ошибка. Не надо ничего возвращать из Execute.
0
0 / 0 / 0
Регистрация: 28.05.2016
Сообщений: 41
01.07.2020, 09:40  [ТС] 19
Не понимаю где может быть ошибка, в connection ее точно нет, а в query вроде все верно и я проверил, сейчас execute правильно используется и нет ошибок. Единственное в чем вопрос. Может быть в sql запросе я указал townID , а а Execute будет только townName, я же правильно понимаю, что написанная функция будет автоматически увеличивать townID на единицу и в execute этого делать не нужно?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    public class TownRepository : ITownRepository
    {
        private readonly ILogger<TownRepository> _logger;
        protected readonly IConnectionFactory _connectionFactory;
 
        public TownRepository(ILogger<TownRepository> logger
                                , IConnectionFactory connectionFactory)
        {
            _logger = logger;
            _connectionFactory = connectionFactory;
        }
 
        public Town InsertTownName(string townName)
        {
            using var connection = _connectionFactory.GetConnection();
 
            var query = @"INSERT INTO town (townName) VALUES (@townName);
                        SELECT TOP 1 * FROM town WHERE townID = scope_identity()";
 
            return connection.Execute(query, new { townName });
 
 
        }
    }
}
0
Эксперт .NET
7398 / 5164 / 889
Регистрация: 21.01.2016
Сообщений: 19,892
01.07.2020, 09:46 20
КИРилл_123, как-то сложно с вами общаться.

Метод Execute возвращает int. Вот пример. Он возвращает число затронутых запросом строк. А вы что делаете?

C#
1
2
3
4
5
6
        public Town InsertTownName(string townName)
        {
            ...
 
            return connection.Execute(query, new { townName }); // int32 должно преобразоваться в Town ?
        }
На сами первичные ключи в таблицах принято навешивать автоматический счётчик. В SQL Server это IDENTITY. Такой счётчик сам будет знечения генерировать.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.07.2020, 09:46

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Проблема с insert sql - Incorrect syntax near '@Om'
Ку всем такая проблема, не могу добавть данные в базу собственно код: private async void...

Команда DELETE SQL не срабатывает: Incorrect syntax near '='
Здравствуйте, у меня есть функция которая при нажатии кнопки должна вывезти форму в которой можно...

Ошибка при запуске программы: Incorrect syntax near FROMItems
Здравствуйте! Есть база данных на удаленном сервере, пишу приложение на типизированном dataset. При...

Появилась ошибка в запросе - Incorrect syntax near the keyword 'Table'
Объясните пожалуйста: выходит ошибка в этом месте, не знаю, почему sel.Fill(dt); -Incorrect syntax...

Ошибка Incorrect syntax near '.' при запросе к двум таблицам
Доброго времени суток, подскажите пожалуйста в чем может быть проблема, не могу разобраться. ...

Как исправить исключение при работе с таблицей (Incorrect syntax near...)?
DateTime data = dateTimePicker1.Value; SqlCommand cmd = new SqlCommand(&quot;insert into GreenWich...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.