【问题标题】:Operand type clash: nvarchar is incompatible with user-defined table type操作数类型冲突:nvarchar 与用户定义的表类型不兼容
【发布时间】:2015-10-20 07:50:05
【问题描述】:

我是新来的,目前遇到了麻烦,我的情况是我想将 Excel 中的数据插入和更新到 SQL Server 表中。

对于插入部分,它可以完美运行,但是在更新时我不知道该怎么做。我已经搜索了一些方法,我发现这对我来说是使用存储过程最舒服的。

这是我现在正在使用的代码。当我尝试时,它给了我这个错误:

操作数类型冲突: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 代码:

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);
    }
}

请帮我检查一下,我很感激。谢谢

P/S:我再次确认我的用户定义表类型与我的表具有相同的数据类型。

【问题讨论】:

  • 您应该查看Can we stop using AddWithValue() already? 并停止使用.AddWithValue() - 它可能会导致意想不到和令人惊讶的结果...
  • 您将数据加载到DataTable,如果您想传递表值参数,这是正确的做法。然后你忽略它,而是将字符串 path 传递到数据的来源,而不是传递你的 DateTable 对象。
  • @Damien_The_Unbeliever 谢谢我刚刚注意到。

标签: c# sql-server visual-studio-2010 stored-procedures


【解决方案1】:

MERGE 语句中的INSERT 中,我建议明确 定义要插入的列。最有可能的是,这就是错误的原因 - 您正在插入列 - 但您没有指定应该插入的哪些目标列。

由于您没有指定,因此您必须按照准确顺序为表中的每一列提供值被定义-真的是这样吗?例如。你在表的ID 列中插入了什么??

假设您的实际数据库表上的 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]);

还建议不要使用 T-SQL 保留关键字,如 statusdatetime 作为你的列名 - 你只是自找麻烦这样做。使用更具表现力的名称 - 与您的业务领域真正相关的名称 - 不仅仅是 datetime.....

【讨论】:

  • 感谢您的建议,我已修复错误。我会自己解决刚刚发现的错误;)
猜你喜欢
  • 2015-10-21
  • 2021-09-01
  • 2013-08-08
  • 1970-01-01
  • 2019-11-19
  • 2020-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多