C# - SQL Сервер: оператор INSERT конфликтует с ограничением FOREIGN KEY - необработанное исключение - PullRequest
0 голосов
/ 07 апреля 2020

Я написал небольшое приложение C#, которое читает файл Excel и должно импортировать данные в существующую SQL серверную базу данных.

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

IF NOT EXISTS (SELECT * FROM [dbo].[InvoiceAccount] 
               WHERE Caption = @Caption) 
    INSERT INTO [dbo].[InvoiceAccount] (Caption, IdInvoiceAccountType, Account)     
    VALUES (@Caption, @IdInvoiceAccountType, @Account)

на моей машине для разработки Выполнение моего приложения и попытка вставить лист Excel работают без проблем.

Как только я делаю то же самое на другом P C, я получаю ThreadExceptionDialog, хотя запрос SQL работает, как и ожидалось.

Код C# выглядит следующим образом:

foreach (DataGridViewRow row in dataGridViewToInsert.Rows)
{
    using (SqlConnection con = new SqlConnection(ConfigurationManager.AppSettings.Get("connectionString")))
    {
        using (SqlCommand cmd = new SqlCommand("IF NOT EXISTS (SELECT * FROM [dbo].[InvoiceAccount] WHERE Caption = @Caption) INSERT INTO [dbo].[InvoiceAccount] (Caption, IdInvoiceAccountType, Account) VALUES (@Caption, @IdInvoiceAccountType, @Account)", con))
        {
            Debug.WriteLine(cmd.CommandText);

            cmd.Parameters.AddWithValue("@Caption", row.Cells[1].Value);

            switch (row.Cells[2].Value)
            {
                case "Erlöskonto":
                case "Revenue account":
                    cmd.Parameters.AddWithValue("@IdInvoiceAccountType", 1);
                    break;

                case "Kostenkonto":
                case "Expense Account":
                    cmd.Parameters.AddWithValue("@IdInvoiceAccountType", 2);
                    break;

                case "Geldkonto":
                case "Cash Account":
                    cmd.Parameters.AddWithValue("@IdInvoiceAccountType", 3);
                    break;

                case "Abschreibungskonto":
                case "Depreciation Account":
                    cmd.Parameters.AddWithValue("@IdInvoiceAccountType", 4);
                    break;

                default:
                    cmd.Parameters.AddWithValue("@IdInvoiceAccountType", 2);
                    break;
            };

            cmd.Parameters.AddWithValue("@Account", row.Cells[0].Value);

            con.Open();
            addedRows = cmd.ExecuteNonQuery();
            con.Close();
        }
    }

    if (addedRows > 0)
    {
        insertedRows = insertedRows + addedRows;
    }
}

Так что я действительно не понимаю, что я делаю здесь неправильно и почему Я получаю ThreadExceptionDialog только на других машинах, тогда как моя разработка P C.

Что я могу сделать, чтобы предотвратить такое поведение?


Исключение:

System.Data.SqlClient.SqlException (0x80131904): The INSERT statement conflicted with the FOREIGN KEY constraint "FK_VatType2InvoiceAccount_InvoiceAccount". The conflict occurred in database "easyjob", table "dbo.InvoiceAccount", column 'IdInvoiceAccount'.
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_VatType2InvoiceAccount_InvoiceAccount". The conflict occurred in database "easyjob", table "dbo.InvoiceAccount", column 'IdInvoiceAccount'.
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_VatType2InvoiceAccount_InvoiceAccount". The conflict occurred in database "easyjob", table "dbo.InvoiceAccount", column 'IdInvoiceAccount'.
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_VatType2InvoiceAccount_InvoiceAccount". The conflict occurred in database "easyjob", table "dbo.InvoiceAccount", column 'IdInvoiceAccount'.
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_VatType2InvoiceAccount_InvoiceAccount". The conflict occurred in database "easyjob", table "dbo.InvoiceAccount", column 'IdInvoiceAccount'.
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_VatType2InvoiceAccount_InvoiceAccount". The conflict occurred in database "easyjob", table "dbo.InvoiceAccount", column 'IdInvoiceAccount'.
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_VatType2InvoiceAccount_InvoiceAccount". The conflict occurred in database "easyjob", table "dbo.InvoiceAccount", column 'IdInvoiceAccount'.
The statement has been terminated.
The statement has been terminated.
The statement has been terminated.
The statement has been terminated.
The statement has been terminated.
The statement has been terminated.
   bei System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   bei System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   bei System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   bei System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   bei System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
   bei System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
   bei System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   bei ejDatabaseAnonymizer.MasterDataUserControl.buttonImport_Click(Object sender, EventArgs e)
   bei System.Windows.Forms.Control.OnClick(EventArgs e)
   bei System.Windows.Forms.Button.OnClick(EventArgs e)
   bei System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   bei System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   bei System.Windows.Forms.Control.WndProc(Message& m)
   bei System.Windows.Forms.ButtonBase.WndProc(Message& m)
   bei System.Windows.Forms.Button.WndProc(Message& m)
   bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   bei System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
ClientConnectionId:d94a62b5-fb09-4d31-9561-76b2525c7321
Fehlernummer (Error Number):547,Status (State):0,Klasse (Class):16

Ответы [ 2 ]

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

Позор мне! Исключение было вызвано другим запросом sql, который был вызван сразу после указанного выше. Так что я смог это исправить.

Но я до сих пор не понимаю, почему ThreadExceptionDialog не появился на моей машине для разработки, хотя я также запускал ту же версию на нем. ..

Спасибо за вашу помощь.

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

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

Проверьте, существует ли строка, на которую ссылается внешний ключ.

Посмотрите, я думаю, это поможет вам: http://www.sql-server-helper.com/error-messages/msg-547-insert.aspx

...