首页 > 解决方案 > 如何通过 SQL Server 插入的索引有效地替换长字符串?

问题描述

我有一个非常大的DataTable对象,我需要通过 ODBC 从客户端将其导入 MS SQL-Server 数据库。

原始数据表有两列:*第一列是Office Location(相当长的字符串)*第二列是booking value(整数)

现在我正在寻找将这些数据插入外部 SQL-Server 的最有效方法。我的目标是用索引自动替换每个办公室位置,而不是使用完整的字符串,因为每个位置都经常出现在初始表中。

这可以通过触发器还是通过 SQL 服务器上的视图来实现?

最后,我想在脚本中插入数据而不触及它们,因为这对于这些大量数据来说非常慢,并且让 SQL Server 完成优化。

我希望如果我插入包含 Office 位置的数据,SQL Server 会查找已导入位置的索引,然后仅使用该索引。如果索引表/视图中不存在该位置,则应在此处创建一个新条目,然后使用新索引。

这是我需要通过 ODBC 导入 SQL-Server 的数据示例:

OfficeLocation             | BookingValue
EU-Germany-Hamburg-Ostend1 | 12
EU-Germany-Hamburg-Ostend1 | 23
EU-Germany-Hamburg-Ostend1 | 34
EU-France-Paris-Eifeltower | 42
EU-France-Paris-Eifeltower | 53
EU-France-Paris-Eifeltower | 12

结果,我在 SQL-Server 上需要的是类似于以下 2 个表的内容:

OId|BookingValue      OfficeLocation             |Oid
  1|12                EU-Germany-Hamburg-Ostend1 | 1
  1|23                EU-France-Paris-Eifeltower | 2
  1|43
  2|42
  2|53
  2|12

我最初的想法是,将数据写入临时表并使用智能触发器(或视图?)之类的东西对任何插入到该表中的内容做出反应,以创建 2 个所需的(优化的)表。

任何提示都非常受欢迎!

标签: sql-serverstringreplaceviewtriggers

解决方案


是的,您可以创建一个带有INSERT触发器的视图来处理这个问题。就像是:

CREATE TABLE dbo.Locations (
    OId int IDENTITY(1,1) not null PRIMARY KEY,
    OfficeLocation varchar(500) not null UNIQUE
)
GO
CREATE TABLE dbo.Bookings (
    OId int not null,
    BookingValue int not null
)
GO
CREATE VIEW dbo.CombinedBookings
WITH SCHEMABINDING
AS
    SELECT
        OfficeLocation,
        BookingValue
    FROM
        dbo.Bookings b
            INNER JOIN
        dbo.Locations l
            ON
                b.OId = l.OId
GO
CREATE TRIGGER CombinedBookings_Insert
ON dbo.CombinedBookings
INSTEAD OF INSERT
AS
    INSERT INTO Locations (OfficeLocation)
    SELECT OfficeLocation
    FROM inserted where OfficeLocation not in (select OfficeLocation from Locations)

    INSERT INTO Bookings (OId,BookingValue)
    SELECT OId, BookingValue
    FROM
          inserted i
              INNER JOIN
          Locations l
              ON
                  i.OfficeLocation = l.OfficeLocation

如您所见,我们首先将任何缺失的位置添加到位置表中,然后填充预订表。

类似的触发器可以处理更新。我通常会让 Locations 表增长,而不是尝试用触发器清理它(对于不再引用的位置)。如果增长是一个问题,定期工作通常就足够了。

请注意,某些工具(例如批量插入)可能不会调用触发器,因此这些工具无法用于上述视图。


推荐阅读