gpt4 book ai didi

c# - SQL/C# : DataTable to stored procedure (INSERT from user-defined table type) - Converting error

转载 作者:行者123 更新时间:2023-12-04 19:48:34 25 4
gpt4 key购买 nike

我正在尝试将我的 DataTable 传递给存储过程。 DataTable 包含 Excel 工作表的内容。 Excel 工作表有两个空列,五个是文本,五个是小数。空列是 OppdragsMVAkodeOppdragsgebyrMVAkode

如果我运行我的应用程序,我会得到这个异常:

System.ArgumentException: Input string was not in a correct format. Couldn't store <> in OppdragsMVAkode Column. Expected type is Decimal.

如果我添加一个临时号码,我会得到这个异常:

System.Data.SqlClient.SqlException: Error converting data type nvarchar to numeric.

我不明白为什么要将它作为字符串读取。

我的存储过程(spGetTrips):

ALTER PROCEDURE [dbo].[spGetTrips]
@trips udtTripsPerMonth readonly

AS
BEGIN
INSERT INTO tblTripsPerMonth
SELECT
[KjøretøyID],
SUBSTRING([År], 7, 4),
SUBSTRING([Måned], 4, 2),
[Betaling (brutto)],
[Betaling (netto)],
[Bestillingsgebyr (netto)],
[Betalingsgebyr (netto)],
[OppdragsMVAkode],
CONCAT(LøyvehaverFakturaID, + 'UF-' + SUBSTRING([År], 9, 2) + SUBSTRING([Måned], 4, 2)),
[Oppdragsgebyr (netto)],
[OppdragsgebyrMVAkode],
CONCAT([RidelRegionFakturaID], + 'UF-' + SUBSTRING([År], 9, 2) + SUBSTRING([Måned], 4, 2))
FROM @trips

UPDATE tblTripsPerMonth
SET [OppdragsMVAkode] = (
SELECT [ID]
FROM [tblMVAkoder]
WHERE [ID] = 'MVAkode2'
);

UPDATE tblTripsPerMonth
SET [OppdragsgebyrMVAkode] = (
SELECT [ID]
FROM [tblMVAkoder]
WHERE [ID] = 'MVAkode5'
);
END

正如您在上面看到的,我在存储过程中使用 UPDATE 子句设置两个空列的值。无论它们在 Excel 工作表中为空,还是具有一些初步值,然后被覆盖,我都不关心 - 我只是希望它能正常工作。

这是我的用户定义表类型 (udtTripsPerMonth):

CREATE TYPE [dbo].[udtTripsPerMonth] AS TABLE(
[KjøretøyID] [nvarchar](50) NULL,
[År] [nvarchar](50) NULL,
[Måned] [nvarchar](50) NULL,
[Betaling (brutto)] [decimal](10, 2) NULL,
[Betaling (netto)] [decimal](10, 2) NULL,
[Bestillingsgebyr (netto)] [decimal](10, 2) NULL,
[Betalingsgebyr (netto)] [decimal](10, 2) NULL,
[OppdragsMVAkode] [decimal](10, 2) NULL,
[LøyvehaverFakturaID] [nvarchar](50) NULL,
[Oppdragsgebyr (netto)] [decimal](10, 2) NULL,
[OppdragsgebyrMVAkode] [decimal](10, 2) NULL,
[RidelRegionFakturaID] [nvarchar](50) NULL
)
GO

还有我的表(tblTripsPerMonth):

CREATE TABLE [dbo].[tblTripsPerMonth](
[ID] [int] IDENTITY(1,1) NOT NULL,
[KjøretøyID] [nvarchar](50) NULL,
[År] [nvarchar](50) NULL,
[Måned] [nvarchar](50) NULL,
[Betaling (brutto)] [decimal](10, 2) NULL,
[Betaling (netto)] [decimal](10, 2) NULL,
[Bestillingsgebyr (netto)] [decimal](10, 2) NULL,
[Betalingsgebyr (netto)] [decimal](10, 2) NULL,
[OppdragsMVAkode] [decimal](10, 2) NULL,
[LøyvehaverFakturaID] [nvarchar](50) NULL,
[Oppdragsgebyr (netto)] [decimal](10, 2) NULL,
[OppdragsgebyrMVAkode] [decimal](10, 2) NULL,
[RidelRegionFakturaID] [nvarchar](50) NULL,
PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

我在 UPDATE 子句 (tblMVAkoder) 中引用的另一个表:

CREATE TABLE [dbo].[tblMVAkoder](
[ID] [nvarchar](50) NOT NULL,
[Startdato] [date] NULL,
[Sluttdato] [date] NULL,
[MVAsats] [decimal](10, 2) NULL,
PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

这是我的 C# 代码(Excel 到 DataTable):

private void btnExport_Click(object sender, RoutedEventArgs e) {

OpenFileDialog of = new();
of.Filter = "Excel Files | *.xlsx;";
of.Title = "Importer Excel fil.";

if (of.ShowDialog() == true) {

dgPaidTrip.ItemsSource = ImportExceltoDataTable(of.FileName).DefaultView;
btnClearForm.IsEnabled = true;
}

using (SqlConnection con = new(ConnectionString.connectionString))
using (var cmd = new SqlCommand("spGetTrips", con) { CommandType = CommandType.StoredProcedure }) {

con.Open();
DataTable dt = ImportExceltoDataTable(of.FileName);
cmd.Parameters.Add(new SqlParameter("@trips", dt));
cmd.ExecuteNonQuery();
}
}

public static DataTable ImportExceltoDataTable(string filePath) {

using (XLWorkbook wb = new(filePath)) {

IXLWorksheet ws = wb.Worksheet(1);
int tl_Row = ws.FirstCellUsed().Address.RowNumber;
int tl_Col = ws.FirstCellUsed().Address.ColumnNumber;
int br_Row = ws.LastCellUsed().Address.RowNumber;
int br_Col = ws.LastCellUsed().Address.ColumnNumber;

DataTable dt = new();

dt.Columns.Add("KjøretøyID", typeof(string));
dt.Columns.Add("År", typeof(string));
dt.Columns.Add("Måned", typeof(string));
dt.Columns.Add("Betaling (brutto)", typeof(decimal));
dt.Columns.Add("Betaling (netto)", typeof(decimal));
dt.Columns.Add("Bestillingsgebyr (netto)", typeof(decimal));
dt.Columns.Add("Betalingsgebyr (netto)", typeof(decimal));
dt.Columns.Add("OppdragsMVAkode", typeof(decimal));
dt.Columns.Add("LøyvehaverFakturaID", typeof(string));
dt.Columns.Add("Oppdragsgebyr (netto)", typeof(decimal));
dt.Columns.Add("OppdragsgebyrMVAkode", typeof(decimal));
dt.Columns.Add("RidelRegionFakturaID", typeof(string));

IXLRow currentRow;

for (int dtRow = 0; dtRow < br_Row - tl_Row; dtRow++) {

currentRow = ws.Row(tl_Row + dtRow + 1);
dt.Rows.Add();

for (int dtCol = 0; dtCol < br_Col - tl_Col + 1; dtCol++) {

dt.Rows[dtRow][dtCol] = currentRow.Cell(tl_Col + dtCol).Value;
}
}

return dt;
}
}

据我所知,我的所有列类型及其顺序都匹配。我将所有类型更改为 nvarchar,并且代码“有效”。但是比我聪明的人告诉我,伪造列类型不是一个好主意。

我错过了什么?

最佳答案

要传递空值,您需要将列值设置为 DBNull.Value。您可以像这样设置 DBNull

dt.Rows[dtRow][dtCol] = currentRow.Cell(tl_Col + dtCol).Value ?? (object)DBNull.Value;

您还必须设置 SqlDBType TypeNameDirection 属性

cmd.Parameters.Add(
new SqlParameter("@trips", SqlDBType.Structured)
{
TypeName = "dbo.udtTripsPerMonth",
Direction = ParameterDirection.Input,
Value = dt
});

关于c# - SQL/C# : DataTable to stored procedure (INSERT from user-defined table type) - Converting error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69198578/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com