【问题标题】:Cannot insert into table with types in SQL Server无法插入到带有 SQL Server 类型的表中
【发布时间】:2017-08-27 14:38:09
【问题描述】:

我有一个 C# 应用程序,我使用 type 插入到 SQL Server 表中:

CREATE TYPE [dbo].[taradodType] AS TABLE
(
    [IDP] [int] NULL,
    [date] [datetime] NULL,
    [day] [nvarchar](max) NULL,
    [nobatkari] [nvarchar](max) NULL,
    [code] [nvarchar](max) NULL
)

C#代码:

SqlConnection sqlconn = new SqlConnection(DBsetting.Connstring);
sqlconn.Open();

using (sqlconn)
{
    try
    {
        SqlCommand cmd = new SqlCommand("InsertTaradod", sqlconn);
        cmd.CommandType = CommandType.StoredProcedure;

        SqlParameter dtparam = cmd.Parameters.AddWithValue("@taradodType", dtreadd);
        dtparam.SqlDbType = SqlDbType.Structured;

        cmd.ExecuteNonQuery();

        MessageBox.Show("Saved!");
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

存储过程:

ALTER PROCEDURE [dbo].[InsertTaradod]
    @taradodType dbo.taradodType READONLY
AS
BEGIN
    INSERT INTO dbo.taradod 
        SELECT * FROM @taradodType
END

而且我不想在表中插入重复的行。所以我定义了一个不插入重复数据的索引。但是这里有一个问题。如果数据集合中只有 1 个重复行。没有插入任何数据,但我想插入其他不重复的数据

数据:

    1   2017-06-20 13:28:44 1   0   1   0
    4   2017-06-22 12:18:13 1   0   1   0
    2   2017-06-22 12:49:41 1   0   1   0
    3   2017-06-22 13:15:24 1   0   1   0
    1   2017-06-22 13:50:07 1   0   1   0
    3   2017-06-24 06:56:05 1   0   1   0
    1   2017-06-24 07:02:47 1   0   1   0
    5   2017-06-24 07:29:37 1   0   1   0
    7   2017-06-24 13:18:57 1   0   1   0
    6   2017-06-24 13:19:00 1   0   1   0
    8   2017-06-24 13:19:03 1   0   1   0
    5   2017-06-24 13:19:07 1   0   1   0
    3   2017-06-24 14:35:14 1   0   1   0
    1   2017-06-24 14:38:04 1   0   1   0
    3   2017-06-25 06:45:24 1   0   1   0
    2   2017-06-25 06:54:48 1   0   1   0
    1   2017-06-25 06:56:02 1   0   1   0
    5   2017-06-25 07:51:32 1   0   1   0
    6   2017-06-25 07:57:25 1   0   1   0
    7   2017-06-25 07:57:30 1   0   1   0
    8   2017-06-25 07:57:34 1   0   1   0
    2   2017-06-25 13:03:55 1   0   1   0
    5   2017-06-25 13:26:34 1   0   1   0
    6   2017-06-25 13:32:56 1   0   1   0
    8   2017-06-25 13:33:07 1   0   1   0
    7   2017-06-25 13:33:10 1   0   1   0
    1   2017-06-25 14:38:51 1   0   1   0
    3   2017-06-25 14:39:21 1   0   1   0
    4   2017-06-28 06:44:48 1   0   1   0
    3   2017-06-28 06:45:48 1   0   1   0
    1   2017-06-28 06:59:51 1   0   1   0
    5   2017-06-28 07:21:28 1   0   1   0
    9   2017-06-28 07:38:38 1   0   1   0
    8   2017-06-28 07:49:19 1   0   1   0
    6   2017-06-28 08:11:29 1   0   1   0
    7   2017-06-28 08:11:34 1   0   1   0
    8   2017-06-28 13:32:17 1   0   1   0
    9   2017-06-28 13:32:20 1   0   1   0
    7   2017-06-28 13:32:23 1   0   1   0
    6   2017-06-28 13:32:27 1   0   1   0
    5   2017-06-28 13:32:42 1   0   1   0
    4   2017-06-28 14:17:00 1   0   1   0
    3   2017-06-28 14:43:18 1   0   1   0
    1   2017-06-28 15:27:57 1   0   1   0
    4   2017-06-29 06:28:16 1   0   1   0
    1   2017-06-29 06:55:45 1   0   1   0
    3   2017-06-29 06:55:53 1   0   1   0
    5   2017-06-29 07:34:44 1   0   1   0
    8   2017-06-29 07:55:54 1   0   1   0
    6   2017-06-29 07:55:57 1   0   1   0
    9   2017-06-29 07:56:01 1   0   1   0
    7   2017-06-29 08:00:26 1   0   1   0
    9   2017-06-29 12:57:04 1   0   1   0
    7   2017-06-29 12:57:12 1   0   1   0
    8   2017-06-29 12:57:15 1   0   1   0
    6   2017-06-29 12:57:33 1   0   1   0
    5   2017-06-29 12:57:54 1   0   1   0
    4   2017-06-29 13:01:06 1   0   1   0
    3   2017-06-29 13:31:41 1   0   1   0
    1   2017-06-29 13:31:50 1   0   1   0
    4   2017-07-01 06:27:33 1   0   1   0
    2   2017-07-01 06:50:55 1   0   1   0
    3   2017-07-01 06:51:52 1   0   1   0
    1   2017-07-01 07:02:29 1   0   1   0
    5   2017-07-01 07:18:49 1   0   1   0
    9   2017-07-01 07:27:00 1   0   1   0
    8   2017-07-01 07:27:03 1   0   1   0
    7   2017-07-01 07:52:45 1   0   1   0
    6   2017-07-01 07:52:47 1   0   1   0
    2   2017-07-01 12:54:23 1   0   1   0
    7   2017-07-01 13:32:05 1   0   1   0
    8   2017-07-01 13:32:15 1   0   1   0
    9   2017-07-01 13:32:37 1   0   1   0
    6   2017-07-01 13:32:52 1   0   1   0
    4   2017-07-01 13:32:58 1   0   1   0
    5   2017-07-01 13:33:07 1   0   1   0
    1   2017-07-01 14:32:01 1   0   1   0
    3   2017-07-01 14:32:32 1   0   1   0
    4   2017-07-02 06:27:25 1   0   1   0
    3   2017-07-02 06:47:46 1   0   1   0
    1   2017-07-02 07:00:37 1   0   1   0
    2   2017-07-02 07:00:42 1   0   1   0
    5   2017-07-02 07:11:05 1   0   1   0
    8   2017-07-02 07:23:47 1   0   1   0
    9   2017-07-02 07:23:55 1   0   1   0
    7   2017-07-02 07:34:37 1   0   1   0
    6   2017-07-02 07:34:39 1   0   1   0
    2   2017-07-02 13:00:14 1   0   1   0
    8   2017-07-02 13:22:30 1   0   1   0
    9   2017-07-02 13:22:34 1   0   1   0
    6   2017-07-02 13:23:09 1   0   1   0
    7   2017-07-02 13:23:23 1   0   1   0
    5   2017-07-02 13:26:15 1   0   1   0
    4   2017-07-02 14:05:00 1   0   1   0
    3   2017-07-02 14:56:15 1   0   1   0
    1   2017-07-02 15:27:23 1   0   1   0
    4   2017-07-03 06:33:45 1   0   1   0
    1   2017-07-03 07:04:39 1   0   1   0
    5   2017-07-03 07:15:34 1   0   1   0
    6   2017-07-03 08:37:04 1   0   1   0
    7   2017-07-03 08:37:07 1   0   1   0
    8   2017-07-03 09:59:10 1   0   1   0
    9   2017-07-03 09:59:14 1   0   1   0
    8   2017-07-03 13:59:10 1   0   1   0
    9   2017-07-03 13:59:25 1   0   1   0
    5   2017-07-03 13:59:33 1   0   1   0
    7   2017-07-03 13:59:42 1   0   1   0
    6   2017-07-03 13:59:46 1   0   1   0
    4   2017-07-03 14:05:22 1   0   1   0
    1   2017-07-03 14:35:43 1   0   1   0
    4   2017-07-04 06:28:15 1   0   1   0
    2   2017-07-04 06:46:19 1   0   1   0
    1   2017-07-04 07:06:26 1   0   1   0
    3   2017-07-04 07:10:29 1   0   1   0
    5   2017-07-04 07:18:38 1   0   1   0
    8   2017-07-04 07:55:10 1   0   1   0
    9   2017-07-04 07:55:14 1   0   1   0
    1   2017-07-04 07:55:42 1   0   1   0
    7   2017-07-04 07:57:51 1   0   1   0
    6   2017-07-04 07:57:54 1   0   1   0
    1   2017-07-04 08:57:36 1   0   1   0

索引位于IDdatetime

【问题讨论】:

  • 为什么不将SELECT * FROM @taradodType 查询更改为过滤器,只选择不同的行进行插入。
  • 否。问题是 taradodType 中没有重复的行。我的意思是表中有该行,当它想要插入 taradodType 中的重复数据时,它不能,也没有可以插入,因为只有 1 个重复行

标签: c# sql-server sql-insert user-defined-types


【解决方案1】:

您的插入命令正在像批处理一样执行。

您的整个类型被传递到 SQL Server 存储过程,并作为要插入的批处理执行。

在存储过程的INSERT 语句中,添加NOT EXISTS 检查,如下所示:

INSERT INTO dbo.taradod 
    SELECT Distinct * 
    FROM @taradodType a 
    WHERE NOT EXISTS (SELECT 1 
                      FROM dbo.taradod 
                      WHERE IDP = a.IDP 
                        AND Code = a.Code
                        ...and other conditions which decide duplicate rows for you.)

或者,您可以从@taradodType 中删除已经存在于dbo.taradod 中的行,然后执行您的插入语句。

【讨论】:

    【解决方案2】:

    您似乎在dbo.taradod 中已经有一些数据,并且在从@taradodType 插入新数据时,您想过滤掉dbo.taradod 中已经存在的行。

    您可以尝试像这样选择查询:

    SELECT * FROM @taradodType t1
    left outer join dbo.taradod  t2 on t1.IDP = t2.IDP
            and t1.date = t2.date
    where t2.IDP is null
    

    【讨论】:

      【解决方案3】:

      最简单的解决方法...在定义索引时只需使用 IGNORE_DUP_KEY = ON 选项。

      CREATE UNIQUE NONCLUSTERED INDEX ixu_IndexName ON dbo.taradodType (IDP)
      WITH (DROP_EXISTING = ON, IGNORE_DUP_KEY = ON) ON [PRIMARY];
      

      遇到欺骗时不会抛出错误,而是简单地省略有问题的数据行并像什么都没发生一样继续前进。

      HTH,杰森

      【讨论】:

      • 那么 DROP_EXISTING 会在这里做什么?
      • 您无法更改现有索引。它们必须被删除并重新创建。 DROP_EXISTING = ON 只是自动处理 DROP INDEX 部分......它完全是可选的。
      猜你喜欢
      • 2013-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-22
      • 1970-01-01
      • 2018-01-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多