I plan to send a data table to the SQL Server database, and INSERT
the new rows. There will be multiple insert posts for each row in the program. No errors are returned but the rows aren't added to the table. The product table has got more columns than [dbo].[CSV_ADDProducts]
but I have selected the columns it would map to.
Can anyone spot the mistake I'm making or suggest a better way to do this? Thanks
SQL Server stored procedure
CREATE PROCEDURE [dbo].[spUpload_AddBulkProducts]
@uploadedTable [dbo].[CSV_ADDProducts] readonly
AS
BEGIN TRY
INSERT INTO [dbo].[Products]
([Product Item],[Product SKU],[Product Name],[Product Active],[Product Selling Price],[Product Description],[Product Purchase Description],[Product VAT Code ID],[Product Last Update])
SELECT
[Product Item],[Product SKU],[Product Name],[Product Active],[Product Selling Price],[Product Description],[Product Purchase Description],[Product VAT Code ID],[Product Last Update]
FROM @uploadedTable
END TRY
BEGIN CATCH
END CATCH
C# program
DataTable POSTCSVCREATE = new DataTable();
POSTCSVCREATE.Columns.Add("Product Item", typeof(SqlString));
POSTCSVCREATE.Columns.Add("Product SKU", typeof(SqlInt64));
POSTCSVCREATE.Columns.Add("Product Name", typeof(SqlString));
POSTCSVCREATE.Columns.Add("Product Active", typeof(SqlString));
POSTCSVCREATE.Columns.Add("Product Selling Price", typeof(SqlMoney));
POSTCSVCREATE.Columns.Add("Product Description", typeof(SqlString));
POSTCSVCREATE.Columns.Add("Product Purchase Description", typeof(SqlString));
POSTCSVCREATE.Columns.Add("Product VAT Code ID", typeof(SqlInt64));
POSTCSVCREATE.Columns.Add("Product Last Update", typeof(SqlDateTime));
foreach (ParseQBProduct.Product i in create)
{
var rows = VAT.Tables[0].Select();
string VATID = "1";
foreach (DataRow row in rows)
{
if (row["VAT Name"].ToString() == i.VAT.ToString())
{
VATID = row["VAT ID"].ToString();
}
}
string dt = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
if (i.ProductSellingPrice.Trim() != "")
{
POSTCSVCREATE.Rows.Add(i.UniqueTitle, Convert.ToInt64(i.manunum), i.name, i.ProductActive, (SqlMoney)Convert.ToDecimal(i.ProductSellingPrice), i.ProductDescription, i.ProductPurchaseDescription, Convert.ToInt64(VATID), (SqlDateTime)Convert.ToDateTime(dt));
recentAddedfile.Add(i.manunum+" -- " +i.UniqueTitle);
}
}
Authentication.LoginUC.instance.Session.Procedure_UploadTable("spUpload_AddBulkProducts", POSTCSVCREATE);
User defined Table
CREATE TYPE [dbo].[CSV_ADDProducts] AS TABLE(
[Product Item] [nvarchar](max) NULL,
[Product SKU] [bigint] NULL,
[Product Name] [nvarchar](max) NULL,
[Product Active] [nchar](10) NULL,
[Product Selling Price] [money] NULL,
[Product Description] [nvarchar](max) NULL,
[Product Purchase Description] [nvarchar](max) NULL,
[Product VAT Code ID] [bigint] NOT NULL,
[Product Last Update] [datetime] NULL
)
GO
When I run this, it does work as a query on the DBMS
DECLARE @Table AS [dbo].[CSV_ADDProducts]
Insert into @Table
Values ('test',1,'test name','true',10.44,'des','pdes',2,'2020-09-10 12:12:12.000')
EXECUTE spUpload_AddBulkProducts @Table
My source: https://www.sqlshack.com/table-valued-parameters-in-sql-server/
the commented out code is what was not working. command.Parameters.AddWithValue("@uploadedTable", DT);
works fine
public bool Procedure_UploadTable(string procedure,DataTable DT)
{
DBConn.Open();
using (var command = new SqlCommand(procedure) { CommandType = CommandType.StoredProcedure })
{
command.Connection = DBConn;
command.Parameters.AddWithValue("@uploadedTable", DT);
//SqlParameter param = new SqlParameter("@uploadedTable", SqlDbType.Structured)
//{
// TypeName = "[dbo].[TBLCSV_ADDProducts]",
// Value = DT
//};
try
{
command.ExecuteNonQuery();
DBConn.Close();
return true;
}
catch(Exception e) {
DBConn.Close();
MessageBox.Show(e.Message);
return false; }
}
}