Member 14939572 Ответов: 1

Ошибка записи данных Sql в таблицу


У меня нет подробных знаний о SQL ,

Мы создали базу данных на SQL server . Согласно проекту , другая база данных записывает значения в эту базу данных . Но когда он начинает записывать значения тегов в предопределенную таблицу.

Я проверил журналы . Ниже приведен пример журнала ошибок , Sql не может записать теги в таблицу.

5/09/2020 18:01:55.876 khuDbClient ошибка системного журнала SqlHelper.SqlInsertCommand() --> значения: 10 ,FP100_FDHL160_MPFM_MVHIST.FI101H ,9/15/2020 6:00:54 PM ,80 ,DM_QUALITY_GOOD ,
15/09/2020 18:01:55.960 khuDbClient ошибка системного журнала SqlHelper.SqlInsertCommand() --&ГТ; не удалось выполнить вставить в WT_SNAPSHOT(WT_ID, TAG_NAME, время , стоимость , качество)значения(@параметр1,@параметр param2,@param3,@param4,@param5)
System.Data.SqlClient.SqlException (0x80131904): строковые или двоичные данные будут усечены.
Заявление было прекращено.
в системе.Данных.Sqlclient как.Объект sqlconnection.OnError(исключение SqlException, логическое breakConnection, действие`1 wrapCloseInAction)
в System.Data.SqlClient.SqlInternalConnection.OnError(исключение SqlException, логическое breakConnection, действие`1 wrapCloseInAction)
в System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
в System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
в системе.Данных.Sqlclient как.Свойство sqlcommand.FinishExecuteReader(объект sqldatareader, ДС, RunBehavior runBehavior, строки resetOptionsString, логическое isInternal, логическое forDescribeParameterEncryption, логическое shouldCacheForAlwaysEncrypted)
в системе.Данных.Sqlclient как.Свойство sqlcommand.RunExecuteReaderTds(метода commandbehavior cmdBehavior, RunBehavior runBehavior, логическое returnStream, логическое асинхронный, типа int32 время ожидания задач&амп; задач, логическое asyncWrite, логическое inRetry, объект sqldatareader, ДС, логическое describeParameterEncryptionRequest)
в системе.Данных.Sqlclient как.Свойство sqlcommand.RunExecuteReader(метода commandbehavior cmdBehavior, RunBehavior runBehavior, логическое returnStream, метод String, TaskCompletionSource`1 завершение, типа int32 время ожидания задач&амп; задач, логическое и amp; usedCache, логическое asyncWrite, логическое inRetry)
в системе.Данных.Sqlclient как.Свойство sqlcommand.InternalExecuteNonQuery(TaskCompletionSource`1 завершение, строка имяметода, логическое sendToPipe, типа int32 время ожидания, логическое и amp; usedCache, логическое asyncWrite, логическое inRetry)
в системе.Данных.Sqlclient как.Свойство sqlcommand.Метод executenonquery()
в компании Siemens.Ху.Для SQL.SqlHelper.SqlInsertCommand(String cmdText, Object[] values)
ClientConnectionId:a45c9b05-941c-4737-a622-a21085c6d786
Номер Ошибки:8152,Состояние:2,Класс:16

Что я уже пробовал:

Обе базы данных на одной машине.

разрешение DNS

Брандмауэр отключен

Кроме того , входящие и исходящие правила определяют для порта № 1433

0x01AA

String or binary data would be truncated будет показано например при попытке вставить строку из 50 символов в поле базы данных например VARCHAR 20

1 Ответов

Рейтинг:
9

OriginalGriff

Посмотрите на ошибку: она содержит явную информацию.

String or binary data would be truncated.

Это означает, что одно из полей, которое вы пытаетесь вставить, короче, чем данные, которые вы пытаетесь вставить.
Например, поле NVARCHAR(5) и данные 'ABCDEF'
Поскольку строка длиннее, чем предоставленное пространство, SQL справедливо отказывается вставлять данные, потому что ему пришлось бы выбросить некоторые из них, и ему это не нравится.

Чтобы исправить это, сначала выясните, какие данные вы пытаетесь вставить, и сравните их с вашим определением таблицы, чтобы узнать, какое поле показывает проблему.
Затем либо увеличьте поле, чтобы оно соответствовало данным, либо в вашем программном обеспечении для презентаций проверьте входные данные, чтобы убедиться, что они действительно вписываются в существующий столбец.

На практике вам, вероятно, следует делать и то, и другое!
Цитата:
И последнее , не могли бы вы сказать мне, что означает (@param1 , @param2 .......)
Я немного понимаю, что это 5 полей таблицы, которые будет писать SQL.


Базовая вставка SQL выглядит следующим образом:
INSERT INTO MyTable (Column1Name, Column2Name) VALUES (ValueForColumn1, ValueForColumn2)

Но это опасно, когда вы начинаете отправлять текст из приложения, потому что это оставляет вас широко открытыми для случайной или преднамеренной атаки SQL-инъекции, которая может уничтожить всю вашу базу данных.

Когда вы объединяете строки, вы вызываете проблемы, потому что SQL получает такие команды, как:
SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
Цитата, добавленная пользователем, завершает строку в том, что касается SQL, и вы получаете проблемы. Но могло быть и хуже. Если я приду и наберу вместо этого: "x';DROP TABLE MyTable;--", то SQL получит совсем другую команду:
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
Которые SQL видит как три отдельные команды:
SELECT * FROM MyTable WHERE StreetAddress = 'x';
Совершенно правильный выбор
DROP TABLE MyTable;
Вполне допустимая команда "удалить таблицу"
--'
А все остальное-это комментарии.
Так оно и происходит: выбирает любые совпадающие строки, удаляет таблицу из базы данных и игнорирует все остальное.
Это вообще считается плохим делом. :Д

Чтобы предотвратить это, следует использовать параметризованные запросы - или быть готовым к частому восстановлению базы данных из резервной копии. Вы ведь регулярно делаете резервные копии, не так ли?

Параметризованный запрос выглядит почти так же, как базовая вставка:
INSERT INTO MyTable (Column1Name, Column2Name) VALUES (@ValueForColumn1, @ValueForColumn2)
Символ "@" указывает SQL, какое значение вставить из какого параметра в запрос, и параметры добавляются с помощью специального кода, который отличается от языка к языку.
Для C#:
using (SqlConnection con = new SqlConnection(strConnect))
    {
    con.Open();
    using (SqlCommand cmd = new SqlCommand("INSERT INTO myTable (myColumn1, myColumn2) VALUES (@C1, @C2)", con))
        {
        cmd.Parameters.AddWithValue("@C1", myValueForColumn1);
        cmd.Parameters.AddWithValue("@C2", myValueForColumn2);
        cmd.ExecuteNonQuery();
        }
    }
И части "@name" связывают их вместе.


Member 14939572

Я постараюсь найти варианты , о которых вы упомянули.

Member 14939572

У нас есть такая же система на сайте, работающая должным образом . Мы не сталкивались с какой-либо проблемой на месте. Я сделал копию этой системы для внутреннего тестирования и столкнулся с этой проблемой. Я проверил размер символов для всех полей . Кажется, все в порядке. На самом деле , у меня нет исходного кода приложения . Есть ли какой-нибудь способ проверить журналы в базе данных на наличие точной ошибки.

OriginalGriff

Журналы будут просто показывать то, что у вас есть, в значительной степени - они не будут показывать данные, которые вы пытались добавить, и это то, что вам нужно знать.

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

Member 14939572

ладно , я понял , спасибо за информацию

Member 14939572

Я постараюсь получить исходный код

Member 14939572

И последнее , не могли бы вы сказать мне, что означает (@param1 , @param2 .......)
Я немного понимаю, что это 5 полей таблицы, которые будет писать SQL.

OriginalGriff

Решение обновлено.

Member 14939572

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

Member 14939572

Я должен проверить размер столбца и его значение . В одном значении размер символа больше того, что определено в размере столбца . Вручную выполняется команда Insert запросов SQL и изменить размер символов введенного объема . База данных обновилась . Из пяти значений только значение имеет проблему размера . Поскольку я не могу изменить ширину столбца конкретного значения , это требует удаления таблицы и повторного создания таблицы . Но в качестве обходного пути я могу попытаться уменьшить размер символов вводимых данных . Это может решить проблему . Кстати, спасибо за помощь и информацию.

OriginalGriff

Всегда пожалуйста!