简体   繁体   English

操作数类型冲突:nvarchar与用户定义的表类型不兼容

[英]Operand type clash: nvarchar is incompatible with user-defined table type

I'm new here and I'm facing a trouble currently, my scenario is that I wanted to insert and update data from Excel into a SQL Server table. 我是新来的人,目前正遇到麻烦,我的情况是我想将Excel中的数据插入并更新到SQL Server表中。

For the insert part it works perfectly but when it comes to update I have no idea how should I do that. 对于插入部分,它可以完美工作,但是在进行更新时,我不知道该怎么做。 I have search for few methods and I found this is the most comfortable for me by using stored procedure. 我搜索了几种方法,发现使用存储过程对我来说最舒适。

Here is my code that I'm using now. 这是我现在正在使用的代码。 When I try it gave me this error: 当我尝试它给我这个错误:

Operand type clash: nvarchar is incompatible with user-defined table type 操作数类型冲突:nvarchar与用户定义的表类型不兼容

--- Stored procedure ---
CREATE PROCEDURE [dbo].[chkUpdate]
    @Operator IC_CHK READONLY
AS
BEGIN
    set nocount on;

    MERGE INTO tb_Operator c1
    USING @Operator c2 ON c1.IC = c2.IC

    WHEN MATCHED THEN
      UPDATE SET
            c1.Name = c2.Name,
            --c1.IC = c2.IC,
            c1.Email = c2.Email,
            c1.Status = c2.Status,
            c1.Datetime = c2.Datetime

    WHEN NOT MATCHED THEN
      INSERT VALUES(c2.Name, c2.IC, c2.Email, c2.[Status], c2.[Datetime]);
end

--- User-defined table type ---
CREATE TYPE [dbo].[IC_CHK] as table 
(
    [Id] [int] NULL,
    [Name] [nvarchar](50) NULL,
    [IC] [bigint] NULL,
    [Email] [nvarchar](MAX) NULL,
    [Status] [nvarchar](50) NULL,
    [Datetime] [datetime] NULL
)

VS 2010 code: VS 2010代码:

protected void btnImport_Click1(object sender, EventArgs e)
{
    int i = 0;

    try
    {
        string path = string.Concat(Server.MapPath("~/Excel/" + UploadExcel.FileName));
        UploadExcel.SaveAs(path);

        String strCon = string.Format("Provider=Microsoft.Ace.OLEDB.12.0;Data Source={0}; Extended Properties=Excel 12.0;",path);
        OleDbDataAdapter myda = new OleDbDataAdapter("SELECT * FROM [sheet1$]", strCon);

        DataTable myds = new DataTable();
        myda.Fill(myds);

        for (i = 0; i <= myds.Rows.Count - 1; i++)
        {
            String constr = ConfigurationManager.ConnectionStrings["conn"].ConnectionString;

            using (SqlConnection con = new SqlConnection(constr))
            using (SqlCommand cmd = new SqlCommand("chkUpdate"))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Connection = con;

                cmd.Parameters.AddWithValue("@Operator", path);

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

        MsgBox1.alert("Import success");
        View.Visible = true;

        vBinds();
    }
    catch (Exception ex)
    {
        MsgBox1.alert(ex.Message);
    }
}

Do check for me and I'm appreciate it. 帮我检查一下,我很感激。 Thank you 谢谢

P/S: I double confirm that my user-defined table type has the same data type with my table. P / S:我再次确认用户定义的表类型与表具有相同的数据类型。

In the INSERT in your MERGE statement, I would recommend to explicitly define the columns you're inserting into. 建议您在MERGE语句中的INSERT中, 明确定义要插入的列。 Most likely, that's the cause of the error - you're inserting your columns - but you're not specifying which target columns those should be inserted into. 这很可能是导致错误的原因-您正在插入列-但未指定应将目标列插入哪些目标列。

Since you're not specifying that, you must supply values for each column in the table, in the exact order in which they are defined - is that really the case?? 由于指定,您必须按照定义它们的确切顺序为表中的每一列提供值-确实是这样吗? Eg what do you insert into your ID column in the table?? 例如,您要在表格的ID列中插入什么?

Assuming the ID column on your actual database table is an IDENTITY column, I would use (otherwise, you'd have to list ID in the list of columns to insert into as well and provide a value in the VALUES list of values): 假设实际数据库表上的ID列是IDENTITY列,我将使用(否则,您还必须在要插入的列列表中列出ID并在VALUES列表中提供一个值):

WHEN NOT MATCHED THEN
  INSERT(Name, IC, Email, [Status], [DateTime])
  VALUES(c2.Name, c2.IC, c2.Email, c2.[Status], c2.[Datetime]);

and I would also recommend not to use T-SQL reserved keywords like status or datetime as your column names - you're just asking for trouble doing so. 并且我还建议不要使用statusdatetime类的T-SQL保留关键字作为您的列名 -您这样做只是在麻烦。 Use more expressive names - something that really relates to your business domain - not just datetime ..... 使用更具表现力的名称-与您的业务领域确实相关的名称-而不仅仅是datetime .....

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

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