繁体   English   中英

OpenXML和C#错误在SQL Server中插入数据表

[英]OpenXML and c# error to insert datatable in sql server

我有一个C#应用程序,用于从.XLSX文件中恢复数据并将数据插入到SQL Server表中。

例如,我有一个包含Identity和3列的数据表。 当我执行SQL命令时。 我有这个错误:

插入表列中不允许的标识列。 表值参数“ @product”的数据与参数的表类型不一致。 SQL Server错误为:200,状态:7

储存程序

ALTER PROCEDURE [dbo].[InserimentoDatiExcel](@product [udtInserimentoDatiExcel] readonly)

AS
BEGIN
    INSERT INTO Prova
    (ID, PIPPO, PLUTO, PAPERINO)
    SELECT *
    FROM @product
    --FROM Prova
    --WHERE ID IN (SELECT ID FROM @product)

END

CREATE TYPE [dbo].[udtInserimentoDatiExcel] AS TABLE(
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [PIPPO] [varchar](1) NOT NULL,
    [PLUTO] [varchar](1) NOT NULL,
    [PAPERINO] [varchar](1) NOT NULL,
    PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (IGNORE_DUP_KEY = ON)
)
GO

数据表图像

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

namespace BatchReadExcel
{
    class Program
    {
        static void Main()
        {
            try
            {
                DataTable dt = new DataTable();
                using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(@"C:\Users\f.piano\Documents\prova.xlsx", false))
                {
                    WorkbookPart workbookPart = spreadSheetDocument.WorkbookPart;
                    IEnumerable<Sheet> sheets = spreadSheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();
                    string relationshipId = sheets.First().Id.Value;
                    WorksheetPart worksheetPart = (WorksheetPart)spreadSheetDocument.WorkbookPart.GetPartById(relationshipId);
                    Worksheet workSheet = worksheetPart.Worksheet;
                    SheetData sheetData = workSheet.GetFirstChild<SheetData>();
                    IEnumerable<Row> rows = sheetData.Descendants<Row>();
                    //TEST
                    //dt.Columns.Add("ID", typeof(Int32));
                    dt.Columns.Add("ID", typeof(Guid));
                    dt.Columns["ID"].AutoIncrement = true;
                    dt.Columns["ID"].AutoIncrementSeed = 0;
                    dt.Columns["ID"].AutoIncrementStep = 1;
                    //TEST
                    foreach (Cell cell in rows.ElementAt(0))
                    {
                        dt.Columns.Add(GetCellValue(spreadSheetDocument, cell));
                    }
                    foreach (Row row in rows) //this will also include your header row...
                    {
                        DataRow tempRow = dt.NewRow();
                        /*Si inserisce columnIndex = 1 quando devi utilizzare
                          l'autoincrement sulla prima colonna (in questo caso ID)*/
                        int columnIndex = 1;
                        foreach (Cell cell in row.Descendants<Cell>())
                        {
                            // Gets the column index of the cell with data
                            int cellColumnIndex = (int)GetColumnIndexFromName(GetColumnName(cell.CellReference));
                            //cellColumnIndex--; //zero based index
                            if (columnIndex < cellColumnIndex)
                            {
                                do
                                {
                                    tempRow[columnIndex] = 1;
                                    columnIndex++;
                                }
                                while (columnIndex < cellColumnIndex);
                            }

                            tempRow[columnIndex] = GetCellValue(spreadSheetDocument, cell);

                            columnIndex++;
                        }
                        dt.Rows.Add(tempRow);
                    }
                }
                dt.Rows.RemoveAt(0); //rimuove la prima riga in cui ci sono le colonne

                //leggo le righe di una colonna specifica
                //string pippoRows = "";
                //for (int i = 0; i < dt.Rows.Count; i++)
                //{
                //    //pippoRows = Convert.ToInt32(dt.Rows[i]["PIPPO"]);
                //    pippoRows = Convert.ToString(dt.Rows[i]["PIPPO"]);
                //    //Similarly for QuantityInIssueUnit_uom.
                //}

                //TODO: Insert data in SQL Server
                var stringaConnessione = Properties.Settings.Default.connectionString;
                SqlConnection sqlcon = new SqlConnection();
                sqlcon.ConnectionString = stringaConnessione;
                SqlCommand sqlcmd = new SqlCommand("InserimentoDatiExcel", sqlcon);
                sqlcmd.CommandType = CommandType.StoredProcedure;

                //sqlcmd.Parameters.AddWithValue("@pippo", dt.Columns["PIPPO"].Container);
                sqlcmd.Parameters.AddWithValue("@product", dt);
                //sqlcmd.Parameters.Add(new SqlParameter("@pippo", dt.Columns["PIPPO"].ColumnMapping));
                sqlcon.Open();
                sqlcmd.ExecuteNonQuery();
                sqlcon.Close();

            }
            catch (Exception ex)
            {
            }
        }
        /// <summary>
        /// Given a cell name, parses the specified cell to get the column name.
        /// </summary>
        /// <param name="cellReference">Address of the cell (ie. B2)</param>
        /// <returns>Column Name (ie. B)</returns>
        public static string GetColumnName(string cellReference)
        {
            // Create a regular expression to match the column name portion of the cell name.
            Regex regex = new Regex("[A-Za-z]+");
            Match match = regex.Match(cellReference);
            return match.Value;
        }
        /// <summary>
        /// Given just the column name (no row index), it will return the zero based column index.
        /// Note: This method will only handle columns with a length of up to two (ie. A to Z and AA to ZZ). 
        /// A length of three can be implemented when needed.
        /// </summary>
        /// <param name="columnName">Column Name (ie. A or AB)</param>
        /// <returns>Zero based index if the conversion was successful; otherwise null</returns>
        public static int? GetColumnIndexFromName(string columnName)
        {

            //return columnIndex;
            string name = columnName;
            int number = 0;
            int pow = 1;
            for (int i = name.Length - 1; i >= 0; i--)
            {
                number += (name[i] - 'A' + 1) * pow;
                pow *= 26;
            }
            return number;
        }
        public static string GetCellValue(SpreadsheetDocument document, Cell cell)
        {
            SharedStringTablePart stringTablePart = document.WorkbookPart.SharedStringTablePart;
            if (cell.CellValue == null)
            {
                return "";
            }
            string value = cell.CellValue.InnerXml;
            if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
            {
                return stringTablePart.SharedStringTable.ChildElements[Int32.Parse(value)].InnerText;
            }
            else
            {
                return value;
            }
        }
    }
}

在您的第一个代码段中,您要插入ID列,该列是一个标识列(无法插入)。

您需要更新代码以不包括ID列。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM