【发布时间】:2020-04-07 09:33:02
【问题描述】:
我编写了一个小型 C# 应用程序,它读取 Excel 文件并将数据导入现有的 SQL Server 数据库。
由于表中有一个外键约束,条目应该被插入到,我已经通过使用
在我的 SQL 查询中直接防止了这个错误IF NOT EXISTS (SELECT * FROM [dbo].[InvoiceAccount]
WHERE Caption = @Caption)
INSERT INTO [dbo].[InvoiceAccount] (Caption, IdInvoiceAccountType, Account)
VALUES (@Caption, @IdInvoiceAccountType, @Account)
在我的开发机器上,执行我的应用程序并尝试插入 Excel 工作表工作正常,没有任何问题。
当我在另一台 PC 上执行相同操作时,我确实得到了一个 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,然后是我的开发电脑。
我能做些什么来防止这种行为?
例外:
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
【问题讨论】:
-
该表上存在哪些 FK?
-
捕捉异常放在这里,message和innerException属性会有用。
-
我将例外添加到主帖。
标签: c# sql-server constraints thread-exceptions