【问题标题】:SQL - Write Query with field names and table name stored in a table?SQL - 使用存储在表中的字段名和表名编写查询?
【发布时间】:2014-05-07 02:07:00
【问题描述】:

我在一家保险公司工作并创建了一个自定义应用程序。当我们将承保范围应用于保单时,它会存储在具有限额、免赔额和保费字段的表中。但是,有许多保险不符合规范。它们对限额、免赔额和保费使用不同的字段,甚至存储在不同的表中。 (不要问为什么,甚至不要试图理解他们仍在这样做的事实,所以我需要留下逻辑以允许像这样的额外覆盖范围。)他们选择的领域也没有押韵或理由漂浮不定。

因此,我们决定创建“查找”表,用于存储覆盖范围所需的所有信息。这避免了许多连接——我们遇到了应用程序的速度和性能问题。

我需要找到一种方法将所有这些字段预填充到表格中。我想要性能方面的最佳选择。这最终将成为一项夜间作业——因此,当我们收到新的数据快照时,我们将运行此查询并预填充/更新表的值。

这是我的表的示例,它包含险种名称 (Coverage)、表 (File) 以及限额、免赔额和保费字段。 PolicyNum 字段是 LOB + Policy + Module 的串联。我需要所有这三个字段来加入策略。我想使用一个表格,因为他们将添加新的覆盖范围。请记住,我创建了这些表,因此可以向其中添加更多字段。

这是我的表格的创建脚本 - 我从 Excel 电子表格中填写它,因此将所有字段设置为 nVarChar(255) 以使该过程顺利运行:

USE [PolicySummary]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Coverage](
    [CoverageID] [int] IDENTITY(1,1) NOT NULL,
    [LOB] [nvarchar](255) NULL,
    [Coverage] [nvarchar](255) NULL,
    [Description] [nvarchar](255) NULL,
    [File] [nvarchar](255) NULL,
    [Limit] [nvarchar](255) NULL,
    [Deductible] [nvarchar](255) NULL,
    [Premium] [nvarchar](255) NULL,
    [IsMultLimit] [bit] NULL,
    [IsMultDeductible] [bit] NULL,
    [IsMultPremium] [bit] NULL,
    [InsuranceLine] [nvarchar](255) NULL,
    [PolicyNum] [nvarchar](255) NULL,
 CONSTRAINT [PK_Coverage] PRIMARY KEY CLUSTERED 
(
    [CoverageID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,     ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

因此,简而言之,保单的承保范围可能为 BP0713。然后我查看这个表,发现我需要运行以下查询: 选择 BYAGVA 作为限额,BYPPTX 作为自付额,BYA3VA 作为溢价 FROM ASBYCPP WHERE BYARTX+BYASTX+BYADNB = @PolNum

该表包含表名、3 个字段和策略编号的串联。

目前,我正在遍历策略中的每个覆盖范围,并在 WHLIE 循环中一次选择一个值。工作,但它很慢,我多次点击查询只是为了打开应用程序(每个策略有多个单元,因此将为每个单元运行)。

SELECT @SQL = N'SELECT @Limit=' + ISNULL(Limit, '''''') + N',@Deductible=' +     ISNULL(Deductible, '''''') + N',@Premium=' + ISNULL(Premium, '''''') + N' FROM PHI_PIJ.dbo.'     + [File] + N' WHERE ' + PolicyNum + N' = ''' + @PolNum +'''' + N' AND ' + @CovField +     N'='''+Coverage +''''
FROM PolicySummary.dbo.Coverage 
WHERE Coverage = @Coverage 
AND LOB = @LOB           

EXEC sp_executesql @SQL, N'@Limit nVarChar(255) output,@Deductible nVarChar(255)         output,@Premium nVarChar(255) output', @Limit output, @Deductible output, @Premium output

INSERT INTO #OptCov2 VALUES(@Coverage, @Description, @LOB, @Limit, @Deductible,     @Premium)

我是否可以帮助我找到一种方法来每晚填充我的“查找”表,所以我所要做的就是 从 CoverageLookUp 中选择限制、免赔额、溢价,其中 PolicyNum = @PolicyNum

我正在使用 Microsoft SQL Server Management Studio。

这是我到目前为止所得到的。运行前 1000 条记录需要将近 4 分钟,总共需要运行 614,497 条记录。

SELECT @SQL = N'SELECT @Limit=' + ISNULL(Limit, '''''') + N',@Deductible=' +   ISNULL(Deductible, '''''') + N',@Premium=' + ISNULL(Premium, '''''') + N'     FROM PHI_PIJ.dbo.ASBYCPP' + N' WHERE ' + PolicyNum + N' = ''' + @PolicyKey +'''' + N' AND BYAOTX' + N'='''+Coverage +''''
FROM PolicySummary.dbo.Coverage 
WHERE Coverage = @Coverage 
AND LOB = 'BOP'         

EXEC sp_executesql @SQL, N'@Limit nVarChar(255) output,@Deductible nVarChar(255) output,@Premium nVarChar(255) output', @Limit output, @Deductible output, @Premium output              

UPDATE PolicySummary.dbo.CoverageLkup
SET Limit = @Limit, Deductible = @Deductible, Premium = @Premium
WHERE CovAbbrev = @Coverage
AND PolicyKey = @PolicyKey

【问题讨论】:

  • 您能分享您从中提取的表的架构/布局吗?
  • 我从 Excel 电子表格中填写表格,因此最简单的方法是将所有字段设为 nVarChar(255) :) 我为上面的表格附加了我的创建脚本。
  • 我更新了问题以显示我目前使用的代码。这是我的循环中的一块。它可以工作,但速度很慢。

标签: sql sql-server-2008 while-loop dynamic-sql


【解决方案1】:

我意识到这可能并不完全是您所拥有的,但希望这会为您指明正确的方向。您肯定希望避免循环,尤其是对每个策略都这样做。

从易于更新的角度来看,我建议如下:

这是您的表格,其中包含表格名称和字段名称。它将用于构建您的 select 语句。此处每个表应该只有 1 条记录。

create table tableref (
  tablename nvarchar(255), 
  lobfield nvarchar(255), 
  policyfield nvarchar(255), 
  modulefield nvarchar(255),
  limitfield nvarchar(255), 
  deductfield nvarchar(255),
  premiumfield nvarchar(255))

现在创建您的 select 语句以从 tableref 的表中提取所有数据

declare @sql nvarchar(max) = '', @unionall nvarchar(50) = ''
select @sql = @sql + @unionall 
    + ' select ' + lobfield + '+' + policyfield + '+' + modulefield + ' as policynumber, ' 
    + limitfield + ' as limit, ' 
    + deductfield + ' as deduct, ' 
    + premiumfield + ' as premium '
    + ' from ' + tablename
  , @unionall = ' union all '
from tableref

最后但同样重要的是,将记录插入到查找表中

select @sql = 'insert into lookuptable (policynum, limit, deduct, premium) ' + @sql
exec (@sql)

要进行微调,请在适当的地方添加索引。此外,此解决方案将在 @sql 中的 8000 个字符后中断,因此根据您的情况,您可能需要将其中断。

【讨论】:

    【解决方案2】:

    我认为你是从错误的角度来解决这个问题的。我将您的计划表述为“创建一个映射表,您可以使用动态 SQL 路线图连接到源数据。”相反,我认为您应该将来自不同表的源数据复制到单个主查找表中。

    虽然这会“复制”数据,但它会导致更有效的查找。

    *copy:我最初写了replication,但我不认为Replication 是这里正确的技术。这可能是可能的,但它不是复制的预期用例。

    您需要一种不同类型的 ETL,可能是非常简单的作业或 SSIS(甚至触发器),以使您的查找主机与所有单独的部分保持同步。

    用没有意义的评论告诉我。或者,如果我似乎遗漏了什么。

    【讨论】:

      猜你喜欢
      • 2018-10-04
      • 1970-01-01
      • 2021-03-20
      • 2015-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-02
      • 2012-08-18
      相关资源
      最近更新 更多